Pod 详解:从生命周期到高级调度全解析
Pod 详解
一、Pod 生命周期:状态与阶段全解析
1.1 核心生命周期阶段
Pod 从创建到终止的完整流程涵盖多个关键阶段:
- 创建阶段:用户提交请求 → API Server 验证存储 → Scheduler 调度节点 → Kubelet 启动容器;
- 初始化阶段:运行初始化容器(Init Containers),为主容器准备依赖环境;
- 运行阶段:主容器启动,执行生命周期钩子(PostStart/PreStop)与健康探测(Liveness/Readiness Probe);
- 终止阶段:标记为 Terminating,执行 PreStop 钩子,优雅关闭或强制终止容器。
二、初始化容器(Init Containers):主容器的前置关卡
初始化容器是主容器启动前的"前置任务执行者",需按顺序执行且全部成功后,主容器才会启动。
2.1 核心特性
- 必须按定义顺序执行,前一个失败则重启,直至成功;
- 可为主容器预处理依赖(如等待数据库、生成配置文件)。
2.2 配置示例:等待 MySQL 和 Redis 就绪
# pod-initcontainer.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-initcontainer
namespace: dev
spec:
# 主容器:Nginx 服务
containers:
- name: main-container
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
# 初始化容器:按顺序执行
initContainers:
# 第一个初始化容器:等待 MySQL 服务可达
- name: test-mysql
image: busybox:1.30
command: ['sh', '-c', 'until ping 192.168.100.110 -c 1; do echo waiting for mysql...; sleep 2; done;']
# 第二个初始化容器:等待 Redis 服务可达
- name: test-redis
image: busybox:1.30
command: ['sh', '-c', 'until ping 192.168.100.120 -c 1; do echo waiting for redis...; sleep 2; done;']
执行效果:
# 查看 Pod 状态(初始化阶段会显示 Init:0/2,完成后变为 Running)
kubectl get pod pod-initcontainer -n dev
三、生命周期钩子(Lifecycle Hooks):事件驱动的自定义逻辑
钩子函数允许在容器生命周期的关键节点执行自定义命令,支持 postStart(启动后)和 preStop(终止前)。
3.1 钩子类型与实现方式
| 钩子类型 | 触发时机 | 支持方式 |
|---|---|---|
postStart |
容器创建后立即执行 | Exec 命令、TCPSocket、HTTPGet |
preStop |
容器终止前同步执行 | 同上 |
3.2 配置示例:修改 Nginx 首页与优雅关闭
# pod-hook-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-hook-exec
namespace: dev
spec:
containers:
- name: main-container
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
lifecycle:
# 启动后钩子:修改 Nginx 首页内容
postStart:
exec:
command: ["/bin/sh", "-c", "echo luoqi > /usr/share/nginx/html/index.html"]
# 终止前钩子:优雅关闭 Nginx
preStop:
exec:
command: ["/usr/sbin/nginx", "-s", "quit"]
验证效果:
# 访问 Pod IP,确认首页内容
kubectl get pod pod-hook-exec -n dev -o wide # 获取 Pod IP
curl <Pod IP> # 输出:luoqi
四、容器探测:保障服务可用性的健康检查
容器探测通过探针(Probe)检测应用状态,支持 存活性探针(Liveness) 和 就绪性探针(Readiness)。
4.1 探针类型与作用
- 存活性探针:检测容器是否正常运行,失败则重启容器;
- 就绪性探针:检测容器是否可接收请求,失败则从 Service 移除。
4.2 三种探测方式配置示例
1. Exec 命令探测(检查文件是否存在)
# pod-liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-exec
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
livenessProbe:
exec:
command: ["/bin/cat", "/tmp/hello.txt"] # 检查文件是否存在
initialDelaySeconds: 5 # 启动后 5 秒首次探测
periodSeconds: 10 # 每 10 秒探测一次
效果:若 /tmp/hello.txt 不存在,容器会反复重启(RESTARTS 递增)。
2. TCPSocket 探测(检查端口是否可连接)
# pod-liveness-tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-tcpsocket
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
livenessProbe:
tcpSocket:
port: 8080 # 探测 8080 端口(Nginx 默认不监听,会失败)
initialDelaySeconds: 3
periodSeconds: 5
效果:8080 端口不可达,容器会反复重启。
3. HTTPGet 探测(检查 HTTP 接口状态)
# pod-liveness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-httpget
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
livenessProbe:
httpGet:
path: /test1 # 检查 /test1 路径
port: 80 # 端口
scheme: HTTP # 协议
initialDelaySeconds: 3
periodSeconds: 5
效果:若 /test1 页面不存在(404),容器会反复重启。
五、重启策略:容器故障的自愈规则
重启策略定义容器故障时的处理逻辑,适用于 Pod 内所有容器。
5.1 三种策略对比
| 策略 | 触发条件 | 示例场景 |
|---|---|---|
Always |
容器终止(无论成功/失败) | 长期运行的 Web 服务 |
OnFailure |
容器异常终止(退出码非 0) | 批处理任务(失败后重试) |
Never |
永不重启 | 一次性任务(如日志收集) |
5.2 配置示例:禁止重启(Never)
# pod-restartpolicy.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-restartpolicy
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
livenessProbe:
httpGet:
path: /test1 # 不存在的路径,探测会失败
port: 80
restartPolicy: Never # 禁止重启
效果:容器探测失败后状态变为 Failed,RESTARTS 始终为 0。
六、Pod 调度:控制 Pod 运行节点
Kubernetes 提供多种调度方式,从强制绑定到灵活亲和性,满足不同场景需求。
6.1 定向调度:强制绑定节点
1. NodeName(直接指定节点名称)
# pod-nodename.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-nodename
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
nodeName: node3 # 强制调度到 node3(若 node3 不存在,Pod 会失败)
2. NodeSelector(通过标签匹配节点)
# pod-nodeselector.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeselector
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
nodeSelector:
env: dev # 调度到标签为 env=dev 的节点
前提:需先为节点添加标签:
kubectl label nodes node1 env=dev # 为 node1 添加 env=dev 标签
6.2 亲和性调度:灵活选择节点
1. NodeAffinity(节点亲和性)
# pod-nodeaffinity-required.yaml(硬限制)
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity-required
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity:
nodeAffinity:
# 硬限制:必须满足条件
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: app
operator: In
values: ["1", "2", "3"] # 节点标签 app 必须为 1/2/3
2. PodAffinity(Pod 亲和性)
# 参照 Pod(已运行在 node1)
# pod-podaffinity-target.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-podaffinity-target
namespace: dev
labels:
podenv: pro
spec:
containers:
- name: nginx
image: nginx:1.17.1
nodeName: node1
---
# 新 Pod:与参照 Pod 同节点
# pod-podaffinity-required.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-podaffinity-required
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: podenv
operator: In
values: ["pro"] # 与标签 podenv=pro 的 Pod 同节点
topologyKey: kubernetes.io/hostname # 按节点划分拓扑域
6.3 污点与容忍:节点的"黑白名单"
1. 为节点添加污点(拒绝 Pod 调度)
# 为 node1 添加污点:key=disk, value=ssd, effect=NoSchedule(禁止无容忍的 Pod 调度)
kubectl taint nodes node1 disk=ssd:NoSchedule
# 移除污点
kubectl taint nodes node1 disk:NoSchedule-
2. Pod 配置容忍(忽略节点污点)
# pod-toleration.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-toleration
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
tolerations:
- key: "disk" # 匹配污点的 key
operator: "Equal" # 匹配方式(Equal/Exists)
value: "ssd" # 匹配污点的 value
effect: "NoSchedule" # 匹配污点的 effect
七、总结
Pod 是 Kubernetes 最小部署单元,其生命周期管理(初始化容器、钩子函数、健康探测)和调度策略(定向调度、亲和性、污点容忍)是保障服务稳定性的核心。通过合理配置,可实现服务的自愈、依赖管理和资源优化,为生产环境的微服务部署提供坚实基础。