容器的资源限制
本文最后更新于110 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

OOME:资源用多了,系统为了维持内核运转会随机杀死进程

1.Cgroup

Linux Cgroup 全称 Linux Control Group, 是 Linux 内核的一个功能,用来限制,控制与分离(想要把其中的几个进程剥离出来限制就是分离)一个进程组群的资源(如 CPU、内存、磁盘输入输出等)。这个项目最早是由 Google 的工程师在 2006 年发起,最早的名称为进程容器( process containers 在一些比较老的古籍里可以看见叫这个)。在 2007 年时,因为在 Linux 内核中,容器(container)这个名词太过广泛,为避免混乱,被重命名为 cgroup,并且被合并到 2.6.24 版的内核中去

  • 限制资源使用————核心功能
  • 优先级控制
  • 一些审计或一些统计(比如每个进程消耗的数量)
  • 挂起进程,恢复执行进程

子系统

(了解一下,太底层了,知识有限,没看懂。)在挂载完Cgroup之后,会显示当前挂载的目录,在目录下有各个子系统的目录

file

cpu     子系统,主要限制进程的cpu使用率
cpuacct 子系统,可以统计 cgroups 中的进程的 cpu 使用报告
cpuset  子系统,可以为cgroups 中的进程分配单独的cpu 节点或者内存节点
memory  子系统,可以限制进程的 memory 使用量
blkio   子系统,可以限制进程的块设备io
devices 子系统,可以控制进程能够访问某些设备
net_cls 子系统,可以标记 cgroups 中进程的网络数据包,然后可以使用 tc 模块(trafficcontrol)对数据包进行控制
net_prio 这个子系统用来设计网络流量的优先级
freezer 子系统,可以挂起或者恢复cgroups 中的进程
ns   子系统,可以使不同 cgroups 下面的进程使用不同的 namespace
hugetlb 这个子系统主要针对于HugeTLB系统进行限制,这是一个大页文件系统

原理

docker就是利用Cgroup来进行的限制

# 查看 Cgroup 挂载点    

[root@master ~]# mount -t cgroup

# 创建隔离组

[root@master cpu]# cd /sys/fs/cgroup/cpu

[root@master cpu]# mkdir cpu_test
[root@master cpu]# vim main.c
# 示例代码(这是C语言的,是源码,需要先转为可执行文件,然后才能执行,用gcc编译成可执行文件),无限循环占用CPU资源

int main(void)

{ 

int i = 0;
for(;;) i++;
return 0;
}
[root@master cpu]# gcc main.c
[root@master cpu]# ./main.c
[root@master cpu]# echo 20000 > /sys/fs/cgroup/cpu/cpu_test/cpu.cfs_quota_us

[root@master cpu]# echo 23732 >> /sys/fs/cgroup/cpu/cpu_test/tasks
top查看CPU使用情况

不限制的情况下容器会用物理机的所有内存

  • 挂载完Cgroup后可以看见一堆子系统的目录
    子系统的目录下有好多文件,就相当于CPU子系统的根空间,如果想对某些进程进行限制,就可以创建对应的目录,目录相当于进程组名,把它的进程号放在目录下的tasks中,tasks文件记录了当前子空间的所有可以被限制的进程
    想要对它限制的话,需要有配额和周期,资源使用率=配额除以周期
    系统默认的配额是十万,想给多少给多少,cpu.cfs_quota_us
    在限额附近浮动,不可能正好相等
    子系统下可以有子系统,但是要被上级空间约束,下级使用率不能超过上级

过程原理小结:

  • 挂载Cgroup——去/sys/fs/cgroup/cpu目录下——找对应的文件(或者创建新的目录,把进程加入这个目录的tasks中)——修改cpu.cfs_quota_us进行限制配额
    file

2.内存限制

默认情况下,如果不对容器做任何限制,容器能够占用当前系统能给容器提供的所有资源

  • Docker 限制可以从 Memory、CPU、Block I/O 三个方面(磁盘I/O限制没啥意义)

  • OOME:Out Of Memory Exception
    一旦发生 OOME,任何进程都有可能被杀死,包括 docker daemon 在内
    为此,Docker 调整了 docker daemon 的 OOM 优先级,以免被内核关闭

    file

    -m,--memory 最小4M
    -memory-swap 物理+虚拟!!!
    --memory-reservation
    软限制,李纳斯认为,有资源不用是王八蛋,所以如果设置软限制为50
    你最大可以硬限制为100,内存不一样,linux中对应的使用策略不一样
    一般用于测试环境中
    --oom-kill-disable
    相当于免死金牌,但是这很危险,所以一般是先给他做限制,然后再给金牌
    一般用于比较重要的服务,不如数据库
    --oom-score-adj 优先级,越小越不容易被杀死,越大越容易被杀
    --memory-swappiness
    当年内存不够大,才搞得虚拟内存,现在基本不用虚拟内存,大于16G可以关闭
    一般来说有策略,八二分,有的进程必须要物理内存才能启动,所以他可以设置策略
    --kernel-memory 给内核留点内存,内核也要运行,当然一般不用管,容器内无法影响外部

file


3.CPU限制

默认情况下,如果不对容器做任何限制,容器能够占用当前系统中的所有 CPU 资源

大多数进程是采用 CFS 调度算法,CFS是内核本身提供的公平算法,平均分配资源到每个进程
1.13 Docker 版本后支持实时调度算法

file

  • --cpuset(-cpus)="" -cpus是--cpuset的缩写,可以写0-3 0-2,4 1,2,3
  • -c,--cpu-share=0 三个CPU可以用到300%,默认权重是2048,都不设置就是公平调度
  • --cpuset-merms="" 可以选择对应的内存节点,就是假如选择1这个内存上读写,数据量不大,那么速度快一点
  • --cpus 这里说的是CPU核心的数量,可以和第一个结合,使用1,2,3核心,但是总数是2,那么可以1用50%,2用25%,3用25%。支持小数,支持0.01

测试命令

# lorel/docker-stress-ng:latest stress -vm 2
# 这是一个乌班图封装的镜像,后面的stress 就是用两个线程同时进行内存压测
# 内存压测原理很简单,就是不断地加加加
docker run --name stress -it --rm -m 256m lorel/docker-stress-ng:latest stress -vm 2

docker run --name stress -it --rm --cpus 2 lorel/docker-stress-ng:latest stress --cpu 8

docker run --name stress -it --rm --cpuset-cpus 0 lorel/docker-stress-ng:latest stress --cpu 8

扩展

为什么只有OOME,限制内存,没有OOCE,OODE(CPU和磁盘)限制?

因为:

资源分类
    可压缩性资源
        磁盘I/O,网络I/O,CPU都是可压缩,压缩一些影响不大,原本每顿吃100元,现在吃50,不会死
    不可压缩性资源
        内存    他需要承载进程,启动进程,如果内存不够大,压根加载不起来,那就啥也干不了,所以他是不可压缩  

UMA:内存一致性架构

把所有内存当做一个整体,CPU也当做一个整体
如果只插一个内存条,那么四个CPU都能调用这个内存条,一家的,但是不容易横向扩展,地址总线也不好设计

NUMA:内存非一致性架构

分家了,一个CPU管几个内存条
内存传输的更快,横向扩展方便
缺点:比如1的内存用完了,但是CPU资源还有很多,2的内存很多,CPU满了,他们的资源不能共享
如果存储小文件,存在多个内存条上,反而更慢,如果数据量不多的话,应该在一条内存条上读写,速率更高
双通道也就是同时读两个内存

北桥:固态硬盘,传输速率比较高,一般有散热器压住的是北桥
南桥:比如USB接口,传输速率比较低

Docker 是一个基于 LXC 技术的通过 golang 开发的高级容器引擎 托管在 github 之上遵循 apache 协议开源。 Docker 使用了大量的 Linux kernel 原生的机制。比如:

  • 基于 CGROUP 实现资源限制
  • 基于 NS 实现隔离,像 Network 级别可以隔离网络
  • 基于 netfilter 实现 SNAT 以及 DNAT
  • 基于 VETH 设备 + bridge 实现网络的连通性
  • 基于 chroot 实现伪根
  • 基于 Overlay 实现 UFS 逻辑,像镜像的层级叠加包括可写成都是由它实现
男孩子都是香香软软的小猪
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇