容器和编排开篇之Docker进程之cgroups

前两篇文章简单的介绍了有关容器和有关Docker的一些基本的操作和用法,也简单的说了本人对于容器的基本理解和工作中使用docker的情况,这个系列定调在容器的原理和编排方面,前面文章中一笔带过的东西我将深入的做阐述和研究。

本文的目的是告诉大家容器其实也没有什么特别的神奇的地方,对于操作系统来说它也是一个进程,也是一个从磁盘上被操作系统装载的二进制文件。那么容器技术带来的这个进程和其他进程有什么区别呢或者说容器到底做了什么呢?

容器技术的核心功能,就是通过约束和修改进程的动态表现,从而创造出一个边界,那么如何实现所谓的创造一个边界呢?
Docker等容器技术是依靠Linux内核提供的cgroup技术来制造约束,而通过namespaces技术来时动态修改进程的表现。
我们先围绕什么是cgroups展开本文。

那什么是cgroups呢?
CGroup 是 Control Groups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组 (process groups) 所使用的物力资源 (如 cpu memory i/o 等等) 的机制。2007 年进入 Linux 2.6.24 内核,CGroups 不是全新创造的,它将进程管理从 cpuset 中剥离出来。可以看出cgroups主要限制了容器进程对于计算机硬件或者物理资源的使用,不至于当系统中存在大量容器的时候某些进程无限制的使用计算机资源造成系统假死等现象。来看下cgroups在Linux下究竟使用和体现。作为一个万物都是文件的系统,Linux下的cgroup自然也是文件。

CGroup 功能及组成

CGroup 是将任意进程进行分组化管理的 Linux 内核功能。CGroup 本身是提供将进程进行分组化管理的功能和接口的基础结构,I/O 或内存的分配控制等具体的资源管理功能是通过这个功能来实现的。这些具体的资源管理功能称为 CGroup 子系统或控制器。CGroup 子系统有控制内存的 Memory 控制器、控制进程调度的 CPU 控制器等。运行中的内核可以使用的 Cgroup 子系统由/proc/cgroup 来确认。

[root@lokie-web ~]# ls /proc/cgroups 
/proc/cgroups

CGroup 提供了一个 CGroup 虚拟文件系统,作为进行分组管理和各子系统设置的用户接口。要使用 CGroup,必须挂载 CGroup 文件系统。这时通过挂载选项指定使用哪个子系统。
来看下在Linux下如何应用cgroups限制一个进程的cpu使用。
cgroup已文件和目录的方式组织在操作系统的/sys/fs/cgroup下

[root@lokie-web ~]# ls /sys/fs/cgroup/
blkio  cpu  cpuacct  cpu,cpuacct  cpuset  devices  freezer  hugetlb  memory  net_cls  net_cls,net_prio  net_prio  perf_event  pids  systemd

也可以通过

 mount -t cgroup
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)

那对于cpu我们可以看到有

ls /sys/fs/cgroup/cpu
cgroup.clone_children  cgroup.procs          cpuacct.stat   cpuacct.usage_percpu  cpu.cfs_quota_us  cpu.rt_runtime_us  cpu.stat  notify_on_release  system.slice  user.slice
cgroup.event_control   cgroup.sane_behavior  cpuacct.usage  cpu.cfs_period_us     cpu.rt_period_us  cpu.shares         docker    release_agent      tasks

好如何使用呢这些配置文件呢?

[root@lokie-web cpu]# mkdir container #创建一个新的组
[root@lokie-web cpu]# ls container/ 
cgroup.clone_children  cgroup.procs  cpuacct.usage         cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release
cgroup.event_control   cpuacct.stat  cpuacct.usage_percpu  cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    tasks

通过执行

[root@localhost cpu]# echo 'while True: pass'|python &
[1] 8994

[root@localhost cpu]# echo 50000 >/sys/fs/cgroup/cpu/container/cpu.cfs_quota_us
[root@localhost cpu]# top
top - 22:48:47 up 127 days, 11:15,  5 users,  load average: 2.34, 1.56, 1.33
Tasks: 290 total,   2 running, 288 sleeping,   0 stopped,   0 zombie
%Cpu(s): 10.4 us,  0.6 sy,  0.0 ni, 88.4 id,  0.1 wa,  0.0 hi,  0.5 si,  0.0 st
KiB Mem :  3876192 total,   314580 free,  3075640 used,   485972 buff/cache
KiB Swap:  8388604 total,  5817712 free,  2570892 used.   532504 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                         
 8994 root      20   0  123208   4432   1940 R  89.5  0.1   0:09.07 python  
 

此时cpu 100%

echo 8994 > /sys/fs/cgroup/cpu/foo/tasks 
[root@localhost cpu]# top

top - 22:49:28 up 127 days, 11:15,  5 users,  load average: 1.79, 1.51, 1.32
Tasks: 290 total,   2 running, 288 sleeping,   0 stopped,   0 zombie
%Cpu(s): 11.5 us,  0.3 sy,  0.0 ni, 88.0 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
KiB Mem :  3876192 total,   313496 free,  3076672 used,   486024 buff/cache
KiB Swap:  8388604 total,  5817804 free,  2570800 used.   531412 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                         
 8994 root      20   0  123208   4432   1940 R  49.5  0.1   0:46.05 python      
 

以上结果表明生效,CPU被限制为50%.

那对于docker是怎么体现这个限制的呢?如何设置呢?毫无疑问是通过docker run命令加参数来实现的。

docker run --help | grep cpu
  --cpu-count int                         CPU count (Windows only)
  --cpu-percent int                       CPU percent (Windows only)
  --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 (default 0.000)
  --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)

来看下是不是创建了cgoups
docker的cgroups路径,很明显在
/sys/fs/cgroup/cpu/docker
根据每个容器都有个uuid组,如下:

[root@localhost docker]# ls
2da17847579a2e33ce13fd5740c0412ceca2910886303408248685e28b76915d  cgroup.procs          cpu.rt_runtime_us
6f3e7c28e465ef224a63d4f30884ef0e0e6251bcff97b56db47a8d693c1d4855  cpuacct.stat          cpu.shares
716146baed45fd69ec8e9ff8e8f6d44538076a6225f7db667351176d875c4117  cpuacct.usage         cpu.stat
866ebb91d7ed3778936caa8a31b88d0c6c3febab3ee2fa68992f07dcb618f313  cpuacct.usage_percpu  d82f0adca7ae2f0bc6cf0fda9832b453b735648f0480a94a6015be41c6511e51
ad93c9022f308f55cde59858407cd15872f43ae2a82b2451e7c52bc29ebc0f53  cpu.cfs_period_us     feadb6f11aec9b6b32934f2b75ff220c133df5adbb7c4448afecea2e16bdb559
cgroup.clone_children                                             cpu.cfs_quota_us      notify_on_release
cgroup.event_control                                              cpu.rt_period_us      tasks

如下过程即可证明docker是创建了cgroup来限制cpu使用的

docker run --cpu-rt-period 20000 -d redis 
dd3c56a92a824d68c4a92f038737de09bd9534f55d37040d8680e750e49dda0d
[root@localhost docker]# docker ps
CONTAINER ID        IMAGE                                    COMMAND                  CREATED             STATUS              PORTS                    NAMES
dd3c56a92a82        redis                                    "docker-entrypoint..."   8 seconds ago       Up 5 seconds        6379/tcp                 heuristic_roentgen
716146baed45        redis                                    "docker-entrypoint..."   7 months ago        Up 4 months         0.0.0.0:6379->6379/tcp   clever_wescoff
6f3e7c28e465        dotnet                                   "bash"                   22 months ago       Up 4 months         0.0.0.0:8086->80/tcp     supplierApi
2da17847579a        dotnet                                   "bash"                   22 months ago       Up 4 months         0.0.0.0:8085->80/tcp     openevalApi
feadb6f11aec        microsoft/dotnet:latest                  "bash"                   22 months ago       Up 4 months         0.0.0.0:8084->80/tcp     fileApi
ad93c9022f30        dotnet:latest                            "bash"                   23 months ago       Up 4 months         0.0.0.0:8083->80/tcp     tradeApi
866ebb91d7ed        microsoft/dotnet:1.1.0-sdk-projectjson   "bash"                   23 months ago       Up 4 months         0.0.0.0:8081->80/tcp     toolapi
d82f0adca7ae        mysql:5.6                                "docker-entrypoint..."   23 months ago       Up 4 months         0.0.0.0:3306->3306/tcp   mysql
[root@localhost docker]# cat dd3c56a92a824d68c4a92f038737de09bd9534f55d37040d8680e750e49dda0d/cpu
cpuacct.stat          cpuacct.usage_percpu  cpu.cfs_quota_us      cpu.rt_runtime_us     cpu.stat              
cpuacct.usage         cpu.cfs_period_us     cpu.rt_period_us      cpu.shares            
[root@localhost docker]# cat dd3c56a92a824d68c4a92f038737de09bd9534f55d37040d8680e750e49dda0d/cpu.rt_period_us 
20000

下篇文章会详细研究namespace对于docker的作用

Lokie博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论
  • 本博客使用免费开源的 laravel-bjyblog v5.5.1.1 搭建 © 2014-2018 lokie.wang 版权所有 ICP证:沪ICP备18016993号
  • 联系邮箱:kitche1985@hotmail.com