JobPlus知识库 IT 大数据 文章
Docker容器硬盘热扩容-centos6

今天这里梳理下docker容器空间扩展的操作。默认情况下,docker容器的空间是10G。在实际生产环境下,对docker容器进行热扩容(动态扩容)是非常重要的一个需求。

[html] 

  1. Docker容器动态扩展的优点:  
  2. 1)不需要修改docker配置,不需要重启docker服务;  
  3. 2)可以直接对运行中的容器进行动态扩展(只能增,无法缩);  
  4.     
  5. Docker容器动态扩展的条件:  
  6. 1)docker所在宿主机分区的格式必须是ext2、ext3、ext4;  
  7. 2)docker存储引擎必须是devicemapper  
  8. ---------------------------------------------------------------------------------------------------------------------------  
  9. 这里需要说明一下我在实际操作中遇到的问题:  
  10. 以下Docker容器动态扩容的操作步骤,我在centos7上操作是不可行的!  
  11. xfs是CentOS7的默认文件系统类型,可以在centos7系统安装时手动指定所在分区为ext4格式。但即使这样,创建容器后,发现容器的/分区仍然是xfs格式!  
  12. 就是说centos7下宿主机分区已改为ext4,但容器还是xfs。这就导致后面的容器扩展失败!(使用resize2fs或xfs_growfs都不行)  
  13. 具体原因不明  


下面的操作均是在centos6下操作的:

[html] 

  1. 宿主机分区的格式是ext4  
  2. [root@localhost ~]# df -hT  
  3. Filesystem     Type   Size  Used Avail Use% Mounted on  
  4. /dev/sda3      ext4   193G  103G   80G  57% /  
  5. tmpfs          tmpfs   32G     0   32G   0% /dev/shm  
  6. /dev/sda1      ext4   194M   79M  106M  43% /boot  
  7. /dev/sda2      ext4   721G  136G  549G  20% /home  
  8.    
  9. 1)下载私有仓库里的镜像(centos6和centos7下的docker命令和配置还是有所不同的)  
  10. [root@localhost ~]# vim /etc/sysconfig/docker  
  11. ......  
  12. other_args='--insecure-registry=192.168.1.23:5000'  
  13. .....  
  14.    
  15. [root@localhost ~]# service docker restart  
  16. Stopping docker:                                           [  OK  ]  
  17. Starting docker:                                           [  OK  ]  
  18.      
  19. [root@localhost ~]# docker pull 192.168.1.23:5000/tomcat7  
  20. latest: Pulling from 192.168.1.23:5000/tomcat7  
  21. 3690474eb5b4: Pull complete  
  22. 0a444b299d5a: Pull complete  
  23. a04895de1996: Pull complete  
  24. 08e1d80f2b80: Pull complete  
  25. fa7cc393f68b: Pull complete  
  26. Digest: sha256:b28f263bb8d5de3c93d64e85a5e9ee5cd6a1042f45ecbb951888d897d99e14e2  
  27. Status: Downloaded newer image for 192.168.1.23:5000/tomcat7:latest  
  28.    
  29. [root@localhost ~]# docker images  
  30. REPOSITORY                  TAG                 IMAGE ID            CREATED             VIRTUAL SIZE  
  31. 192.168.1.23:5000/tomcat7   latest              fa7cc393f68b        2 weeks ago         562.3 MB  
  32.    
  33. 2)创建容器  
  34. [root@localhost ~]# docker run -ti -d --name my-test -p 8998:8080 192.168.1.23:5000/tomcat7 /bin/bash  
  35. 813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3  
  36.    
  37. [root@localhost ~]# docker ps  
  38. CONTAINER ID        IMAGE                       COMMAND             CREATED             STATUS              PORTS                    NAMES  
  39. 813389572d7f        192.168.1.23:5000/tomcat7   "/bin/bash"         29 seconds ago      Up 28 seconds       0.0.0.0:8998->8080/tcp   my-test  
  40.    
  41. [root@localhost ~]# docker exec -ti my-test /bin/bash  
  42. [root@813389572d7f /]# df -HT  
  43. Filesystem                                                                                      Type   Size  Used Avail Use% Mounted on  
  44. /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 ext4    9.9G  703M  8.7G   8% /  
  45. tmpfs                                                                                           tmpfs   34G     0   34G   0% /dev  
  46. shm                                                                                             tmpfs   68M     0   68M   0% /dev/shm  
  47. /dev/sda3                                                                                       ext4   207G  111G   86G  57% /etc/hosts  
  48.    
  49. 注意  
  50. 容器my-test的大小为默认的10G。  
  51. 上面命令结果中的/dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3文件就是my-test容器存储的文件名。  
  52.    
  53. 3)--------------下面开始进行容器空间的动态扩容------------------  
  54.    
  55. 使用dmsetup查看该文件扇区信息.下面命令结果中的第二个数字(即20971520)是设备的大小,表示有多少个 512-bytes 的扇区. 这个值略高于 10GB 的大小。  
  56. [root@localhost ~]# dmsetup table /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3  
  57. 0 20971520 thin 253:0 13  
  58.    
  59. 计算20G所需扇区数目  
  60. [root@localhost ~]# echo $((20*1024*1024*1024/512))  
  61. 41943040  
  62.    
  63. 精简快照目标的一个神奇的特点是它不会限制卷的大小。当创建它的时候,一个精简的卷使用0个块,当开始往块里面写入的时候,它们会从共用的块池中进行分配。  
  64. 可以写0个块,或者是10亿个块,这个和精简快照目标没关系。文件系统的大小只和Device Mapper表有关系。  
  65. 只需要装载一个新的表,这个完全和之前的是一样的,但是有更多的扇区。仅此而已。  
  66.      
  67. 将新的扇区大小写入,注意只是改变旧表中的第二个数字20971520的数字,其他数字不变!  
  68. [root@localhost ~]# echo 0 41943040 thin 253:0 13 | dmsetup load /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3  
  69.    
  70. 将修改后的容器存储文件激活  
  71. [root@localhost ~]# dmsetup resume /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3  
  72.    
  73. 重新查看文件信息  
  74. [root@localhost ~]# dmsetup table /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3  
  75. 0 41943040 thin 253:0 13  
  76.    
  77. 更改文件系统大小,使变更生。  
  78. [root@localhost ~]# resize2fs /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3  
  79. resize2fs 1.41.12 (17-May-2010)  
  80. Filesystem at /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 is mounted on /var/lib/docker/devicemapper/mnt/813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3; on-line resizing required  
  81. old desc_blocks = 1, new_desc_blocks = 2  
  82. Performing an on-line resize of /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 to 5242880 (4k) blocks.  
  83. The filesystem on /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 is now 5242880 blocks long.  
  84.    
  85. ------------------------------------------------------------------------------------------------------------------  
  86. 如果这一步出现下面报错:  
  87. resize2fs 1.42.9 (28-Dec-2013)  
  88. resize2fs: 设备或资源忙 当尝试打开 /dev/mapper/docker-253:0-268868570-2163383f446357876b301fb3942b706436b5eea111c06a3acba0006ec5272372 时找不到有效的文件系统超级块.  
  89.    
  90. 原因是resize2fs仅能支持ext2、ext3、ext4,不支持xfs。将docker服务器的文件系统格式调整为ext4即可。  
  91. 本文操作机是centos6系统,分区都是ext4格式,故不会出现这个报错  
  92. ------------------------------------------------------------------------------------------------------------  
  93.    
  94. 再次登录my-test容器,发现容器大小已经更新为20G!  
  95. [root@localhost ~]# docker exec -ti my-test /bin/bash  
  96. [root@813389572d7f /]# df -hT  
  97. Filesystem                                                                                      Type   Size  Used Avail Use% Mounted on  
  98. /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 ext4    20G  708M   18G   4% /  
  99. tmpfs                                                                                           tmpfs   32G     0   32G   0% /dev  
  100. shm                                                                                             tmpfs   64M     0   64M   0% /dev/shm  
  101. /dev/sda3                                                                                       ext4   193G  103G   80G  57% /etc/hosts  
  102.    
  103. ------------------------------------------------------------  
  104. 扩容后可能出现的问题:停止该容器后,无法重新启动-  
  105. 当容器扩容之后,由于dm认为设备块大小仍然为之前设置的初始大小,所以会发生无法起启动的情况,这时只要重新操作即可。  
  106. 1)必须要先启动一下,让其生成dm文件才能修改  
  107. [root@localhost ~]# docker start my-test  
  108. #此时会报错,不要理会,执行以下操作即可  
  109. [root@localhost ~]# echo 0 41943040 thin 253:3 725 | dmsetup load /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3  
  110. [root@localhost ~]# dmsetup resume /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3  
  111. ---------------  


为了方便后续容器动态扩容,可以采用下面的Dynamic_Modify_Docker_Disk.sh脚本(经测试可以使用)

[html]

  1. #!/bin/bash  
  2. #This script is dynamic modify docker container disk  
  3. #Author Deng Lei  
  4. if [ -z $1 ] || [ -z $2 ]; then  
  5.     echo "Usage: container_name increase_capacity"  
  6.     echo "Example: I want increase 11G to test"  
  7.     echo "The command is:   sh `basename $0` test 11"  
  8.     exit 1  
  9.                                                                                                                                                         fi  
  10. if [ `docker inspect $1 &>>/dev/null &&  echo 0 || echo 1` -eq 1 ];then  
  11.     echo "The container $1 is no exist!"  
  12.     exit 1  
  13. fi  
  14. container_id=`docker inspect -f '{{ .Id }}' $1`  
  15. now_disk=`dmsetup table /dev/mapper/docker-*-$container_id|awk '{print $2}'`  
  16. disk=$(($2*1024*1024*1024/512))  
  17. if [ $disk -lt $now_disk ];then  
  18.     echo "I can't shink container $1 from $(($now_disk*512/1024/1024/1024))G to ${2}G!I only modify contanier increase disk!"  
  19.     exit 1  
  20. fi  
  21. dmsetup table /dev/mapper/docker-*-$container_id|sed "s/0 [0-9]* thin/0 $disk thin/"|dmsetup load /dev/mapper/docker-*-$container_id  
  22. dmsetup resume /dev/mapper/docker-*-$container_id  
  23. resize2fs /dev/mapper/docker-*-$container_id  
  24. if [ $? -eq 0 ];then  
  25.     echo "dynamic container $1 disk to ${2}G is success!"  
  26. else  
  27.     echo "dynamic container $1 disk to ${2}G is fail!"  
  28. fi  
  29. 比如给my-test容器动态扩容到30G  
  30.   
  31.   
  32. [root@localhost ~]# chmod 755 Dynamic_Modify_Docker_Disk.sh  
  33. [root@localhost ~]# sh Dynamic_Modify_Docker_Disk.sh my-test 30  
  34. resize2fs 1.41.12 (17-May-2010)  
  35. Filesystem at /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 is mounted on /var/lib/docker/devicemapper/mnt/813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3; on-line resizing required  
  36. old desc_blocks = 2, new_desc_blocks = 2  
  37. Performing an on-line resize of /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 to 7864320 (4k) blocks.  
  38. The filesystem on /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 is now 7864320 blocks long.  
  39.    
  40. dynamic container my-test disk to 30G is success!  
  41.    
  42. 登陆容器查看,已扩容至30G!  
  43. [root@localhost ~]# docker exec -ti my-test /bin/bash  
  44. [root@813389572d7f /]# df -hT  
  45. Filesystem                                                                                      Type   Size  Used Avail Use% Mounted on  
  46. /dev/mapper/docker-8:3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 ext4    30G  708M   28G   3% /  
  47. tmpfs                                                                                           tmpfs   32G     0   32G   0% /dev  
  48. shm                                                                                             tmpfs   64M     0   64M   0% /dev/shm  
  49. /dev/sda3  
  50. 动态扩容后,对容器进行重启,会发生报错,此时再运行一次该脚本进行重新扩容(空间大小要等于或大于之前的设置,出现报错不用管),再启动容器即可(注意:docker容器目前是无法进行动态缩减的,仅能进行增加操作)。   
  51.   
  52. --------------------------------------- 下面说下Docker镜像和容器存放目录修改方法------------------------------------------  
  53.   
  54.   
  55. 这里为了测试效果,将xfs格式的home分区盘卸载,格式化为ext4后重新挂载(当然也可以再用之前的xfs格式)。然后将Docker的镜像、容器存放目录由之前默认的/var/lib/docker修改为home分区下的路径。  
  56. (当然,也可以另外新建一个分区,格式化,然后直接挂载到/var/lib/docker目录下)  
  57. [root@localhost ~]# df -hT  
  58. 文件系统                类型      容量  已用  可用 已用% 挂载点  
  59. /dev/mapper/centos-root xfs       150G  5.7G  145G    4% /  
  60. devtmpfs                devtmpfs   32G     0   32G    0% /dev  
  61. tmpfs                   tmpfs      32G     0   32G    0% /dev/shm  
  62. tmpfs                   tmpfs      32G  474M   31G    2% /run  
  63. tmpfs                   tmpfs      32G     0   32G    0% /sys/fs/cgroup  
  64. /dev/mapper/centos-home xfs          774G   33M  774G    1% /home  
  65. /dev/sda2               xfs       397M  120M  278M   31% /boot  
  66. tmpfs                   tmpfs     6.3G     0  6.3G    0% /run/user/0  
  67.    
  68. [root@localhost ~]# umount /home/         //卸载home分区盘  
  69. [root@localhost ~]# mkfs.ext4 /dev/mapper/centos-home        //格式化home盘为ext4文件格式  
  70. [root@localhost ~]# mount /dev/mapper/centos-home /home      //重新挂载  
  71. [root@localhost ~]# df -hT  
  72. 文件系统                类型      容量  已用  可用 已用% 挂载点  
  73. /dev/mapper/centos-root xfs       150G  5.7G  145G    4% /  
  74. devtmpfs                devtmpfs   32G     0   32G    0% /dev  
  75. tmpfs                   tmpfs      32G     0   32G    0% /dev/shm  
  76. tmpfs                   tmpfs      32G  474M   31G    2% /run  
  77. tmpfs                   tmpfs      32G     0   32G    0% /sys/fs/cgroup  
  78. /dev/sda2               xfs       397M  120M  278M   31% /boot  
  79. tmpfs                   tmpfs     6.3G     0  6.3G    0% /run/user/0  
  80. /dev/mapper/centos-home ext4      762G   73M  723G    1% /home  
  81.    
  82.    
  83. 接着就可以移动Docker的数据到ext4格式的home磁盘上了:  
  84. 先停止docker服务,保证移动的时候数据完整  
  85. [root@localhost ~]# service docker stop  
  86.    
  87. 移动Docker的目录到一个备份的目录(可以mv改目录名,docker重启后会自动生成这个目录;也可以将目录下内容全部拷贝到别处,届时要想恢复docker数据,只需要将备份内容拷贝回来,然后重启docker服务即可)  
  88. [root@localhost ~]# mv /var/lib/docker /var/lib/docker_bak    //这样,再次启动docker服务后,镜像及容器数据都不在了。只有将拷贝内容移回来,数据才会恢复。  
  89.    
  90. 修改开启自挂载配置,将home分区由之前的xfs改为ext4.  
  91. [root@localhost ~]# cat /etc/fstab  
  92.    
  93. #  
  94. # /etc/fstab  
  95. # Created by anaconda on Wed Oct 19 15:16:20 2016  
  96. #  
  97. # Accessible filesystems, by reference, are maintained under '/dev/disk'  
  98. # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info  
  99. #  
  100. /dev/mapper/centos-root /                        xfs      defaults        0 0  
  101. UUID=349c9816-43e9-4c46-991a-e34e2370ab3f /boot  xfs      defaults        0 0  
  102. /dev/mapper/centos-home /home                    ext4     defaults        0 0  
  103. /dev/mapper/centos-swap swap                     swap     defaults        0 0  
  104.    
  105. [root@localhost ~]# mount -a    //这条命令是重新加载/etc/fstab文件,没有文件里定义的分区挂载没有挂,这条命令就会自动挂载上。  
  106. [root@localhost ~]# mount |grep home  
  107. /dev/mapper/centos-home on /home type ext4 (rw,relatime,seclabel,data=ordered)  
  108.    
  109. 最后修改docker的镜像和容器存放路径,比如修改为/home/var/docker。  
  110. [root@localhost ~]# mkdir -p /home/var/docker  
  111. [root@localhost ~]# vim /etc/sysconfig/docker  
  112. ......  
  113. OPTIONS='--selinux-enabled --log-driver=journald --graph=/home/var/docker'    //添加--graph=/home/var/docker参数  
  114.    
  115. 然后启动docker服务,发现在新指定的目录/home/var/docker下产生了新数据  
  116. [root@localhost ~]# service docker start  
  117. [root@localhost ~]# ls /home/var/docker/  
  118. containers  devicemapper  image  network  tmp  trust  volumes  
  119.    
  120. 接着恢复之前的镜像数据  
  121. [root@localhost ~]# service docker stop  
  122. [root@localhost ~]# rm -rf /home/var/docker/*  
  123. [root@localhost ~]# mv /var/lib/docker_bak/* /home/var/docker/  
  124. [root@localhost ~]# service docker start  
  125. [root@localhost ~]# docker images         //发现镜像数据已恢复到新目录/home/var/docker下了  
  126. REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE  
  127. 192.168.1.23:5000/tomcat7      latest              47c5123914a1        8 days ago          562.3 MB  
  128. docker.io/redis                latest              83d6014ac5c8        13 days ago         183.6 MB  
  129. docker.io/ubuntu               latest              0ef2e08ed3fa        5 weeks ago         130 MB  
  130. docker.io/centos               latest              67591570dd29        3 months ago        191.8 MB  
  131. docker.io/tomcat               latest              ebb17717bed4        5 months ago        355.4 MB  


----------------------------------------------------温馨提示------------------------------------------------

[html] 

  1. 1)无法卸载分区  
  2. [root@localhost ~]# umount /home/  
  3. umount: /home: device is busy.  
  4. (In some cases useful info about processes that use  
  5. the device is found by lsof(8) or fuser(1))  
  6.    
  7. 如上,卸载分区时提示无法卸载,则是有进程占用/home。  
  8. 可以使用下面命令来终止占用进程:  
  9. [root@localhost ~]# fuser -m -k /home  
  10. /home: 1409 1519ce 1531e 1532e 1533e 1534e 1535e 1536e 1537e 1538e 1539e 1541e 1543e 1544e 1545e 1546e 1547e 1548e 1549e 1550e 1601m  
  11.    
  12. 再次卸载home分区就成功了。  
  13. [root@localhost ~]# umount /home/  
  14.    
  15. -k 表示自动把霸占home分区的进程kill掉!  
  16. 如果你不是很明确是否要杀死所有霸占设备的程序,还可以加一个-i 参数,这样每杀死一个程序前,都会询问!(即fuser -m -v -i -k /home)  
  17.    
  18. 2)如按照上面步骤,将docker的存放目录更换到/home/var/docker下。  
  19. 如果后续再对home分区进行强制卸载,然后再重新挂载或格式化的时候,会发现有报错:  
  20. [root@localhost ~]# fuser -m -k /home  
  21. [root@localhost ~]# mkfs.xfs -f /dev/mapper/centos-home  
  22. mkfs.xfs: /dev/mapper/centos-home contains a mounted filesystem  
  23. [root@localhost ~]# mount/dev/mapper/centos-home  
  24. mount: /dev/mapper/centos-home is already mounted or /home busy  
  25.    
  26. 这是因为docker数据还占用着home分区,需要将docker服务停了才可以。  



如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
387人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序