Docker容器硬盤熱擴容操做記錄

 

前面已介紹了docker不少知識點的操做記錄,今天這裏梳理下docker容器空間擴展的操做。默認狀況下,物理機下建立的docker容器的空間是10G(虛擬機下建立的docker容器空間就是虛擬機的空間)。在實際生產環境下,對docker容器進行熱擴容(動態擴容)是很是重要的一個需求。linux

Docker容器動態擴展的優勢:
1)不須要修改docker配置,不須要重啓docker服務;
2)能夠直接對運行中的容器進行動態擴展(只能增,沒法縮);

Docker容器動態擴展的條件:
1)docker所在宿主機分區的格式必須是ext二、ext三、ext4;
2)docker存儲引擎必須是devicemapperredis

下面的操做均是在centos6下操做的:sql

宿主機分區的格式是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僅能支持ext二、ext三、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認爲設備塊大小仍然爲以前設置的初始大小,因此會發生沒法起啓動的狀況,這時只要從新操做便可。
必需要先啓動一下,讓其生成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腳本(經測試可使用)docker

#!/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容器動態擴容到30Gubuntu

[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容器目前是沒法進行動態縮減的僅能進行增長操做)。 vim

================================================================================
這裏須要注意一下:
上面的操做在centos6下進行docker容器的硬盤擴容能夠順利完成,但在centos7下進行這些操做可能有點問題。
雖然centos 7裏使用docker的時候默認存儲引擎是devicemapper,可是在docker容器硬盤擴容的resize2fs這一步會出現相似下面報錯:
resize2fs 1.42.9 (28-Dec-2013)
resize2fs: Device or resource busy while trying to open /dev/mapper/docker-253:1-1270544-d2d2cef71c86910467c1afdeb79c1a008552f3f9ef9507bb1e04d77f2ad5eac4
Couldn't find valid filesystem superblock.centos

緣由是resize2fs命令僅能支持ext二、ext三、ext4,不支持xfs,而xfs是CentOS7的默認文件系統類型
因此建議docker服務器的文件系統格式調整爲ext4(在centos7系統安裝時能夠手動指定所在分區爲ext4格式)。tomcat

======================下面說下Docker鏡像和容器存放目錄修改方法======================bash

這裏爲了測試效果,將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)沒法卸載分區
[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.ext4 /dev/mapper/centos-home 
mkfs.ext4: /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服務停了才能夠。
相關文章
相關標籤/搜索