Pod 生命周期与管理
Pod 创建、状态管理、Init 容器、Sidecar、Static Pod、删除与终止
概述
Pod 是 Kubernetes 中最小的可部署单元,包含一个或多个容器。理解 Pod 生命周期是 CKA 考试的基础。
一、创建 Pod
1.1 命令式创建
kubectl run nginx --image=nginx --restart=Never
# 带标签
kubectl run nginx --image=nginx --labels="app=web,env=prod"
# 暴露端口
kubectl run nginx --image=nginx --port=80
# 指定命令和参数
kubectl run busybox --image=busybox --restart=Never -- sleep 3600
# 生成 YAML 但不创建(--dry-run=client -o yaml)
kubectl run nginx --image=nginx --restart=Never --dry-run=client -o yaml > pod.yaml
1.2 声明式创建(YAML)
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: web
env: prod
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
kubectl apply -f pod.yaml
二、Pod 阶段与状态
| 阶段 | 说明 |
|---|---|
Pending | 已被集群接受,但容器尚未运行(拉取镜像、调度等待) |
Running | 至少一个容器正在运行 |
Succeeded | 所有容器成功退出(Job 类 Pod) |
Failed | 所有容器退出且至少一个退出码非 0 |
Unknown | 无法获取 Pod 状态(通常节点失联) |
# 查看 Pod 状态
kubectl get pods
kubectl get pods -o wide
kubectl describe pod <pod-name>
# 查看 Pod 详细信息(含事件)
kubectl describe pod <pod-name>
# 查看容器重启原因
kubectl logs <pod-name>
kubectl logs <pod-name> -c <container-name>
kubectl logs --previous <pod-name> # 查看上一次容器日志
容器状态
- Waiting:拉取镜像或等待启动
- Running:正常运行
- Terminated:容器已退出(含退出码)
# 监控 Pod 状态变化
kubectl get pods -w
三、Init 容器
Init 容器在应用容器之前运行,必须成功完成后应用容器才会启动。
配置示例
apiVersion: v1
kind: Pod
metadata:
name: init-pod
spec:
initContainers:
- name: init-db-wait
image: busybox:1.28
command: ['sh', '-c', 'until nc -z db-service 3306; do echo waiting for db; sleep 2; done']
- name: init-migrate
image: busybox:1.28
command: ['sh', '-c', 'echo running migration && sleep 5']
containers:
- name: app
image: nginx
使用场景
- 等待依赖服务就绪(Database、API)
- 数据库 Schema 迁移
- 初始化数据卷权限
- 生成配置文件
注意事项
- Init 容器不支持
readinessProbe - 每个 Init 容器必须依次成功完成
- Init 容器失败默认重启策略为
Always(Pod 重启策略控制) - Init 容器资源 request/limit 取所有 Init 容器最大值参与调度
# 查看 Init 容器状态
kubectl get pod init-pod
kubectl describe pod init-pod | grep -A 10 Init
kubectl logs init-pod -c init-db-wait
四、Sidecar 容器模式(Kubernetes 1.29+)
Sidecar 是 Init 容器的增强,在 Pod 生命周期内持续运行,但启动顺序优先于应用容器。
apiVersion: v1
kind: Pod
metadata:
name: sidecar-pod
spec:
initContainers:
- name: log-collector
image: fluentd
restartPolicy: Always # Sidecar 标志
containers:
- name: app
image: nginx
特征:
- 设置
restartPolicy: Always的 Init 容器即为 Sidecar - 在应用容器之前启动
- 与应用容器同时运行
- 不会阻止 Pod 进入 Ready 状态
- 适用:日志收集、代理、服务网格
五、Static Pods
由 kubelet 直接管理,在指定目录下创建 YAML 文件即可自动启动。
配置
# 查看 Static Pod 路径
ps aux | grep kubelet | grep -- --pod-manifest-path
# 或者查看 kubelet 配置
cat /var/lib/kubelet/config.yaml | grep staticPodPath
# 默认路径
ls /etc/kubernetes/manifests/
创建 Static Pod
# 创建 YAML 文件到 manifests 目录
cat <<EOF > /etc/kubernetes/manifests/static-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-nginx
spec:
containers:
- name: nginx
image: nginx
EOF
# 查看 Static Pod(名称后缀会带有节点名)
kubectl get pods -n kube-system | grep static-nginx
kubectl get pods -A | grep <node-name>
特征
- 由 kubelet 管理,不通过 API Server 创建
- 删除 YAML 文件即可停止
- kubelet 会自动在 API Server 中创建镜像 Pod(只读)
- 不能通过 Deployment/ReplicaSet 管理
- 常用于 Control Plane 组件(etcd、apiserver、scheduler、controller-manager)
考试技巧
# 查找 Static Pod 路径
kubectl get pod kube-apiserver-controlplane -n kube-system -o yaml | grep pod-manifest-path
# 查找正在运行 control plane 静态 Pod 的节点
kubectl get nodes
六、Pod 删除与终止
正常终止(Graceful Termination)
kubectl delete pod <pod-name>
流程:
- Pod 进入
Terminating状态 - 执行
preStop回调(如果配置) - 发送 SIGTERM 到主进程(PID 1)
- 等待
terminationGracePeriodSeconds(默认 30s) - 超时后发送 SIGKILL
# 自定义优雅终止
spec:
terminationGracePeriodSeconds: 60
containers:
- name: app
image: nginx
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10 && nginx -s quit"]
强制删除(Force Delete)
# 强制立即删除(跳过优雅终止)
kubectl delete pod <pod-name> --grace-period=0 --force
# 删除所有 Evicted/Terminating Pod
kubectl delete pod --all
kubectl delete pods --field-selector=status.phase=Failed
删除所有 Pod
kubectl delete pods --all -n <namespace>
kubectl delete pods --all --all-namespaces # 慎重
七、实用命令总结
# 查询资源定义
kubectl explain pod
kubectl explain pod.spec
kubectl explain pod.spec.containers
kubectl explain pod.spec.containers.resources
# 生成 Pod YAML
kubectl run test --image=nginx --restart=Never --dry-run=client -o yaml
kubectl run test --image=busybox --restart=Never --dry-run=client -o yaml -- sleep 3600
# Pod 交互
kubectl exec -it <pod-name> -- /bin/sh
kubectl exec <pod-name> -- env
kubectl logs -f <pod-name>
# 临时 Pod(用于调试)
kubectl run debug --image=nicolaka/netshoot --restart=Never --rm -it -- /bin/bash
kubectl run busybox --image=busybox --restart=Never --rm -it -- wget -O- <service-ip>
🧪 完整操作实例:创建带 Init 容器的 Pod 并观察生命周期
场景描述
创建一个包含 init 容器和主容器的 Pod,观察各阶段状态变化。
前置条件
- 可用的 Kubernetes 集群(kubeadm/minikube)
- kubectl 已配置连接集群
操作步骤
Step 1: 创建 Init 容器 Pod YAML
cat <<'EOF' > init-pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: init-pod-demo
spec:
initContainers:
- name: init-wait
image: busybox:1.28
command: ['sh', '-c', 'echo "Init: Step 1 - Waiting for 10s..."; sleep 10; echo "Init: Step 1 done"']
- name: init-check
image: busybox:1.28
command: ['sh', '-c', 'echo "Init: Step 2 - Checking config..."; sleep 5; echo "Init: Step 2 done"']
containers:
- name: main-app
image: nginx
ports:
- containerPort: 80
EOF
# 预期输出:无(文件创建成功)
Step 2: 创建 Pod 并观察初始状态
kubectl apply -f init-pod-demo.yaml
# 预期输出:pod/init-pod-demo created
kubectl get pod init-pod-demo
# 预期输出:NAME READY STATUS RESTARTS AGE
# init-pod-demo 0/1 Init:0/2 0 <seconds>
# STATUS 显示 Init:0/2 表示 2 个 Init 容器尚未完成
Step 3: 观察 Init 容器执行过程
# 实时监控状态变化
kubectl get pod init-pod-demo -w
# 预期输出(顺序变化):
# init-pod-demo 0/1 Init:0/2 0 0s
# init-pod-demo 0/1 Init:1/2 0 10s ← 第一个 init 完成
# init-pod-demo 0/1 Init:1/2 0 10s ← 第二个 init 开始
# init-pod-demo 0/1 PodInitializing 0 15s ← init 全部完成
# init-pod-demo 1/1 Running 0 17s ← 主容器运行
Step 4: 查看 Init 容器日志
# 查看第一个 Init 容器日志
kubectl logs init-pod-demo -c init-wait
# 预期输出:
# Init: Step 1 - Waiting for 10s...
# Init: Step 1 done
# 查看第二个 Init 容器日志
kubectl logs init-pod-demo -c init-check
# 预期输出:
# Init: Step 2 - Checking config...
# Init: Step 2 done
Step 5: 验证主容器运行
kubectl get pod init-pod-demo
# 预期输出:NAME READY STATUS RESTARTS AGE
# init-pod-demo 1/1 Running 0 <minutes>
kubectl describe pod init-pod-demo | grep -A 5 Init
# 预期输出显示 Init 容器已完成
验证结果
# 确认主容器 Web 服务正常
kubectl exec init-pod-demo -- curl -s -o /dev/null -w "%{http_code}" localhost
# 预期输出:200
# 清理
kubectl delete pod init-pod-demo
# 预期输出:pod "init-pod-demo" deleted
考试提示
- CKA 考试中 Init 容器的 YAML 格式必须准确:
initContainers在spec下且与containers并列 - 每个 Init 容器必须成功完成后下一个才能启动
- 考试常用
busybox:1.28镜像,体积小启动快 - 使用
kubectl describe pod查看 Init 容器状态和事件是最可靠的排错方式 - 注意 Init 容器不支持
readinessProbe,但支持resources和securityContext