一、场景

服务器突然出现使用cd + tab功能的时候,提示磁盘空间不足。就使用df -h 查看磁盘空间,看到如下图,根目录被占满的情况:

[root@ecs-8f49 ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        7.8G     0  7.8G   0% /dev
tmpfs           7.8G     0  7.8G   0% /dev/shm
tmpfs           7.8G   73M  7.7G   1% /run
tmpfs           7.8G     0  7.8G   0% /sys/fs/cgroup
/dev/vda1        40G   40G   1k  100% /
tmpfs           1.6G     0  1.6G   0% /run/user/0
/dev/mapper/huawei-lun2p1     16T  5.8T  9.8T   38% /stor2

如上图,根目录下的40G都已经使用完毕,如果再进行其他程序的运行,很可能导致程序的终止。所以需要排查哪个目录占用空间比较大。使用如下命令可以一层层进行目录排查:

sudo du -lh --max-depth=1

从根目录一层层排查,发现/var/lib/docker目录占用了15G的空间,而且dpcker目录可以人工干预进行数据的迁移。那。。。就干吧

说明:中间的很多展示数据有虚构,就别太计较了。。。

二、/var/lib/docker 目录迁移

1、查看docker自身的内存占用
docker system df
[root@ecs-8f49 ~]# docker system df
TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
Images              16                  12                  2.893 GB            1.535 GB (53%)
Containers          12                  1                   155.6 MB            155.6 MB (100%)
Local Volumes       1                   1                   4.212 GB            0 B (0%)
2、【可跳过】若需要清理磁盘,请进入

如果需要清理磁盘,删除关闭的容器,无用的数据卷和网络,以及dangling镜像(即无tag的镜像),使用如下命令:

docker system prune

日志:

WARNING! This will remove:
 - all stopped containers
 - all volumes not used by at least one container
 - all networks not used by at least one container
 - all dangling images
 Are you sure you want to continue? [y/N] y
 Deleted Containers:
 9bd48276fcd28b3882605fd67a156a7ea848f8fbfe16c3588b630955dfda253d
 74af4504bdefbc58b83a476c12d6ce10260f91349eed0e5bfca5e51b86fb8474
 d405d43eeb7908472b4b8712f668ca3b97f3796f6afc1c1d19a15879140ddf64
 9f645670de22840d04249351d07b2f68f77754e4dfebdb4b39c56d827d6b6805
 79d32c6b3c34bb359cbbf8309d7be34074da391d3b48083f456a5911259a5213
 ad7137d7e018144e17790a3c86a8217a95faecd07a39003bc4df275c8c8d351d
 b02eb42677a52663e50fc4a2b1344d37a8d2a2cca445fe5eae49648a0ca54b13
 0813454a5421cf380b72265c2e6832411a590479424dbc3470e47e1cc9cdd740
 a58b5f545ce1cd03a2899ba277641b5f52203802d9672c72f281f2d5a31fc219
 936e65f72c60d754cb2a1441d0cdeb18f9a7ebde353f091fc44a034733fed52c
 ad86565bd85af04f5847703ba213d226c7d7b69e5210211e4170671d3ea4051cDeleted Volumes:
37620879ca58c052c47e7677a1851f45c25cbc0437c8883cc2fe8e70e1cb921a

Total reclaimed space: 4.368 GB

还有个清理更加彻底的命令:

docker system prune -a

可以将没有容器使用Docker镜像都删掉。
注意,这两个命令会把你暂时关闭的容器,以及暂时没有用到的Docker镜像都删掉了…所以使用之前一定要想清楚.。
我没用过,因为会清理 没有开启的 Docker 镜像。

3、迁移/var/lib/docker目录。
(1)停止docker服务
systemctl stop docker
(2)迁移/var/lib/docker目录下面的文件到 /home/docker/lib

创建迁移的目录,我的迁移目录为/stor2/docker,
(rsync是linux文件夹同步的命令,参数要加一个-r,因为文件夹要递归copy,如果在同一台服务器上面,直接cp也是可以的)

mkdir -p /stor2/docker
rsync -r -avz /var/lib/docker /stor2/docker/lib/
(3)配置 /etc/systemd/system/docker.service.d/devicemapper.conf。

查看 devicemapper.conf 是否存在。如果不存在,就新建目录和文件。

mkdir -p /etc/systemd/system/docker.service.d/
vi /etc/systemd/system/docker.service.d/devicemapper.conf

在打开的文件中,输入如下内容:
注:–graph= /stor2/docker/lib/docker 中,黑体部分替换为迁移目录路径。

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --graph=/stor2/docker/lib
(4)重新加载docker
systemctl daemon-reload	# 重载

  systemctl restart docker	# 重启

  systemctl enable docker	# 开机自动重启
(5)确认是否迁移成功

为了确认一切顺利,运行

docker info

查看内容如下:


Docker Root Dir: /stor2/docker/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false

如上图发现,docker root dir已经迁移成功。
至此,大功告成,当然,为确保万一,可以使用如下命令,查看镜像和容器是否还在,当然也可以启动容器或者新建容器。

docker ps -a # 查看所有容器
docker images # 查看所有镜像
...

三、参考资料

1、docker的存储目录迁移

四、报错解决

1、若迁移成功后,在docker start 旧容器的时候,出现如下的报错:

Error response from daemon: driver failed programming external connectivity on endpoint mysql (e3464a0363cbbf6ce7091deda6978ee53b0e68e9463831bea5d20bc7ded055e1): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 9023 -j DNAT --to-destination 172.19.0.5:3306 ! -i br-d4450ddbb06a: iptables: No chain/target/match by that name.
 (exit status 1))
 Error: failed to start containers: mysql

那么,只需要重启docker即可:

sudo systemctl restart docker

解决。

2、特殊情况,如果上述操作完成后,重启docker服务,发现docker images中的内容仍然为空,那么尝试添加如下内容:

sudo vi /etc/docker/daemon.json

{
  。。。
  "data-root": "/www/docker"
}

重启,即成功。