📘 Day 07:Pod 资源综合实战

🎯 今日目标

  • 在一个命名空间内从零搭建多类型工作负载
  • 通过故障注入验证 K8s 自愈能力
  • 完成完整的版本发布与回滚流程
  • 能根据业务需求选择正确的工作负载类型

🧠 理论精讲(10 分钟)

工作负载选型决策树

需要运行容器?
├── 需要每节点一个?──→ DaemonSet
├── 需要稳定网络标识 + 持久存储?──→ StatefulSet
├── 一次性任务?──→ Job
├── 定时任务?──→ CronJob
├── 无状态、需要滚动更新?──→ Deployment
└── 单个 Pod,不需要自愈?──→ Pod(restartPolicy: Never)

🔧 动手实操(150 分钟)

练习 7.1:从零构建微服务应用

# 创建独立命名空间
kubectl create ns microshop

# === 1. 数据库层(StatefulSet) ===
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: db-svc
  namespace: microshop
spec:
  clusterIP: None
  selector:
    app: shop-db
  ports:
  - port: 6379
    targetPort: 6379
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: shop-db
  namespace: microshop
spec:
  serviceName: db-svc
  replicas: 1
  selector:
    matchLabels:
      app: shop-db
  template:
    metadata:
      labels:
        app: shop-db
    spec:
      containers:
      - name: redis
        image: redis:7-alpine
        ports:
        - containerPort: 6379
        volumeMounts:
        - name: db-data
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: db-data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 100Mi
EOF

# === 2. 后端服务(Deployment) ===
cat <<'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  namespace: microshop
spec:
  replicas: 2
  selector:
    matchLabels:
      app: shop-backend
  template:
    metadata:
      labels:
        app: shop-backend
    spec:
      containers:
      - name: api
        image: nginx:alpine
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 3
          periodSeconds: 3
        resources:
          requests:
            cpu: 50m
            memory: 64Mi
          limits:
            cpu: 200m
            memory: 128Mi
EOF

kubectl expose deploy backend -n microshop --name=backend-svc --port=80

# === 3. 前端服务(Deployment) ===
kubectl create deploy frontend -n microshop --image=nginx:alpine --replicas=3
kubectl expose deploy frontend -n microshop --name=frontend-svc --port=80

# === 4. 日志采集(DaemonSet) ===
cat <<'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: log-agent
  namespace: microshop
spec:
  selector:
    matchLabels:
      app: log-agent
  template:
    metadata:
      labels:
        app: log-agent
    spec:
      containers:
      - name: logger
        image: busybox:1.36
        command:
        - sh
        - -c
        - |
          while true; do
            echo "[$(date)] Node: $(hostname) - collecting logs"
            sleep 10
          done
EOF

# === 5. 定时清理(CronJob) ===
cat <<'EOF' | kubectl apply -f -
apiVersion: batch/v1
kind: CronJob
metadata:
  name: log-cleanup
  namespace: microshop
spec:
  schedule: "0 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: cleanup
            image: busybox:1.36
            command:
            - sh
            - -c
            - echo "Cleaning old logs at $(date)"
          restartPolicy: Never
EOF

# 6. 验证全部资源
kubectl get all -n microshop
# 预期:
# - Pod: frontend×3, backend×2, shop-db-0×1, log-agent×3
# - Service: db-svc, backend-svc, frontend-svc
# - DaemonSet: log-agent
# - StatefulSet: shop-db
# - CronJob: log-cleanup

练习 7.2:故障演练

# 故障 1:删除 Pod(验证自愈)
kubectl get pod -n microshop -l app=shop-backend
POD_NAME=$(kubectl get pod -n microshop -l app=shop-backend -o name | head -1)
kubectl delete $POD_NAME -n microshop
kubectl get pod -n microshop -l app=shop-backend -w
# 观察:旧 Pod Terminating,新 Pod 自动创建并 Running

# 故障 2:杀掉容器进程(验证 livenessProbe)
BACKEND_POD=$(kubectl get pod -n microshop -l app=shop-backend -o name | head -1)
kubectl exec $BACKEND_POD -n microshop -- nginx -s stop
# 预期:livenessProbe 失败 → 容器重启
kubectl get $BACKEND_POD -n microshop -w
# RESTARTS 列递增

# 故障 3:缩容 frontend(验证可用性)
kubectl scale deploy/frontend -n microshop --replicas=1
kubectl get pod -n microshop -l app=shop-frontend
# 只保留 1 个

# 故障 4:模拟节点不可用(cordon)
kubectl cordon k8s-node1
# 注意:已有 Pod 不受影响,新 Pod 不调度到 node1

# 恢复
kubectl uncordon k8s-node1
kubectl scale deploy/frontend -n microshop --replicas=3

练习 7.3:版本演练

# 1. 记录当前版本
kubectl get deploy -n microshop backend -o jsonpath='{.spec.template.spec.containers[0].image}'
# nginx:alpine

# 2. 更新 backend
kubectl set image deploy/backend -n microshop api=nginx:alpine-slim
kubectl annotate deploy/backend -n microshop kubernetes.io/change-cause="switch to slim image"
kubectl rollout status deploy/backend -n microshop

# 3. 查看历史
kubectl rollout history deploy/backend -n microshop

# 4. 制造一个失败更新
kubectl set image deploy/backend -n microshop api=nginx:9.9.9-invalid
kubectl annotate deploy/backend -n microshop kubernetes.io/change-cause="invalid update"

# 5. 发现失败,立即回滚
kubectl rollout undo deploy/backend -n microshop
kubectl rollout status deploy/backend -n microshop

# 6. 最终验证
kubectl get deploy -n microshop backend
kubectl rollout history deploy/backend -n microshop

🏆 赛题模拟(40 分钟)

⚠️ 严格限时 40 分钟

题目:微服务应用全流程部署

【场景】
为一个电商系统部署基础设施,包含缓存层、API 层、Web 层和监控组件。

【环境要求】
- 新建命名空间:ecommerce

【操作要求】
1. 缓存层:StatefulSet redis-cache(2 副本)
   - 镜像 redis:7-alpine
   - Headless Service redis-cache-svc
   - 每个 Pod 独立 PVC(50Mi)

2. API 层:Deployment api-server(3 副本)
   - 镜像 nginx:alpine
   - 配置 livenessProbe + readinessProbe
   - 资源限制:cpu 100m, memory 128Mi
   - 滚动策略:maxSurge=1, maxUnavailable=0
   - ClusterIP Service api-svc

3. Web 层:Deployment web-front(3 副本)
   - 镜像 httpd:alpine
   - ClusterIP Service web-svc

4. 监控层:DaemonSet node-exporter
   - 镜像 busybox:1.36
   - 每 5 秒输出主机名和时间

5. 备份任务:CronJob data-backup
   - 镜像 busybox:1.36
   - 每 15 分钟执行备份命令

6. 故障测试:
   - 删除一个 api-server Pod → 验证自愈
   - 缩容 redis-cache 到 1 → 观察顺序缩容
   - 模拟 API 版本更新并回滚

【评分标准】
- 所有资源正确创建(40 分)
- Service 正确关联(15 分)
- 探针配置正确(15 分)
- 故障测试通过(20 分)
- 版本回滚成功(10 分)

🧹 环境清理

# 练习结束后清理
kubectl delete ns microshop
kubectl delete ns ecommerce

📋 命令速查

命令功能注解
kubectl apply -f <manifest>.yaml声明式部署资源综合实战中一次性部署多种资源
kubectl get all查看所有资源Pod/Service/Deploy/RS/StatefulSet/DaemonSet/Job 一览
kubectl get pods --show-labelsPod + 标签验证标签是否与 Service Selector 匹配
kubectl get pods -L app,version按指定标签列显示 Pod-L 将标签值作为独立列展示
kubectl describe svc <name>Service 详情查看 Endpoints 是否绑定到正确的 Pod
kubectl get endpoints <svc>查看 Service 后端 Endpoints为空说明 Selector 不匹配或 Pod 未就绪
kubectl run tmp --image=busybox --rm -it -- wget -O- http://<svc>:<port>临时 Pod 测试服务连通性--rm 退出即删,测试网络首选
kubectl exec <pod> -- env查看容器环境变量验证 ConfigMap/Secret 注入是否正确
kubectl exec <pod> -- cat /etc/config/key查看挂载的配置文件验证 ConfigMap/Secret 挂载内容
kubectl exec <pod> -- nslookup <svc-name>验证 DNS 解析确认 CoreDNS 正常工作
kubectl -n <ns> logs -l app=<name> --tail=20按标签批量查看日志-l 按标签选择器筛选 Pod
kubectl top pods --sort-by=cpu按 CPU 排序 Pod 用量找出资源消耗最大的 Pod
kubectl get events --sort-by=.metadata.creationTimestamp按时间排序事件按时间线排查问题

📚 参考来源

来源链接 / 说明
Kubernetes 官方:工作负载https://kubernetes.io/docs/concepts/workloads/
Kubernetes 官方:标签与选择器https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
Kubernetes 官方:Servicehttps://kubernetes.io/docs/concepts/services-networking/service/
Kubernetes 官方:应用排错https://kubernetes.io/docs/tasks/debug/debug-application/