docker 文档 Select a storage driver 中推荐按照下面的顺序选择 storage driver:
aufs
btrfs,zfs
overlay2
overlay
devicemapper
docker还支持vfs,也就是直接存文件。各种 storage driver 的特点如下:
Name Type Storage-opt
-----------------------------------------
aufs 基于文件 不支持
btrfs 基于块 支持
zfs 基于块 支持
overlay2 基于文件 基于 XFS 时支持
overlay 基于文件 不支持
devicemapper 基于块 支持
–storage-opt 是 docker run
时的参数,支持设定容器的根文件系统的大小,注意和 docker daemon 的storage-driver-options 参数区分。
docker run -it --storage-opt size=120G fedora /bin/bash
docker run 中提示:
This (size) will allow to set the container rootfs size to 120G at creation time.
This option is only available for the devicemapper, btrfs, overlay2, windowsfilter
and zfs graph drivers. For the devicemapper, btrfs, windowsfilter and zfs graph
drivers, user cannot pass a size less than the Default BaseFS Size. For the overlay2
storage driver, the size option is only available if the backing fs is xfs and
mounted with the pquota mount option. Under these conditions, user can pass any size
less then the backing fs size.
卸载已有的 docker 并清理残余文件:
systemctl stop docker
for i in `rpm -qa |grep docker`;do yum erase $i;done
rm -rf /var/lib/docker
如果是 device mapper,重建lvs:
lvremove /dev/mapper/docker-thinpool
lvcreate -T -L 95g -n thinpool docker
从 docker download 中下载最新的 rpm,安装最新的 docker:
yum install -y ./XXX.rpm
docker 的配置核实无错后启动:
systemctl start docker
chkconfig docker on
创建一个名为 docker 的 vg、一个名为 thinpool 的 thin。
pvcreate /dev/vdc1
vgcreate docker /dev/vdc1
lvcreate -T -L 95g -n thinpool docker
在 /etc/docker/daemon.json 中配置 storage-driver 和 storage-opts:
{
"hosts": ["unix:///var/run/docker.sock"],
"storage-driver": "devicemapper",
"storage-opts": ["dm.basesize=10G",
"dm.thinpooldev=/dev/mapper/docker-thinpool",
"dm.use_deferred_removal=true",
"dm.use_deferred_deletion=true"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "20m",
"max-file": "10"
}
}
overlay2 的使用参考 overlay2 限制单个容器可用存储空间。
升级内核:
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
yum -y --enablerepo=elrepo-kernel install kernel-ml
修改 /etc/default/grub:
GRUB_DEFAULT=0
执行命令更新 grub2 配置:
grub2-mkconfig -o /boot/grub2/grub.cfg
格式化并挂载用于 docker 的磁盘,格式化时必须指定 ftype=1,挂载时必须使用 pquota:
pvcreate /dev/vdc1
vgcreate docker /dev/vdc1
lvcreate -L 95g -n graph docker
mkfs.xfs -f -n ftype=1 /dev/mapper/docker-graph
mount -o pquota /dev/mapper/docker-graph /var/lib/docker/
在 /etc/fstab 中添加配置,保证开机时自动挂载:
/dev/mapper/docker-graph /var/lib/docker/ xfs defaults,pquota 1 1
编辑 /etc/docker/daemon.json,指定 storage-driver 和 storage-opts。在CentOS上使用 overlay2,必须添加 opts “overlay2.override_kernel_check=true”:
{
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
docker overlayfs 会改变两个系统调用的行为,如果应用用到这两个系统调用需要注意:
open(2): 同一个文件修改之后的再次 open 得到文件句柄指向的是另一个文件。下面的 fd1和fd2将指向两个不同的文件,fd1指定的 lower layer 中的foo 文件,fd2 指向的复制到 upperdir 中的 foo 文件。
fd1=open("foo", O_RDONLY) //修改foo之前
fd2=open("foo", O_RDONLY) //修改foo之后
rename(2): overlayfs 不支持 rename 系统调用。
docker btrfs 中建议在 ubuntu 和 debian 上使用 btrfs:
Docker CE: For Docker CE, btrfs is only recommended on Ubuntu or Debian.
Docker EE: For Docker EE and CS-Engine, btrfs is only supported on SLES.
测试机器如下:
Node OS Kernel Docker Driver
-----------------------------------------------------------------------
10.39.0.114 CentOS7.2.1511 3.10.0 1.12.6 device mapper
10.39.0.115 CentOS7.2.1511 3.10.0 17.06 device mapper
10.39.0.137 CentOS7.2.1511 4.12.2 17.06 overlay2
docker run --name=test-default -idt harbor.enncloud.cn/lijiaob/sshproxy:master
docker exec -it test-default /bin/sh
df
Node Result
---------------------------------------------
10.39.0.114(device mapper) dockerd 配置的默认大小,10G
10.39.0.115(device mapper) dockerd 配置的默认大小,10G
10.39.0.137(overlay2) /var/lib/docker中剩余可用空间
docker run --name=test-default -idt --storage-opt size=0M harbor.enncloud.cn/lijiaob/sshproxy:master
docker exec -it test-default /bin/sh
df
Node Result
---------------------------------------------
10.39.0.114(device mapper) dockerd 配置的默认大小,10G
10.39.0.115(device mapper) dockerd 配置的默认大小,10G
10.39.0.137(overlay2) /var/lib/docker中剩余可用空间
docker run --name=test-default -idt --storage-opt size=1M harbor.enncloud.cn/lijiaob/sshproxy:master
docker exec -it test-default /bin/sh
df
Node Result
---------------------------------------------
10.39.0.114(device mapper) 创建失败,不能小于dockerd指定的默认大小
10.39.0.115(device mapper) 创建失败,不能小于dockerd指定的默认大小
10.39.0.137(overlay2) 1M
docker run --name=test-default -idt --storage-opt size=200G harbor.enncloud.cn/lijiaob/sshproxy:master
docker exec -it test-default /bin/sh
df
dd if=/dev/zero of=/test.dat bs=1G count=200
Node Result
---------------------------------------------
10.39.0.114(device mapper) 显示可用200G,dd命令写满真实可用空间后,卡住
10.39.0.115(device mapper) 显示可用200G,dd命令写满真实可用空间后,卡住
10.39.0.137(overlay2) 现实/var/lib/docker中剩余可用空间,dd命令写满后退出
docker run --name=test-default-1 -idt --storage-opt size=50G harbor.enncloud.cn/lijiaob/sshproxy:master
docker run --name=test-default-2 -idt --storage-opt size=50G harbor.enncloud.cn/lijiaob/sshproxy:master
docker run --name=test-default-3 -idt --storage-opt size=50G harbor.enncloud.cn/lijiaob/sshproxy:master
docker run --name=test-default-4 -idt --storage-opt size=50G harbor.enncloud.cn/lijiaob/sshproxy:master
Node Result
---------------------------------------------
10.39.0.114(device mapper) 创建成功,均显示设置的可用空间
10.39.0.115(device mapper) 创建成功,均显示设置的可用空间
10.39.0.137(overlay2) 创建成功,均显示设置的可用空间
容器执行执行真实写入:
docker exec -idt test-default-1 bash -c "sleep 10; dd if=/dev/zero of=/test.dat bs=1G count=40"
docker exec -idt test-default-2 bash -c "sleep 10; dd if=/dev/zero of=/test.dat bs=1G count=40"
docker exec -idt test-default-3 bash -c "sleep 10; dd if=/dev/zero of=/test.dat bs=1G count=40"
docker exec -idt test-default-4 bash -c "sleep 10; dd if=/dev/zero of=/test.dat bs=1G count=40"
docker exec -it test-default-1 ls -lh /test.dat
docker exec -it test-default-2 ls -lh /test.dat
docker exec -it test-default-3 ls -lh /test.dat
docker exec -it test-default-4 ls -lh /test.dat
Node Result
---------------------------------------------
10.39.0.114(device mapper) 状态异常,node 空间接近饱和后,容器内的写入几乎不再增长,响应迟钝,docker 重启失败
10.39.0.115(device mapper) 状态异常,node 空间接近饱和后,容器内的写入几乎不再增长,响应迟钝,docker 重启卡住
10.39.0.137(overlay2) node 空间写满后,每个容器显示还有空余空间,但无法再写入
docker run --name=test-default -idt --storage-opt size=15G harbor.enncloud.cn/lijiaob/sshproxy:master
Node Result
---------------------------------------------
10.39.0.114(device mapper) 创建失败,提示空间不足
10.39.0.115(device mapper) 创建失败,提示空间不足
10.39.0.137(overlay2) 可以创建,显示设置的可用空间,但实际无法继续写入
docker run --name=test-default -idt --storage-opt size=11G harbor.enncloud.cn/lijiaob/sshproxy:master
docker exec -it test-default /bin/sh
df
dd if=/dev/zero of=/test.dat bs=1G count=200
Node Result
---------------------------------------------
10.39.0.114(device mapper) 超过11G后,dd程序退出
10.39.0.115(device mapper) 超过11G后,dd程序退出
10.39.0.137(overlay2) 超过11G后,dd程序退出
device mapper:
优势: 可以在容器的配置文件中指定每个容器的默认的大小
以块设备的形式挂载到容器中,遵循 posix 协议
劣势: 容器大小不能小于默认的大小
node 的实际存储空间接近 100% 时,docker 不能正常工作
kernel 日志中经常出现 device mapper 的 thin 删除失败日志
node 上的存储耗尽时,容器内的程序感知不到,会卡住
overlay2:
优势: 在存储空间 100% 的情况下,docker 仍能很好的运行
劣势: 必须明确指定容器的大小,否则就默认使用所有可用空间
以文件merge的方式的提供,不严格遵守posix中的read()定义,不支持posix中定义的rename()
kubernetes 不支持指定容器的大小,需要修改 kubelet 或者修改 docker