docker 容器备份与迁移
有时在 docker 中产生的数据,我们需要进行相应的备份和迁移到另一台服务器上,并在另一台服务器上进行数据恢复,docker 容器备份与迁移是在 docker 的镜像层级操作,我们介绍了三种容器备份与迁移的方法:
- 离线迁移
- DockerHub
- 私有镜像仓库
首先我们需要将需要备份的容器打包成镜像。假设我们有一个容器,名为 nvidia/cuda:11.6.0-cudnn8-devel-ubuntu18.04
,首先停止容器:
1 | docker stop nvidia_cuda |
使用 docker commit
命令将该容器打包成镜像
1 | docker commit -m "nvidia_cuda" nvidia_cuda my_container:1.0 |
可以看到我们生成的镜像信息,已成功制作镜像 my_container:1.0
离线迁移
镜像文件经常有在服务器之间传输的需求,为此 docker 提供了镜像打包和镜像加载的命令,docker save
命令可将镜像打包成 tar
压缩文件,使用示例
1 | docker save -o my_container:1.0.tar my_container:1.0 |
在当前目录下能生成 7.8G 的镜像压缩包 my_container:1.0.tar
之后需要将文件传输到其它主机上,在局域网内可实现高速传输,在压缩包所在目录打开 http
端口
1 | python3 -m http.server 9000 |
监听服务器的 9000 号端口,如果显示端口被占用,换一个数字即可。
在浏览器中输入10.24.83.40:9000
,找到我们的镜像压缩文件 my_container:1.0.tar
,右键复制链接地址
在另一台主机上执行
1 | wget ${刚才复制的地址} |
文件开始传输(如果卡住刷新下浏览器就行,这种端口映射不支持并行传输)
至此,镜像压缩文件从一台主机传输到了另一台主机,之后需要从tar文件载入镜像。
docker load
命令可以从tar文件载入镜像,执行示例:
1 | docker load -i my_container:1.0.tar |
查看镜像是否添加进 docker 里面:
然后使用 docker run
创建容器
1 | docker run -it --gpus all --name my_container -v /mnt/data:/data -p 40000:40000 -p 40001:40001 -p 9000:22 my_container:1.0 /bin/bash |
可能能用上的参数说明:
- –gpus:容器内能使用GPU
- –name:容器名称
- -v:文件挂载,通常需要将主机上的机械硬盘目录挂载进容器内
- -p:端口映射,9000:22表示将容器的22号端口映射到主机的9000号端口,用于容器的Shell连接,40000:40000表示将容器的40000号端口映射到主机的40000的端口,便于容器的局域网络服务
容器启动成功:
在主机上运行设置容器自启动
1 | docker start my_container |
Docker Hub
我们可以将自己制作的 docker 镜像发布至 DockerHub 公共仓库,需要科学上网才能进入,使用这种方式的核心命令:
docker push
:用于将本地 docker 镜像上传到远程仓库,让其它用户可以使用docker pull
:用于从 DockerHub 或其它镜像仓库中下载镜像到本地 docker 环境
首先注册一个 DockerHub 账号,然后 docker login
命令使用 docker ID 和密码登录:
推送镜像至仓库,我们将 my_container:1.0
镜像拉取至本地,然后再上传至 DockerHub 仓库中:
1 | docker tag my_container:1.0 lizhongliang123/my_container:1.0 |
可以看到镜像已经被push上去了:
我们在另一台主机上拉取镜像,测试镜像能否被拉取
1 | docker pull lizhongliang123/my_container:1.0 |
使用完退出当前账号登录
1 | docker logout |
后续容器的构建可以参考离线迁移后半部分的内容。
私有镜像仓库
像 DockerHub、阿里云这样的公共镜像仓库有时候用起来不太方便,DockerHub 网速太慢,阿里云需要花钱买云主机;另外,涉及内部资源的保密性,有的机构不太可能将镜像提供给公网,因此需要创建一个基于内部项目的镜像,构造本地私人仓库供给团队使用。因此,docker 提供了 docker-registry 工具,可以用于构建私有镜像仓库。
docker-registry
工具也是个 docker 镜像,它的功能就是用于创建私服版的 DockerHub,使用 docker-compose
部署带有图形界面的 docker-registry
,首先编写 credentials.yml
:
1 | mkdir registry-ui |
设置容器开机自启动,文件的内容为:
1 | version: '2.0' |
新建鉴权配置文件:
1 | mkdir registry-config |
配置文件内容为:
1 | version: 0.1 |
添加密码文件,需要安装 passwd
:
1 | sudo apt install apache2-utils |
然后执行
1 | htpasswd -Bbn admin admin > ./registry-config/htpasswd |
启动Registry服务:
1 | docker-compose -f credentials.yml up -d |
registry 映射到了 8080 号端口,访问 http://localhost:8080/ 即可访问镜像仓库,默认用户名为 admin
,密码为 admin
接下来需要向镜像仓库推送镜像,首先登录,用户名为 admin
,密码为 admin
1 | login后面如果不加地址默认是登录DockerHub |
一个bug:输入用户名和密码后出现错误
解决方法:https://blog.csdn.net/qcdh1234/article/details/100639420,但是它是docker-compose的依赖库,需要login的时候就remove,不需要的时候就装回去:
1 | # docker login |
接下来就是镜像推送,以registry镜像为例
首先打标签
1 | docker tag registry:latest 10.24.83.22:8080/registry:latest |
然后就可以推送镜像了
1 | docker push 10.24.83.22:8080/registry:latest |
在局域网主机上使用docker pull可以从私有仓库中拉取镜像,在拉取镜像前,由于私服采用的是http协议,默认不被Docker信任,需要进行配置,改为https协议,使用docker pull的主机都需要修改
1 | 打开docker配置文件 |
然后使用docker pull从私有仓库中拉取镜像
1 | docker pull 10.24.83.22:8080/registry:latest |
鉴权
若要修改用户名和密码,执行以下命令
1 | htpasswd -Bbn admin admin > ./registry-config/htpasswd |
指定需要修改的用户名和密码。
清空
删除镜像在网页端操作,如果某个repos下面一个镜像都没有,需要采用删除文件夹的方式将0镜像的repos去除,镜像文件夹存储位置/mnt/data/registry/docker/registry/v2/repositories/
。
批量删除打标签10.24.83.22:8080”的镜像
1 | docker rmi $(docker images | grep 10.24.83.22:8080 | awk '{name=$1":"$2;print name}') |