【Namespace、Cgroups】 浅析与实践(下)

说明:
Docker中使用的Namespace、Cgroups 技术来自Linux 内核(Kernel)提供的功能

资源控制:Linux Cgroups

Cgroups全称Control Groups,可以理解为把系统资源以组的形式分配给进程,是Linux内核实现资源虚拟化的技术基石,也是docker容器所用到的资源隔离技术

Cgroup是Linux内核提供的物理资源隔离机制,通过这种机制,可以实现对Linux进程或者进程组的资源限制、隔离和统计功能。比如使用特定数目的cpu核数和特定大小的内存,如果资源超限的情况下,会被暂停或者杀掉

查看Linux Cgroups

查看Cgroups都管理哪些系统资源

[root@localhost ~]# cd /sys/fs/cgroup/
[root@localhost cgroup]# ls -ll
总用量 0
drwxr-xr-x. 2 root root  0 5月  17 15:12 blkio
lrwxrwxrwx. 1 root root 11 5月  17 15:12 cpu -> cpu,cpuacct
lrwxrwxrwx. 1 root root 11 5月  17 15:12 cpuacct -> cpu,cpuacct
drwxr-xr-x. 2 root root  0 5月  17 15:12 cpu,cpuacct
drwxr-xr-x. 2 root root  0 5月  17 15:12 cpuset
drwxr-xr-x. 5 root root  0 5月  17 15:12 devices
drwxr-xr-x. 2 root root  0 5月  17 15:12 freezer
drwxr-xr-x. 2 root root  0 5月  17 15:12 hugetlb
drwxr-xr-x. 2 root root  0 5月  17 15:12 memory
lrwxrwxrwx. 1 root root 16 5月  17 15:12 net_cls -> net_cls,net_prio
drwxr-xr-x. 2 root root  0 5月  17 15:12 net_cls,net_prio
lrwxrwxrwx. 1 root root 16 5月  17 15:12 net_prio -> net_cls,net_prio
drwxr-xr-x. 2 root root  0 5月  17 15:12 perf_event
drwxr-xr-x. 5 root root  0 5月  17 15:12 pids
drwxr-xr-x. 5 root root  0 5月  17 15:12 systemd
复制代码
目录名称 说明
blkio 限制进程的块设备io速度
cpu 限制进程的 cpu 使用率
cpuacct 统计 cgroups 中的进程的 cpu 使用报告
cpuset 为cgroups中的进程分配单独的cpu节点或者内存节点
devices 控制进程能够访问某些设备
freezer 挂起或者恢复cgroups中的进程
hugetlb 限制HugeTLB的使用
memory 限制进程的memory使用量
net_cls 标记cgroups中进程的网络数据包,然后可以使用tc模块(traffic control)对数据包进行控制
net_prio 限制进程网络流量的优先级
perf_event 对cgroup进行性能监控
pids 限制一个cgroup及其子孙cgroup中的总进程数
systemd

实践Linux Cgroups

环境:这里需要打开多个连接到linux服务的session

说明:这里以redis容器为例,通过新建控制组方式,修改 memory.limit_in_bytes(控制组内可用内存信息) 将redis容器的进程ID写入到控制组cgroup.procs文件内,验证该进程是否会受到影响

  1. 安装redis
[root@localhost ~]# docker pull redis
Using default tag: latest
latest: Pulling from library/redis
69692152171a: Pull complete 
a4a46f2fd7e0: Pull complete 
bcdf6fddc3bd: Pull complete 
b7e9b50900cc: Pull complete 
5f3030c50d85: Pull complete 
63dae8e0776c: Pull complete 
Digest: sha256:365eddf64356169aa0cbfbeaf928eb80762de3cc364402e7653532bcec912973
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
redis         latest    bc8d70f9ef6c   5 days ago     105MB
tomcat        0.1       c894562ab388   11 days ago    672MB
tomcat        latest    c0e850d7b9bb   3 weeks ago    667MB
mysql         5.7.34    87eca374c0ed   4 weeks ago    447MB
mysql         latest    0627ec6901db   4 weeks ago    556MB
hello-world   latest    d1165f221234   2 months ago   13.3kB

复制代码
  1. 启动redis容器
[root@localhost ~]# docker run -itd --name redis -p 6379:6379 redis
98b12fd534709ea405a729287e966a228288b16cac2eea76162a80c999031b2f
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                       NAMES
98b12fd53470   redis:latest   "docker-entrypoint.s…"   25 seconds ago   Up 24 seconds   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp   adoring_bardeen
[root@localhost ~]# 
复制代码
  1. 创建新的cgroups
[root@localhost ~]# mkdir /sys/fs/cgroup/memory/test_memory
[root@localhost ~]# cd /sys/fs/cgroup/memory/test_memory
[root@localhost test_memory]# ls -ll
总用量 0
-rw-r--r--. 1 root root 0 5月  17 16:08 cgroup.clone_children
--w--w--w-. 1 root root 0 5月  17 16:08 cgroup.event_control
-rw-r--r--. 1 root root 0 5月  18 21:48 cgroup.procs
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.failcnt
--w-------. 1 root root 0 5月  17 16:08 memory.force_empty
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.kmem.failcnt
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.kmem.limit_in_bytes
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.kmem.max_usage_in_bytes
-r--r--r--. 1 root root 0 5月  17 16:08 memory.kmem.slabinfo
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.kmem.tcp.failcnt
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.kmem.tcp.limit_in_bytes
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.kmem.tcp.max_usage_in_bytes
-r--r--r--. 1 root root 0 5月  17 16:08 memory.kmem.tcp.usage_in_bytes
-r--r--r--. 1 root root 0 5月  17 16:08 memory.kmem.usage_in_bytes
-rw-r--r--. 1 root root 0 5月  18 21:21 memory.limit_in_bytes
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.max_usage_in_bytes
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.memsw.failcnt
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.memsw.limit_in_bytes
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.memsw.max_usage_in_bytes
-r--r--r--. 1 root root 0 5月  17 16:08 memory.memsw.usage_in_bytes
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.move_charge_at_immigrate
-r--r--r--. 1 root root 0 5月  17 16:08 memory.numa_stat
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.oom_control
----------. 1 root root 0 5月  17 16:08 memory.pressure_level
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.soft_limit_in_bytes
-r--r--r--. 1 root root 0 5月  17 16:08 memory.stat
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.swappiness
-r--r--r--. 1 root root 0 5月  17 16:08 memory.usage_in_bytes
-rw-r--r--. 1 root root 0 5月  17 16:08 memory.use_hierarchy
-rw-r--r--. 1 root root 0 5月  17 16:08 notify_on_release
-rw-r--r--. 1 root root 0 5月  17 16:08 tasks

复制代码
  1. 修改test_memory内存资源
[root@localhost test_memory]# echo '1024' > memory.limit_in_bytes 
[root@localhost test_memory]# cat memory.limit_in_bytes 
0
#(没有任何内存使用空间)
复制代码
  1. 进入redis容器内,连接客户端(先不要忙着操作)
[root@localhost test_memory]# docker run -itd --name redis -p 6379:6379 redis
f547ebda09bc69f77c6843a739bba219a509c3252ba714796680910031a5d54d
[root@localhost test_memory]#  docker exec -it redis /bin/bash
root@f547ebda09bc:/data# redis-cli -h localhost -p 6379
localhost:6379> 
复制代码
  1. 查看redis进程,将进程ID添加到cgroup.procs内
[root@localhost test_memory]# pwd
/sys/fs/cgroup/memory/test_memory
[root@localhost test_memory]# ps -ef|grep redis
polkitd   13933  13913  0 21:57 pts/0    00:00:00 redis-server *:6379
root      13974  12586  0 21:57 pts/6    00:00:00 docker exec -it redis /bin/bash
root      14006  13990  0 21:57 ?        00:00:00 redis-cli -h localhost -p 6379
root      14016  12525  0 21:58 pts/0    00:00:00 grep --color=auto redis
[root@localhost test_memory]# echo '13933' > cgroup.procs 
复制代码
  1. 对第5步开始操作(一起见证奇迹的时刻)
localhost:6379> set java 666
[root@localhost test_memory]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS                        PORTS     NAMES
f547ebda09bc   redis     "docker-entrypoint.s…"   8 minutes ago   Exited (137) 33 seconds ago             redis
# 直接挂掉

复制代码

结论:

通过获取进程ID将其加入到新的控制组内,进程是可以受到控制组资源限定的影响

欢迎大家多多评论,一起学习,一起进步

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享