Linux运维知识之容器之 CGroup
小标 2019-03-15 来源 : 阅读 751 评论 0

摘要:本文主要向大家介绍Linux运维知识之容器之 CGroup了,通过具体的内容向大家展现,希望对大家学习Linux运维知识有所帮助。

本文主要向大家介绍Linux运维知识之容器之 CGroup了,通过具体的内容向大家展现,希望对大家学习Linux运维知识有所帮助。

<


  

   <div id="content-index" style="margin:0 0 10px 10px;float:right;"><div>文章目录</div><span>[<a id="content-index-togglelink" href="javascript:content_index_toggleToc()">隐藏</a>]</span>
<script type="text/javascript" language="javascript">
window.content_index_showTocToggle=true;function content_index_toggleToc(){var tts="显示";var tth="隐藏";if(window.content_index_showTocToggle){window.content_index_showTocToggle=false;document.getElementById("content-index-contents").style.display="none";document.getElementById("content-index-togglelink").innerHTML=tts}else{window.content_index_showTocToggle=true;document.getElementById("content-index-contents").style.display="block";document.getElementById("content-index-togglelink").innerHTML=tth}}
</script>
<ul id="content-index-contents"><li><a href="https://www.centos.bz/2018/08/%e5%ae%b9%e5%99%a8%e4%b9%8b-cgroup/#简介" title="简介"><span>简介</span></a></li><li><a href="https://www.centos.bz/2018/08/%e5%ae%b9%e5%99%a8%e4%b9%8b-cgroup/#使用简介" title="使用简介"><span>使用简介</span></a><ul><li><a href="https://www.centos.bz/2018/08/%e5%ae%b9%e5%99%a8%e4%b9%8b-cgroup/#使用步骤" title="使用步骤"><span>使用步骤</span></a></li><li><a href="https://www.centos.bz/2018/08/%e5%ae%b9%e5%99%a8%e4%b9%8b-cgroup/#CPU" title="CPU"><span>CPU</span></a></li><li><a href="https://www.centos.bz/2018/08/%e5%ae%b9%e5%99%a8%e4%b9%8b-cgroup/#内存" title="内存"><span>内存</span></a></li></ul></li><li><a href="https://www.centos.bz/2018/08/%e5%ae%b9%e5%99%a8%e4%b9%8b-cgroup/#systemd" title="systemd"><span>systemd</span></a><ul><li><a href="https://www.centos.bz/2018/08/%e5%ae%b9%e5%99%a8%e4%b9%8b-cgroup/#常见命令" title="常见命令"><span>常见命令</span></a></li></ul></li><li><a href="https://www.centos.bz/2018/08/%e5%ae%b9%e5%99%a8%e4%b9%8b-cgroup/#libcgroup" title="libcgroup"><span>libcgroup</span></a></li><li><a href="https://www.centos.bz/2018/08/%e5%ae%b9%e5%99%a8%e4%b9%8b-cgroup/#参考" title="参考"><span>参考</span></a></li></ul></div>
<p>在 <a href="https://www.centos.bz/tag/centos/">CentOS</a> 7 中,已经通过 systemd 替换了之前的 <a href="https://www.centos.bz/tag/cgroup/">cgroup</a>-tools 工具,为了防止两者冲突,建议只使用 systemd ,只有对于一些不支持的,例如 net_prio ,才使用 cgroup-tools 工具。</p>
<p>在此,简单介绍其使用。</p>
<h2 id="简介">简介</h2>
<p>在系统设计时,经常会遇到类似的需求,就是希望能限制某个或者某些进程的分配资源。</p>
<p>由此,就有了容器的概念,在容器中,有分配好的特定比例的 CPU、IO、内存、网络等资源,这就是 controller group ,简称为 cgroup ,最初由 <a href="https://www.centos.bz/tag/google/">Google</a> 工程师提出,后来被整合进 <a href="https://www.centos.bz/tag/linux/">Linux</a> 内核中。</p>
<p>cgroup 本身提供了将进程进行分组化管理的功能和接口的基础结构。</p>
<h2 id="使用简介">使用简介</h2>
<p>在 CentOS 7 中需要通过 yum install libcgroup libcgroup-tools 安装额外的 cgroup 工具,对系统来说,默认会挂载到 /sys/fs/cgroup/ 目录下。</p>
<pre><code>----- 查看系统已经存在cgroup子系统及其挂载点
# lssubsys -am
----- 或者通过<a href="https://www.centos.bz/tag/mount/">mount</a>查看cgroup类型的挂载点
# mount -t cgroup

----- 可以命令行挂载和卸载子系统,此时再次执行上述命令将看不到memory挂载点
# umount /sys/fs/cgroup/memory/
----- 挂载cgroup的memory子系统,其中最后的cgroup参数是在/proc/mounts中显示的名称
# mount -t cgroup -o memory cgroup /sys/fs/cgroup/memory/
# mount -t cgroup -o memory none /sys/fs/cgroup/memory/
</code></pre>
<p>另外,在 CentOS 中有 /etc/cgconfig.conf 配置文件,该文件中可用来配置开机自动启动时挂载的条目:</p>
<pre><code>mount {
    net_prio = /sys/fs/cgroup/net_prio;
}
</code></pre>
<p>然后,通过 systemctl restart cgconfig.service 重启服务即可,然后可以通过如下方式使用。</p>
<h3 id="使用步骤">使用步骤</h3>
<p>简单介绍如何通过 libcgroup-tools 创建分组并设置资源配置参数。</p>
<p><strong>1. 创建控制组群</strong></p>
<p>可以通过如下方式创建以及删除群组,创建后会在 cpu 挂载目录下 /sys/fs/cgroup/cpu/ 目录下看到一个新的目录 test,这个就是新创建的 cpu 子控制组群。</p>
<pre><code># cgcreate -g cpu:/test
# cgdelete -g cpu:/test
</code></pre>
<p><strong>2. 设置组群参数</strong></p>
<p>cpu.shares 是控制 CPU 的一个属性,更多的属性可以到 /sys/fs/cgroup/cpu 目录下查看,默认值是 1024,值越大,能获得更多的 CPU 时间。</p>
<pre><code># cgset -r cpu.shares=512 test
</code></pre>
<p><strong>3. 将进程添加到控制组群</strong></p>
<p>可以直接将需要执行的命令添加到分组中。</p>
<pre><code>----- 直接在cgroup中执行
# cgexec -g cpu:small some-program
----- 将现有的进程添加到cgroup中
# cgclassify -g subsystems:path_to_cgroups pidlist
</code></pre>
<p>例如,想把 sshd 添加到一个分组中,可以通过如下方式操作。</p>
<pre><code># cgclassify -g cpu:/test `pidof sshd`
# cat /sys/fs/cgroup/cpu/test/tasks
</code></pre>
<p>就会看到相应的进程在这个文件中。</p>
<h3 id="CPU">CPU</h3>
<p>在 CGroup 中,与 CPU 相关的子系统有 cpusets、cpuacct 和 cpu 。</p>
<ul>
<li>CPUSET 用于设置CPU、内存的亲和性,可以指定运行CPU或者不运行在某个CPU上,一般只会在一些高性能场景使用。</li>
<li>CPUACCT 显示当前cgroup所用CPU的统计信息。</li>
</ul>
<p>这里简单介绍 cpu 子系统,包括怎么限制 cgroup 的 CPU 使用上限及与其它 cgroup 的相对值。</p>
<p><strong>cpu.cfs_period_us &amp; cpu.cfs_quota_us</strong></p>
<p>其中 cfs_period_us 用来配置时间周期长度;cfs_quota_us 用来配置当前 cgroup 在设置的周期长度内所能使用的 CPU 时间数,两个文件配合起来设置 CPU 的使用上限。</p>
<p>两个文件单位是微秒,cfs_period_us 的取值范围为 [1ms, 1s],默认 100ms ;cfs_quota_us 的取值大于 1ms 即可,如果 cfs_quota_us 的值为 -1(默认值),表示不受 cpu 时间的限制。</p>
<p>下面是几个例子:</p>
<pre><code>----- 1.限制只能使用1个CPU,每100ms能使用100ms的CPU时间
# echo 100000 &gt; cpu.cfs_quota_us
# echo 100000 &gt; cpu.cfs_period_us

------ 2.限制使用2个CPU核,每100ms能使用200ms的CPU时间,即使用两个内核
# echo 200000 &gt; cpu.cfs_quota_us
# echo 100000 &gt; cpu.cfs_period_us

------ 3.限制使用1个CPU的50%,每100ms能使用50ms的CPU时间,即使用一个CPU核心的50%
# echo 50000 &gt; cpu.cfs_quota_us
# echo 100000 &gt; cpu.cfs_period_us
</code></pre>
<p><strong>cpu.shares</strong></p>
<p>用于设置相对值,这里针对的是所有 CPU (多核),默认是 1024,假如系统中有两个 A(1024) 和 B(512),那么 A 将获得 1024/(1204+512)=66.67% 的 CPU 资源,而 B 将获得 33% 的 CPU 资源。</p>
<p>对于 shares 有两个特点:</p>
<ul>
<li>如果A不忙,没有使用到66%的CPU时间,那么剩余的CPU时间将会被系统分配给B,即B的CPU使用率可以超过33%;</li>
<li>添加了一个新的C,它的shares值是1024,那么A和C的限额变为1024/(1204+512+1024)=40%,B的资源变成了20%;</li>
</ul>
<p>也就是说,在空闲时 shares 基本上不起作用,只有在 CPU 忙的时候起作用。但是这里设置的值是需要与其它系统进行比较,而非设置了一个绝对值。</p>
<p><strong>示例</strong></p>
<p>演示一下如何控制CPU的使用率。</p>
<pre><code>----- 创建并查看当前的分组
# cgcreate -g cpu:/small
# ls /sys/fs/cgroup/cpu/small

----- 查看当前值,默认是1024
# cat /sys/fs/cgroup/cpu/small/cpu.shares
# cgset -r cpu.shares=512 small

----- 执行需要运行的程序,或者将正在运行程序添加到分组
# cgexec -g cpu:small ./foobar
# cgclassify -g cpu:small &lt;PID&gt;

----- 设置只能使用1个cpu的20%的时间
# echo 50000 &gt; cpu.cfs_period_us
# echo 10000 &gt; cpu.cfs_quota_us

----- 将当前bash加入到该cgroup
# echo $$
5456
# echo 5456 &gt; cgroup.procs

----- 启动一个bash内的死循环,正常情况下应该使用100%的cpu,消耗一个核
# while :; do echo test &gt; /dev/null; done
</code></pre>
<p>注意,如果是在启动进程之后添加的,实际上 CPU 资源限制的速度会比较慢,不是立即就会限制死的,而且不是严格准确。如果起了多个子进程,那么各个进程之间的资源是共享的。</p>
<p><strong>其它</strong></p>
<p>可以通过如下命令查看进程属于哪个 cgroup 。</p>
<pre><code># ps -O cgroup
# cat /proc/PID/cgroup
</code></pre>
<h3 id="内存">内存</h3>
<p>相比来说,内存控制要简单的多,只需要注意物理内存和 SWAP 即可。</p>
<pre><code>----- 创建并查看当前的分组
# cgcreate -g memory:/small
# ls /sys/fs/cgroup/memory/small

----- 查看当前值,默认是一个很大很大的值,设置为1M
# cat /sys/fs/cgroup/memory/small/memory.limit_in_bytes
# cgset -r memory.limit_in_bytes=10485760 small

----- 如果开启了swap之后,会发现实际上内存只限制了RSS,设置时需要确保没有进程在使用
# cgset -r memory.memsw.limit_in_bytes=104857600 small

----- 启动测试程序
# cgexec -g cpu:small -g memory:small ./foobar
# cgexec -g cpu,memory:small ./foobar
</code></pre>
<p><strong>OOM</strong></p>
<p>当进程试图占用的内存超过了 cgroups 的限制时,会触发 out of memory 导致进程被强制 kill 掉。</p>
<pre><code>----- 关闭默认的OOM
# echo 1 &gt; memory.oom_control
# cgset -r memory.oom_control=1 small
</code></pre>
<p>注意,及时关闭了 OOM,对应的进程会处于 uninterruptible sleep 状态。</p>
<h2 id="systemd">systemd</h2>
<p>CentOS 7 中默认的资源隔离是通过 systemd 进行资源控制的,systemd 内部使用 cgroups 对其下的单元进行资源管理,包括 CPU、BlcokIO 以及 MEM,通过 cgroup 可以 。</p>
<p>systemd 的资源管理主要基于三个单元 service、scope 以及 slice:</p>
<ul>
<li>service<br>
通过 unit 配置文件定义,包括了一个或者多个进程,可以作为整体启停。</li>
<li>scope<br>
任意进程可以通过 fork() 方式创建进程,常见的有 session、container 等。</li>
<li>slice<br>
按照层级对 service、scope 组织的运行单元,不单独包含进程资源,进程包含在 service 和 scope 中。</li>
</ul>
<p>常用的 slice 有 A) system.slice,系统服务进程可能是开机启动或者登陆后手动启动的服务,例如crond、mysqld、<a href="https://www.centos.bz/category/web-server/nginx/">nginx</a>等服务;B) user.slice 用户登陆后的管理,一般为 session;C) machine.slice 虚机或者容器的管理。</p>
<p>对于 cgroup 默认相关的参数会保存在 /sys/fs/cgroup/ 目录下,当前系统支持的 subsys 可以通过 cat /proc/cgroups 或者 lssubsys 查看。</p>
<h3 id="常见命令">常见命令</h3>
<p>常用命令可以参考如下。</p>
<pre><code>----- 查看slice、scope、service层级关系
# systemd-cgls

----- 当前资源使用情况
# systemd-cgtop

----- 启动一个服务
# systemd-run --unit=name --scope --slice=slice_name command
   unit   用于标示,如果不使用会自动生成一个,通过systemctl会输出;
   scope  默认使用service,该参数指定使用scope ;
   slice  将新启动的service或者scope添加到slice中,默认添加到system.slice,
          也可以添加到已有slice(systemctl -t slice)或者新建一个。
# systemd-run --unit=toptest --slice=test top -b
# systemctl stop toptest

----- 查看当前资源使用状态
$ systemctl show toptest
</code></pre>
<p>各服务配置保存在 /usr/lib/systemd/system/ 目录下,可以通过如下命令设置各个服务的参数。</p>
<pre><code>----- 会自动保存到配置文件中做持久化
# systemctl set-property name parameter=value

----- 只临时修改不做持久化
# systemctl set-property --runtime name property=value

----- 设置CPU和内存使用率
# systemctl set-property <a href="https://www.centos.bz/tag/httpd/">httpd</a>.service CPUShares=600 MemoryLimit=500M
</code></pre>
<p>另外,在 213 版本之后才开始支持 CPUQuota 参数,可直接修改 cpu.cfs_{<a href="https://www.centos.bz/tag/quota/">quota</a>,period}_us 参数,也就是在 /sys/fs/cgroup/cpu/ 目录下。</p>
<h2 id="libcgroup">libcgroup</h2>
<p>基于 libcgroup 实现一套容器的管理,详细的文档可以参考 //libcg.sourceforge.net/html/index.html 中的相关介绍。</p>
<p>可以参考 <a href="https://www.centos.bz/tag/https/">https</a>://<a href="https://www.centos.bz/tag/github/">github</a>.com/geokat/cgfy 中的实现,该程序是通过 libcgroup 实现,功能类似于 cgexec 。</p>
<p>另外,也可以参考 https://github.com/vodik/clique ,是直接利用 DBus 与 Systemd 进行通讯。</p>
<h2 id="参考">参考</h2>
<p>关于 systemd 的资源控制,详细可以通过 man 5 systemd.resource-control 命令查看帮助,或者查看 //www.jinbuguo.com/systemd/systemd.resource-control.html 中文手册;详细的内容可以参考 https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/resource_management_guide/index</p>            <p>原文出处:github -&gt; <a rel="nofollow" href="https://jin-yang.github.io/post/linux-container-cgroup-introduce.html">https://jin-yang.github.io/post/linux-container-cgroup-introduce.html</a></p>      

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注系统运维Linux频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程