Docker-资源隔离、资源控制

1、资源隔离

1.1、需求

在一个操作系统中,启动了多个应用容器,那么这些应用容器如何来保障互相的操作不受影响?
-- 资源隔离

1.2、简介

Linux内核实现namespace的主要目的,就是为了实现轻量级虚拟化技术服务。在同一个namespace下的进程合一感知彼此的变化,而对外界的进程一无所知。
Docker通过linux的 pid、net、ipc、mnt、uts、user这六类的namespace将容器的进程、网络、消息、文件系统、UTS和操作系统资源隔离开。
从而让容器中的进程产生错觉,仿佛自己置身一个独立的系统环境中,以达到隔离的目的。

1.3、namespace

1.3.1、分类

namespace     系统调用参数        隔离内容
UTS           CLONE_NEWUTS      主机名或域名
IPC           CLONE_NEWIPC      信号量、消息队列和共享内存
PID           CLONE_NEWPID      进程编号
Network       CLONE_NEWNET      网络设备、网络战、端口等
Mount         CLONE_NEWNS       挂载点(文件系统)
User          CLONE_NEWUSER     用户组和用户组
Time          CLONE_NEWTIME     启动和单调时钟

1.3.2、通过命令查询ns

]# ps -aux | grep docker | grep -v grep 
root      32141  0.0  1.9 1096140 72988 ?       Ssl  15:16   0:03 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock


]# ll /proc/32141/ns/ lrwxrwxrwx. 1 root root 0 5月 18 18:51 ipc -> ipc:[4026531839] lrwxrwxrwx. 1 root root 0 5月 18 18:51 mnt -> mnt:[4026531840] lrwxrwxrwx. 1 root root 0 5月 18 18:51 net -> net:[4026531956] lrwxrwxrwx. 1 root root 0 5月 18 18:51 pid -> pid:[4026531836] lrwxrwxrwx. 1 root root 0 5月 18 18:51 user -> user:[4026531837] lrwxrwxrwx. 1 root root 0 5月 18 18:51 uts -> uts:[4026531838]

1.4、环境准备

1.4.1、启动2个nginx容器【nginx80,nginx81】

docker run -d --rm --name nginx80 nginx
docker run -d --rm --name nginx81 nginx

1.4.2、查询基本信息

docker inspect nginx80
docker inspect nginx81

1.5、隔离级别-实战

1.5.1、文件系统隔离

# nginx80
]# docker exec -it nginx80 cat /proc/self/mountinfo | head -5
185 122 0:51 / / rw,relatime master:68 - overlay overlay rw,seclabel,lowerdir=/var/lib/docker/overlay2/l/2IYIZJRREC556PKKX43OBOFM5W:/var/lib/docker/overlay2/l/2UFXEGQEPFQFJD7FSGBOJZOEFF:/var/lib/docker/overlay2/l/54URWT4BBGRSLW4CMO6EDCWNP5:
/var/lib/docker/overlay2/l/HJCFS3MVHVODBCH3ITLJJAMKX4:/var/lib/docker/overlay2/l/BOZLGSVQXEAZ7YORN76HBA7GJH:/var/lib/docker/overlay2/l/3BVRX2BKGYF5V56C4PCECSOSFS:/var/lib/docker/overlay2/l/6LEGS22UCMTWB5QBNC5TO3GIV3,upperdir=/var/lib/docker/
overlay2/be42eef2b650ab981e4bd9141ddaeaff0aae3fe7317d6b4cb0f8edaae06caf9d/diff,workdir=/var/lib/docker/overlay2/be42eef2b650ab981e4bd9141ddaeaff0aae3fe7317d6b4cb0f8edaae06caf9d/work 186 185 0:53 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw 187 185 0:54 / /dev rw,nosuid - tmpfs tmpfs rw,seclabel,size=65536k,mode=755 188 187 0:55 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,seclabel,gid=5,mode=620,ptmxmode=666 189 185 0:56 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs ro,seclabel # nginx81 ]# docker exec -it nginx81 cat /proc/self/mountinfo | head -5 238 174 0:63 / / rw,relatime master:71 - overlay overlay rw,seclabel,lowerdir=/var/lib/docker/overlay2/l/PI3ZEHEP46H5BW6II33FK3SFLS:/var/lib/docker/overlay2/l/2UFXEGQEPFQFJD7FSGBOJZOEFF:/var/lib/docker/overlay2/l/54URWT4BBGRSLW4CMO6EDCWNP5:
/var/lib/docker/overlay2/l/HJCFS3MVHVODBCH3ITLJJAMKX4:/var/lib/docker/overlay2/l/BOZLGSVQXEAZ7YORN76HBA7GJH:/var/lib/docker/overlay2/l/3BVRX2BKGYF5V56C4PCECSOSFS:/var/lib/docker/overlay2/l/6LEGS22UCMTWB5QBNC5TO3GIV3,upperdir=/var/lib/docker/
overlay2/abf9cd19e452f4922e0258b4bef1b35b8601aedae3dde5dde161e4287b4eaa7f/diff,workdir=/var/lib/docker/overlay2/abf9cd19e452f4922e0258b4bef1b35b8601aedae3dde5dde161e4287b4eaa7f/work 239 238 0:65 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw 240 238 0:66 / /dev rw,nosuid - tmpfs tmpfs rw,seclabel,size=65536k,mode=755 241 240 0:67 / /dev/pts rw,nosuid,noexec,relatime - devpts devpts rw,seclabel,gid=5,mode=620,ptmxmode=666 242 238 0:68 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs ro,seclabel # 发现到workdir是不一样的

1.5.2、UTC资源隔离

]# cat /var/lib/docker/containers/ea887c4677393fde4dcd98709f21769e551e312d51014faf1d91029a1db221b9/hostname 
ea887c467739


]# cat /var/lib/docker/containers/ea887c4677393fde4dcd98709f21769e551e312d51014faf1d91029a1db221b9/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.4 ea887c467739

1.5.3、IPC资源隔离

# 宿主机的IPCS
]# ipcmk -Q
消息队列 id:0

]# ipcs

--------- 消息队列 -----------
键        msqid      拥有者  权限     已用字节数 消息      
0x48951c54 0          root       644        0            0           

------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     nattch     状态      

--------- 信号量数组 -----------
键        semid      拥有者  权限     nsems  

# 容器的IPCS
]# docker exec -it nginx80 /bin/bash
root@2bcea13a72c7:/# ipcs 

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      

------ Semaphore Arrays --------
key        semid      owner      perms      nsems 


ipcmk -Q # 建立一个消息队列
ipcs     # 查看消息情况

1.5.4、PID资源隔离

# 宿主机的PID
]# docker inspect --format '{{.State.Pid}}' nginx80
51094

]# pstree -g 51094
nginx(51094)───nginx(51094)

# 容器内的PID
]# docker exec -it nginx80 /bin/bash
root@2bcea13a72c7:/# pstree -g
nginx(1)---nginx(1)

1.5.5、net资源隔离

]# ls /var/lib/docker/network/files/local-kv.db 
/var/lib/docker/network/files/local-kv.db

]# docker exec -it nginx80 ifconfig | grep inet
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        inet 127.0.0.1  netmask 255.0.0.0

]# docker exec -it nginx81 ifconfig | grep inet
        inet 172.17.0.4  netmask 255.255.0.0  broadcast 172.17.255.255
        inet 127.0.0.1  netmask 255.0.0.0

1.5.6、User资源隔离

]# docker exec -it nginx80 id
uid=0(root) gid=0(root) groups=0(root)


]# docker exec -it nginx81 id uid=0(root) gid=0(root) groups=0(root)

2、资源控制

2.1、基础知识

2.1.1、简介

对于容器的资源限制,LXC给出的方法是Cgroup,Cgroup 全称Control group,Docker把它继承过来了。
CGroup其实就是通过创建一个虚拟的文件系统交给容器使用,同时还能对容器的容量做出限制。
通过CGroup可以实现的功能:资源限制、优先级分配、资源统计、任务控制

2.1.2、默认情况下,资源限制的功能已经开启

]# grep -i cgroup /boot/config-3.10.0-1160.el7.x86_64 
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y
CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_NETPRIO_CGROUP=y

2.1.3、系统cgroup的体现

]# ll /sys/fs/cgroup/
drwxr-xr-x. 5 root root  0 5月  15 03:41 blkio
lrwxrwxrwx. 1 root root 11 5月  15 03:41 cpu -> cpu,cpuacct
lrwxrwxrwx. 1 root root 11 5月  15 03:41 cpuacct -> cpu,cpuacct
drwxr-xr-x. 5 root root  0 5月  15 03:41 cpu,cpuacct
drwxr-xr-x. 3 root root  0 5月  15 03:41 cpuset
drwxr-xr-x. 5 root root  0 5月  15 03:41 devices
drwxr-xr-x. 3 root root  0 5月  15 03:41 freezer
drwxr-xr-x. 3 root root  0 5月  15 03:41 hugetlb
drwxr-xr-x. 5 root root  0 5月  15 03:41 memory
lrwxrwxrwx. 1 root root 16 5月  15 03:41 net_cls -> net_cls,net_prio
drwxr-xr-x. 3 root root  0 5月  15 03:41 net_cls,net_prio
lrwxrwxrwx. 1 root root 16 5月  15 03:41 net_prio -> net_cls,net_prio
drwxr-xr-x. 3 root root  0 5月  15 03:41 perf_event
drwxr-xr-x. 5 root root  0 5月  15 03:41 pids
drwxr-xr-x. 5 root root  0 5月  15 03:41 systemd

2.1.4、以CPU限制为例

]# tree /sys/fs/cgroup/cpu/docker
/sys/fs/cgroup/cpu/docker
├── 2bcea13a72c7ab25d8ce8067c1f4a97e9532b09380318d57ea7f1b9f6a79ed23
│   ├── cgroup.clone_children
│   ├── cgroup.event_control
│   ├── cgroup.procs
│   ├── cpuacct.stat
│   ├── cpuacct.usage
│   ├── cpuacct.usage_percpu
│   ├── cpu.cfs_period_us
│   ├── cpu.cfs_quota_us
│   ├── cpu.rt_period_us
│   ├── cpu.rt_runtime_us
│   ├── cpu.shares
│   ├── cpu.stat
│   ├── notify_on_release
│   └── tasks
├── 61a640daad394d4c1d6e44bd184fd44fdbdd955175cb7da4931a4868cd3cd155
│   ├── cgroup.clone_children
│   ├── cgroup.event_control
│   ├── cgroup.procs
│   ├── cpuacct.stat
│   ├── cpuacct.usage
│   ├── cpuacct.usage_percpu
│   ├── cpu.cfs_period_us
│   ├── cpu.cfs_quota_us
│   ├── cpu.rt_period_us
│   ├── cpu.rt_runtime_us
│   ├── cpu.shares
│   ├── cpu.stat
│   ├── notify_on_release
│   └── tasks

2.2、资源限制的命令和工具介绍

2.2.1、简介

默认情况下,容器没有资源的 "使用限制" -- 可以使用尽可能多的主机资源。
Docker提供了控制容器使用资源的方法,可以限制当前容器可以使用的内存数量和cpu资源。我们可以通过docker run的参数来进行简单的控制

2.2.2、资源限制的命令

]# docker run --help | grep -iE 'cpu|oom|memory'
      --cpu-period int                 Limit CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int                  Limit CPU CFS (Completely Fair Scheduler) quota
      --cpu-rt-period int              Limit CPU real-time period in microseconds
      --cpu-rt-runtime int             Limit CPU real-time runtime in microseconds
  -c, --cpu-shares int                 CPU shares (relative weight)
      --cpus decimal                   Number of CPUs
      --cpuset-cpus string             CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string             MEMs in which to allow execution (0-3, 0,1)
      --kernel-memory bytes            Kernel memory limit
  -m, --memory bytes                   Memory limit
      --memory-reservation bytes       Memory soft limit
      --memory-swap bytes              Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --memory-swappiness int          Tune container memory swappiness (0 to 100) (default -1)
      --oom-kill-disable               Disable OOM Killer
      --oom-score-adj int              Tune host's OOM preferences (-1000 to 1000)

2.2.3、docker-stress-ng压测工具的介绍

网上有一个非常好的容器压力测试工具,docker-stress-ng 我们可以基于该镜像来进行各种容量的限制测试

# 查看帮忙信息
]# docker run -it --rm lorel/docker-stress-ng:latest  | grep -iE 'cpu|mem'
       --affinity N       start N workers that rapidly change CPU affinity
 -C N, --cache N          start N CPU cache thrashing workers
       --cache-flush      flush cache after every memory write (x86 only)
 -c N, --cpu N            start N workers spinning on sqrt(rand())
       --cpu-ops N        stop when N cpu bogo operations completed
 -l P, --cpu-load P       load CPU by P %%, 0=sleep, 100=full load (see -c)
       --cpu-method m     specify stress cpu method m, default is all
       --memcpy N         start N workers performing memory copies
       --memcpy-ops N     stop when N memcpy bogo operations completed
       --vm-hang N        sleep N seconds before freeing memory
       --vm-keep          redirty memory instead of reallocating
       --vm-locked        lock the pages of the mapped region into memory

2.3、内存资源限制-实战 

2.3.1、开启两个work的容器,每个work默认占256m,当前容器占 512m【--vm】

]# docker run --name mem_stress -it --rm lorel/docker-stress-ng:latest --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

]# docker stats
CONTAINER ID   NAME         CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O     PIDS
280cbd4988f8   mem_stress   99.41%    514.2MiB / 3.612GiB   13.90%    656B / 0B         0B / 0B       5

2.3.2、调整最大的容器内存量为 100m【-m】

#  关闭容器后,调整最大的容器内存量为 100m
]# docker run --name mem_stress -it --rm -m 100m lorel/docker-stress-ng:latest --vm 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 vm

]# docker stats
CONTAINER ID   NAME         CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O        PIDS
db65e6d9b724   mem_stress   95.49%    99.94MiB / 100MiB     99.94%    656B / 0B         3.6MB / 12.6GB   5

2.4、CPU资源限制-实战 

2.4.1、查看当前的cpu信息

]# lscpu | grep CPU
CPU op-mode(s):        32-bit, 64-bit
CPU(s):                1
On-line CPU(s) list:   0
CPU 系列:          23
CPU MHz:             2894.563
NUMA 节点0 CPU:    0

2.4.2、开启使用两个cpu的容器【--cpu】

]# docker run --name cpu_stress -it --rm lorel/docker-stress-ng:latest  --cpu 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 cpu

# 查看状态
]# docker stats --no-stream
CONTAINER ID   NAME         CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O   PIDS
7f58ff01d9ef   cpu_stress   100.06%   6.016MiB / 3.612GiB   0.16%     656B / 0B   0B / 0B     3

2.4.3、调整cpu的使用数量为1,压测的CPU为2【--cpus】

# 限制只能使用一半的CPU
]# docker run --name cpu_stress -it --rm --cpus 0.5 lorel/docker-stress-ng:latest --cpu 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 cpu

# 查看状态
]# docker stats --no-stream
CONTAINER ID   NAME         CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O   PIDS
514173c9426a   cpu_stress   50.29%    6.016MiB / 3.612GiB   0.16%     586B / 0B   0B / 0B     3

2.4.5、定制cpu绑定操作【--cpuset-cpus】

]# docker run -it --rm --name cpu_stress --cpus 0.5 --cpuset-cpus 0 lorel/docker-stress-ng:latest --cpu 2
stress-ng: info: [1] defaulting to a 86400 second run per stressor
stress-ng: info: [1] dispatching hogs: 2 cpu

]# docker stats
CONTAINER ID   NAME         CPU %     MEM USAGE / LIMIT     MEM %     NET I/O     BLOCK I/O   PIDS
9cef3ce365c9   cpu_stress   49.97%    6.023MiB / 3.612GiB   0.16%     656B / 0B   0B / 0B     3

 

posted @ 2023-05-18 21:38  小粉优化大师  阅读(217)  评论(0编辑  收藏  举报