Docker容器硬盘动态扩容

Posted 云上的天涯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker容器硬盘动态扩容相关的知识,希望对你有一定的参考价值。

扩容容器

docker容器默认的空间是10G,如果想指定默认容器的大小(在启动容器的时候指定),可以在docker配置文件里通过dm.basesize参数指定,比如

1
docker -d --storage-opt dm.basesize=20G

是指定默认的大小为20G,具体参数可以参考https://github.com/docker/docker/tree/master/daemon/graphdriver/devmapper

上面方法只是真的生成容器的时候进行的,并且修改后需要重启docker,无法做到动态给运行容器指定大小,下面我介绍一下如何动态的扩展容器空间大小。

动态扩展的优点:

1、不需要修改docker配置,并且重启docker服务;

2、可以直接对运行中的容器进行动态扩展(只能增,无法缩);

缺点:

1、docker所在宿主机分区的格式必须是ext2、ext3、ext4;

2、docker存储引擎必须是devicemapper

 

 

首先,我们来创建容器。我们不需要在这个容器里运行任何东西,只需要这个文件(或者关联的文件系统)存在。为了演示,我们会在这个容器里运行 df ,来看一下根文件系统的大小。

 

$ docker run -d ubuntu df -h /
4ab0bdde0a0dd663d35993e401055ee0a66c63892ba960680b3386938bda3603

 

由于需要修改 Device Mapper 管理中的一些卷的信息,我们现在用 root 的身份来运行一些命令。所有以#开头的命令都必须以 root 身份来执行。只要能访问 Docker 的 Socket 服务,你也可以用普通用户的身份来执行其他的命令(以$开头)。

 

让我们看一下 /dev/mapper ,那里应该有一个对应容器文件系统的符号链接,以 docker-X:Y-Z- 开头:

 

# ls -l /dev/mapper/docker-*-4ab0bdde0a0dd663d35993e401055ee0a66c63892ba960680b3386938bda3603
lrwxrwxrwx 1 root root 7 Jan 31 21:04 /dev/mapper/docker-0:37-1471009-4ab0bdde0a0dd663d35993e401055ee0a66c63892ba960680b3386938bda3603 -> ../dm-8

 

注意记住那个全名,我们未来会用到。

 开始扩容:

1、首先让我们来看一下当前卷的信息表:

# dmsetup table docker-0:37-1471009-4ab0bdde0a0dd663d35993e401055ee0a66c63892ba960680b3386938bda3603
0 20971520 thin 254:0 7

第二个数字是设备的大小,表示有多少个 512-bytes 的扇区. 这个值略高于 10GB 的大小。

 

2、我们来计算一下一个 20GB 的卷需要多少扇区,

 $ echo $((20*1024*1024*1024/512))

41943040

 

精简快照目标的一个神奇的特点是它不会限制卷的大小。当你创建它的时候,一个精简的卷使用0个块,当你开始往块里面写入的时候,它们会从共用的块池中进行分配。你可以写0个块,或者是10亿个块,这个和精简快照目标没关系。文件系统的大小只和 Device Mapper 表有关系。

 

觉得困惑?不要担心。我们只是需要装载一个新的表,这个完全和之前的是一样的,但是有更多的扇区。仅此而已

 

3、旧表是 0 20971520 thin 254:0 7 。我们会改变第个数字,要非常小心保持其他的值不变。你的卷可能不是 7 ,所以要使用正确的值!

这样操作:

# echo 0 41943040 thin 254:0 7 | dmsetup load docker-0:37-1471009-4ab0bdde0a0dd663d35993e401055ee0a66c63892ba960680b3386938bda3603

4、现在如果我们再次检查表的信息,步骤和前面一样。首先使用下面的命令激活新表: 

# dmsetup resume docker-0:37-1471009-4ab0bdde0a0dd663d35993e401055ee0a66c63892ba960680b3386938bda3603

执行完命令后,再次检查一下表的信息,发现它会使用新的扇区数量。

5、我们已经调整了块设备的大小,但是我们仍然需要调整文件系统的大小,我们使用 xfs_growfs 来操作:

(网上很多说到的resize2fs后来看到xfs方式的使用dumpe2fs,该命令在16.04下可能出现文件正在使用或者找不到超级块的错误,)

# xfs_growfs docker-0:37-1471009-4ab0bdde0a0dd663d35993e401055ee0a66c63892ba960680b3386938bda3603

至此,docker动态容器扩容成功。

 6、停止该容器后,无法重新启动 
当容器扩容之后,由于dm认为设备块大小仍然为之前设置的初始大小,所以会发生无法起启动的情况,这时只要重新进行扩容操作即可。

$ docker start test#必须要先启动一下,让其生成dm文件才能修改。  即生成 /dev/mapper/docker-* --> /dev/dm-*
#此时会报错,不要理会,执行以下操作即可
$ echo 0 41943040 thin 252:0 9 | dmsetup load docker-253:1-131179-a835d492b6864a13eb11eddd17c3cabf5226f20bc01fbfe90964d80112a0df69
$ dmsetup resume docker-253:1-131179-a835d492b6864a13eb11eddd17c3cabf5226f20bc01fbfe90964d80112a0df69

 

 -----------------------------------------------------------------------------------------------------------------------------

已经测试的脚本如下:

复制代码

#!/bin/bash 
#This script is dynamic modify docker container disk 
if [ -z $1 ] || [ -z $2 ]; then
echo "Usage: container_name increase_capacity"
echo "Example: I want increase 11G to test"
echo "The command is: sh `basename $0` test 11"
exit 1 
fi
if [ `docker inspect $1 &>>/dev/null && echo 0 || echo 1` -eq 1 ];then
echo "The container $1 is no exist!"
exit 1 
fi
devicename=`docker inspect -f \'{{ .GraphDriver.Data.DeviceName }}\' $1` 
now_disk=`dmsetup table /dev/mapper/$devicename|awk \'{print $2}\'` 
disk=$(($2*1024*1024*1024/512)) 
if [ $disk -lt $now_disk ];then
echo "I can\'t shink container $1 from $(($now_disk*512/1024/1024/1024))G to ${2}G!I only modify contanier increase disk!"
exit 1 
fi
dmsetup table /dev/mapper/$devicename|sed "s/0 [0-9]* thin/0 $disk thin/"|dmsetup load /dev/mapper/$devicename 
dmsetup resume /dev/mapper/$devicename
xfs_growfs /dev/mapper/$devicename
if [ $? -eq 0 ];then
echo "dynamic container $1 disk to ${2}G is success!"
else
echo "dynamic container $1 disk to ${2}G is fail!"
fi

复制代码

 

例如给test容器进行动态增加到20G空间

# sh dynamic_modify_docker_disk.sh wjoyxt 20 

容器重启后,会发生报错,此时再运行一次该脚本进行重新扩容(空间大小要等于或大于之前的设置,出现报错不用管),再启动容器即可。 

 

 

参考资料:http://dl528888.blog.51cto.com/2382721/1606170

以上是关于Docker容器硬盘动态扩容的主要内容,如果未能解决你的问题,请参考以下文章

Docker容器学习梳理-容器硬盘热扩容

docker 容积硬盘扩容小坑一个

docker硬盘扩容脚本

linux rhel虚拟机中如何给磁盘动态扩容(增加硬盘)

docker容器overlay存放目录磁盘空间已满(解决)

docker mysql 容器报too many connections 引发的liunx磁盘扩容操作