• Docker 原理探索:cgroups


    简介

    这是 《容器和容器云》的阅读笔记,本文主要关于 cgroups。cgroups 提供了物理资源控制的相关机制,可以控制不同子系统上的资源分配,比如 cpu,内存等。cgroups 核心有四个概念。任务,指的是进程或者线程。控制组,资源控制以组为单位。子系统,资源调度控制器,比如 CPU 子系统可以控制 CPU 时间分配。层级,cgroups 会有层级,系统默认的 cgroups 里面会包含所有的任务,通过在这个 cgroups 下面创建不同的子 cgroups 来将不同的任务加入到子 cgroups 来实现分组控制。

    cgroups 以文件系统的方式进行操作,通过操作文件系统可以进行资源限制,优先级分配,资源统计,任务控制。换言之,cgroups 的使用方式,就是操作目录那么简单。

    规则

    前面提到了 cgroups 中的四个重要概念:任务,控制组,子系统,层级。下面分析它们相互间的关系。

    1. 同一层级可以附加多个子系统
    2. 一个子系统可以附加到多个层级,当且仅当目标层级只有一个子系统。
    3. 新建一个层级时,所有任务默认加入新建层级的初始化 cgroup。
    4. 任务只能存在于同个层级中的一个 cgroup,能存在于多个层级中的多个 cgroup
    5. fork/clone 子任务的创建,默认加入父任务的 cgroup。

    子系统

    子系统可以通过下面的命令列举,在 /sys/fs/cgroup/ 目录下面,每个目录对应一个子系统,每个目录下面的文件,代表着子系统的控制配置。通过操作这些文件,就可以控制对应的资源。比如 cpu.shares 这个文件,可以控制任务在 CPU 上的执行时间权重,默认是 1024,权重越大,被调度到的机会越大。cgroups 的实现原理,本质上是给任务加上钩子,当涉及某种资源时,就触发钩子上附带的子系统。cgroup 和任务之间是多对多的关系。

    (base) percent1@ubuntu:~$ mount -t cgroup
    cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
    cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
    cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
    cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
    cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
    cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
    cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
    cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
    cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
    cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
    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)
    

    Docker 和 cgroups

    通过下面的命令,可以创建一个在 cpu 子系统下面的控制组,控制组里面的文件,都是 cgroups 自动生成的。只要往 cgroup.procs 里面写 pid,就可以将进程加入到对应的控制组里面。

    (base) percent1@ubuntu:~/code$ 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  rdma  systemd  unified
    (base) percent1@ubuntu:/sys/fs/cgroup/cpu$ sudo mkdir cg1
    [sudo] password for percent1: 
    (base) percent1@ubuntu:/sys/fs/cgroup/cpu$ ls cg1   # 下面这些都是系统生成的
    cgroup.clone_children  cpuacct.stat   cpuacct.usage_all     cpuacct.usage_percpu_sys   cpuacct.usage_sys   cpu.cfs_period_us  cpu.shares  notify_on_release
    cgroup.procs           cpuacct.usage  cpuacct.usage_percpu  cpuacct.usage_percpu_user  cpuacct.usage_user  cpu.cfs_quota_us   cpu.stat    tasks
    

    Docker 和 cgroups:docker 会在 /sys/fs/cgroup/docker 这个控制组下面,为每个容器创建一个子控制组。比如我们可以使用下面的命令,启动一个容器。根据容器 id,可以找到对应的目录,并且在 cpu 子目录里面,可以看到 cpu.shares 的权重。

    # 终端1 绑定一个容器
    (base) root@ubuntu:~/code/cmake_cpp_cuda/build# docker run -it --rm --cpu-shares 10000  busybox
    / # 
    
    # 终端2 可以查看
    (base) percent1@ubuntu:/sys/fs/cgroup/cpu$ docker container ls
    ...  # 根据 container id 找到对应的目录
    (base) percent1@ubuntu:/sys/fs/cgroup/cpu$ cat docker/71f8e3aef5d17b60ecf7c1fedd0a82227bb1ade4b7da88013e4f2a00132e56a2/cpu.shares 
    10000
    

    总结

    通过上面的简单探索,对 cgroups 有一个感性的认识。Docker 使用它来资源限制,优先级分配,资源统计,任务控制等,核心概念有四个:任务,子系统,控制组,cgroups 层级。

  • 相关阅读:
    SAP C4C基于自定义BO开发的OWL UI,如何实现动态访问控制
    如何将SAP C4C自定义BO中类型为图片的附件用PDF文档显示出来
    如何使用SAP Cloud Application Studio创建一个PDF form
    如何让SAP C4C自定义BO实现附件上传的功能
    分盘存储:实现数据库备集群备份文件分散存储
    智能对联模型太难完成?华为云ModelArts助你实现!手把手教学
    五种C语言非数值计算的常用经典排序算法
    软件教练说:性能优化与性能设计,“相亲相爱”的一对
    两种端到端通用目标检测方法
    架构解读丨Volcano作业资源预留设计原理
  • 原文地址:https://www.cnblogs.com/zzk0/p/16133659.html
Copyright © 2020-2023  润新知