十、Docker容器:磁盤&內存&CPU資源限制實戰


一、實驗環境

inode1 192.168.31.101 ----- docker version:Docker version 1.13.1, build cccb291/1.13.1

inode2 192.168.31.102 ----- docker version:Docker version 19.03.8, build afacb8b(docker-ce)

二、宿主機與docker 容器的磁盤、內存、cpu資源對比

啟動一個docker容器

[root@node1 ~]# docker ps 
CONTAINER ID    IMAGE       COMMAND      CREATED     STATUS     PORTS          NAMES
aca49b0226ad    web:v1    "sleep 9999d" 25 hours ago  Up 19 seconds            web01

1、磁盤的對比

宿主機的磁盤

 
[root@node1 ~]# df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/sda2      xfs        20G  3.0G   17G  15% /
devtmpfs       devtmpfs  233M     0  233M   0% /dev
tmpfs          tmpfs     243M     0  243M   0% /dev/shm
tmpfs          tmpfs     243M  5.2M  238M   3% /run
tmpfs          tmpfs     243M     0  243M   0% /sys/fs/cgroup
/dev/sda1      xfs       497M  117M  380M  24% /boot
tmpfs          tmpfs      49M     0   49M   0% /run/user/0

宿主機上docker容器的磁盤

[root@node1 ~]# docker exec web01 df -Th
Filesystem     Type     Size  Used Avail Use% Mounted on
overlay        overlay   20G  3.0G   17G  15% /
tmpfs          tmpfs    243M     0  243M   0% /dev
tmpfs          tmpfs    243M     0  243M   0% /sys/fs/cgroup
/dev/sda2      xfs       20G  3.0G   17G  15% /etc/hosts
shm            tmpfs     64M     0   64M   0% /dev/shm
tmpfs          tmpfs    243M     0  243M   0% /proc/acpi
tmpfs          tmpfs    243M     0  243M   0% /proc/scsi
tmpfs          tmpfs    243M     0  243M   0% /sys/firmware

2、內存的對比

宿主機的內存

[root@node1 ~]# free -mh
              total        used        free      shared  buff/cache   available
Mem:           485M         98M        184M        5.2M        203M        345M
Swap:          2.0M          0B        2.0M

宿主機上docker容器的內存

 
[root@node1 ~]# docker exec web01 free -mh
              total        used        free      shared  buff/cache   available
Mem:           485M        105M        173M        5.2M        206M        338M
Swap:          2.0M          0B        2.0M

3、CPU的對比

宿主機的cpu

#物理cpu數
[root@node1 ~]# grep 'physical id' /proc/cpuinfo|sort|uniq|wc -l
1
#cpu的核數
[root@node1 ~]#  grep 'cpu cores' /proc/cpuinfo|uniq|awk -F ':' '{print $2}'
 1

宿主機上的docker容器的cpu

[root@node1 ~]# docker exec web01 grep 'physical id' /proc/cpuinfo|sort|uniq|wc -l
1
[root@node1 ~]# docker exec web01 grep 'cpu cores' /proc/cpuinfo|uniq|awk -F ':' '{print $2}'
 1

從上面的對比可以看到宿主機和容器的磁盤、內存和cpu是一樣的;docker默認容器和宿主機時共享所有的cpu、內存、磁盤資源的。為了不讓個別容器因為受到攻擊,大肆占用資源,造成宿主機資源耗盡,同時也造成其他容器因資源不夠而崩潰,我們需要對每個容器的資源多少進行限制。

4、查看單個容器的內存、cpu資源使用

#實時查看容器web01的內存和cpu資源
[root@node1 ~]# docker stats web01
CONTAINER           CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
web01               0.00%               88 KiB / 485.7 MiB   0.02%               4.29 kB / 1.34 kB   6.64 MB / 0 B       1

CONTAINER           CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
web01               0.00%               88 KiB / 485.7 MiB   0.02%               4.29 kB / 1.34 kB   6.64 MB / 0 B       1

CONTAINER           CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
web01               0.00%               88 KiB / 485.7 MiB   0.02%               4.29 kB / 1.34 kB   6.64 MB / 0 B       1

CONTAINER           CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
web01               0.00%               88 KiB / 485.7 MiB   0.02%               4.29 kB / 1.34 kB   6.64 MB / 0 B       1

#查看容器web01瞬時的內存和cpu資源
[root@node1 ~]# docker stats --no-stream web01
CONTAINER           CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
web01               0.00%               88 KiB / 485.7 MiB   0.02%               4.42 kB / 1.42 kB   6.64 MB / 0 B       1
[root@node1 ~]# 

三、對新容器的CPU和內存資源限制的配置

CPU和內存的資源限制

docker run -itd --cpuset-cpus=0-0 -m 4MB --name=test web:v1 /bin/bash
--cpuset-cpus:設置cpu的核數,0-01-12-2...(這種是綁定cpu,把本虛擬機綁定在一個邏輯cpu上);0-10-20-3和0,10,20,3(這兩種形式都是指定多個邏輯cpu,每次隨機使用一個邏輯cpu,相當於是共享cpu)
#注意:一個docker容器綁定一個邏輯cpu便於監控容器占用cpu的情況;而共享cpu可以更好利用cpu資源,而且要選好cpu調度算法!
-m:設置內存的大小

[root@node1 ~]# docker run -itd --cpuset-cpus=0-0 -m 4MB --name=test web:v1 /bin/bash
de30929be801fe3d0262b7a8f2de15234c53bc07b7c8d05d27ea4845b3c5f479
[root@node1 ~]# docker ps
CONTAINER ID    IMAGE    COMMAND     CREATED    STATUS           PORTS       NAMES
de30929be801     web:v1  "/bin/bash"  3 seconds ago Up 2 seconds             test

查看內存

[root@node1 ~]# docker stats --no-stream test
CONTAINER      CPU %     MEM USAGE / LIMIT   MEM %   NET I/O         BLOCK I/O       PIDS
test           0.00%       372 KiB / 4 MiB   9.08%   1.34 kB / 734 B  1.53 MB / 0 B    1
#內存被限制在了4M

另外啟動一個容器test2,cpu設置為2核

 
[root@node1 ~]# docker run -itd --cpuset-cpus=0-1 -m 4MB --name=test2 web:v1 /bin/bash
1944e0f432d57d4ad48015a74d4b537f6fa76bda09e32d204a4d20a38fa6594a
/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:235: starting container process caused "process_linux.go:327: setting cgroup config for procHooks process caused \"failed to write 0-1 to cpuset.cpus: write /sys/fs/cgroup/cpuset/system.slice/docker-1944e0f432d57d4ad48015a74d4b537f6fa76bda09e32d204a4d20a38fa6594a.scope/cpuset.cpus: permission denied\"".

#報錯,因為宿主機的cpu核數只有1顆,給docker容器配置2顆會報錯

從上面可以看到docker的cpu和內存資源有被限制

 

四、對容器硬盤資源的限制

 

1、硬盤資源的限制是要修改配置文件

Docker version 1.13.1

docker配置文件:/etc/sysconfig/docker(注意不是docker-storage文件)中,OPTIONS參數后面添加如下代碼:

OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false --storage-opt overlay2.size=10G'

Docker version 19.03.8(docker-ce)

docker配置文件:/usr/lib/systemd/system/docker.service中,OPTIONS參數后面添加如下代碼:

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --storage-opt overlay2.size=10G

重啟docker服務

[root@node1 ~]# systemctl restart docker
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.

[root@node1 ~]# tail -fn 50 /var/log/messages
......
Apr  1 06:29:21 node1 dockerd-current: Error starting daemon: error initializing graphdriver: Storage option overlay2.size not supported. Filesystem does not support Project Quota: Failed to set quota limit for projid 1 on /var/lib/docker/overlay2/backingFsBlockDev: function not implemented
......
[root@node2 ~]# systemctl restart docker.service 
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.

[root@node2 ~]tail -fn 50 /var/log/messages
......
Apr  1 06:34:29 node2 dockerd: time="2020-04-01T06:34:29.701688085+08:00" level=error msg="[graphdriver] prior storage driver overlay2 failed: Storage Option overlay2.size only supported for backingFS XFS. Found <unknown>"
......

可以發現docker無法啟動,其報錯信息的意思為文件系統不支持磁盤配額。

原因:

Overlay2 Docker磁盤驅動模式,如果要調整其大小,需要讓Linux文件系統設置為xfs,並且支持目錄級別的磁盤配額功能;默認情況下,我們在安裝系統時,不會做磁盤配額限制的。

什么叫支持目錄的磁盤配額?

就是支持在固定大小目錄中分配磁盤大小。目錄有大小怎么理解?將一個固定大小的硬盤掛載到此目錄,這個目錄的大小就是硬盤的大小。然后目錄可分配指定大小的硬盤資源給其下的文件

2、做支持目錄級別的磁盤配額功能

准備工作:備份docker images

[root@node1 ~]# docker image save busybox > /tmp/busybox.tar

第一步:添加一個新硬盤sdb

[root@node1 ~]# fdisk -l

Disk /dev/sda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x0004ff38

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     1026047      512000   83  Linux
/dev/sda2         1026048    41938943    20456448   83  Linux
/dev/sda3        41938944    41943039        2048   82  Linux swap / Solaris

Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

第二步:格式化硬盤為xfs文件系統格式

[root@node1 ~]# mkfs.xfs -f /dev/sdb
meta-data=/dev/sdb               isize=512    agcount=4, agsize=1310720 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=5242880, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

第三步:創建data目錄,后續將作為docker數據目錄;

[root@node1 ~]# mkdir /data/ -p

第四步:掛載data目錄,並且開啟磁盤配額功能(默認xfs支持配額功能)

[root@node1 ~]# mount -o uquota,prjquota /dev/sdb /data/

第五步:查看配額-配置詳情

[root@node1 ~]# xfs_quota -x -c 'report' /data/
User quota on /data (/dev/sdb)
                               Blocks                     
User ID          Used       Soft       Hard    Warn/Grace     
---------- -------------------------------------------------- 
root                0          0          0     00 [--------]

Project quota on /data (/dev/sdb)
                               Blocks                     
Project ID       Used       Soft       Hard    Warn/Grace     
---------- -------------------------------------------------- 
#0                  0          0          0     00 [--------]

運行了xfs_quota這個命令后,顯示如上,說明,/data/這個目錄已經支持了目錄配額功能

第六步:從/data/docker/作軟鏈接到/var/lib下

把/var/lib目錄下docker目錄備份走,再重新做一個/data/docker的軟連接到/var/lib下;

不支持目錄級別的磁盤配額功能的源/var/lib/docker/目錄移走,把支持目錄級別的磁盤配額功能軟鏈接到/data/docker/目錄下的/var/lib/docker/目錄

 
cd /var/lib
mv docker docker.bak
mkdir -p /data/docker
ln -s /data/docker/ /var/lib/

第七步:重啟docker服務

 
[root@node1 ~]# systemctl restart docker

[root@node1 ~]# ps -ef |grep docker
root      3842     1  0 07:11 ?        00:00:00 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json --selinux-enabled --log-driver=journald --signature-verification=false --storage-opt overlay2.size=10G --storage-driver overlay2 -b=br0
root      3848  3842  0 07:11 ?        00:00:00 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc --runtime-args --systemd-cgroup=true
root      3929  1759  0 07:13 pts/0    00:00:00 grep --color=auto docker

#會看到一個"--storage-opt overlay2.size=10G"參數,表示磁盤配置成功

第八步:啟動一個busybox容器

 
#導入我們備份的docker images
[root@node1 ~]#docker image load -i busybox:latest /tmp/busybox.tar
#啟動容器
[root@node1 ~]# docker run -itd --name=test --privileged --cpuset-cpus=0 -m 4M busybox /bin/sh
0c4465b350551011e1dfebd6f8fc057a336ff7980736c60e31871ab67c42ac42

查看容器的磁盤大小

[root@node1 ~]# docker exec test df -Th
Filesystem           Type            Size      Used Available Use% Mounted on
overlay              overlay        10.0G      8.0K     10.0G   0% /
tmpfs                tmpfs         242.9M         0    242.9M   0% /dev
tmpfs                tmpfs         242.9M         0    242.9M   0% /sys/fs/cgroup
/dev/sdb             xfs            20.0G     33.6M     20.0G   0% /etc/resolv.conf
/dev/sdb             xfs            20.0G     33.6M     20.0G   0% /etc/hostname
/dev/sdb             xfs            20.0G     33.6M     20.0G   0% /etc/hosts
shm                  tmpfs          64.0M         0     64.0M   0% /dev/shm
/dev/sdb             xfs            20.0G     33.6M     20.0G   0% /run/secrets

查看容器的內存大小

 
[root@node1 ~]# docker stats --no-stream test
CONTAINER    CPU %   MEM USAGE / LIMIT   MEM %   NET I/O        BLOCK I/O        PIDS
test        0.00%       56 KiB / 4 MiB   1.37%   780 B / 734 B  0 B / 0 B           1

五、注意事宜

1、無論是磁盤大小的限制、還是cpu、內存,它們都不能超出實際擁有的大小!
比如我這台vmware的內存是4G、cpu兩核、硬盤20G(因為這里可配額的/data/目錄就只有20G),因為centos系統運行還需要占部分內存,所以容器指定內存最好不要超過3G,cpu不能超過兩核(即0-01-10-1都可以)、硬盤不能超過20G(最好在15G以下)
2、做磁盤資源限制時,磁盤分區需要做支持目錄級別的磁盤配額功能
3、配置新磁盤支持目錄級別的磁盤配額功能后,重啟docker服務,docker會被重新初始化,注意備份docker images

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM