Kubernetes 生产运维实践:集群管理、升级与故障排查

Kubernetes 生产运维实践:集群管理、升级与故障排查

1. 生产集群高可用架构

1.1 推荐架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌─────────────────────────────────────────────────────────────┐
│ 外部负载均衡(HAProxy / AWS NLB / 云 LB) │
│ VIP: 10.0.0.100:6443
└──────────────────────────┬──────────────────────────────────┘

┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
Master 1 │ │ Master 2 │ │ Master 3
│ apiserver │ │ apiserver │ │ apiserver │
│ scheduler │ │ scheduler │ │ scheduler │
│ ctrl-mgr │ │ ctrl-mgr │ │ ctrl-mgr │
│ etcd │ │ etcd │ │ etcd │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
└─────────────────┼─────────────────┘

┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Worker 1 │ │ Worker 2 │ │ Worker N │
│ kubelet │ │ kubelet │ │ kubelet │
│ kube-proxy │ │ kube-proxy │ │ kube-proxy │
└─────────────┘ └─────────────┘ └─────────────┘

1.2 节点规划建议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 节点角色分离(生产推荐)
Master 节点:
- 3 5 个(奇数,保证 etcd quorum)
- 污点:node-role.kubernetes.io/control-plane:NoSchedule
- 不运行业务 Pod

Worker 节点分组:
- 通用节点:运行大多数业务
- GPU 节点:AI/ML 工作负载
- 高内存节点:数据库、缓存
- 边缘节点:Ingress Controller

节点标签规范:
node-role.kubernetes.io/worker: ""
topology.kubernetes.io/zone: us-east-1a
node.kubernetes.io/instance-type: m5.2xlarge
workload-type: general/gpu/high-memory

2. 集群版本升级

2.1 升级策略

1
2
3
Kubernetes 版本格式:Major.Minor.Patch(如 1.29.3
支持策略:最新 3 个 Minor 版本
升级原则:每次只升级一个 Minor 版本(1.271.281.29

2.2 使用 kubeadm 升级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# ===== 升级 Control Plane =====

# 1. 升级 kubeadm
apt-get update
apt-get install -y kubeadm=1.29.0-00

# 2. 验证升级计划
kubeadm upgrade plan

# 3. 执行升级(第一个 Master)
kubeadm upgrade apply v1.29.0

# 4. 升级 kubelet 和 kubectl
apt-get install -y kubelet=1.29.0-00 kubectl=1.29.0-00
systemctl daemon-reload
systemctl restart kubelet

# 5. 升级其他 Master 节点
kubeadm upgrade node # 在其他 Master 上执行

# ===== 升级 Worker 节点(逐个操作)=====

# 1. 驱逐节点上的 Pod
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data

# 2. 升级 kubeadm/kubelet/kubectl
apt-get install -y kubeadm=1.29.0-00 kubelet=1.29.0-00 kubectl=1.29.0-00
kubeadm upgrade node
systemctl daemon-reload
systemctl restart kubelet

# 3. 恢复节点调度
kubectl uncordon node-1

# 4. 验证节点状态
kubectl get nodes

2.3 升级前检查清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 检查集群健康状态
kubectl get nodes
kubectl get pods --all-namespaces | grep -v Running | grep -v Completed

# 检查 etcd 健康
etcdctl endpoint health --cluster

# 备份 etcd
etcdctl snapshot save /backup/etcd-before-upgrade.db

# 检查 API 废弃
kubectl api-resources
# 使用 pluto 检查废弃 API
pluto detect-all-in-cluster

# 检查 PodDisruptionBudget
kubectl get pdb --all-namespaces

3. 节点管理

3.1 节点维护操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 标记节点不可调度(不驱逐现有 Pod)
kubectl cordon node-1

# 驱逐节点上的 Pod(维护前)
kubectl drain node-1 \
--ignore-daemonsets \ # 忽略 DaemonSet Pod
--delete-emptydir-data \ # 删除使用 emptyDir 的 Pod
--grace-period=60 \ # 优雅终止时间
--timeout=300s # 超时时间

# 恢复节点调度
kubectl uncordon node-1

# 查看节点资源使用
kubectl top nodes
kubectl describe node node-1 | grep -A 10 "Allocated resources"

3.2 节点自动扩缩容(Cluster Autoscaler)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Cluster Autoscaler 配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
spec:
template:
spec:
containers:
- name: cluster-autoscaler
image: registry.k8s.io/autoscaling/cluster-autoscaler:v1.29.0
command:
- ./cluster-autoscaler
- --cloud-provider=aws
- --nodes=2:20:my-node-group # min:max:group-name
- --scale-down-delay-after-add=10m
- --scale-down-unneeded-time=10m
- --skip-nodes-with-local-storage=false
- --expander=least-waste # 扩容策略

4. 资源配额管理

4.1 Namespace 资源配额

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: v1
kind: ResourceQuota
metadata:
name: production-quota
namespace: production
spec:
hard:
# 计算资源
requests.cpu: "100"
requests.memory: 200Gi
limits.cpu: "200"
limits.memory: 400Gi

# 对象数量
pods: "500"
services: "50"
persistentvolumeclaims: "100"
secrets: "200"
configmaps: "200"

# LoadBalancer 数量(成本控制)
services.loadbalancers: "5"
services.nodeports: "0"

4.2 LimitRange(默认资源限制)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: production
spec:
limits:
- type: Container
default: # 默认 limits
cpu: 500m
memory: 512Mi
defaultRequest: # 默认 requests
cpu: 100m
memory: 128Mi
max: # 最大值
cpu: "4"
memory: 8Gi
min: # 最小值
cpu: 50m
memory: 64Mi

- type: PersistentVolumeClaim
max:
storage: 100Gi
min:
storage: 1Gi

5. PodDisruptionBudget(中断预算)

1
2
3
4
5
6
7
8
9
10
11
12
# 确保滚动更新/节点维护时服务不中断
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-pdb
namespace: production
spec:
minAvailable: 2 # 最少保持 2 个 Pod 可用
# maxUnavailable: 1 # 或者最多 1 个不可用
selector:
matchLabels:
app: web

6. 故障排查手册

6.1 Pod 故障排查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# === Pod Pending ===
kubectl describe pod <pod> | grep -A 20 Events
# 常见原因:
# - Insufficient cpu/memory → 增加节点或降低资源请求
# - No nodes are available → 检查节点状态和污点
# - PVC not bound → 检查 StorageClass 和 PV

# === Pod CrashLoopBackOff ===
kubectl logs <pod> --previous # 查看崩溃前日志
kubectl describe pod <pod> # 查看退出码
# 退出码 137 = OOM Kill → 增加内存限制
# 退出码 1 = 应用错误 → 查看应用日志

# === Pod OOMKilled ===
kubectl describe pod <pod> | grep -i "oom\|killed\|memory"
# 解决:增加 memory limits 或优化应用内存使用

# === Pod Evicted ===
kubectl get pods --field-selector=status.phase=Failed
kubectl describe pod <evicted-pod>
# 原因:节点资源压力(内存/磁盘)
# 解决:清理节点资源,调整 QoS 等级

# === ImagePullBackOff ===
kubectl describe pod <pod> | grep -A 5 "Failed to pull"
# 原因:镜像不存在、认证失败、网络问题
# 解决:检查镜像名称、imagePullSecrets

6.2 节点故障排查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 节点 NotReady
kubectl describe node <node>
# 检查 Conditions 部分

# 查看 kubelet 日志
journalctl -u kubelet -f --since "30 minutes ago"

# 检查节点资源
df -h # 磁盘使用
free -h # 内存使用
top # CPU 使用
systemctl status containerd # 容器运行时

# 节点磁盘压力
# 清理未使用的镜像
crictl rmi --prune
# 清理已停止的容器
crictl rm $(crictl ps -a -q --state exited)

# 节点内存压力
# 查看内存使用最多的 Pod
kubectl top pods --all-namespaces --sort-by=memory | head -20

6.3 网络故障排查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Service 无法访问
# 1. 检查 Endpoints
kubectl get endpoints <service>
# 如果 Endpoints 为空:检查 Pod 标签和 Service selector

# 2. 检查 Pod 就绪状态
kubectl get pods -l app=my-app
# 如果 READY 为 0/1:检查 readinessProbe

# 3. 测试 Service 连通性
kubectl run test --image=busybox --rm -it -- \
wget -O- http://<service-name>.<namespace>.svc.cluster.local

# 4. 检查 kube-proxy
kubectl logs -n kube-system -l k8s-app=kube-proxy | tail -50

# DNS 解析失败
kubectl run dns-test --image=busybox --rm -it -- nslookup kubernetes
kubectl logs -n kube-system -l k8s-app=kube-dns

# 跨节点网络不通
# 检查 CNI 插件状态
kubectl get pods -n kube-system | grep -E "calico|cilium|flannel"
# 检查节点路由
ip route show

6.4 etcd 故障排查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 检查 etcd 集群健康
etcdctl endpoint health --cluster \
--endpoints=https://10.0.0.1:2379,https://10.0.0.2:2379,https://10.0.0.3:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key

# 查看 etcd 成员
etcdctl member list --write-out=table

# etcd 空间不足
etcdctl compact $(etcdctl endpoint status --write-out="json" | \
jq '.[0].Status.header.revision')
etcdctl defrag

# 查看 etcd 指标
curl -s https://localhost:2379/metrics | grep etcd_mvcc_db_total_size

6.5 apiserver 故障排查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 检查 apiserver 状态
kubectl get componentstatuses # 已废弃,但仍可用
kubectl get --raw /healthz
kubectl get --raw /readyz

# 查看 apiserver 日志
kubectl logs -n kube-system kube-apiserver-<master-node>

# apiserver 响应慢
# 检查 etcd 延迟
kubectl get --raw /metrics | grep apiserver_request_duration

# 检查 inflight 请求
kubectl get --raw /metrics | grep apiserver_current_inflight_requests

7. 集群备份与恢复

7.1 Velero 备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 安装 Velero
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.0 \
--bucket my-backup-bucket \
--backup-location-config region=us-east-1 \
--snapshot-location-config region=us-east-1

# 创建备份
velero backup create production-backup \
--include-namespaces production \
--include-resources deployments,services,configmaps,secrets,pvc

# 定时备份
velero schedule create daily-backup \
--schedule="0 2 * * *" \
--include-namespaces production \
--ttl 720h # 保留 30 天

# 恢复
velero restore create --from-backup production-backup

8. 性能调优

8.1 apiserver 调优

1
2
3
4
5
6
7
8
9
# 增加并发请求数
--max-requests-inflight=800
--max-mutating-requests-inflight=400

# 增加 Watch Cache
--watch-cache-sizes=pods#2000,nodes#200

# 启用 API Priority and Fairness
--enable-priority-and-fairness=true

8.2 etcd 调优

1
2
3
4
5
6
7
8
9
10
11
# SSD 磁盘(必须)
# 调整心跳和选举超时
--heartbeat-interval=100
--election-timeout=1000

# 自动压缩
--auto-compaction-mode=periodic
--auto-compaction-retention=1h

# 增大存储配额
--quota-backend-bytes=8589934592 # 8GB

8.3 节点调优

1
2
3
4
5
6
7
8
9
10
11
# 内核参数优化
cat >> /etc/sysctl.conf << EOF
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 8096
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 512
EOF
sysctl -p

9. 运维自动化

9.1 常用运维脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 批量重启 Deployment
kubectl rollout restart deployment -n production

# 清理 Evicted Pod
kubectl get pods --all-namespaces --field-selector=status.phase=Failed \
-o json | kubectl delete -f -

# 查看所有命名空间的资源使用
kubectl top pods --all-namespaces --sort-by=cpu | head -20

# 查找没有设置资源限制的 Pod
kubectl get pods --all-namespaces -o json | \
jq '.items[] | select(.spec.containers[].resources.limits == null) |
.metadata.namespace + "/" + .metadata.name'

# 查找长时间未更新的 Deployment
kubectl get deployments --all-namespaces \
-o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,AGE:.metadata.creationTimestamp'

10. 总结

生产 Kubernetes 运维的核心原则:

  1. 高可用:3/5 Master 节点,etcd 奇数节点,多可用区部署
  2. 渐进升级:逐个 Minor 版本升级,先升 Master 再升 Worker
  3. 资源管理:ResourceQuota + LimitRange + PDB 三件套
  4. 可观测性:监控、日志、告警缺一不可
  5. 备份:etcd 定期备份 + Velero 应用备份
  6. 故障演练:定期进行混沌工程测试(Chaos Mesh)
  7. 自动化:GitOps + CI/CD,减少人工操作

Kubernetes 生产运维实践:集群管理、升级与故障排查
https://k8s.chucz.asia/Kubernetes生产运维实践/
作者
K8s Engineer
发布于
2026年1月27日
许可协议