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

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

前面已介绍了docker很多知识点的操作记录,今天这里梳理下docker容器空间扩展的操作。默认情况下,docker容器的空间是10G。在实际生产环境下,对docker容器进行热扩容(动态扩容)是非常重要的一个需求。

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


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

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


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

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
#!/bin/bash
#This script is dynamic modify docker container disk
#Author Deng Lei
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
container_id=`docker inspect -f  '{{ .Id }}'  $1`
now_disk=`dmsetup table  /dev/mapper/docker- *-$container_id| 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/docker- *-$container_id| sed  "s/0 [0-9]* thin/0 $disk thin/" |dmsetup load  /dev/mapper/docker- *-$container_id
dmsetup resume  /dev/mapper/docker- *-$container_id
resize2fs  /dev/mapper/docker- *-$container_id
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


比如给my-test容器动态扩容到30G

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@localhost ~] # chmod 755 Dynamic_Modify_Docker_Disk.sh
[root@localhost ~] # sh Dynamic_Modify_Docker_Disk.sh my-test 30
resize2fs 1.41.12 (17-May-2010)
Filesystem at  /dev/mapper/docker-8 :3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 is mounted on  /var/lib/docker/devicemapper/mnt/813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 ; on-line resizing required
old desc_blocks = 2, new_desc_blocks = 2
Performing an on-line resize of  /dev/mapper/docker-8 :3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 to 7864320 (4k) blocks.
The filesystem on  /dev/mapper/docker-8 :3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 is now 7864320 blocks long.
  
dynamic container my- test  disk to 30G is success!
  
登陆容器查看,已扩容至30G!
[root@localhost ~] # docker exec -ti my-test /bin/bash
[root@813389572d7f /] # df -hT
Filesystem                                                                                      Type   Size  Used Avail Use% Mounted on
/dev/mapper/docker-8 :3-4850707-813389572d7f569e7b3705070033b43cf9e42ed9d304e03662c92533838ddec3 ext4    30G  708M   28G   3% /
tmpfs                                                                                           tmpfs   32G     0   32G   0%  /dev
shm                                                                                             tmpfs   64M     0   64M   0%  /dev/shm
/dev/sda3


动态扩容后,对容器进行重启,会发生报错,此时再运行一次该脚本进行重新扩容(空间大小要等于或大于之前的设置,出现报错不用管),再启动容器即可(注意:docker容器目前是无法进行动态缩减的,仅能进行增加操作)。 


--------------------------------------- 下面说下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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
这里为了测试效果,将xfs格式的home分区盘卸载,格式化为ext4后重新挂载(当然也可以再用之前的xfs格式)。然后将Docker的镜像、容器存放目录由之前默认的 /var/lib/docker 修改为home分区下的路径。
(当然,也可以另外新建一个分区,格式化,然后直接挂载到/var /lib/docker 目录下)
[root@localhost ~] # df -hT
文件系统                类型      容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root  xfs       150G  5.7G  145G    4% /
devtmpfs                devtmpfs   32G     0   32G    0%  /dev
tmpfs                   tmpfs      32G     0   32G    0%  /dev/shm
tmpfs                   tmpfs      32G  474M   31G    2%  /run
tmpfs                   tmpfs      32G     0   32G    0%  /sys/fs/cgroup
/dev/mapper/centos-home  xfs          774G   33M  774G    1%  /home
/dev/sda2                xfs       397M  120M  278M   31%  /boot
tmpfs                   tmpfs     6.3G     0  6.3G    0%  /run/user/0
  
[root@localhost ~] # umount /home/         //卸载home分区盘
[root@localhost ~] # mkfs.ext4 /dev/mapper/centos-home        //格式化home盘为ext4文件格式
[root@localhost ~] # mount /dev/mapper/centos-home /home      //重新挂载
[root@localhost ~] # df -hT
文件系统                类型      容量  已用  可用 已用% 挂载点
/dev/mapper/centos-root  xfs       150G  5.7G  145G    4% /
devtmpfs                devtmpfs   32G     0   32G    0%  /dev
tmpfs                   tmpfs      32G     0   32G    0%  /dev/shm
tmpfs                   tmpfs      32G  474M   31G    2%  /run
tmpfs                   tmpfs      32G     0   32G    0%  /sys/fs/cgroup
/dev/sda2                xfs       397M  120M  278M   31%  /boot
tmpfs                   tmpfs     6.3G     0  6.3G    0%  /run/user/0
/dev/mapper/centos-home  ext4      762G   73M  723G    1%  /home
  
  
接着就可以移动Docker的数据到ext4格式的home磁盘上了:
先停止docker服务,保证移动的时候数据完整
[root@localhost ~] # service docker stop
  
移动Docker的目录到一个备份的目录(可以 mv 改目录名,docker重启后会自动生成这个目录;也可以将目录下内容全部拷贝到别处,届时要想恢复docker数据,只需要将备份内容拷贝回来,然后重启docker服务即可)
[root@localhost ~] # mv /var/lib/docker /var/lib/docker_bak    //这样,再次启动docker服务后,镜像及容器数据都不在了。只有将拷贝内容移回来,数据才会恢复。
  
修改开启自挂载配置,将home分区由之前的xfs改为ext4.
[root@localhost ~] # cat /etc/fstab
  
#
# /etc/fstab
# Created by anaconda on Wed Oct 19 15:16:20 2016
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root  /                        xfs      defaults        0 0
UUID=349c9816-43e9-4c46-991a-e34e2370ab3f  /boot   xfs      defaults        0 0
/dev/mapper/centos-home  /home                     ext4     defaults        0 0
/dev/mapper/centos-swap  swap                     swap     defaults        0 0
  
[root@localhost ~] # mount -a    //这条命令是重新加载/etc/fstab文件,没有文件里定义的分区挂载没有挂,这条命令就会自动挂载上。
[root@localhost ~] # mount |grep home
/dev/mapper/centos-home  on  /home  type  ext4 (rw,relatime,seclabel,data=ordered)
  
最后修改docker的镜像和容器存放路径,比如修改为 /home/var/docker
[root@localhost ~] # mkdir -p /home/var/docker
[root@localhost ~] # vim /etc/sysconfig/docker
......
OPTIONS= '--selinux-enabled --log-driver=journald --graph=/home/var/docker'     // 添加--graph= /home/var/docker 参数
  
然后启动docker服务,发现在新指定的目录 /home/var/docker 下产生了新数据
[root@localhost ~] # service docker start
[root@localhost ~] # ls /home/var/docker/
containers  devicemapper  image  network  tmp  trust  volumes
  
接着恢复之前的镜像数据
[root@localhost ~] # service docker stop
[root@localhost ~] # rm -rf /home/var/docker/*
[root@localhost ~] # mv /var/lib/docker_bak/* /home/var/docker/
[root@localhost ~] # service docker start
[root@localhost ~] # docker images         //发现镜像数据已恢复到新目录/home/var/docker下了
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
192.168.1.23:5000 /tomcat7       latest              47c5123914a1        8 days ago          562.3 MB
docker.io /redis                 latest              83d6014ac5c8        13 days ago         183.6 MB
docker.io /ubuntu                latest              0ef2e08ed3fa        5 weeks ago         130 MB
docker.io /centos                latest              67591570dd29        3 months ago        191.8 MB
docker.io /tomcat                latest              ebb17717bed4        5 months ago        355.4 MB


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

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





本文转自 dengaosky 51CTO博客,原文链接:http://blog.51cto.com/dengaosky/2068073,如需转载请自行联系原作者
相关文章
|
25天前
|
Docker 容器
进入Docker容器中
进入Docker容器中
34 2
|
4天前
|
存储 运维 监控
构建高效稳定的Docker容器监控体系
【4月更文挑战第18天】 在现代微服务架构中,Docker容器已成为部署和运行应用的标准环境。随之而来的挑战是如何有效监控这些容器的性能与健康状况,确保系统的稳定性和可靠性。本文将探讨构建一个高效稳定的Docker容器监控体系的关键技术和方法,包括日志管理、性能指标收集以及异常检测机制,旨在为运维人员提供实用的指导和建议。
9 0
|
13天前
|
Linux Docker 容器
docker 容器常用命令
docker 容器常用命令
12 0
|
13天前
|
Linux Shell 虚拟化
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
19 0
|
13天前
|
存储 Linux Shell
centos 部署docker容器 安装 、基本使用方法(一)
centos 部署docker容器 安装 、基本使用方法(一)
23 0
|
22天前
|
Kubernetes 网络协议 Docker
Docker 容器的DNS
Docker 容器的DNS
25 1
|
24天前
|
关系型数据库 MySQL Nacos
【深入浅出Nacos原理及调优】「实战开发专题」采用Docker容器进行部署和搭建Nacos服务以及“坑点”
【深入浅出Nacos原理及调优】「实战开发专题」采用Docker容器进行部署和搭建Nacos服务以及“坑点”
46 1
|
1月前
|
Java Go 开发者
Docker容器技术简介及其与Go语言的结合点
【2月更文挑战第23天】本文首先概述了Docker容器技术的核心概念和优势,接着探讨了Go语言与Docker容器技术的结合点。通过阐述Docker的轻量级、可移植性和版本控制等特性,以及Go语言在容器化应用中的优势,本文旨在说明两者结合能够实现更高效、灵活的应用开发和部署。
|
1月前
|
Oracle 关系型数据库 数据库
|
25天前
|
NoSQL 关系型数据库 MySQL
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
110 1