Kubernetes 的配置信息管理
K8s-配置相关
一、使用ConfigMap配置您的应用程序
Kubernetes ConfigMap 可以将配置信息和容器镜像解耦,以使得容器化的应用程序可移植。
二、管理容器的计算资源
概述
在 Kubernetes 中创建工作负载时,您可以为 Pod 中的每一个容器指定其所需要的内存(RAM)大小和 CPU 数量。如果这些信息被指定了,Kubernetes 调度器可以更好的决定将 Pod 调度到哪一个节点。对于容器来说,其所需要的资源也将依据其指定的数值得到保证
资源类型及计量
当计算资源的时候,主要是指 CPU 和 内存。CPU 的计量单位是内核的单元数,内存的计量单位是 byte 字节数。应用程序可以按量请求、分配、消耗计算资源
CPU 的计量
Kubernetes 中,0.5 代表请求半个 CPU 资源。表达式 0.1 等价于 表达式 100m。在 API Server 中,表达式 0.1 将被转换成 100m,精度低于 1m 的请求是不受支持的。 CPU 的计量代表的是绝对值,而非相对值,例如,请求了 0.1 个 CPU,无论节点是 单核、双核、48核,得到的 CPU 资源都是 0.1 核。
内存的计量
内存的计量单位是 byte 字节。可以使用一个整数来表达内存的大小,也可以使用后缀来表示(E、P、T、G、M、K)。也可以使用 2 的幂数来表示内存大小,其后缀为(Ei、Pi、Ti、Gi、Mi、Ki)。例如,下面的几个表达方式所表示的内存大小大致相等:
1 | 128974848, 129e6, 129M, 123Mi |
容器组及容器的计算资源请求及限制
Kubernetes 中,可以为容器指定计算资源的请求数量 request 和限制数量 limit。尽管资源的请求/限制数量只能在容器上指定,我们仍然经常讨论容器组的资源请求/限制数量。容器组对某一个类型的资源请求/限制数量是该容器组中所有工作容器对该资源请求/限制数量的求和。
带有资源请求的容器组是如何调度的
当创建 Pod 时(直接创建,或者通过控制器创建),Kubernetes 调度程序选择一个节点去运行该 Pod。每一个节点都有一个最大可提供的资源数量:CPU 数量和内存大小。调度程序将确保:对于每一种资源类型,已调度的 Pod 对该资源的请求之和小于该节点最大可供使用资源数量。
尽管某个节点实际使用的CPU、内存数量非常低,如果新加入一个 Pod 使得该节点上对 CPU 或内存请求的数量之和大于了该节点最大可供使用 CPU 或内存数量,则调度程序不会将该 Pod 分配到该节点。Kubernetes 这样做可以避免在日常的流量高峰时段,节点上出现资源短缺的情况。
带有资源限制的容器组是如何运行的
Kubelet 启动容器组的容器时,将 CPU、内存的最大使用限制作为参数传递给容器引擎。
以 Docker 容器引擎为例:
- 容器的 cpu 请求将转换成 docker 要求的格式,并以
--cpu-shares标志传递到docker run命令 - 容器的 cpu 限制将也将转换成 millicore 表达式并乘以 100。结果数字是每 100ms 的周期内,该容器可以使用的 CPU 份额
- 容器的内存限制将转换成一个整数,并使用
--memory标志传递到docker run命令
如下情况可能会发生:
- 如果某个容器超出了其内存限制,它可能将被终止。如果 restartPolicy 为 Always 或 OnFailure,kubelet 将重启该容器
- 如果某个容器超出了其内存申请(仍低于其内存限制),当节点超出内存使用时,该容器仍然存在从节点驱逐的可能性
- 短时间内容器有可能能够超出其 CPU 使用限制运行。kubernetes 并不会终止这些超出 CPU 使用限制的容器
三、将容器组调度到指定的节点
概述
在 Kubernetes,可以限定 Pod 只能在特定的节点上运行,或者优先选择在特定的节点上运行。通常您并不需要这样做,而应该交由 kubernetes 调度程序根据资源使用情况自动地为 Pod 分配节点。但是少数情况下,这种限定仍然是必要的,例如:
- 确保某些 Pod 被分配到具有固态硬盘的节点
- 将相互通信频繁的两个 Pod 分配到同一个高可用区的节点
Kubernetes 一共提供了四种方法,可以将 Pod 调度到指定的节点上,这些方法从简便到复杂的顺序如下:
- 指定节点 nodeName
- 节点选择器 nodeSelector(Kubernetes 推荐用法)
- Node isolation/restriction
- Affinity and anti-affinity
指定节点 nodeName
nodeName 是四种方法中最简单的一个,但是因为它的局限性,也是使用最少的。nodeName 是 PodSpec 当中的一个字段。如果该字段非空,调度程序直接将其指派到 nodeName 对应的节点上运行。
通过 nodeName 限定 Pod 所运行的节点有如下局限性:
- 如果 nodeName 对应的节点不存在,Pod 将不能运行
- 如果 nodeName 对应的节点没有足够的资源,Pod 将运行失败,可能的原因有:OutOfmemory /OutOfcpu
- 集群中的 nodeName 通常是变化的(新的集群中可能没有该 nodeName 的节点,指定的 nodeName 的节点可能从集群中移除)
节点选择器 nodeSelector
nodeSelector 是 PodSpec 中的一个字段。指定了一组名值对。节点的 labels 中必须包含 Pod 的 nodeSelector 中所有的名值对,该节点才可以运行此 Pod。最普遍的用法中, nodeSelector 只包含一个名值对。