行吧!让我们开始这段感情吧!
还是容器,之前咱们简单聊了一下namespace,可以把它想象成用来存储进程固定参数的盒子。如果两个进程希望彼此更进一步了解对方,那就把他们的参数放在一个盒子里,仅此而已。
OK!这样确实把相同或者不同的进程区分或者归类了。那么问题来了。我们要多大的盒子来存放这个进程?
引入我们今天的主脚cgroup!
定义(抄的):
Cgroups是control groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:cpu,memory,IO等等)的机制。
大白话:限制进程使用资源的一种内核机制。
既然是限制,那就得有最低值和最高值对吧。然后还有你不能干这个,不能干那个。你得让着点这个,让着点那个。反正就跟交通规则一样。并且呢这个规矩还可以随时变化。你得听,不听就收拾你。人生亦是如此对吧!
那么既然它是一种内核机制。那么要想使用它就得给我们提供了一个接口。这个接口就是我们最最最最常见的文件系统。记账哒!~,,配置文本文件明白没?对!就类似那玩意。
你按他的规定,在规定的文件中写上规定格式的数值它就明白你要干啥了。
一个命令解开cgroup神秘的面纱
hchen@ubuntu:~$ mount -t cgroup cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,relatime,cpuset) cgroup on /sys/fs/cgroup/cpu type cgroup (rw,relatime,cpu) cgroup on /sys/fs/cgroup/cpuacct type cgroup (rw,relatime,cpuacct) cgroup on /sys/fs/cgroup/memory type cgroup (rw,relatime,memory) cgroup on /sys/fs/cgroup/devices type cgroup (rw,relatime,devices) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,relatime,freezer) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,relatime,blkio) cgroup on /sys/fs/cgroup/net_prio type cgroup (rw,net_prio) cgroup on /sys/fs/cgroup/net_cls type cgroup (rw,net_cls) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,relatime,perf_event) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,relatime,hugetlb)
看到没?你只要执行这一句,就能把cgroup给刨出来。
别蒙圈奥,你现在就记住cgroup就是文件系统。文件系统就得可读可写。所以咱们可以往里写东西。
这些目录分别对应着不用的限制项。然后在这里面写一个最大值,写个最小值就完成了限制。
OK,如果只是想弄明白cgroup概念的同志,读到这就行了。你能大概理解是什么玩意了。其实就是一堆配置文件。
想多了解点的同志呢?
先说干的,上面出来那堆玩意是默认的,你也可以自己随便起名创建
上栗子:
测试效果,咱们先来个累死牛脚本(跑CPU的)
x=0 while [ True ];do x=$x+1 done;
注意看CPU:
mkdir -p /cgroup/cpu/foo/ #新建一个控制组foo echo 50000 > /sys/fs/cgroup/cpu/foo/cpu.cfs_quota_us #将cpu.cfs_quota_us设为50000,相对于cpu.cfs_period_us的100000是50% echo 30142 > /sys/fs/cgroup/cpu/foo/tasks #写上你要控制额进程PID到这个文件
这个tasks文件名可不能变。就得叫这个名!
再来看
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 30142 root 20 0 105m 2884 1024 R 49.4 0.2 23:32.53 sh
是不是懂啦?
我们再看刚刚创建的文件夹下面一下就多出好多东西
[root@localhost ~]# ls /sys/fs/cgroup/cpu/foo/ cgroup.event_control cgroup.procs cpu.cfs_period_us cpu.cfs_quota_us cpu.rt_period_us cpu.rt_runtime_us cpu.shares cpu.stat notify_on_release tasks
都是自动生成哒,而且都是控制CPU的哦~
是不是非常简单?再来个内存的例子:
x="a" while [ True ];do x=$x$x done;
内存给老子起!!!!!
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 30215 root 20 0 871m 501m 1036 R 99.8 26.7 0:38.69 sh 30215 root 20 0 1639m 721m 1036 R 98.7 38.4 1:03.99 sh 30215 root 20 0 1639m 929m 1036 R 98.6 49.5 1:13.73 sh
再给老子去死!!!!
mkdir -p /sys/fs/cgroup/memory/foo echo 1048576 > /cgroup/memory/foo/memory.limit_in_bytes #分配1MB的内存给这个控制组 echo 30215 > /cgroup/memory/foo/tasks
他很听话的:
[root@localhost ~]# sh /home/test.sh 已杀死
其他的类似,就不演练了。可以自己看看
那么这么挨个写的限制岂不要累死人?
上面那些我们只是简单的说了一下底层的原理,底层都是这么实现的。但是调用方式就不一样了
与操作系统类似,容器可使用的内存包括两部分:物理内存和 swap。 Docker 通过下面两组参数来控制容器内存的使用量。
- -m 或 --memory:设置内存的使用限额,例如 100M, 2G。
- --memory-swap:设置 内存+swap 的使用限额。
当我们执行如下命令:
docker run -m 200M --memory-swap=300M ubuntu
其含义是允许该容器最多使用 200M 的内存和 100M 的 swap。默认情况下,上面两组参数为 -1,即对容器内存和 swap 的使用没有限制。
下面我们将使用 progrium/stress 镜像来学习如何为容器分配内存。该镜像可用于对容器执行压力测试。执行如下命令:
docker run -it -m 200M --memory-swap=300M progrium/stress --vm 1 --vm-bytes 280M
- --vm 1:启动 1 个内存工作线程。
- --vm-bytes 280M:每个线程分配 280M 内存。
默认情况下,容器可以使用主机上的所有空闲内存。
与 CPU 的 cgroups 配置类似,docker 会自动为容器在目录 /sys/fs/cgroup/memory/docker/<容器的完整长ID>中创建相应 cgroup 配置文件。
运行结果如下:
在相应的cgroup的目录文件下写上我们所选的相关参数对其运行的容器进行限制。
总结一下:
cgroup就是一个叫cgroup的文件系统,我们可以在里面写相应的参数。然后再把相应的进行PID写进去就可以限制进程的资源使用啦!
简单不?哈哈哈哈哈哈!
下期写JWT认证吧,最近写的项目用到了。
非常牛叉的东西!