1. 为什么需要关注EKS集群升级?
作为AWS上的托管Kubernetes服务,EKS的版本升级从来都不是简单的"点一下按钮"就能完成的操作。我经历过从1.33到1.35的完整升级过程,深刻体会到这其中的技术细节和潜在风险。与自建Kubernetes集群不同,EKS的升级涉及控制平面和工作节点的双重变更,需要特别关注API废弃、组件兼容性和工作负载影响这三个核心维度。
在1.33到1.35的版本跨度中,最值得注意的变化包括:
- kube-apiserver默认启用API优先级和公平性(APF)
- CoreDNS升级到1.10.1版本
- 对Windows节点的支持策略变更
- kubectl的某些命令行为调整
这些变化看似微小,但实际升级中可能引发服务中断。比如我们团队就曾遇到APF导致的重要业务Pod被限流的情况,当时花了整整两天才定位到问题根源。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 升级前的关键准备工作
2.1 环境检查清单
在点击升级按钮前,建议按照以下清单逐项检查:
- 当前集群状态验证:
bash复制kubectl get nodes -o wide
eksctl get cluster --name=<集群名称>
aws eks describe-cluster --name=<集群名称> --query "cluster.status"
- 工作负载兼容性评估:
- 使用kubent工具扫描API废弃情况:
bash复制kubent --k8s-version=v1.35.0
- 特别检查使用这些API的资源:
- extensions/v1beta1
- apps/v1beta1
- networking.k8s.io/v1beta1
- 关键组件版本矩阵:
| 组件 | 1.33版本 | 1.35要求 | 检查命令 |
|------|----------|----------|----------|
| CNI插件 | ≥1.12.5 | ≥1.14.0 | kubectl describe daemonset aws-node -n kube-system | grep Image |
| CoreDNS | 1.9.3 | 1.10.1 | kubectl get deployment coredns -n kube-system -o jsonpath='{.spec.template.spec.containers[0].image}' |
| kube-proxy | 1.33.0 | 1.35.0 | kubectl get daemonset kube-proxy -n kube-system -o jsonpath='{.spec.template.spec.containers[0].image}' |
2.2 必须完成的预处理步骤
- ETCD备份:
虽然EKS控制平面会自动备份,但建议额外执行:
bash复制aws eks describe-cluster --name <集群名称> --query "cluster.resourcesVpcConfig"
- 工作节点排水策略:
创建自定义Pod中断预算(PDB):
yaml复制apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: critical-pods
spec:
minAvailable: 80%
selector:
matchLabels:
app: critical
- 测试环境验证:
使用eksctl创建临时集群:
bash复制eksctl create cluster --version=1.35 --name=upgrade-test --nodes=3
3. 控制平面升级实战
3.1 通过AWS控制台升级
控制平面升级相对简单但有几个关键注意点:
- 在AWS控制台找到EKS服务 → 选择集群 → 点击"更新集群版本"
- 选择1.35版本后,系统会显示预估时间(通常20-40分钟)
- 升级过程中监控这些指标:
kube-apiserver_request_duration_secondsetcd_db_total_size_in_bytescontroller_manager_queue_depth
重要提示:控制平面升级期间不要进行任何kubectl操作,特别是大规模部署或删除操作
3.2 验证控制平面升级
升级完成后,运行以下诊断命令:
bash复制kubectl version --short
aws eks describe-cluster --name <集群名称> --query "cluster.version"
检查核心组件日志:
bash复制kubectl logs -n kube-system -l k8s-app=kube-apiserver --tail=50
kubectl logs -n kube-system -l k8s-app=kube-controller-manager --tail=50
4. 工作节点升级策略
4.1 蓝绿升级法(推荐)
- 创建新的节点组:
bash复制eksctl create nodegroup --cluster=<集群名称> --version=1.35 --name=ng-1-35
- 逐步迁移工作负载:
bash复制kubectl get pods -o wide | grep <旧节点组>
kubectl drain <旧节点> --ignore-daemonsets --delete-emptydir-data
- 验证新节点稳定性后删除旧节点组
4.2 原地升级法
适用于无法承受节点扩容的场景:
bash复制kubectl get nodes -o jsonpath='{.items[*].metadata.labels.eks\.amazonaws\.com/nodegroup}'
aws eks update-nodegroup-version --cluster-name <集群名称> --nodegroup-name <节点组名称>
监控节点状态变化:
bash复制watch -n 5 'kubectl get nodes -L eks.amazonaws.com/nodegroup'
5. 升级后必须的验证步骤
5.1 核心功能测试清单
- 网络连通性验证:
bash复制kubectl run -it --rm --restart=Never test-pod --image=busybox -- ping <服务域名>
- 存储卷测试:
bash复制kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pvc-test
spec:
containers:
- name: pvc-test
image: busybox
command: ["/bin/sh", "-c", "while true; do echo $(date) >> /data/out.txt; sleep 1; done"]
volumeMounts:
- name: persistent-storage
mountPath: /data
volumes:
- name: persistent-storage
persistentVolumeClaim:
claimName: <你的PVC名称>
EOF
- Ingress控制器测试:
bash复制kubectl get ingress --all-namespaces
curl -v <Ingress地址>/healthz
5.2 性能基准对比
使用kubectl-benchmark工具:
bash复制# 安装
curl -L https://github.com/kubernetes-sigs/kubectl-benchmark/releases/download/v0.0.1/kubectl-benchmark_0.0.1_linux_amd64.tar.gz | tar xz
# 运行测试
./kubectl-benchmark --count=100 --concurrency=10 create -f test-pod.yaml
比较1.33和1.35版本的:
- Pod启动延迟
- API响应时间
- 调度器决策速度
6. 常见问题与解决方案
6.1 CoreDNS解析失败
症状:Pod内无法解析集群服务域名
排查步骤:
bash复制kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system <coredns-pod>
kubectl describe configmap/coredns -n kube-system
修复方案:
更新CoreDNS配置:
yaml复制apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods verified
fallthrough in-addr.arpa ip6.arpa
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
6.2 节点NotReady状态
典型原因:
- CNI插件版本不兼容
- kubelet与API版本不匹配
诊断命令:
bash复制journalctl -u kubelet -n 100 --no-pager
aws eks describe-nodegroup --cluster-name <集群> --nodegroup-name <节点组>
修复步骤:
- 更新CNI插件:
bash复制kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/v1.14.0/config/v1.14/aws-k8s-cni.yaml
- 重启kubelet:
bash复制systemctl restart kubelet
7. 升级后的优化建议
7.1 启用新版本特性
- API优先级和公平性(APF)调优:
yaml复制apiVersion: flowcontrol.apiserver.k8s.io/v1beta2
kind: PriorityLevelConfiguration
metadata:
name: customer-high
spec:
type: "Exempt"
- 使用kubectl debug命令:
bash复制kubectl debug -it <故障Pod> --image=busybox --target=<容器名称>
7.2 监控配置更新
Prometheus新增监控项:
yaml复制- job_name: 'kube-apiserver'
metrics_path: '/metrics'
scheme: 'https'
tls_config:
insecure_skip_verify: true
bearer_token_file: '/var/run/secrets/kubernetes.io/serviceaccount/token'
static_configs:
- targets: ['kubernetes.default.svc:443']
Grafana仪表板需要新增:
- APF排队请求监控
- 淘汰Pod数量趋势
- 存储卷挂载延迟
我在实际升级过程中发现,1.35版本对大规模集群的调度性能有明显提升,但需要特别注意kubelet的内存配置。建议将--kube-reserved参数调整为:
yaml复制kubeReserved:
cpu: "500m"
memory: "1Gi"
ephemeral-storage: "5Gi"
