一、  Kubelet Node Allocatable

  • Kubelet Node Allocatable用来为Kube组件和System进程预留资源,从而保证当节点出现满负荷时也能保证Kube和System进程有足够的资源。
  • 目前支持cpu, memory, ephemeral-storage三种资源预留。
  • Node Capacity是Node的所有硬件资源,kube-reserved是给kube组件预留的资源,system-reserved是给System进程预留的资源, eviction-threshold是kubelet eviction的阈值设定,allocatable才是真正scheduler调度Pod时的参考值(保证Node上所有Pods的request resource不超过Allocatable)。

Node Capacity

--------------------------------

|     kube-reserved         |

|-------------------------------|

|     system-reserved      |

|-------------------------------|

|    eviction-threshold     |

|-------------------------------|

|      allocatable              |

|   (available for pods)   |

--------------------------------

可分配资源

Node Allocatable Resource = Node Capacity - Kube-reserved - system-reserved - eviction-threshold

二、  Kubernetes配置资源预留

以下均为kubelet组件参数

  • --enforce-node-allocatable,默认为pods,要为kube组件和System进程预留资源,则需要设置为pods,kube-reserved,system-reserve。
  • --cgroups-per-qos,Enabling QoS and Pod level cgroups,默认开启。开启后,kubelet会将管理所有workload Pods的cgroups。
  • --cgroup-driver,默认为cgroupfs,另一可选项为systemd。取决于容器运行时使用的cgroup driver,kubelet与其保持一致。比如你配置docker使用systemd cgroup driver,那么kubelet也需要配置--cgroup-driver=systemd。
  • --kube-reserved,用于配置为kube组件(kubelet,kube-proxy,dockerd等)预留的资源量,比如—kube-reserved=cpu=1000m,memory=8Gi,ephemeral-storage=16Gi。
  • --kube-reserved-cgroup,如果你设置了--kube-reserved,那么请一定要设置对应的cgroup,并且该cgroup目录要事先创建好,否则kubelet将不会自动创建导致kubelet启动失败。比如设置为kube-reserved-cgroup=/kubelet.service 。
  • --system-reserved,用于配置为System进程预留的资源量,比如—system-reserved=cpu=500m,memory=4Gi,ephemeral-storage=4Gi。
  • --system-reserved-cgroup,如果你设置了--system-reserved,那么请一定要设置对应的cgroup,并且该cgroup目录要事先创建好,否则kubelet将不会自动创建导致kubelet启动失败。比如设置为system-reserved-cgroup=/system.slice。
  • --eviction-hard,用来配置kubelet的hard eviction条件,只支持memory和ephemeral-storage两种不可压缩资源。当出现MemoryPressure时,Scheduler不会调度新的Best-Effort QoS Pods到此节点。当出现DiskPressure时,Scheduler不会调度任何新Pods到此节点。关于Kubelet Eviction的更多解读,请参考我的相关博文

Kubelet Node Allocatable的代码很简单,主要在pkg/kubelet/cm/node_container_manager.go,感兴趣的同学自己去走读一遍。

示例:

以如下的kubelet资源预留为例,Node Capacity为memory=32Gi, cpu=16, ephemeral-storage=100Gi,我们对kubelet进行如下配置:

--enforce-node-allocatable=pods,kube-reserved,system-reserved
--kube-reserved-cgroup=/kubelet.service
--system-reserved-cgroup=/system.slice
--kube-reserved=cpu=1,memory=2Gi,ephemeral-storage=1Gi
--system-reserved=cpu=500m,memory=1Gi,ephemeral-storage=1Gi
--eviction-hard=memory.available<500Mi,nodefs.available<10%

NodeAllocatable = NodeCapacity - Kube-reserved - system-reserved - eviction-threshold = cpu=14.5,memory=28.5Gi,ephemeral-storage=98Gi.

Scheduler会确保Node上所有的Pod Resource Request不超过NodeAllocatable。Pods所使用的memory和storage之和超过NodeAllocatable后就会触发kubelet Evict Pods。

1.    Kube Reserved

Kubelet Flag: --kube-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]
Kubelet Flag: --kube-reserved-cgroup=

kube-reserved 是为了给诸如 kubelet、container runtime、node problem detector 等 kubernetes 系统守护进程争取资源预留。这并不代表要给以 pod 形式运行的系统守护进程保留资源。kube-reserved 通常是节点上的一个 pod 密度(pod density) 功能。 这个性能仪表盘 从 pod 密度的多个层面展示了 kubelet 和 docker engine 的 cpu 和 memory使用情况。

要选择性的在系统守护进程上执行 kube-reserved,需要把 kubelet 的 --kube-reserved-cgroup 标志的值设置为 kube 守护进程的父控制组。

推荐将 kubernetes 系统守护进程放置于顶级控制组之下(例如 systemd 机器上的 runtime.slice)。理想情况下每个系统守护进程都应该在其自己的子控制组中运行。请参考这篇文档,获取更过关于推荐控制组层次结构的细节。

请注意,如果 --kube-reserved-cgroup 不存在,Kubelet 将不会创建它。如果指定了一个无效的 cgroup,Kubelet 将会失败。

2.    系统预留值(System Reserved)

Kubelet Flag: --system-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]
Kubelet Flag: --system-reserved-cgroup=

system-reserved 用于为诸如 sshd、udev 等系统守护进程争取资源预留。system-reserved 也应该为 kernel 预留 内存,因为目前 kernel 使用的内存并不记在 Kubernetes 的 pod 上。同时还推荐为用户登录会话预留资源(systemd 体系中的 user.slice)。

要想在系统守护进程上可选地执行 system-reserved,请指定 --system-reserved-cgroup kubelet 标志的值为 OS 系统守护进程的父级控制组。

推荐将 OS 系统守护进程放在一个顶级控制组之下(例如 systemd 机器上的system.slice)。

请注意,如果 --system-reserved-cgroup 不存在,Kubelet 不会创建它。如果指定了无效的 cgroup,Kubelet 将会失败。

3.    驱逐阈值(Eviction Thresholds)

Kubelet Flag: --eviction-hard=[memory.available<10%][,][ephemeral-storage<1Gi]

节点级别的内存压力将导致系统内存不足(System OOMs),这将影响到整个节点及其上运行的所有 pod。节点可以暂时离线直到内存已经回收为止。为了防止(或减少可能性)系统内存不足,kubelet 提供了 资源不足(Out of Resource) 管理。驱逐(Eviction)操作只支持 memory 和ephemeral-storage。通过 --eviction-hard 标志预留一些内存后,当节点上的可用内存降至保留值以下时,kubelet 将尝试 驱逐 pod。假设,如果节点上不存在系统守护进程,pod 将不能使用超过 capacity-eviction-hard 的资源。因此,为驱逐而预留的资源对 pod 是不可用的。

eviction-hard的值支持1Gi或者10%格式。

kubelet的默认eviction-hard值如下:

  • memory.available<100Mi
  • nodefs.available<10%
  • nodefs.inodesFree<5%
  • imagefs.available<15%

1.    执行节点 Allocatable

Kubelet Flag: --enforce-node-allocatable=pods[,][system-reserved][,][kube-reserved]

调度器将 Allocatable 按 pod 的可用 capacity 对待。

kubelet 默认在 pod 中执行 Allocatable。无论何时,如果所有 pod 的总用量超过了 Allocatable,驱逐 pod 的措施将被执行。有关驱逐策略的更多细节可以在 这里 找到。请通过设置 kubelet --enforce-node-allocatable 标志值为 pods 控制这个措施。

可选的,通过在相同标志中同时指定 kube-reserved 和 system-reserved 值能够使 kubelet 执行 kube-reserved 和 system-reserved。请注意,要想执行 kube-reserved 或者 system-reserved时,需要分别指定 --kube-reserved-cgroup 或者 --system-reserved-cgroup。

三、  一般原则

系统守护进程期望被按照类似 Guaranteed pod 一样对待。系统守护进程可以在其范围控制组中爆发式增长,您需要将这个行为作为 kubernetes 部署的一部分进行管理。例如,kubelet 应该有它自己的控制组并和容器运行时(container runtime)共享 Kube-reserved 资源。然而,如果执行了 kube-reserved,则 kubelet 不能突然爆发并耗尽节点的所有可用资源。

在执行 system-reserved 预留操作时请加倍小心,因为它可能导致节点上的关键系统服务 CPU 资源短缺或因为内存不足(OOM)而被终止。

在 pods 上执行 Allocatable 作为开始。

一旦足够用于追踪系统守护进程的监控和告警的机制到位,请尝试基于用量探索(usage heuristics)方式执行 kube-reserved。

随着时间推进,如果绝对必要,可以执行 system-reserved。

随着时间的增长以及越来越多特性的加入,kube 系统守护进程对资源的需求可能也会增加。以后 kubernetes 项目将尝试减少对节点系统守护进程的利用,但目前那并不是优先事项。所以,请期待在将来的发布中将 Allocatable 容量降低。

四、  示例场景

这是一个用于说明节点 Allocatable 计算方式的示例:

节点拥有 32Gi 内存,16 核 CPU 和 100Gi 存储

--kube-reserved 设置为 cpu=1,memory=2Gi,storage=1Gi

--system-reserved 设置为 cpu=500m,memory=1Gi,storage=1Gi

--eviction-hard 设置为 memory.available<500Mi,nodefs.available<10%

在这个场景下,Allocatable 将会是 14.5 CPUs、28.5Gi 内存以及 98Gi 存储。调度器保证这个节点上的所有 pod 请求的内存总量不超过 28.5Gi,存储不超过 88Gi。当 pod 的内存使用总量超过 28.5Gi 或者磁盘使用总量超过 88Gi 时,Kubelet 将会驱逐它们。如果节点上的所有进程都尽可能多的使用 CPU,则 pod 加起来不能使用超过 14.5 CPUs 的资源。

当没有执行 kube-reserved 和/或 system-reserved 且系统守护进程使用量超过其预留时,如果节点内存用量高于 31.5Gi 或存储大于 90Gi,kubelet 将会驱逐 pod。

可用特性

截至 Kubernetes 1.2 版本,已经可以可选的指定 kube-reserved 和 system-reserved 预留。当在相同的发布中都可用时,调度器将转为使用 Allocatable 替代 Capacity。

截至 Kubernetes 1.6 版本,eviction-thresholds 是通过计算 Allocatable 进行考虑。要使用旧版本的行为,请设置 --experimental-allocatable-ignore-eviction kubelet 标志为 true。

截至 Kubernetes 1.6 版本,kubelet 使用控制组在 pod 上执行 Allocatable。要使用旧版本行为,请取消设置 --enforce-node-allocatable kubelet 标志。请注意,除非 --kube-reserved 或者 --system-reserved 或者 --eviction-hard 标志没有默认参数,否则 Allocatable 的实施不会影响已经存在的 deployment。

截至 Kubernetes 1.6 版本,kubelet 在 pod 自己的 cgroup 沙箱中启动它们,这个 cgroup 沙箱在 kubelet 管理的 cgroup 层次结构中的一个独占部分中。在从前一个版本升级 kubelet之前,要求操作员 drain 节点,以保证 pod 及其关联的容器在 cgroup 层次结构中合适的部分中启动。

截至 Kubernetes 1.7 版本,kubelet 支持指定 storage 为 kube-reserved 和 system-reserved 的资源。

五、  Openshift配置

在kubelet中新增参数system-reserved和kube-reserved,

可以在每个node节点的/etc/origin/node/node-config.yaml修改,但是这是临时生效,

想要永久生效,需要修改openshift-node命名空间里的configmap,想改哪个group的参数就修改哪个configmap。

在openshift中新增或者修改kubelet的参数都可以通过这种方式。

例如:给compute-normal group新增system-reserved和kube-reserved参数:

kubectl edit -n openshift-node cm node-config-compute-normal

    kubeletArguments:
bootstrap-kubeconfig:
- /etc/origin/node/bootstrap.kubeconfig
cert-dir:
- /etc/origin/node/certificates
enable-controller-attach-detach:
- 'true'
feature-gates:
- RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true
node-labels:
- node-role.kubernetes.io/compute-normal=true
pod-manifest-path:
- /etc/origin/node/pods
rotate-certificates:
- 'true'
evction-hard:
- 'memory.available<500Mi,nodefs.available<10%'
system-reserved:
- 'cpu=200m,memory=1Gi'
kube-reserved:
- "cpu=200m,memory=1Gi"

如果修改的是master组件的参数,而不是kubelet的,则按照下面的方法。

修改master的配置在每个master的/etc/origin/master/master-config.yaml

kubernetesMasterConfig:

  controllerArguments: 

    node-monitor-period:

    - "10m"

重启相关组件

# master-restart
api

# master-restart
controllers

修改pod-evction-timeout参数:

1.修改每个master上/etc/origin/master/master-config.yaml

podEvictionTimeout: "2m0s"

2.重启controller:

master-restart
controllers

六、  参数资料

http://docs.kubernetes.org.cn/723.html

https://my.oschina.net/jxcdwangtao/blog/1629059

https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/

https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/

kubernets资源预留的更多相关文章

  1. Kubelet资源预留

    目录 Kubelet Node Allocatable 配置参数 配置示例 Kubelet Node Allocatable Kubelet Node Allocatable用来为Kube组件和Sys ...

  2. Kubernetes实践技巧:资源预留

    ubernetes 的节点可以按照节点的资源容量进行调度,默认情况下 Pod 能够使用节点全部可用容量.这样就会造成一个问题,因为节点自己通常运行了不少驱动 OS 和 Kubernetes 的系统守护 ...

  3. Kubernets 资源类型简介

    # Node 代表 Kubernets 集群运行的宿主物理机或者虚拟服务器, 为容器提供必要的计算资源: 内存 与 CPU 等. # Pod 最底层的抽象. 一个 Pod 中可以包含一个或者多个运行的 ...

  4. kubernetes资源预留---转发

    下面内容还处于测试阶段,生产上是否能保证集群稳定暂时还不清楚.

  5. kubelet 预留system、kube资源

    kubelet 预留system.kube资源 Kubernetes 的节点可以按照 Capacity 调度.默认情况下 pod 能够使用节点全部可用容量.这是个问题,因为节点自己通常运行了不少驱动 ...

  6. kubernets之statefulset资源

    一  了解Statefulset 1.1  对比statefulset与RS以及RC的区别以及相同点 Statefulset是有状态的,而RC以及RS等是没有状态的 Statefulset是有序的,拥 ...

  7. kubernets之从应用访问pod元数据以及其他资源

    一  downwardAPI的应用 1.1  前面我们介绍了如何通过configmap以及secret将配置传入到pod的容器中,但是传递的这些都是预先能够安排和只晓得,对于那些只有当pod创建起来之 ...

  8. 大型Kubernetes集群的资源编排优化

    背景 云原生这个词想必大家应该不陌生了,容器是云原生的重要基石,而Kubernetes经过这几年的快速迭代发展已经成为容器编排的事实标准了.越来越多的公司不论是大公司还是中小公司已经在他们的生产环境中 ...

  9. kubernetes 降本增效标准指南| 资源利用率提升工具大全

    背景 公有云的发展为业务的稳定性.可拓展性.便利性带来了极大帮助.这种用租代替买.并且提供完善的技术支持和保障的服务,理应为业务带来降本增效的效果.但实际上业务上云并不意味着成本一定较少,还需适配云上 ...

随机推荐

  1. Codeforces Round #649 (Div. 2) A. XXXXX

    题目链接:https://codeforces.com/contest/1364/problem/A 题意 找出大小为 $n$ 的数组 $a$ 的最长连续子数组,其元素和不被 $x$ 整除. 题解 如 ...

  2. 【译】Async/Await(五)—— Executors and Wakers

    原文标题:Async/Await 原文链接:https://os.phil-opp.com/async-await/#multitasking 公众号: Rust 碎碎念 翻译 by: Praying ...

  3. 01、mysql安装配置

    1.下载mysql软件安装包 MySQL版本:5.7.17 mysql下载地址:http://rj.baidu.com/soft/detail/12585.html?ald 2.配置mysql数据库与 ...

  4. requests -- Python

    使用requests方法后,会返回一个response对象,其存储了服务器响应的内容:如下r表示get请求后的响应对象r = requests.get('http://hz.58.com/sale.s ...

  5. C++ STL (基础)

    STL是什么(STL简介) 本节主要讲述 STL 历史.STL 组件.STL 基本结构以及 STL 编程概述.STL 历史可以追溯到 1972 年 C 语言在 UNIX 计算机上的首次使用.直到 19 ...

  6. 关于谷歌浏览器不支持html5中audio的autoplay解决方法(js代码解决)

    当我们直接写autoplay时,在chrome中浏览器并没有自动播放音频: 如果直接通过js来调用audio的play()方法也不行: 控制台还会报错 大概意思:play()调用失败,因为用户没有与文 ...

  7. Apple & 人体工程学

    Apple & 人体工程学 https://support.apple.com/zh-cn/HT205655 MBP 2018 https://help.apple.com/macbookpr ...

  8. 钉钉 & URL Scheme & Universal Link & Deep Link

    钉钉 & URL Scheme & Universal Link & Deep Link DD link https://www.cnblogs.com/xgqfrms/p/1 ...

  9. anatomy app

    anatomy app https://appolicious.com/the-best-iphone-apps-for-anatomy-students/ ios anatomy app Compl ...

  10. vue & $router & History API

    vue & $router gotoTemplateManage(e) { e.preventDefault(); this.$router.push({ path: `/operate-to ...