k8s的Cgroup学习

Cgroups驱动

k8s有两种 cgroup 驱动:一种是 systemd,另外一种是 cgroupfs:

cgroupfs 比较好理解,比如说要限制内存是多少、要用 CPU share 为多少,其实直接把 pid 写入到对应 cgroup task 文件中,然后把对应需要限制的资源也写入相应的 memory cgroup 文件和 CPU 的 cgroup 文件就可以了;

另外一个是 systemd 的 cgroup 驱动,这个驱动是因为 systemd 本身可以提供一个 cgroup 管理方式。所以如果用 systemd 做 cgroup 驱动的话,所有的写 cgroup 操作都必须通过 systemd 的接口来完成,不能手动更改 cgroup 的文件;

kubernetes 中默认 kubelet 的 cgroup 驱动就是 cgroupfs,若要使用 systemd,则必须将 kubelet 以及 runtime 都需要配置为 systemd 驱动。

查看k8s使用的cgroup驱动
[root@iamdemo1 templates]# cat /etc/containerd/config.toml | grep Cgroup
systemdCgroup = true

k8s使用cgroup对资源进行限制从Node的Root Cgroup上到下使用了四个层级,分别是
Node-》Qos-》Pod-》Container

本质上来说,Cgroup是内核附加在程序上的一系列钩子,通过程序运行时对资源的调度触发钩子以对资源进行跟踪和限制

Pod的cgroup学习

以一个Deployment为例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: front-end
  labels:
    app: front-end
spec:
  replicas: 1
  selector:
    matchLabels:
      app: front-end
  template:
    metadata:
      labels:
        app: front-end
    spec:
      nodeSelector:
        app: demo3
      containers:
      - name: nginx
        image: autoregistry.rd.tp-link.net/auto/nginx:1.18
        imagePullPolicy: IfNotPresent
        resources:
          requests:
            cpu: 2
          limits:
            cpu: 3
        ports:
        - name: http
          containerPort: 80
          protocol: TCP

在resources下对cpu的requests和limits做出了限制,最终在部署的时候会写入Pod运行的节点的Cgroup对应文件中

(1)查看这个Pod运行的节点
[root@iamdemo1 ~]# k get pod -o wide | grep front

(2)到Pod运行的节点上,查看容器名nginx对应的CONTAINER ID
[root@iamdemo3 ~]# crictl ps | grep nginx

(3)查看对应容器的Cgroup参数
[root@iamdemo3 ~]# crictl inspect fd35fc385366c | grep -A3 cgroup

可以得到Pod对应的组目录为 kubepods-burstable-podb2253f4f_92ae_4d96_af6b_5b5f416ed2e6.slice

Container对应的目录为cri-containerd-fd35fc385366cfe4a215a4aaa6ec406c9f943c90b3f9967a405d2caa114208d5

(4)到容器所在节点的cgroup目录下
/sys/fs/cgroup/cpu/kubepods.slice/kubepods-burstable.slice
再cd kubepods-burstable-podb2253f4f_92ae_4d96_af6b_5b5f416ed2e6.slice
就可以看到当前目录有很多cpu相关参数文件

(5)cpu.shares文件的内容为2048,对应resources.requests.cpu的2

(6)cd到Container对应的目录cri-containerd-fd35fc385366cfe4a215a4aaa6ec406c9f943c90b3f9967a405d2caa114208d5.scope中查看cgroup.procs文件内容,即为Pod中的进程在宿主机上的PID,可以看到两个进程分别对应nginx的master和daemon进程

另一个目录cri-containerd-66dfbd4fabcd692b6630e3fb62304ea5f6a87a5cc22723adde339c0966a95b33.scope是Pod的Pause容器目录,Pause容器是一种特殊的容器,本身不包含任何业务逻辑,为其他容器提供一个可靠的隔离的运行环境,确保Pod中各个容器的启动顺序和依赖关系,确保容器网络连接的可靠性

image

image

image

image

image

在同一目录下,resources的cpu.cfs_quota_us÷cpu.cfs_period_us=2,即对应cpu.limit的2个cpu

image

在memory的cgroup目录下,memroy.limit是由memory.limit_in_bytes控制的
在k8s中 memory request并不会在container的cgroup文件中有所体现,调度不看memroy request

image

K8s的QoS(Quality Of Service)

QoS分为3种
(1)Guaranteed
这种为必须保障资源的Pod
特点为定义的Resources限制,limit=request且都不为0
(2)Bustable
这种为尽量保证资源的Pod
特点为定义了limit和request但request小于limit
(3)BestEffort
这种为没有定义resources的Pod

在Node上的资源不足时,QoS优先级最低的Pod会优先被驱逐
每个QoS对应一个子Cgroup,包含了该QoS中所有的子资源限额
posted @ 2024-02-23 17:55  付同學  阅读(63)  评论(0编辑  收藏  举报