Qingular

Pod 生命周期与管理

·CKAk8s练习

Pod 创建、状态管理、Init 容器、Sidecar、Static Pod、删除与终止

← 返回 CKA 练习目录

概述

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>

流程:

  1. Pod 进入 Terminating 状态
  2. 执行 preStop 回调(如果配置)
  3. 发送 SIGTERM 到主进程(PID 1)
  4. 等待 terminationGracePeriodSeconds(默认 30s)
  5. 超时后发送 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 格式必须准确:initContainersspec 下且与 containers 并列
  • 每个 Init 容器必须成功完成后下一个才能启动
  • 考试常用 busybox:1.28 镜像,体积小启动快
  • 使用 kubectl describe pod 查看 Init 容器状态和事件是最可靠的排错方式
  • 注意 Init 容器不支持 readinessProbe,但支持 resourcessecurityContext

官方文档链接