一、docker 底层实现

docker 通过namespace实现资源隔离;通过cgroup实现资源限额


二、namespace说明

2.1.概述

namespace使得容器像一台独立的计算机,namespace实现容器间资源隔离。linux六中namespace

mnt namespace 让容器拥有文件系统,允许不同 namespace 的进程看到的文件结构不同

UTS("UNIX Time-sharing System") namespace 让容器拥有独立的hostname和domain name

IPC namespace 让容器拥有共享内核和信号量来实现进程间通信

PID namespace 让容器拥有自己的PID

Network namespace 让容器拥有自己独立的网络资源如网卡、IP等

User namespace  让容器能够管理自己用户


2.2.查看当前容器的namespace

查看当前容器进程:

# ps -ef | grep docker
root      8137 18518  0 21:13 pts/0    00:00:00 grep --color=auto docker
root     21861     1  0 03:56 ?        00:02:04 /usr/bin/dockerd --insecure-registry 192.168.2.120:5000 -H unix://

查看namespace:

# ls -l /proc/21861/ns/
total 0
lrwxrwxrwx 1 root root 0 Dec 17 21:13 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 Dec 17 21:13 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 Dec 17 21:13 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 Dec 17 21:13 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 Dec 17 21:13 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Dec 17 21:13 uts -> uts:[4026531838]

一、docker 底层实现

docker 通过namespace实现资源隔离;通过cgroup实现资源限额


二、namespace说明

2.1.概述

namespace使得容器像一台独立的计算机,namespace实现容器间资源隔离。linux六中namespace

  • mnt namespace 让容器拥有文件系统,允许不同 namespace 的进程看到的文件结构不同

  • UTS("UNIX Time-sharing System") namespace 让容器拥有独立的hostname和domain name

  • IPC namespace 让容器拥有共享内核和信号量来实现进程间通信

  • PID namespace 让容器拥有自己的PID

  • Network namespace 让容器拥有自己独立的网络资源如网卡、IP等

  • User namespace  让容器能够管理自己用户


2.2.查看当前容器的namespace

查看当前容器进程:

# ps -ef | grep docker
root      8137 18518  0 21:13 pts/0    00:00:00 grep --color=auto docker
root     21861     1  0 03:56 ?        00:02:04 /usr/bin/dockerd --insecure-registry 192.168.2.120:5000 -H unix://

查看namespace:

# ls -l /proc/21861/ns/
total 0
lrwxrwxrwx 1 root root 0 Dec 17 21:13 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 Dec 17 21:13 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 Dec 17 21:13 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 Dec 17 21:13 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 Dec 17 21:13 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Dec 17 21:13 uts -> uts:[4026531838]

3.2.docker cgroup限制资源

3.2.1.查看当前容器进程

# docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES

37803352e3fa        registry:latest     "/entrypoint.sh /etc…"   17 hours ago        Up 17 hours         0.0.0.0:5000->5000/tcp   ckl-registry


3.2.2.查看当前容器的crgoup目录,目录名为进程长ID

CPU:

# ls /sys/fs/cgroup/cpu/docker/37803352e3fab5a357cab42ba6f2ec03ede5d3138dcc1ff9fec6c5e0ed44651d/

MEM:

# ls /sys/fs/cgroup/memory/docker/37803352e3fab5a357cab42ba6f2ec03ede5d3138dcc1ff9fec6c5e0ed44651d/

BIO:

# ls /sys/fs/cgroup/blkio/docker/37803352e3fab5a357cab42ba6f2ec03ede5d3138dcc1ff9fec6c5e0ed44651d/

四、docker cgroup限制内存

docker 启动参数内存限制,内存单位 b、k、m、g,分别对应 bytes、KB、MB、和 GB

  • -m --memory:容器能使用的最大内存大小,最小值为 4m

  • --memory-swap:容器能够使用的 swap 大小

  • --memory-swappiness:默认情况下,主机可以把容器使用的匿名页(anonymous page)swap 出来,你可以设置一个 0-100 之间的值,代表允许 swap 出来的比例

  • --memory-reservation:设置一个内存使用的 soft limit,如果 docker 发现主机内存不足,会执行 OOM 操作。这个值必须小于 --memory 设置的值

  • --kernel-memory:容器能够使用的 kernel memory 大小,最小值为 4m。

4.1.测试限额128M内存

# docker run --rm -it -m 128M progrium/stress --vm 1 --vm-bytes 100M 
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [8] forked
stress: dbug: [8] allocating 104857600 bytes ...  #分配100M 
stress: dbug: [8] touching bytes in strides of 4096 bytes ...
stress: dbug: [8] freed 104857600 bytes  #释放100M 
stress: dbug: [8] allocating 104857600 bytes ...
stress: dbug: [8] touching bytes in strides of 4096 bytes ... #分配100M
stress: dbug: [8] freed 104857600 bytes  #释放100M
stress: dbug: [8] allocating 104857600 bytes ...
stress: dbug: [8] touching bytes in strides of 4096 bytes ...
stress: dbug: [8] freed 104857600 bytes
stress: dbug: [8] allocating 104857600 bytes ...
stress: dbug: [8] touching bytes in strides of 4096 bytes ...
stress: dbug: [8] freed 104857600 bytes
stress: dbug: [8] allocating 104857600 bytes ...
stress: dbug: [8] touching bytes in strides of 4096 bytes ...
stress: dbug: [8] freed 104857600 bytes

#-rm 当进程退出,自动删除容器

#--vm 1 启动一个内存工作线程

#--vm-bytes 设置每个线程分配多少内存

 

当线程内存超出限额后:

# docker run --rm -it -m 128M progrium/stress --vm 1 --vm-bytes 130M
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [9] forked
stress: dbug: [9] allocating 136314880 bytes ...
stress: dbug: [9] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (416) <-- worker 9 got signal 9
stress: WARN: [1] (418) now reaping child worker processes
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 0s

#内存超过限额后,容器退出

五、docker cgroup限制CPU

--cpu-period #限制CPU CFS优先级

--cpu-quota  #限制CPU CFS配额

--cpu-rt-period  #限制CPU运行时钟期间优先级

--cpu-rt-runtime  #限制CPU运行时钟期间runtime 时长

--cpu-shares , -c  #设置使用CPU权重

--cpus   #设置可以使用CPU的核数

--cpuset-cpus  #设置运行在CPU哪些核数上运行


5.1.用4个CPU模拟压力

5.1.1.启动一个stree容器4个进程来计算压力,主机8个cpu

# docker run --rm -it progrium/stress --cpu 4
stress: info: [1] dispatching hogs: 4 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 12000us
stress: dbug: [1] --> hogcpu worker 4 [8] forked
stress: dbug: [1] using backoff sleep of 9000us
stress: dbug: [1] --> hogcpu worker 3 [9] forked
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] --> hogcpu worker 2 [10] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [11] forked

5.1.2.查看系统资源

111.png


5.2.限制容器使用CPU核数

5.2.1.运行容器可以使用的核数的

# docker run --rm -it --cpus 1.5 progrium/stress --cpu 2  #--cpus 限制使用CPU核数的多少,这里1.5,就是使用1.5个CPU,总共是两个
stress: info: [1] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] --> hogcpu worker 2 [8] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [9] forked

5.2.2.查看使用系统资源

222.png


5.3.限制容器运行在某些核数

5.3.1.运行容器在指定的核数

# docker run --rm -it --cpuset-cpus=2,3 progrium/stress --cpu 2  #cpu运行在2,3核数上,总共是两个
stress: info: [1] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 6000us
stress: dbug: [1] --> hogcpu worker 2 [6] forked
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogcpu worker 1 [7] forked

5.3.2.查看资源情况

333.png


六、docker cgroup限制IO

--blkio-weight  Block IO相对权重,在10到1000之间,0是禁止,默认是0

--blkio-weight-device Block IO权重,相对设备权重

--device-read-bps:磁盘每秒最多可以读多少比特(bytes)

--device-write-bps:磁盘每秒最多可以写多少比特(bytes)

--device-read-iops:磁盘每秒最多可以执行多少 IO 读操作

--device-write-iops:磁盘每秒最多可以执行多少 IO 写操作


6.1.磁盘写入速度限制

启动容器限制写入速度

# docker run -it --device-write-bps /dev/sda:20M centos
[root@7ebb0799f331 /]# 
[root@7ebb0799f331 /]# dd if=/dev/zero of=/ckl bs=1M count=200 oflag=direct    
200+0 records in
200+0 records out
209715200 bytes (210 MB) copied, 9.92785 s, 21.1 MB/s

写入速度限制在20M,oflag=direct指定用direct IO 方式写文件


6.2.磁盘写入IO限制

启动容器限制写入IO:

# docker run -it --device /dev/sda:/dev/sda --device-write-iops /dev/sda:100 centos 
[root@491c0211698b /]# 
# dd if=/dev/zero of=/ckl bs=1k count=2000 oflag=direct 
2000+0 records in
2000+0 records out
2048000 bytes (2.0 MB) copied, 19.9126 s, 103 kB/s


参考:

https://docs.docker.com/edge/engine/reference/commandline/run/#options

https://blog.csdn.net/notbaron/article/details/76789491