Day 07 - Pod 资源综合实战

📘 Day 07:Pod 资源综合实战

🎯 今日目标

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

🧠 理论精讲(10 分钟)

工作负载选型决策树

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

🔧 动手实操(150 分钟)

练习 7.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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# 创建独立命名空间
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
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
# 故障 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 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 分钟

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

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
37
38
39
40
41
42
【场景】
为一个电商系统部署基础设施,包含缓存层、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 分)

🧹 环境清理

1
2
3
# 练习结束后清理
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-labels Pod + 标签 验证标签是否与 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 官方:Service https://kubernetes.io/docs/concepts/services-networking/service/
Kubernetes 官方:应用排错 https://kubernetes.io/docs/tasks/debug/debug-application/