跳到主要内容

CentOS docker 修改默认镜像存储路径

· 阅读需 7 分钟

环境:CentOS-7,docker 1.13.1。记录一次修改 docker 默认镜像存储路径的完整踩坑过程。

(注意自己的系统与 docker 的版本,请务必看完文章之后再操作,不然后果自负)

docker 默认的镜像存储路径为 /var/lib/docker。我们一般不会采用默认的存储位置,因为镜像文件通常较大,搭建的服务越多,宿主机系统盘的压力就越大,而且每个镜像还有自己的挂载卷等等,这些不在本文的讨论范围。所以不应把数据存放在系统盘上,应切换到对应的数据盘路径。

修改存储路径

进入正题:修改 docker 的配置文件 /usr/lib/systemd/system/docker.service

添加 graph 配置 --graph="your path" \,修改保存之后重新加载配置文件并重启 docker 服务:

# 重新加载 systemd 配置
systemctl daemon-reload
# 重启 docker 服务
systemctl restart docker.service

执行 docker info 查看 docker 服务的当前信息:

Docker Root Dir 显示为 "your path",说明配置成功。建议下载个镜像之后,去对应文件夹里查看是否生效;之后再 reboot 重启服务器,看 docker 里面的镜像是否还在。

docker images 执行之后,如果发现下载的镜像消失了。

恭喜你,和我的情况一样,你可能会怀疑人生。再执行 docker info,发现 Docker Root Dir 的路径并没有问题。这里我的做法是删除掉原来的 /var/lib/docker 文件夹。当然在删除之前,如果你还想要里面的数据,建议先 copy 一份再删除,或者直接移动文件夹并换个名称,不换名称也无所谓,重要的是让 /var/lib/docker 不复存在。之后你再试一试,我想就应该没问题了,至少我是如此。

追记:重启后镜像又消失了(2019-06-16)

本以为是配置好了的,结果事情果然没有那么简单,毕竟我对 docker 的了解还不够多。

这次服务器供应商突然修复服务器的硬件设备,导致大部分服务器强制关机(所以还是不要贪便宜买杂牌云服务器)。我的服务器也关机了,修复好之后服务器重启,我发现我的博客仍然不能访问。我设置的是 docker 开机自启、容器跟随启动,然而好像并没有生效,自然需要去排查问题所在。(我上次真的以为已经配置好了,结果好像被打脸了)

登录服务器之后执行 docker images,发现镜像又像上次一样没了。说明上次那样操作其实并没有真正解决问题——准确地说,配置是生效了的,但随着宿主机重启,配置就出现了问题。

虽然 docker info 下看到的 Docker Root Dir 路径没问题,但其实已经出了故障:执行 docker images 和 docker ps -a 均没有任何信息。而且此时如果执行 service docker stop 关闭 docker 服务,你就再也启动不了 docker 了。执行 service docker start 启动时会报错:

Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.

就算按提示执行 systemctl status docker.service、journalctl -xe 查看错误详情,也根本看不出个所以然。想要看到具体的错误信息,可以直接前台启动 docker 守护进程,就能看到启动日志,从里面排查错误:

# 前台启动 docker 守护进程,直接输出启动日志
dockerd

存储驱动的坑

我在排查这个错误的途中学习到了很多知识,比如 docker 的 5 种存储驱动模式:

简书:https://www.jianshu.com/p/00ffd8df6010

别人的博客:https://blog.csdn.net/qq_34018840/article/details/89853119

AUFS、Btrfs、Device mapper、OverlayFS、ZFS

最后我选择了 OverlayFS 的升级版本 Overlay2。而我原来的驱动模式是 Device mapper——执行 docker info 时最下面有个提示信息,告诉我 Device mapper 这个模式只是测试环境下自动选择的,生产环境可以自行切换。这更加坚定了我切换 Overlay2 的想法,不过我没有着急切换,先继续排查这个神奇的现象:宿主机重启之后,为啥 docker 读取不到 /home/docker_data 下的镜像文件呢?

我在 google、百度、github、知乎、帖子、简书、官方文档里都找不到这个问题,最后在 docker 的官方社区里发现有个外国佬出现了和我差不多的情况。他们讨论说这是版本问题,我就寻思着,好吧,看来要装个新点的版本。

于是彻底删除 docker 之后重新安装(注意:docker 从 1.13 版本之后采用时间线的方式作为版本号,分为社区版 CE 和企业版 EE):

# 彻底卸载旧版本 docker
yum remove docker
yum remove docker-selinux

重新装了 docker-ce-17.12.0.ce 版本(听说是比较稳定的版本),并配置了 /etc/docker/daemon.json

启动 docker,发现我的 linux 内核不能支持 overlay2 存储驱动方式,于是升级了内核,需要 4.0 以上的内核才可以支持。

之后执行 docker info,又有提示告诉我磁盘不支持 d_type。我又去格式化了挂载盘,格式化为 ftype=1 的 xfs:

# 查看文件系统信息,ftype=1 表示支持 d_type
xfs_info /home

并配置 docker 默认的镜像存储位置到这块支持 d_type 的数据挂载盘,重启 docker。

再执行 docker info 就没有任何警告信息了,d_type 已开启,存储方式也修改为了 overlay2。

我感觉这次已经很完美了,毕竟执行 docker info 都没有任何警告。我立刻下载了个 tomcat 镜像,发现镜像已经放在指定的文件夹,太好了!我立刻执行 reboot 重启宿主机。

重启之后 docker images 镜像又没了!!!

我是谁,我在干什么,我做了这么多都是在干嘛?

我真的是服了,不知道我哪一步做错了什么。

最终解决

最后我是这样解决的:把数据盘直接挂载到 /var/lib/docker 这个文件夹下,并设置开机自动挂载,同时删除了 /etc/docker/daemon.json 中 data-root 的配置。

之后宿主机再重启,执行 docker images 就看见了我的镜像,容器也自动启动了起来。这次就算断电、关机都不怕了,宿主机重启后 docker 会自动启动容器。

但之后我换用阿里云服务器,什么事情都没有,一切正常,所以可能还是硬件问题。

小结

修改镜像存储路径看似只是加一个 --graph 参数的事,实际却牵扯出存储驱动、内核版本、文件系统 d_type 支持等一连串问题。折腾一圈后,我的最终方案是反其道而行:不改 docker 的路径配置,直接把数据盘挂载到 /var/lib/docker 并设置开机自动挂载,重启后镜像和容器都能正常恢复。如果你也遇到重启后镜像丢失的情况,可以优先排查存储驱动与磁盘挂载的时序问题,也不排除是廉价服务器本身的硬件毛病。选云服务商这件事,还是别太贪便宜。

评论 / COMMENTS