Kubernetes Pods和节点自动伸缩实战指南
在Kubernetes中,自动伸缩是应对应用负载变化的关键能力。本文将详细介绍如何实现Kubernetes Pods和节点的自动伸缩,包括Horizontal Pod Autoscaler(HPA)和Cluster Autoscaler(CA)的使用。
1. 使用HPA实现Pod自动伸缩
当应用通过ClusterIP Service运行并暴露后,可使用 kubectl port-forward 命令从集群外部访问应用:
$ kubectl port-forward svc/todo-app -n hpa-demo 8081:8081
Forwarding from 127.0.0.1:8081 -> 3000
Forwarding from [::1]:8081 -> 3000
打开浏览器,访问 http://localhost:8081 ,即可看到Todo应用正在运行。在控制台按 Ctrl+C 结束 kubectl port-forward 任务。
接下来,我们将学习如何创建HPA并对部署应用负载以实现自动伸缩。
1.1 安装 hey 工具
hey 是一个轻量级的HTTP负载测试工具,可用于生成模拟工作负载。其安装步骤如下:
1. 为你的操作系统下载 hey 包。
2. 设置可执行权限并将文件复制到可执行路径,例如:
ln -s ~/Downloads/hey_linux_amd64 ~/.local/bin/
1.2 创建HPA资源
根据工作负载为单页Web部署创建HPA资源,步骤如下:
1. 准备HPA YAML文件:
# hpa/todo-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: todo-hpa
namespace: hpa-demo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: todo-app
minReplicas: 1
maxReplicas: 5
metrics:
- resource:
name: cpu
target:
averageUtilization: 80
type: Utilization
type: Resource
- 应用配置并创建HPA:
$ kubectl apply -f hpa/todo-hpa.yaml
horizontalpodautoscaler.autoscaling/todo-hpa created
也可以使用其他方法增加负载,例如运行另一个容器访问应用Pod:
$ kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://todo-app; done"
但这种方法可能无法精确控制工作负载。
1.3 模拟工作负载
再次使用 kubectl port-forward 命令从集群外部访问Todo应用:
$ kubectl port-forward svc/todo-app -n hpa-demo 8081:8081
Forwarding from 127.0.0.1:8081 -> 3000
Forwarding from [::1]:8081 -> 3000
由于此时没有人使用Todo应用,Pod副本数保持为1。使用 hey 工具模拟工作负载:
$ hey -z 4m -c 25 http://localhost:8081
参数说明:
- -z 4m :持续运行4分钟以维持较长时间的负载。
- -c 25 :使用25个并发连接生成更高负载,使CPU使用率接近80%。
- http://localhost:8081 :访问Todo应用的URL。
在 kubectl port-forward 控制台会看到大量连接条目,表明 hey 正在模拟单页Web应用的负载。
1.4 检查Pod资源利用率
打开第三个控制台,检查Pod资源利用率:
$ watch 'kubectl get po -n hpa-demo;kubectl top pods -n hpa-demo'
可以看到由于 hey 对Todo应用施加了更多工作负载,触发HPA创建了更多副本,现在有三个(或更多)Pod被创建。
1.5 检查部署详情
检查部署详情,确认副本数和事件以查看伸缩事件:
$ kubectl describe deployments.apps todo-app -n hpa-demo
至此,你已成功使用HPA为部署配置了水平自动伸缩。作为清理工作,可删除 hpa-demo 命名空间以删除资源:
$ kubectl delete namespaces hpa-demo
2. 使用Cluster Autoscaler实现节点自动伸缩
前面讨论了单个Pod级别的伸缩,实际上还可以对集群本身进行伸缩以适应计算资源需求的变化。Cluster Autoscaler(CA)可以解决这个问题,它是Kubernetes自动伸缩器仓库的一部分。
2.1 CA的工作原理
CA会定期检查Pods和Nodes的状态,并根据以下情况决定是否采取行动:
- 如果由于集群资源不足,有Pods处于Pending状态无法调度,CA会添加更多Nodes,直到达到预定义的最大规模。
- 如果Nodes利用率不足,且减少节点数量仍能调度所有Pods,CA会从集群中移除这些Nodes,除非达到预定义的最小规模。在移除节点之前,会优雅地排空这些节点。
- 对于某些云服务提供商,CA还可以在不同的VM SKU之间进行选择,以更好地优化集群运营成本。
CA可以补充HPA的功能。如果HPA决定为Deployment或StatefulSet创建更多Pods,但无法调度更多Pods时,CA可以介入并增加集群规模。
2.2 CA的局限性
CA存在一些限制,可能会影响其有效性:
- CA向云提供商请求新节点到节点可用之间存在延迟,通常为几分钟,这可能会在高需求期间影响应用性能。
- CA的伸缩决策仅基于Pod资源请求和限制,而非实际CPU或内存利用率。如果Pods过度请求资源,可能导致节点利用率不足和资源低效。
- CA主要设计用于云环境。虽然可以适应本地或其他基础设施,但需要额外的工作,包括自定义脚本或工具来管理节点的供应和退役,以及配置自动伸缩器与这些机制进行交互。没有基于云的自动伸缩功能,管理集群规模会变得更加复杂,需要更密切的监控。
Pod容器必须指定计算资源请求,以使CA正常工作。此外,这些值应反映实际使用情况,否则CA无法为你的工作负载做出正确决策。
2.3 在不同云服务提供商中启用CA
不同云服务提供商启用CA的步骤不同,下面分别介绍:
GKE
在GKE中,从头创建一个启用CA的集群最简单。运行以下命令创建名为 k8sbible 的集群:
$ gcloud container clusters create k8sbible \
--enable-autoscaling \
--num-nodes 3 \
--min-nodes 2 \
--max-nodes 10 \
--region=us-central1-a
命令参数说明:
- gcloud container clusters create k8sbible :创建一个名为 k8sbible 的新Kubernetes集群。
- --enable-autoscaling :为集群的节点池启用自动伸缩。
- --num-nodes 3 :将初始节点数设置为3。
- --min-nodes 2 :将最小节点数设置为2。
- --max-nodes 10 :将最大节点数设置为10。
- --region=us-central1-a :指定区域为 us-central1-a 。
对于现有集群,需要在现有节点池上启用CA。例如,对于名为 k8sforbeginners 的集群和名为 nodepool1 的节点池,运行以下命令:
$ gcloud container clusters update k8sforbeginners --enable-autoscaling --min-nodes=2 --max-nodes=10 --zone=us-central1-a --node-pool=nodepool1
更新需要几分钟时间。使用 gcloud CLI 验证自动伸缩功能:
$ gcloud container node-pools describe default-pool --cluster=k8sdemo |grep autoscaling -A 1
Amazon Elastic Kubernetes Service(EKS)
在Amazon EKS中设置CA目前无法通过一键或一命令完成。需要创建适当的IAM策略和角色,将CA资源部署到Kubernetes集群,并进行手动配置步骤。因此这里不详细介绍,你可以参考官方说明: https://docs.aws.amazon.com/eks/latest/userguide/cluster-autoscaler.html 。
Azure Kubernetes Service(AKS)
AKS提供了与GKE类似的CA设置体验,可以使用一个命令来部署启用CA的新集群或更新现有集群以使用CA。创建一个名为 k8sforbeginners-aks 的新集群:
$ az aks create --resource-group k8sforbeginners-rg \
--name k8sforbeginners-aks \
--node-count 1 \
--enable-cluster-autoscaler \
--min-count 1 \
--max-count 10 \
--vm-set-type VirtualMachineScaleSets \
--load-balancer-sku standard \
--generate-ssh-keys
参数说明:
- --min-count :控制自动伸缩时的最小节点数。
- --max-count :控制自动伸缩时的最大节点数。
对于现有AKS集群,启用CA:
$ az aks update --resource-group k8sforbeginners-rg --name k8sforbeginners-aks --enable-cluster-autoscaler --min-count 2 --max-count 10
更新需要几分钟时间。更多信息可参考官方文档: https://docs.microsoft.com/en-us/azure/aks/cluster-autoscaler 。
2.4 使用CA
配置好CA后,它可能需要一些时间来执行首次操作,这取决于CA的配置,可能因供应商而异。例如,在AKS中,集群每10秒评估一次是否需要进行伸缩。
为了演示,使用一个包含两个节点的GKE集群:
$ kubectl get nodes -o custom-columns=NAME:.metadata.name,CPU_ALLOCATABLE:.status.allocatable.cpu,MEMORY_ALLOCATABLE:.status.allocatable.memory
由于没有简单的方法在容器中实现可预测和变化的CPU使用,我们需要设置一个Deployment和Pod模板。使用 elastic-hamster Deployment,其内部的 hamster.sh 脚本会根据 TOTAL_HAMSTER_USAGE 值增加工作负载。
实现和测试集群自动伸缩的步骤如下:
1. 使用 ca-demo 命名空间隔离测试:
# ca/ca-demo-ns.yaml
---
apiVersion: v1
kind: Namespace
metadata:
labels:
project: ca-demo
name: ca-demo
- 设置额外的RBAC权限以通过Kubernetes API查询Deployments:
# ca/deployment-reader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: ca-demo
name: deployment-reader
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "watch", "list"]
- 为
hamsterPods准备一个ServiceAccount:
# ca/elastic-hamster-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: elastic-hamster
namespace: ca-demo
- 准备一个RoleBinding YAML:
# ca/read-deployments-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-deployments
namespace: ca-demo
subjects:
- kind: ServiceAccount
name: elastic-hamster
namespace: default
roleRef:
kind: Role
name: deployment-reader
apiGroup: rbac.authorization.k8s.io
- 创建
elastic-hamsterDeployment:
...
spec:
serviceAccountName: elastic-hamster
containers:
- name: hamster
image: quay.io/iamgini/elastic-hamster:1.0
resources:
requests:
cpu: 500m
memory: 50Mi
env:
- name: TOTAL_HAMSTER_USAGE
value: "1.0"
- 创建一个HPA来自动伸缩Pods:
# elastic-hamster-hpa.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: elastic-hamster-hpa
namespace: ca-demo
spec:
minReplicas: 1
maxReplicas: 25
metrics:
- resource:
name: cpu
target:
averageUtilization: 75
type: Utilization
type: Resource
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: elastic-hamster
- 一起应用
ca目录下的所有YAML文件:
$ kubectl apply -f ca/
由于HPA配置了最大25个副本,而集群没有足够的容量来调度这些Pods,CA将开始扩展Kubernetes节点。
- 检查Pods,会发现由于容量问题,一些Pods处于Pending状态:
$ kubectl get po -n ca-demo
- 检查节点,会发现集群中现在共有10个节点(即之前配置的最大节点数):
$ kubectl top pod -n ca-demo
这展示了CA如何与HPA协同工作,无缝地同时扩展Deployment和集群以适应工作负载。
通过以上步骤,你可以在Kubernetes中实现Pod和节点的自动伸缩,根据工作负载动态调整资源,提高资源利用率和应用的性能。
3. 自动缩容演示
完成自动扩容的演示后,接下来看看自动缩容的情况。当工作负载降低时,CA会根据资源利用率判断是否需要缩容节点。
3.1 降低工作负载
可以停止之前使用的 hey 工具或其他增加负载的操作,让应用的工作负载自然降低。例如,停止 hey 工具的命令如下:
# 在运行hey命令的控制台,按Ctrl + C停止
3.2 等待缩容决策
CA会定期检查集群的资源利用率,当满足缩容条件时,会触发缩容操作。不同云服务提供商的CA缩容条件和时间间隔可能不同。以AKS为例,若在扩容后需要缩容,会有10分钟的延迟( scale-down-delay-after-add ),当请求资源总和除以容量低于0.5( scale-down-utilization-threshold )时,会触发缩容。
3.3 检查缩容结果
等待一段时间后,检查节点和Pod的状态,确认是否发生了缩容:
# 检查节点
kubectl get nodes -o custom-columns=NAME:.metadata.name,CPU_ALLOCATABLE:.status.allocatable.cpu,MEMORY_ALLOCATABLE:.status.allocatable.memory
# 检查Pod
kubectl get po -n ca-demo
可以看到,随着工作负载的降低,CA会移除一些利用率较低的节点,同时确保所有Pod仍能正常调度。
4. 总结与注意事项
4.1 总结
通过使用Horizontal Pod Autoscaler(HPA)和Cluster Autoscaler(CA),可以在Kubernetes中实现Pod和节点的自动伸缩。HPA根据工作负载自动调整Pod的副本数,而CA则根据集群的资源利用率自动调整节点的数量。两者结合使用,可以根据应用的实际需求动态调整资源,提高资源利用率和应用的性能。
4.2 注意事项
- 资源配置 :Pod容器必须指定计算资源请求,并且这些值应反映实际使用情况,否则CA无法做出正确的伸缩决策。
- 延迟问题 :CA向云提供商请求新节点到节点可用之间存在延迟,可能会在高需求期间影响应用性能。在高并发场景下,需要提前规划资源,避免因延迟导致应用响应缓慢。
- 成本控制 :虽然CA可以根据需求自动调整节点数量,但在配置时要注意设置合理的最大和最小节点数,避免资源过度消耗和成本过高。
- 监控与调优 :定期监控集群的资源利用率和应用性能,根据实际情况调整HPA和CA的配置参数,以实现最佳的伸缩效果。
5. 流程图总结
下面是一个mermaid格式的流程图,总结了使用HPA和CA实现自动伸缩的主要步骤:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(部署应用):::process
B --> C(创建HPA资源):::process
C --> D(模拟工作负载):::process
D --> E{CPU利用率是否达到阈值?}:::decision
E -->|是| F(HPA增加Pod副本):::process
E -->|否| D(模拟工作负载):::process
F --> G{集群资源是否不足?}:::decision
G -->|是| H(CA增加节点):::process
G -->|否| I(继续运行):::process
I --> J(降低工作负载):::process
J --> K{资源利用率是否降低?}:::decision
K -->|是| L(CA移除节点):::process
K -->|否| J(降低工作负载):::process
L --> M([结束]):::startend
6. 表格总结
为了更清晰地对比HPA和CA的功能和使用场景,下面是一个表格总结:
| 功能 | HPA | CA |
| ---- | ---- | ---- |
| 作用对象 | Pod | 节点 |
| 伸缩依据 | 工作负载(如CPU利用率) | 集群资源利用率 |
| 配置方式 | 创建HPA YAML文件并应用 | 根据不同云服务提供商的命令创建或更新集群 |
| 适用场景 | 应用负载波动,需要动态调整Pod副本数 | 集群资源不足或利用率低,需要动态调整节点数量 |
通过以上的步骤和说明,你可以在Kubernetes中实现Pod和节点的自动伸缩,根据工作负载动态调整资源,提高资源利用率和应用的性能。在实际应用中,要根据具体的业务需求和云服务提供商的特点,合理配置HPA和CA,以达到最佳的伸缩效果。
超级会员免费看
3994

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



