kubelet - container manager

2023-05-16

containerManager 负责 node 节点上运行的容器的配置信息,如cgroupcpudevice

 

pod的创建流程参考:

http://www.tianfeiyu.com/?p=2825


   

一构成

1.QOSContainerManager维护pod对应的Qos,用于调度、驱逐、设置各资源的cgroup等模块

2.cgroupManager根据pod的Qos设置不同级别的cgroup参数,并不断根据pod的变化维护这些cgroup参数

3.devicemanager管理节点上的device,主要包含分配、回收、本地记录存储;

4.cpumanager管理节点上的cpu,主要包含分配、回收、本地记录存储

5.devicemanager通过topologymanagercontainer选择最优的device组合

6.cpumanager通过topologymanagercontainer选择最优cpuset

 

调用流程:

1.kubeRuntimeManager.SyncPod创建完container后,通过cpumanager设置container的启动参数;

2.kubeRuntimeManager.SyncPod.startContainer启动container时会调用containerManager获取container跑在device上的参数,最终回调用到devicemanager


3.Kubelet.SyncPod设置cgroup参数阶段-->podContainerManager-->cgroupManager(依赖QOSContainerManager设置QOS)-->runc.libcontainer.cgroupfs将设置的参数apply到container  

 

 

二、Kubelet.syncPod vs kubeRuntimeManager.SyncPod:调用关系:

 

Kubelet.syncPod

1.如果pod需要被删除,调用containerRuntime.KillPod杀掉pod

2.为第一次创建的pod记录创建时间,当pod状态变化时也记录当前时间

3.通过一系列admit判断pod是否能在当前node上运行,如安全相关的appArmorValidatorcontainerRuntime是否允许root Privilege

4.设置podcgroup参数

5.static pod创建mirror pod

6.创建相应的工作目录,如pod的工作目录、存储目录、插件plugins目录

7,等待volume挂载到pod的存储目录下

8.拉取下载container imagesecret

9.调用kubeRuntimeManager.SyncPodpod创建container

10.statusManager更新pod的状态

 

kubeRuntimeManager.SyncPod


//  1. Compute sandbox and container changes.
//  2. Kill pod sandbox if necessary.
//  3. Kill any containers that should not be running.
//  4. Create sandbox if necessary.
//  5. Create ephemeral containers.
//  6. Create init containers.
//  7. Create normal containers.  

这部分的修改不会导致pod重建

 

 

二cgroupmanager

cgroupmanager负责 node 节点上运行的容器的 cgroup 配置信息,kubelet 启动参数如果指定 --cgroups-per-qos 的时候,kubelet 会启动 goroutine 来周期性的更新 pod 的 cgroup 信息,维护其正确性,该参数默认为 true,实现了 pod 的Guaranteed/BestEffort/Burstable 三种级别的 Qos。

目前 kubernetes 仅支持 cpu、memory、pids 、hugetlb 四个 cgroup 子系统

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

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

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


 

Kubelet cgroup level:

/sys/fs/cgroup/cpu/kubepods – kubepods cgroup
/sys/fs/cgroup/cpu/kubepods/burstable – Qos level cgroup
/sys/fs/cgroup/cpu/kubepods/burstable/pod<UID> – pod level cgroup
/sys/fs/cgroup/cpu/kubepods/burstable/pod<UID>/container<UID> – container level cgroup

1.cgroupmanager 会把本机的 allocatable 资源写入到 kubepods 下对应的 cgroup 文件中,比如 kubepods/cpu.share

2.Qos level cgroup有两个cgroupburstable besteffort,分别作为 burstable级别podbesteffort级别pod的父cgroup;而Guaranteed Qos 对应的 pod 会直接在 kubepods 同级的 cgroup 中创建 pod cgroup,原因:guaranteed 级别的 pod 有明确的资源申请量(request)和资源限制量(limit),不需要qos级别的cgroup来管理和限制资源

3.pod level cgroup包含pod对应的container level cgroup

4.创建流程kubepods>qos>pod>container,设置流程container->pod->qos->kubepods,即设置好container level cgroup中各文件的限制,再层层往外更新其它level的限制

5.从级别和目录可以看出:burstable 的 cgroup 需要为比他等级高的 guaranteed 级别的 pod 的内存资源做预留,而 besteffort 需要为 burstable 和 guaranteed 都要预留内存资源。


 

例:

/sys/fs/cgroup/cpu/kubepods/burstable/pod<UID>/container<UID>/cpu.shares=2

/sys/fs/cgroup/cpu/kubepods/burstable/pod<UID>/cpu.shares=204
/sys/fs/cgroup/cpu/kubepods/burstable/cpu.shares=1126
/sys/fs/cgroup/cpu/kubepods/cpu.shares=49512

 

对于每一个 pod 设定的 requests 和 limits,kubernetes 都会转换为 cgroup 中的计算方式,CPU 的转换方式如下所示:

  • cpu.shares = (cpu in millicores * 1024) / 1000

  • cpu.cfs_period_us = 100000 (i.e. 100ms)

  • cpu.cfs_quota_us = quota = (cpu in millicores * 100000) / 1000

  • memory.limit_in_bytes

CPU 最终都会转换为以微秒为单位,memory 会转换为以 bytes 为单位

如果 pod 指定了 requests 和 limits,kubelet 会按以上的计算方式为 pod 设置资源限制,如果没有指定 limit 的话,那么 cpu.cfs_quota_us 将会被设置为 -1,即没有限制。而如果 limit 和 request 都没有指定的话,cpu.shares 将会被指定为 2,这个是 cpu.shares 允许指定的最小数值了,可见针对这种 pod,kubernetes 只会给它分配最少的 cpu 资源。而对于内存来说,如果没有 limit 的指定的话,memory.limit_in_bytes 将会被指定为一个非常大的值,一般是 2^64 ,可见含义就是不对内存做出限制。

参考:https://www.jianshu.com/p/924e3c48cb9b

 

三QOSContainerManager

QoS(Quality of Service) 即服务质量,QoS 是一种控制机制,它提供了针对不同用户或者不同数据流采用相应不同的优先级,或者是根据应用程序的要求,保证数据流的性能达到一定的水准。kubernetes 中有三种 Qos,分别为:

  • 1、Guaranteed:pod 的 requests 与 limits 设定的值相等;

  • 2、Burstable:pod requests 小于 limits 的值且不为 0;

  • 3、BestEffort:pod 的 requests 与 limits 均为 0;

三者的优先级如下所示,依次递增,OOM_SCORE_ADJ递减

BestEffort -> Burstable -> Guaranteed

三种 Qos 在调度和底层表现上都不一样:

  • 1、在调度时调度器只会根据 request 值进行调度;

  • 2、二是当系统 OOM上时对于处理不同 OOMScore 的进程表现不同,OOMScore 是针对 memory 的,当宿主上 memory 不足时系统会优先 kill 掉 OOMScore 值低的进程,可以使用 $ cat /proc/$PID/oom_score 查看进程的 OOMScore。OOMScore 的取值范围为 [-1000, 1000],Guaranteed pod 的默认值为 -998,Burstable pod 的值为 2~999,BestEffort pod 的值为 1000,也就是说当系统 OOM 时,首先会 kill 掉 BestEffort pod 的进程,若系统依然处于 OOM 状态,然后才会 kill 掉 Burstable pod,最后是 Guaranteed pod;

  • 3、三是 cgroup 的配置不同,kubelet 为会三种 Qos 分别创建对应的 QoS level cgroups,Guaranteed Pod Qos 的 cgroup level 会直接创建在 RootCgroup/kubepods 下,Burstable Pod Qos 的创建在 RootCgroup/kubepods/burstable 下,BestEffort Pod Qos 的创建在 RootCgroup/kubepods/BestEffort 下,上文已经说了 root cgroup 可以通过 $ mount | grep cgroup看到,在 cgroup 的每个子系统下都会创建 Qos level cgroups, 此外在对应的 QoS level cgroups 还会为 pod 创建 Pod level cgroups;


 

qos的计算方式:

memoryRequest := container.Resources.Requests.Memory().Value()
        oomScoreAdjust := 1000 - (1000*memoryRequest)/memoryCapacity
        // A guaranteed pod using 100% of memory can have an OOM score of 10. Ensure
        // that burstable pods have a higher OOM score adjustment.
        if int(oomScoreAdjust) < (1000 + guaranteedOOMScoreAdj) {
                return (1000 + guaranteedOOMScoreAdj)
        }
        // Give burstable pods a higher chance of survival over besteffort pods.
        if int(oomScoreAdjust) == besteffortOOMScoreAdj {
                return int(oomScoreAdjust - 1)
        }
        return int(oomScoreAdjust)

可见:pod的container使用memory越多,它的 OOMScore越小,越不容易被驱逐。

 

 

 

三 device manager

 

四topology manager

白话:为container的resource选择最优组合,如同组的cpuset,container所需的device来自同一个NUMA Node.

topology manager不是单独起作用的,当前k8s 1.17.3中,它和CPU manager,device manager共同为pod分配资源,优化资源访问。

topology manager从Hint Providers中以bitmask的形式接受NUMA拓扑信息(Topology Hint),包括当前可用的NUMA节点和倾向的资源分配指示。Topology manager策略对提供的hint进行一系列操作以后将所有的hint决定汇聚起来,得出一个最佳的hint(bestHint)。通过配置的策略(policy),主机节点可以选择接受或者拒绝pod。

topology manager当前所支持的策略有四个:None,BestEffort,Restricted和SingleNumaNode。

 

None是默认的策略,这个策略不会做任何的NUMA感知的资源对齐。

 

BestEffort对于pod里面的每一个container都会调用它们的hint provider来发现它们的资源可用性。topology manager计算存储这些container的NUMA亲和度的信息,如果亲和度不能被满足的话,manager也会存储亲和度信息同时也会允许pod加入这个主机节点。

 

Restricted同样也会对pod里面的每一个container计算NUMA亲和度。不同的是,如果亲和度不能被满足的话,主机节点会拒绝这个pod的加入。这样会导致pod处于Terminated的状态。如果pod被接受了,那么亲和度信息将会被用于container的资源分配。

 

SingleNumaNode策略用来判断单个NUMA节点的亲和度是否满足,如果满足的话hint provider即可利用亲和度信息进行资源分配;如果不满足的话主机节点会拒绝pod的加入,这样也会导致pod处于Terminated的状态。

 

参考:https://blog.csdn.net/qjm1993/article/details/103237944

 

 

 

五cpu manager

白话:根据NUMA为container选择最优的cpuset,让container从cpu方向得到更高的性能

目前CPU Manager支持两种Policy,分别为none和static,通过kubelet --cpu-manager-policy设置,未来会增加dynamic policy做Container生命周期内的cpuset动态调整。

    • none: 为cpu manager的默认值,相当于没有启用cpuset的能力。cpu request对应到cpu share,cpu limit对应到cpu quota。

    • static: 目前,请设置--cpu-manager-policy=static来启用,kubelet将在Container启动前分配绑定的cpu set,分配时还会考虑cpu topology来提升cpu affinity,后面会提到。

  • 确保kubelet为--kube-reserved--system-reserved都配置了值,可以不是整数个cpu,最终会计算reserved cpus时会向上取整。这样做的目的是为了防止CPU Manager把Node上所有的cpu cores分配出去了,导致kubelet及系统进程都没有可用的cpu了。

注意CPU Manager还有一个配置项 --cpu-manager-reconcile-period,用来配置CPU Manager Reconcile Kubelet内存中CPU分配情况到cpuset cgroups的修复周期。如果没有配置该项,那么将使用 --node-status-update-frequency default 10s 配置的值。

使用CPU Manager的Pod、Container具备以下两个条件:

  • Pod QoS为Guaranteed;

  • Pod中该Container的Cpu request必须为整数CPUs;

工作流程:

  • Kuberuntime调用容器运行时去create该Container。

  • 创建完后,调用PreStartContainer将该Container交给CPU Manager处理。

  • 创建业务container时,先把init container占用的cpu释放

  • CPU Manager为Container按照static policy逻辑进行处理。

  • CPU Manager从当前Shared Pool中挑选“最佳”Set拓扑结构的CPU,对于不满足Static Policy的Contianer,则返回Shared Pool中所有CPUS组成的Set。

  • 挑选方式:根据Node上的NUMA CPU Topology划分cpu组,当container需要多个cpu时,让这几个cpu尽量来自同一个组(简单理解为一个插槽),这样同组访问能加快速度提高性能。

  • CPU Manager将对该Container的CPUs分配情况记录到Checkpoint State中,并且从Shared Pool中删除刚分配的CPUs。

  • CPU Manager再从state中读取该Container的CPU分配信息,然后通过UpdateContainerResources cRI接口将其更新到Cpuset Cgroups中,包括对于非Static Policy Container。

  • Kuberuntime调用容器运行时Start该容器。

Checkpoint文件内容就是CPUManagerCheckpoint结构体的json格式,其中Entries的key是ContainerID,value为该Container对应的Assigned CPU Set信息。

当这些通过CPU Manager分配CPUs的Container要Delete时,CPU Manager工作流大致如下:

  1. Kuberuntime会调用CPU Manager去按照static policy中定义逻辑处理。

  2. CPU Manager将该Container分配的Cpu Set重新归还到Shared Pool中。

  3. Kuberuntime调用容器运行时Remove该容器。

  4. CPU Manager会异步地进行Reconcile Loop,为使用Shared Pool中的Cpus的Containers更新CPU集合。

 

CPU Manager Reconcile按照--cpu-manager-reconcile-period配置的周期进行Loop,Reconcile注意进行如下处理:

  • 遍历所有activePods中的所有Containers,注意包括InitContainers,对每个Container继续进行下面处理。

  • 检查该ContainerID是否在CPU Manager维护的Memory State assignments中,

    • 如果不在Memory State assignments中:

      • 再检查对应的Pod.Status.Phase是否为Running且DeletionTimestamp为nil,如果是,则调用CPU Manager的AddContainer对该Container/Pod进行QoS和cpu request检查,如果满足static policy的条件,则调用takeByTopology为该Container分配“最佳”CPU Set,并写入到Memory State和Checkpoint文件(cpu_manager_sate)中,并继续后面流程。

      • 如果对应的Pod.Status.Phase是否为Running且DeletionTimestamp为nil为false,则跳过该Container,该Container处理结束。不满足static policy的Containers因为不在Memory State assignments中,所以对它们的处理流程也到此结束。

    • 如果ContainerID在CPU Manager assignments维护的Memory State中,继续后面流程。

  • 然后从Memory State中获取该ContainerID对应的CPU Set。

  • 最后调用CRI UpdateContainerCPUSet更新到cpuset cgroups中。

 

cpumanager调用State进行validate处理:

  • 当Memory State中Shared(Default) CPU Set为空时,CPU Assginments也必须为空,然后对Memory State中的Shared Pool进行初始化,并写入到Checkpoint文件中(初始化Checkpoint)。

  • 只要我们没有手动去删Checkpoint文件,那么在前面提到的state.NewCheckpointState中会根据Checkpoint文件restore到Memory State中,因此之前Assgned CPU Set、Default CPU Set都还在。

  • 当检测到Memory State已经成功初始化(根据Checkpoint restore),则检查这次启动时reserved cpu set是否都在Default CPU Set中,如果不是(比如kube/system reserved cpus增加了),则报错返回,因为这意味着reserved cpu set中有些cpus被Assigned到了某些Container中了,这可能会导致这些容器启动失败,此时需要用户自己手动的去修正Checkpoint文件。

  • 检测reserved cpu set通过后,再检测Default CPU Set和Assigned CPU Set是否有交集,如果有交集,说明Checkpoint文件restore到Memory State的数据有错,报错返回。

  • 最后检查这次启动时从cAdvisor中获取到的CPU Topology中的所有CPUs是否与Memory State(从Checkpoint中restore)中记录的所有CPUs(Default CPU Set + Assigned CPU Set)相同,如果不同,则报错返回。可能因为上次CPU Manager停止到这次启动这个时间内,Node上的可用CPUs发生变化。

参考:https://blog.csdn.net/weixin_34050389/article/details/92574505

 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kubelet - container manager 的相关文章

  • 使用指定的用户登录container

    root 64 hgdb01 docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bf10ff6bcd03 oracle database 12 2 0 1 ee
  • 连接到 Azure (Resource Manager) 上的 SQL Server 虚拟机

    概述 本主题介绍如何连接到运行于 Azure 虚拟机的 SQL Server 实例 它介绍了一些常规连接方案 xff0c 并提供了在 Azure VM 中配置 SQL Server 连接的详细步骤 Note Azure 具有用于创建和处理资
  • delphi offsetof , container_of 通过结构体成员获得到该结构体地址

    C宏 offsetof type member 该结构体成员相对于该结构体的偏移量 define offsetof TYPE MEMBER size t amp TYPE 0 gt MEMBER 那Delphi版的表示式怎么写呢 Nativ
  • starting container process caused "exec: \"nvidia-smi\": executable file not found in $PATH"

    1 问题描述 xff1a 我在安装好了nvidia docker之后 xff0c 按照网上的教程执行 xff1a nvidia docker run rm nvidia cuda nvidia smi 结果报如下错误 xff1a conta
  • modem manager与network manager

    modem manager ModemManager is a DBus system bus activated service meaning it 39 s started automatically when a request a
  • Attach detach controller manager 流程

    一 xff1a 初始化 1 adc 调用 InitPlugins 初始化 volumeplugins 1 1 初始化 dynamicplugins Currentlyonly Flexvolume plugins are dynamical
  • vscode调试container中的程序

    在写cmu14 445的project时 xff0c 我希望在本地vscode编辑代码 xff0c 然后在docker中编译和测试代码 但是如果测试出了问题 xff0c 直接在本地调试就变得麻烦了 所以希望利用vscode进行远程调试 参考
  • kubelet残留孤儿pod(Orphaned pod)无法删除

    记录kubelet残留孤儿pod Orphaned pod 无法删除的问题分析和解决方法 问题 查看kubelet日志 xff0c 错误信息如下 xff1a E0823 10 31 01 847946 1303 kubelet volume
  • Qnap Docker(Container Station)更改国内镜像源

    0x01qpkg环境 通常qnap市场中下载的qpkg应用 xff0c 其环境变量就在自己的包环境中 所以要修改系统中的配置 xff0c 通常需要修改qpkg应用中对应的配置 即 share CACHEDEV1 DATA qpkg xxx
  • 启用已签名的 kubelet 服务证书

    默认情况下 kubeadm 所部署的 kubelet 服务证书是自签名 Self Signed 这意味着从 metrics server 这类外部服务发起向 kubelet 的链接时无法使用 TLS 来完成保护 要在新的 kubeadm 集
  • Android的第一天

    早就想学下Android开发了 目前为止flash开发Android还不给力 所以还是老老实实的研究用java 开发 apk吧 下载好了 Android开发视频 看了两个视频 现在开始配置环境 ADK https dl ssl google
  • 浅析Kubelet如何上报状态

    浅析Kubelet如何上报状态 1 kubelet上报节点状态 在K8S集群中 由运行在每个节点的Kubelet定期上报心跳到ApiServer 以此来判断Node是否存活 若Node超过一定时间没有上报心跳 则该节点的状态会被设置为Not
  • k8s - kubelet启动失败处理记录

    测试环境好久没有使用了 启动kubelet发现失败了 查看状态 每看到具体报错点 root node1 systemctl status kubelet kubelet service kubelet The Kubernetes Node
  • K8S单master部署四:Kubelet+kube-proxy

    服务器角色分配 角色 地址 安装组件 master 192 168 142 220 kube apiserver kube controller manager kube scheduler etcd node1 192 168 142 1
  • 数学建模竞赛论文中的Word使用

    1 使用样式 除了Word原先所提供的标题 正文等样式外 还可以自定义样式 如果你发现自己是用选中文字然后用格式栏来设定格式的 一定要注意 想想其他地方是否需要相同的格式 如果是的话 最好就定义一个样式 对于相同排版表现的内容一定要坚持使用
  • Kubernetes(k8s)安装和搭建集群时kubeadm init失败

    Kubernetes k8s 按官方文档描述安装和搭建集群遇到kubelet状态异常 环境 Cenots 7 9 2009 adm64 我在搭建master节点时通过以下命令安装了docker kubelet kubectl kubeadm
  • k8s scheduler 调度与 kubelet 启动 Pod 流程总结(四)

    文章目录 scheduler predicate 和 priority 资源需求 把 Pod 调度到指定 Node 上 nodeSelector 亲和性和反亲和性 节点亲和性 Pod 亲和性 污点和容忍度 Controller Manage
  • Windows Vista的安装和配置

    声明 此文章为个人读书笔记 仅记些重要的内容备忘 无盗版之意 更多相关内容请查看 indows Vista使用详解 严禁转载 第二章 Windows Vista的安装和配置 全新安装Windows Vista 从Windows XP升级为W
  • 面经-Bosch博世无锡&UL美华

    工作总算有所眉目了 太多的总结暂时还没有太多心情来理清楚 先来两个面经 给可能现在或以后需要的人们1 Bosch 博世无锡柴油系统博世公司 业内的人都知道 汽车部件的巨无霸 最近几年才来到中国 虽然比起德尔福有些稍晚 但发展前景值得期待 无
  • 带有 pod 标签的 Prometheus kubelet 指标 [关闭]

    Closed 这个问题是与编程或软件开发无关 help closed questions 目前不接受答案 我想弄清楚如何使用 prometheus stack 将 pod 标签从 kubelet 指标获取到指标标签 在我们的环境中 我们需要

随机推荐