主题
第五部分 Kubernetes 集群运维
本部分进入 K8s 运维工程师的核心能力领域:集群部署、升级、巡检、扩容、资源治理和故障排查。
第 17 章 Kubernetes 集群部署与升级
17.1 集群部署方式
| 方式 | 工具 | 适用场景 |
|---|---|---|
| 本地测试 | minikube、kind、Docker Desktop | 学习、开发 |
| 手动部署 | kubeadm | 生产环境 |
| 自动化部署 | kubespray、sealos | 大规模生产环境 |
| 托管服务 | ACK、TKE、EKS、AKS、GKE | 企业生产环境 |
17.2 使用 kubeadm 部署集群
环境准备
bash
# 关闭 swap
sudo swapoff -a
sudo sed -i '/swap/d' /etc/fstab
# 加载内核模块
sudo modprobe overlay
sudo modprobe br_netfilter
# 设置 sysctl
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
# 安装 containerd
sudo apt update
sudo apt install -y containerd.io
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd安装 kubeadm、kubelet、kubectl
bash
# 添加 K8s 仓库
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
# 安装
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl初始化控制平面
bash
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \
--apiserver-advertise-address=<MASTER_IP>
# 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 安装 CNI(Flannel)
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml加入工作节点
bash
# 在 master 上生成加入命令
kubeadm token create --print-join-command
# 在 node 上执行
sudo kubeadm join <MASTER_IP>:6443 --token <TOKEN> --discovery-token-ca-cert-hash sha256:<HASH>17.3 集群升级
升级控制平面
bash
# 1. 升级 kubeadm
sudo apt update
sudo apt install -y kubeadm=1.31.x-00
# 2. 升级集群
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.31.x
# 3. 升级 kubelet 和 kubectl
sudo apt install -y kubelet=1.31.x-00 kubectl=1.31.x-00
sudo systemctl restart kubelet升级工作节点
bash
# 1. 驱逐节点
kubectl drain <NODE_NAME> --ignore-daemonsets
# 2. 升级 kubeadm、kubelet、kubectl
sudo apt update
sudo apt install -y kubeadm=1.31.x-00 kubelet=1.31.x-00 kubectl=1.31.x-00
# 3. 升级节点配置
sudo kubeadm upgrade node
# 4. 重启 kubelet
sudo systemctl restart kubelet
# 5. 恢复节点
kubectl uncordon <NODE_NAME>17.4 高可用集群
高可用架构至少需要 3 个控制平面节点 + 负载均衡器。
┌─────────────┐
│ LB/VIP │
│ API Server │
└──────┬──────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│ Master 1│ │ Master 2│ │ Master 3│
│ API/etcd│ │ API/etcd│ │ API/etcd│
└─────────┘ └─────────┘ └─────────┘
│ │ │
└──────────────────┼──────────────────┘
│
┌────────────┼────────────┐
│ │ │
┌────┴───┐ ┌────┴───┐ ┌────┴───┐
│ Worker1│ │ Worker2│ │ Worker3│
└────────┘ └────────┘ └────────┘17.5 本章练习
- 使用 minikube 或 kind 创建一个本地 K8s 集群。
- 尝试使用 kubeadm 在两台虚拟机上部署一个单 Master 集群。
- 了解 kubeadm 升级的基本流程。
第 18 章 集群巡检与资源治理
18.1 集群巡检内容
| 巡检项 | 检查内容 |
|---|---|
| 节点健康 | 节点状态、资源使用、磁盘压力、内存压力、PID 压力 |
| 控制平面 | API Server、etcd、Scheduler、Controller Manager 健康 |
| 工作负载 | Pod 状态、重启次数、资源使用 |
| 网络 | CNI、DNS、Service、Ingress |
| 存储 | PV/PVC 状态、存储容量 |
| 安全 | RBAC、Secret、NetworkPolicy |
| 证书 | 集群证书有效期 |
18.2 常用巡检命令
bash
# 节点状态
kubectl get nodes -o wide
# 节点资源压力
kubectl describe node <NODE_NAME>
# Pod 状态
kubectl get pods -A --field-selector=status.phase!=Running
# 异常事件
kubectl get events -A --sort-by='.lastTimestamp' | tail -50
# 证书过期
kubeadm certs check-expiration
# etcd 健康(单 master)
kubectl exec -it etcd-<master> -n kube-system -- etcdctl endpoint health18.3 资源治理
资源使用分析
bash
# 查看所有 Pod 资源使用
kubectl top nodes
kubectl top pods -A
# 查看未设置资源限制的 Pod
kubectl get pods -A -o json | jq '.items[] | select(.spec.containers[].resources.limits == null) | .metadata.name'清理无用资源
bash
# 查看所有命名空间
kubectl get ns
# 查看孤立的 PVC
kubectl get pvc -A | grep -v Bound
# 查看失败的 Pod
kubectl get pods -A | grep -E "Error|CrashLoopBackOff|ImagePullBackOff"
# 查看未使用的 ConfigMap/Secret
# 需要借助脚本或工具18.4 成本优化
- 合理设置 requests/limits
- 使用 HPA/VPA 自动扩缩容
- 及时清理测试环境
- 使用 Spot/抢占式实例
- 合理选择实例规格
- 监控资源闲置率
18.5 本章实验
实验 18-1:编写巡检脚本
bash
#!/bin/bash
# k8s-inspect.sh
echo "=== 节点状态 ==="
kubectl get nodes -o wide
echo "=== 非 Running Pod ==="
kubectl get pods -A --field-selector=status.phase!=Running
echo "=== 最近异常事件 ==="
kubectl get events -A --field-selector type=Warning --sort-by='.lastTimestamp' | tail -30
echo "=== 资源使用 Top ==="
kubectl top nodes
kubectl top pods -A --sort-by=cpu | head -20
echo "=== 证书过期时间 ==="
kubeadm certs check-expiration 2>/dev/null || echo "非 kubeadm 集群"18.6 本章练习
- 列出你所在集群的所有异常 Pod。
- 查看节点资源压力条件(Conditions)。
- 编写一个巡检脚本并加入定时任务。
- 找出未设置资源限制的 Pod。
第 19 章 扩缩容与高可用
19.1 手动扩缩容
bash
# Deployment 扩缩容
kubectl scale deployment nginx --replicas=5
# StatefulSet 扩缩容
kubectl scale statefulset web --replicas=519.2 水平自动扩缩容(HPA)
HPA 根据 CPU、内存或自定义指标自动调整 Pod 数量。
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50bash
kubectl apply -f hpa.yaml
kubectl get hpa
kubectl describe hpa nginx-hpa19.3 垂直自动扩缩容(VPA)
VPA 自动调整 Pod 的 CPU/内存 requests/limits。
bash
# 安装 VPA
kubectl apply -f https://github.com/kubernetes/autoscaler/releases/latest/download/vertical-pod-autoscaler.yaml
# 创建 VPA 对象
kubectl apply -f - <<EOF
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: nginx-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
updatePolicy:
updateMode: "Auto"
EOF19.4 集群自动扩缩容(Cluster Autoscaler)
Cluster Autoscaler 根据 Pod 调度需求自动增减节点。
在云环境中使用:
bash
# 阿里云 ACK
kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/alicloud/deploy/cluster-autoscaler.yaml19.5 高可用设计
- 多 Master 部署
- 多可用区部署
- 关键应用多副本
- 使用 PodDisruptionBudget
- 使用反亲和性避免单点故障
yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: nginx-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: nginx19.6 本章实验
实验 19-1:HPA 测试
bash
# 1. 创建 Deployment
kubectl create deployment hpa-demo --image=nginx:1.25
# 2. 配置资源请求
kubectl set resources deployment hpa-demo --requests=cpu=100m
# 3. 创建 HPA
kubectl autoscale deployment hpa-demo --cpu-percent=50 --min=1 --max=5
# 4. 加压测试
kubectl run load-generator --image=busybox:1.36 -- /bin/sh -c "while true; do wget -q -O- http://hpa-demo; done"
# 5. 观察 HPA
kubectl get hpa -w19.7 本章练习
- 为一个 Deployment 配置 HPA。
- 使用压力测试工具触发 HPA 扩容。
- 了解 VPA 和 Cluster Autoscaler 的适用场景。
- 为一个关键应用创建 PodDisruptionBudget。
第 20 章 常见故障排查实战
20.1 Pod Pending 排查
常见原因:
- 资源不足
- 节点亲和性/污点
- PVC 未绑定
- 镜像拉取策略
排查步骤:
bash
# 查看 Pod 事件
kubectl describe pod <POD_NAME>
# 查看节点资源
kubectl describe node <NODE_NAME>
# 查看未调度的 Pod
kubectl get pods -A | grep Pending20.2 CrashLoopBackOff 排查
常见原因:
- 应用启动失败
- 配置错误
- 依赖服务不可用
- 资源不足
排查步骤:
bash
# 查看日志
kubectl logs <POD_NAME> --previous
# 查看事件
kubectl describe pod <POD_NAME>
# 进入容器手动调试
kubectl run debug --image=busybox:1.36 -it --rm -- /bin/sh20.3 ImagePullBackOff 排查
常见原因:
- 镜像不存在
- 镜像仓库认证失败
- 网络不通
- 镜像标签错误
bash
# 查看事件
kubectl describe pod <POD_NAME>
# 手动拉取镜像测试
docker pull <IMAGE>
# 检查 imagePullSecrets
kubectl get pod <POD_NAME> -o yaml | grep imagePullSecrets -A 520.4 OOMKilled 排查
bash
# 查看 Pod 状态
kubectl get pod <POD_NAME> -o yaml | grep -A 5 lastState
# 查看容器退出码 137 = 128 + 9 (SIGKILL)
# 通常是 OOM
# 增加内存限制
kubectl set resources deployment <NAME> --limits=memory=512Mi20.5 节点 NotReady 排查
bash
# 查看节点状态
kubectl describe node <NODE_NAME>
# 登录节点检查 kubelet
sudo systemctl status kubelet
sudo journalctl -u kubelet -f
# 检查容器运行时
sudo systemctl status containerd
crictl ps
# 检查磁盘、内存、PID
df -h
free -h20.6 Service 不通排查
bash
# 查看 Service 端点
kubectl get endpoints <SERVICE_NAME>
# 查看 Service 定义
kubectl get svc <SERVICE_NAME> -o yaml
# 测试 Service DNS
kubectl run -it --rm debug --image=busybox:1.36 -- nslookup <SERVICE_NAME>
# 测试连通性
kubectl run -it --rm debug --image=busybox:1.36 -- wget -O- http://<SERVICE_NAME>20.7 CoreDNS 异常排查
bash
# 查看 CoreDNS Pod
kubectl get pods -n kube-system -l k8s-app=kube-dns
# 查看 CoreDNS 日志
kubectl logs -n kube-system -l k8s-app=kube-dns
# 测试 DNS
kubectl run -it --rm debug --image=busybox:1.36 -- nslookup kubernetes.default常见 CoreDNS 问题:
- 上游 DNS 不可达
- CoreDNS 配置错误
- 节点防火墙拦截 UDP 53
20.8 镜像拉取失败排查
bash
# 检查镜像名称和标签
kubectl get pod <POD_NAME> -o jsonpath='{.spec.containers[0].image}'
# 在节点上手动拉取
docker pull <IMAGE>
# 检查私有仓库凭据
kubectl get secret <SECRET_NAME> -o yaml20.9 故障排查速查表
| 问题 | 排查命令 |
|---|---|
| Pod Pending | kubectl describe pod |
| CrashLoopBackOff | kubectl logs --previous |
| ImagePullBackOff | kubectl describe pod |
| OOMKilled | kubectl describe pod |
| 节点 NotReady | kubectl describe node, journalctl -u kubelet |
| Service 不通 | kubectl get endpoints, nslookup |
| CoreDNS 异常 | kubectl logs -n kube-system -l k8s-app=kube-dns |
| 证书过期 | kubeadm certs check-expiration |
20.10 本章实战案例
案例 20-1:Pod 一直处于 Pending
bash
# 1. 查看 Pod 事件
kubectl describe pod pending-pod
# 可能看到:
# 0/3 nodes are available: 3 Insufficient cpu.
# 2. 查看节点资源
kubectl describe node node-1
# 3. 解决方案:
# - 扩容节点
# - 减少请求资源
# - 清理低优先级 Pod案例 20-2:Deployment 滚动更新失败
bash
# 1. 查看 ReplicaSet
kubectl get rs -l app=nginx
# 2. 查看新 Pod 状态
kubectl get pods -l app=nginx
# 3. 查看日志
kubectl logs <NEW_POD> --previous
# 4. 如果新版本有问题,回滚
kubectl rollout undo deployment/nginx20.11 本章练习
- 手动制造一个 Pod Pending 场景并排查。
- 故意配置错误的镜像名,观察 ImagePullBackOff 并修复。
- 限制 Pod 内存并触发 OOMKilled。
- 模拟节点 NotReady,登录节点排查 kubelet。
- 创建一个 Service,故意让 selector 不匹配,排查端点为空的问题。
第五部分总结
完成本阶段学习后,你应该能够:
- 使用 kubeadm 部署 K8s 集群
- 执行集群升级
- 进行日常巡检和资源治理
- 使用 HPA/VPA/Cluster Autoscaler 实现弹性伸缩
- 排查 Pod Pending、CrashLoopBackOff、ImagePullBackOff、OOMKilled、节点 NotReady、Service 不通、CoreDNS 异常等常见问题
进入下一阶段:可观测性体系。