docker容器默认的空间是10G, Pool 大小默认是100G.
查看 docker 信息 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 > docker info Containers: 3 Running: 3 Paused: 0 Stopped: 0 Images: 2 Server Version: 1.12.1 Storage Driver: devicemapper Pool Name: docker-253:0-117441065-pool Pool Blocksize: 65.54 kB Base Device Size: 107.4 GB Backing Filesystem: xfs Data file: /dev/loop0 Metadata file: /dev/loop1 Data Space Used: 18.32 GB Data Space Total: 107.4 GB Data Space Available: 89.05 GB Metadata Space Used: 12.45 MB Metadata Space Total: 2.147 GB Metadata Space Available: 2.135 GB Thin Pool Minimum Free Space: 10.74 GB Udev Sync Supported: true Deferred Removal Enabled: false Deferred Deletion Enabled: false Deferred Deleted Device Count: 0 Data loop file: /var/lib/docker/devicemapper/devicemapper/data WARNING: Usage of loopback devices is strongly discouraged for production use. Use `--storage-opt dm.thinpooldev` to specify a custom block storage device. Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata Library Version: 1.02.107-RHEL7 (2016-06-09) Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: host bridge overlay null Swarm: inactive Runtimes: runc Default Runtime: runc Security Options: seccomp Kernel Version: 3.10.0-327.28.3.el7.x86_64 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 CPUs: 6 Total Memory: 7.624 GiB Name: mobile-quality ID: NG64:K27K:ASGU:MCBI:NPOZ:Y554:5HME:3INM:UAMI:IIWC:ZQT5:ZKO6 Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ WARNING: bridge-nf-call-iptables is disabled WARNING: bridge-nf-call-ip6tables is disabled Labels: provider=generic Insecure Registries: 127.0.0.0/8
Data Space Total: 107.4 GB
这个就是默认的 Pool 大小
调整 container 大小 新 container 的调整 如果想指定默认容器的大小(在启动容器的时候指定),可以在docker配置文件里通过dm.basesize参数指定
直接使用 docker 命令启动服务 1 docker -d --storage-opt dm.basesize=20G
使用 systemctl 命令启动服务 对于使用 systemctl
管理的docker服务, 可以编辑 systemctl 的启动脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 > vim /etc/systemd/system/docker.service [Unit] Description=Docker Application Container Engine After=network.target [Service] Type=notify ExecStart=/usr/bin/docker daemon -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --registry-mirror=http://8843165a.m.daocloud.io --storage-driver devicemapper --tl sverify --tlscacert /etc/docker/ca.pem --tlscert /etc/docker/server.pem --tlskey /etc/docker/server-key.pem --label provider=generic --storage-opt dm.basesize=20G ExecReload=/bin/kill -s HUP MountFlags=slave LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TimeoutStartSec=0 Delegate=yes KillMode=process Environment= [Install] WantedBy=multi-user.target
以上方式适用于新 run 起来的 container, 会获取到新的空间
已存在的 container 的调整 查看所有的虚拟磁盘信息 1 2 3 4 5 6 7 8 9 10 > dmsetup status docker-253:0-117441065-pool: 0 209715200 thin-pool 39 3039/524288 279539/1638400 - rw discard_passdown queue_if_no_space - docker-253:0-117441065-bb21427f81836c96a53e7cf0ee97c9e907104ad1ce4d8f2bdade4bbfc0fdd5f5: 0 20971520 thin 17858688 209715199 docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e: 0 20971520 thin 19820928 209715199 docker-253:0-117441065-c57286b3ae5bc1bd675573902d043754aba23349306fd3a52bcd74eed5d144cb: 0 20971520 thin 2968320 209715199 centos-swap: 0 3358720 linear centos-root: 0 29163520 linear centos-root: 29163520 71294976 linear centos-root: 100458496 104849408 linear centos-root: 205307904 209707008 linear
最上面4条开头写着 docker 的虚拟磁盘就是我们即将操作的对象
其中可以明显的看出, 第一条中带有 pool
的字样, 没错, 这个就是 docker 默认的 pool 大小,现在我们要调整 container 的大小, 暂时不管 pool 的默认配置
其余的三条磁盘信息就是当前宿主机中, 起来的 container 使用的虚拟磁盘, 如果你需要指定其中一个来调整, 那么你需要找到虚拟磁盘和 container name 或 container id 的对应关系, 不要搞错!
对应关系可以使用 docker exec -it xxxx /bin/bash
进入到 container 中使用df -h
命令查看根分区的虚拟磁盘名称 也可以在 linux 中使用 docker inspect xxx
来查看 xxx 容器的详细信息
找到了它们的对应关系之后, 接下来就可以对其调整大小了
找到映射的虚拟磁盘 默认情况下, 所有的虚拟磁盘的映射都在/dev/mapper/
下
1 2 3 4 5 6 7 8 9 > ls -l total 0 lrwxrwxrwx 1 root root 7 Dec 7 01:45 centos-root -> ../dm-0 lrwxrwxrwx 1 root root 7 Dec 7 01:45 centos-swap -> ../dm-1 crw------- 1 root root 10, 236 Dec 7 01:45 control lrwxrwxrwx 1 root root 7 Dec 7 02:20 docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e -> ../dm-3 lrwxrwxrwx 1 root root 7 Dec 7 02:21 docker-253:0-117441065-bb21427f81836c96a53e7cf0ee97c9e907104ad1ce4d8f2bdade4bbfc0fdd5f5 -> ../dm-4 lrwxrwxrwx 1 root root 7 Dec 7 02:30 docker-253:0-117441065-c57286b3ae5bc1bd675573902d043754aba23349306fd3a52bcd74eed5d144cb -> ../dm-5 lrwxrwxrwx 1 root root 7 Dec 7 01:49 docker-253:0-117441065-pool -> ../dm-2
从上面👆的回显也可以看出实际指向的虚拟磁盘文件(是不是有点绕, 这个文件只不过是虚拟磁盘的软连接而已)
接下来我们需要对其进行扩容操作
第一步: 查看指定虚拟磁盘的容量信息 1 2 > dmsetup table docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e 0 20971520 thin 253:2 25
第二步: 计算所需的容量(扇区数量) 假设你想要的容量为 20G
则该值应该为: 20*1024*1024*1024/512
= 41943040
验算: 20G 的值 41943040 = 默认10G 的值 20971520 *2
公式为: x*1024*1024*1024/512
第三步: 挂起虚拟磁盘 1 > dmsetup suspend docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e
没有回显, 没有消息就是好消息😆
第四步: 写入新参数并重新加载进去 1 > dmsetup reload docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e --table '0 41943040 thin 253:2 25'
把上一步计算出来的值, 覆盖到第一步的回显对应的位置中
第五步: 激活挂起的虚拟磁盘 1 > dmsetup resume docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e
如果执行到这一步的时候报错:
1 2 device-mapper: resume ioctl on docker-253:0-1700-pool failed: Invalid argument Command failed
先不要慌, 稍等片刻, 再重新执行
注意: 由于挂起操作会阻塞住所有的 IO, 为了尽快完成扩容, 我们一般把第三四五步骤用一行命令去执行
1 2 3 > dmsetup suspend docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e \ && dmsetup reload docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e --table '0 41943040 thin 253:2 25' \ && dmsetup resume docker-253:0-117441065-17379f89f95efb5bafb234d95e0e0dfe549f7ba48fbed69c0111e2ea39c0106e
第六步: 为磁盘扩容 1 2 3 > mount /dev/dm-3 /mnt > xfs_growfs /mnt > umount /mnt
需要先挂载再扩容
调整 pool 大小 调整 pool 大小不同于调整 container 的大小, 需要先对其虚拟文件进行扩容, 再对虚拟磁盘扩容
到这里涉及到了三个概念:
虚拟文件大小 —> 硬盘大小/PV/VG
虚拟硬盘设备 —> LV/file system
软连接 —> alias 别名
虚拟硬盘设备是基于虚拟文件的, 就好像我们使用的 lvm 卷, 虚拟硬盘设备就相当于 lv 或是说就相当于我们正在使用的文件系统; 而 docker 中的虚拟文件就好比我们物理机的硬盘, 或是说 PV 与 VG 的大小
在物理服务器中, 磁盘空间不足的话, 我们可以增加硬盘, 条带化成 PV, 再填入到 VG 池中, 然后分配给对应的 LV, 再对其扩容
在 docker 中, 磁盘空间不足的话(pool 不足的话), 我们可以扩充虚拟文件, 然后让虚拟硬盘设备扩容
查看 pool 文件大小信息 1 2 3 4 > ls -lh /var/lib/docker/devicemapper/devicemapper/ total 244M -rw-------. 1 root root 100G Dec 8 18:27 data -rw-------. 1 root root 2.0G Dec 8 18:24 metadata
可以看到 data 是100G 大小, 不要担心他实际占用了100G, 这个是精简配置, 实际用多少就占多少空间, 最大100G
第一步: 给文件扩容 上面看到的 data 文件有100G 的大小, 现在我需要200G 的 pool 大小, 所以需要调整 data 文件的属性
1 truncate -s 214748364800 /var/lib/docker/devicemapper/devicemapper/data
第二步: 检查大小 1 2 3 4 > ls -lh /var/lib/docker/devicemapper/devicemapper/ total 244M -rw-------. 1 root root 200G Dec 8 18:35 data -rw-------. 1 root root 2.0G Dec 8 18:24 metadata
第三步: Reload data loop device 1 2 3 4 5 > blockdev --getsize64 /dev/loop0 107374182400 > losetup -c /dev/loop0 > blockdev --getsize64 /dev/loop0 214748364800
第四步: Reload devicemapper thin pool 第四步基本就是重复上面扩容 container 的步骤, 这里省略了前几步的查看和计算
1 2 3 > dmsetup suspend docker-253:0-1700-pool \ && dmsetup reload docker-253:0-1700-pool --table '0 419430400 thin-pool 7:1 7:0 128 32768 1 skip_block_zeroing' \ && dmsetup resume docker-253:0-1700-pool
注意 扩容 pool 涉及到了两个计算
data 文件大小的计算
devicemapper 扇区数量的计算
上面已经给出了扇区的计算公式: x*1024*1024*1024/512
data 大小的计算公式为: x*1024*1024*1024
参考文档:
https://docs.docker.com/engine/userguide/storagedriver/device-mapper-driver/#/increase-capacity-on-a-running-device https://segmentfault.com/a/1190000002931564 http://www.linuxidc.com/Linux/2015-01/112245.htm http://www.projectatomic.io/blog/2016/03/daemon_option_basedevicesize/