
几个月前,我们接手了一个部署在香港数据中心的高频业务系统。业务高峰期波动剧烈,容器CPU利用率飙升,节点负载不均衡,Kubernetes默认调度策略也无法满足我们的弹性需求。为了提升资源利用率、降低成本并应对突发流量,我们决定在现有Kubernetes集群上实施定制化容器编排与自动扩容策略。
以下是我在香港物理服务器环境中逐步推进这个方案的全过程,涉及节点配置、调度器优化、自动扩容(Cluster Autoscaler + VPA/HPA)实践,以及实际踩坑与调优经验。
一、部署环境概述
| 类型 | 配置 |
|---|---|
| 数据中心 | 香港(A5IDC 机房) |
| 节点规格 | 8 台物理机,Xeon Gold 6338 + 256GB DDR4 + NVMe SSD |
| Kubernetes 版本 | v1.28 |
| 网络插件 | Cilium |
| 容器运行时 | containerd |
| 自动扩容组件 | Cluster Autoscaler、HPA、VPA |
| CI/CD系统 | GitLab + ArgoCD |
二、自定义调度策略的挑战与实现
默认的 kube-scheduler 在资源分布不均和部分关键服务(如推送服务)负载偏移时,往往调度效果并不理想。我们决定:
1. 基于标签的自定义调度约束
通过为业务容器打上资源标签,结合 nodeAffinity 和 taints/tolerations 实现资源分层调度:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "node-tier"
operator: In
values:
- "compute-intensive"
同时在物理节点层设置:
kubectl label nodes node-1 node-tier=compute-intensive
kubectl taint nodes node-1 dedicated=compute:NoSchedule
这样实现了“核心服务上优质节点、辅助服务分散部署”的结构。
三、Cluster Autoscaler 的定制化部署
我们通过修改 Cluster Autoscaler 的启动参数,使其理解自建裸金属服务器池中哪些节点可加入扩容。
1. 自定义 NodeGroup 映射脚本(基于 webhook)
由于我们是裸金属架构,使用 API Hook + PXE 引导的方式接入新节点。CA 不支持裸金属 out-of-box 自动扩容,因此我写了一个定制的 webhook:
// 简化示例:/scale-up webhook 响应新节点IP和配置
func scaleUpHandler(w http.ResponseWriter, r *http.Request) {
req := parseRequest(r)
if req.NeedsNewNode {
go provisionBaremetalNode(req.NodeType) // PXE 部署流程
}
}
Cluster Autoscaler 参数:
--cloud-provider=external
--expander=least-waste
--scale-up-from-zero=true
--nodes=2:8:custom-baremetal-group
四、HPA 与 VPA 协同工作机制实战
为了实现 Pod 资源的弹性纵向+横向扩展,我们将 HPA 和 VPA 协同使用,并划分了不同策略的 workload:
1. CPU 抖动型服务(HPA)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
spec:
maxReplicas: 20
minReplicas: 2
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
2. 内存持续增长型服务(VPA)
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
spec:
updatePolicy:
updateMode: "Auto"
同时设置 resourcePolicy 避免出现 VPA+HPA 冲突。
五、Prometheus + KEDA 事件驱动扩容
对于一些与外部事件强相关(如 Redis 队列积压、Kafka backlog)的服务,我们不采用资源触发,而是引入 KEDA 实现事件驱动扩容:
triggers:
- type: redis
metadata:
address: redis-cluster:6379
listName: task-queue
listLength: "1000"
这种方式极大提升了弹性响应的“提前量”。
六、调优经验
- 定期预热新节点:物理节点从 PXE 启动到可用 Pod 运行平均需 4 分钟。通过 webhook 提前触发预热,缩短初始调度延迟。
- Prometheus 监控资源碎片:我们自定义了 container_resource_usage_percentile 监控项,用于判断是否存在资源空转。
- 避免 VPA 导致 pod 重启频繁:推荐在 StatefulSet 场景关闭 Auto 模式,改用 Off + Prometheus 报警手动干预。
- 合理划分 Namespace 与 ResourceQuota:防止某一业务抢占集群核心资源。
七、效果评估
实施该方案三个月以来,我们的 Kubernetes 集群整体 CPU 利用率从 32% 提升至 68%,节点数量在低峰期自动缩容至最低 4 台,高峰期扩容至 8 台。同时,通过 KEDA 弹性策略,推送服务的响应延迟下降了 23ms,资源浪费率显著下降。
这套定制容器编排与自动扩容体系,是我在香港本地服务器环境中基于实际业务需求构建的。对我来说,Kubernetes 的强大不仅体现在“云原生”,更重要的是它给予我们足够的“控制力”。只要深入理解其机制并结合场景做出裁剪,它就能在任何环境下释放最大效能。











