Skip to content

第五部分 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 本章练习

  1. 使用 minikube 或 kind 创建一个本地 K8s 集群。
  2. 尝试使用 kubeadm 在两台虚拟机上部署一个单 Master 集群。
  3. 了解 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 health

18.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 本章练习

  1. 列出你所在集群的所有异常 Pod。
  2. 查看节点资源压力条件(Conditions)。
  3. 编写一个巡检脚本并加入定时任务。
  4. 找出未设置资源限制的 Pod。

第 19 章 扩缩容与高可用

19.1 手动扩缩容

bash
# Deployment 扩缩容
kubectl scale deployment nginx --replicas=5

# StatefulSet 扩缩容
kubectl scale statefulset web --replicas=5

19.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: 50
bash
kubectl apply -f hpa.yaml
kubectl get hpa
kubectl describe hpa nginx-hpa

19.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"
EOF

19.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.yaml

19.5 高可用设计

  • 多 Master 部署
  • 多可用区部署
  • 关键应用多副本
  • 使用 PodDisruptionBudget
  • 使用反亲和性避免单点故障
yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: nginx-pdb
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: nginx

19.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 -w

19.7 本章练习

  1. 为一个 Deployment 配置 HPA。
  2. 使用压力测试工具触发 HPA 扩容。
  3. 了解 VPA 和 Cluster Autoscaler 的适用场景。
  4. 为一个关键应用创建 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 Pending

20.2 CrashLoopBackOff 排查

常见原因:

  • 应用启动失败
  • 配置错误
  • 依赖服务不可用
  • 资源不足

排查步骤:

bash
# 查看日志
kubectl logs <POD_NAME> --previous

# 查看事件
kubectl describe pod <POD_NAME>

# 进入容器手动调试
kubectl run debug --image=busybox:1.36 -it --rm -- /bin/sh

20.3 ImagePullBackOff 排查

常见原因:

  • 镜像不存在
  • 镜像仓库认证失败
  • 网络不通
  • 镜像标签错误
bash
# 查看事件
kubectl describe pod <POD_NAME>

# 手动拉取镜像测试
docker pull <IMAGE>

# 检查 imagePullSecrets
kubectl get pod <POD_NAME> -o yaml | grep imagePullSecrets -A 5

20.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=512Mi

20.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 -h

20.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 yaml

20.9 故障排查速查表

问题排查命令
Pod Pendingkubectl describe pod
CrashLoopBackOffkubectl logs --previous
ImagePullBackOffkubectl describe pod
OOMKilledkubectl describe pod
节点 NotReadykubectl 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/nginx

20.11 本章练习

  1. 手动制造一个 Pod Pending 场景并排查。
  2. 故意配置错误的镜像名,观察 ImagePullBackOff 并修复。
  3. 限制 Pod 内存并触发 OOMKilled。
  4. 模拟节点 NotReady,登录节点排查 kubelet。
  5. 创建一个 Service,故意让 selector 不匹配,排查端点为空的问题。

第五部分总结

完成本阶段学习后,你应该能够:

  • 使用 kubeadm 部署 K8s 集群
  • 执行集群升级
  • 进行日常巡检和资源治理
  • 使用 HPA/VPA/Cluster Autoscaler 实现弹性伸缩
  • 排查 Pod Pending、CrashLoopBackOff、ImagePullBackOff、OOMKilled、节点 NotReady、Service 不通、CoreDNS 异常等常见问题

进入下一阶段:可观测性体系