Kubernetes Pod 调度与自动伸缩技术详解
1. 理解 Kubernetes 中的静态 Pod
静态 Pod 为 Kubernetes 集群内的 Pod 管理提供了一种不同的方式。与由集群的 Pod 调度器和 API 服务器控制的常规 Pod 不同,静态 Pod 由特定节点上的 kubelet 守护进程直接管理。除了 kubelet 为其创建的镜像 Pod 外,API 服务器并不知道这些 Pod 的存在。
静态 Pod 具有以下关键特性:
-
节点特定性
:静态 Pod 与单个节点绑定,无法在集群内的其他地方移动。
-
Kubelet 管理
:指定节点上的 kubelet 负责启动、停止和重启静态 Pod。
-
镜像 Pod
:kubelet 在 API 服务器上创建镜像 Pod 以反映静态 Pod 的状态,但这些镜像 Pod 无法通过 API 进行控制。
创建静态 Pod 主要有两种方法:
-
文件系统托管配置
:将 YAML 或 JSON 格式的 Pod 定义文件放置在节点上的特定目录中。kubelet 会定期扫描该目录,并根据其中的文件管理 Pod。
-
Web 托管配置
:将 Pod 定义存储在 Web 服务器上的 YAML 文件中。kubelet 配置该文件的 URL,并定期下载以管理静态 Pod。
静态 Pod 常用于在每个节点上引导必要的集群组件,如 API 服务器或控制器管理器。不过,若要在集群的每个节点上运行 Pod,通常建议使用 DaemonSets。静态 Pod 存在一些限制,例如无法引用其他 Kubernetes 对象(如 Secrets 或 ConfigMaps),也不支持临时容器。在需要对单个节点上的 Pod 放置进行严格控制的场景中,了解静态 Pod 会很有用。
2. 扩展 Kubernetes 调度器配置
除了调度器自定义功能外,Kubernetes 还支持一些高级调度配置。
可以使用配置文件自定义调度行为,该文件根据各种标准定义调度器如何为 Pod 对节点进行优先级排序。涉及的关键概念如下:
-
调度配置文件
:配置文件可以指定多个调度配置文件。每个配置文件都有一个独特的名称,并可以配置自己的一组插件。
-
调度插件
:插件就像构建块,在调度过程中执行特定任务。它们可以根据资源可用性、硬件兼容性或其他因素过滤节点。
-
扩展点
:这些是调度过程中的阶段,插件可以在这些阶段插入。不同的插件适用于不同的阶段,例如过滤不合适的节点或对合适的节点进行评分。
Kubernetes 调度器配置文件为管理集群内的 Pod 放置提供了诸多好处,它能灵活地根据需求定制调度行为。例如,可以优先将需要 GPU 的 Pod 调度到具有这些资源的节点上。此外,还可以开发自定义插件来处理默认插件未解决的独特调度需求。最后,定义多个配置文件的能力允许通过为不同类型的 Pod 分配不同的调度配置文件来实现精细控制。
3. 节点隔离和限制
Kubernetes 允许使用节点标签将 Pod 隔离在特定节点上。这些标签可以定义诸如安全要求或法规合规性等属性,确保 Pod 仅调度到满足这些标准的节点上。为防止受损节点为自身利益操纵标签,NodeRestriction 准入插件限制 kubelet 修改具有特定前缀(例如 node-restriction.kubernetes.io/)的标签。
要利用此功能,需要启用 NodeRestriction 插件和节点授权器。然后,可以向节点添加具有受限前缀的标签,并在 Pod 的 nodeSelector 配置中引用这些标签,确保 Pod 仅在预定义的隔离环境中运行。
4. 调整 Kubernetes 调度器性能
在大型 Kubernetes 集群中,高效的调度器性能至关重要。其中一个关键的调整参数是 percentageOfNodesToScore。
percentageOfNodesToScore 设置决定了调度器在为 Pod 寻找合适放置位置时考虑的节点数量。较高的值意味着调度器会检查更多的节点,可能找到更合适的位置,但会花费更长时间;相反,较低的值会使调度更快,但可能导致放置效果不佳。可以在 kube-scheduler 配置文件中配置此值,有效范围是 1% 到 100%,默认值根据集群大小计算(100 个节点时为 50%,5000 个节点时为 10%)。
在 Kubernetes v1.23 之前的版本中,允许通过 kube-scheduler 标志或 ConfigMaps 指定调度策略。这些策略使用谓词(过滤条件)和优先级(评分函数)定义调度器如何为 Pod 选择节点。从 v1.23 版本开始,此功能被调度器配置所取代,新方法为调度行为提供了更多的灵活性和控制。
若要将拥有数百个节点的集群的 percentageOfNodesToScore 设置为 50%,需在调度器文件中包含以下配置:
apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
algorithmSource:
provider: DefaultProvider
...
percentageOfNodesToScore: 50
最优值取决于优先级。如果快速调度至关重要,较低的值可能是可以接受的;但如果确保最佳放置位置比速度更重要,则建议使用较高的值。避免将其设置得过低,以免调度器忽略可能更好的节点。
5. Pod 资源请求和限制
在深入探讨 Kubernetes 中的自动伸缩主题之前,需要更深入地了解如何使用 Pod 容器控制 CPU 和内存资源(即计算资源)的使用。控制计算资源的使用很重要,因为这样可以实施资源治理,有助于更好地规划集群容量,最重要的是可以防止单个容器消耗所有计算资源,从而避免其他 Pod 无法处理请求的情况。
创建 Pod 时,可以指定其容器所需的计算资源量以及允许的最大消耗量。Kubernetes 资源模型将资源分为两类:可压缩资源和不可压缩资源。可压缩资源可以轻松节流,而不会产生严重后果,例如 CPU;不可压缩资源在节流时会产生严重后果,例如内存分配。
为控制 Pod 容器的资源,可以在其规范中指定两个值:
-
requests
:指定系统保证提供的给定资源量,也可以理解为 Pod 容器正常运行所需的资源量。Pod 调度依赖于 requests 值(而非 limits),特别是 PodFitsResources 谓词和 BalancedResourceAllocation 优先级。
-
limits
:指定系统提供的给定资源的最大量。如果与 requests 一起指定,此值必须大于或等于 requests。根据资源是可压缩还是不可压缩,超过限制会有不同的后果:可压缩资源(CPU)将被节流,而不可压缩资源(RAM)可能导致容器被杀死并重启。
可以通过设置不同的 requests 和 limits 值来允许资源超量使用。系统可以更从容地处理短暂的高资源使用期,同时优化整体资源利用率。这是因为一个节点上的所有容器不太可能同时达到其资源限制。因此,Kubernetes 大部分时间可以更有效地利用可用资源,类似于虚拟机的过度配置或航空公司的超售。
在 Kubernetes 中,CPU 和内存的测量单位如下:
-
CPU
:基本单位是 Kubernetes CPU(KCU),1 KCU 相当于例如 Azure 上的 1 vCPU、GCP 上的 1 个核心或裸机机器上的 1 个超线程核心。允许使用小数值,例如 0.1 也可以指定为 100m(毫 KCU)。
-
内存
:基本单位是字节,可以使用标准单位前缀,如 M、Mi、G、Gi。
在更高级的场景中,还可以控制大页面和临时存储的请求和限制。
以下是为 nginx Deployment 中的 Pod 容器启用计算资源请求和限制的 YAML 清单示例:
# resource-limit/nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-example
spec:
replicas: 5
...<removed for brevity>...
spec:
containers:
- name: nginx
image: nginx:1.17
ports:
- containerPort: 80
resources:
limits:
cpu: 200m
memory: 60Mi
requests:
cpu: 100m
memory: 50Mi
当使用
kubectl apply -f resource-limit/nginx-deployment.yaml
将清单应用到集群,并描述运行此 Deployment 的 Pod 的其中一个节点时,可以看到计算资源配额和分配的详细信息:
$ kubectl describe node minikube-m03
...<removed for brevity>...
Non-terminated Pods: (5 in total)
Namespace Name CPU
Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ----
-------- ---------- --------------- ------------- ---
default nginx-deployment-example-6d444cfd96-f5tnq 100m
(5%) 200m (10%) 50Mi (2%) 60Mi (3%) 23s
default nginx-deployment-example-6d444cfd96-k6j9d 100m
(5%) 200m (10%) 50Mi (2%) 60Mi (3%) 23s
default nginx-deployment-example-6d444cfd96-mqxxp 100m
(5%) 200m (10%) 50Mi (2%) 60Mi (3%) 23s
kube-system calico-node-92bdc 250m
(12%) 0 (0%) 0 (0%) 0 (0%) 6d23h
kube-system kube-proxy-5cd4x 0
(0%) 0 (0%) 0 (0%) 0 (0%) 6d23h
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 550m (27%) 600m (30%)
memory 150Mi (7%) 180Mi (9%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events: <none>
基于此信息,可以进行实验,将容器的 CPU requests 设置为高于集群中单个节点的容量。例如,在 resource-limit/nginx-deployment.yaml 中修改值如下:
...
resources:
limits:
cpu: 2000m
memory: 60Mi
requests:
cpu: 2000m
memory: 50Mi
...
应用配置:
$ kubectl apply -f resource-limit/nginx-deployment.yaml
deployment.apps/nginx-deployment-example configured
检查 Pod 状态时,会发现新的 Pod 处于 Pending 状态,因为它们无法调度到匹配的节点:
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-example-59b669d85f-cdptx 1/1 Running 0 52s
nginx-deployment-example-59b669d85f-hdzdf 1/1 Running 0 54s
nginx-deployment-example-59b669d85f-ktn59 1/1 Running 0 54s
通过这些操作,可以更好地理解和控制 Kubernetes 中 Pod 的资源使用和调度。
Kubernetes Pod 调度与自动伸缩技术详解
6. Kubernetes 中的自动伸缩功能概述
在云环境中运行应用程序时,具备自动伸缩能力被视为理想状态。自动伸缩指的是根据终端用户的活动和需求,自动动态调整应用程序可用的计算资源(如 CPU 和内存)的方法。其目标是根据实际情况添加或移除资源,既能为用户提供高可用性的服务,又能降低业务成本。
Kubernetes 作为成熟的容器编排系统,拥有多种内置的自动伸缩功能,部分功能在每个 Kubernetes 集群中都原生支持,部分则需要安装或特定的集群部署类型。自动伸缩主要有以下几个维度:
| 伸缩维度 | 描述 | 实现方式 |
| ---- | ---- | ---- |
| 垂直 Pod 伸缩 | 调整 Pod 可用的 CPU 和内存资源量,防止资源过度消耗,并可自动调整资源限制 | VerticalPodAutoscaler (VPA) |
| 水平 Pod 伸缩 | 动态更改 Deployment 或 StatefulSet 的 Pod 副本数量 | HorizontalPodAutoscaler (HPA) |
| 水平节点伸缩 | 在 Kubernetes 节点级别进行水平扩展,通过添加或移除节点来扩展整个集群 | Cluster Autoscaler (CA),部分云供应商可用 |
7. 垂直 Pod 自动伸缩(VPA)
垂直 Pod 自动伸缩(VPA)用于调整 Pod 可用的 CPU 和内存资源。Pod 可以在指定的 CPU 和内存限制下运行,但这些限制可能需要自动调整,而不是由人工猜测。
VPA 的工作流程如下:
graph LR
A[监控 Pod 资源使用情况] --> B[分析资源需求]
B --> C[调整 Pod 资源限制]
C --> D[应用新的资源配置]
要使用 VPA,需要满足以下技术要求:
- 部署一个 Kubernetes 集群,建议使用多节点集群。
- 一个多节点 Google Kubernetes Engine (GKE) 集群,这是 VPA 和集群自动伸缩的先决条件。
- 在本地机器上安装并配置 Kubernetes CLI (kubectl) 以管理集群。
8. 水平 Pod 自动伸缩(HPA)
水平 Pod 自动伸缩(HPA)用于动态更改 Deployment 或 StatefulSet 的 Pod 副本数量。这些对象本身具有良好的伸缩功能,但可以使用 HPA 自动调整副本数量。
以下是创建 HPA 的步骤:
1. 确保你有一个运行中的 Deployment 或 StatefulSet。
2. 创建一个 HPA 配置文件,例如:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
-
使用
kubectl apply -f <hpa-config-file.yaml>应用 HPA 配置。
HPA 会根据指定的指标(如 CPU 利用率)自动调整 Pod 副本数量,以确保应用程序能够应对不同的负载。
9. 水平节点自动伸缩(CA)
水平节点自动伸缩(CA)用于在 Kubernetes 节点级别进行水平扩展,通过添加或移除节点来扩展整个集群。这需要在支持动态机器供应的环境(如云环境)中运行的 Kubernetes 部署。
CA 的工作原理如下:
graph LR
A[监控集群资源使用情况] --> B[判断是否需要添加或移除节点]
B -- 需要添加节点 --> C[请求云供应商创建新节点]
B -- 需要移除节点 --> D[删除空闲节点]
C --> E[新节点加入集群]
D --> F[节点从集群中移除]
要使用 CA,需要确保你的云供应商支持该功能,并按照其文档进行配置。
10. 替代自动伸缩器
除了 Kubernetes 内置的自动伸缩功能外,还有一些替代自动伸缩器可供选择,它们可能提供额外的功能或更好地适应特定的使用场景。这些替代自动伸缩器通常具有不同的特点和配置方式,在选择时需要根据具体需求进行评估。
总结
本文详细介绍了 Kubernetes 中 Pod 调度和自动伸缩的相关技术。首先介绍了静态 Pod 的概念、特性和创建方法,以及扩展调度器配置、节点隔离和限制、调度器性能调整等高级调度功能。接着深入探讨了 Pod 资源请求和限制的设置,以及不同类型的自动伸缩功能,包括垂直 Pod 自动伸缩、水平 Pod 自动伸缩和水平节点自动伸缩。
通过合理使用这些技术,可以更好地管理 Kubernetes 集群中的资源,提高应用程序的可用性和性能,同时降低成本。在实际应用中,需要根据具体需求和场景选择合适的调度和自动伸缩策略,并进行适当的配置和调整。
超级会员免费看
1787

被折叠的 条评论
为什么被折叠?



