一、一句大白话描述概念
Pod 是 Kubernetes 中最小的部署单元,就像一个豌豆荚🫛,里面住着关系密切的几个”豌豆”(容器),它们共享网络和存储资源。
二、图示
1 | ┌─────────────────────────────────────┐ |
三、知识点
1. 为什么需要 Pod
Kubernetes 不直接部署容器,而是把一个或多个关系紧密的容器包装成 Pod。原因:
- 协同调度:同 Pod 内的容器保证调度到同一节点,可以本地通信
- 资源共享:共享网络命名空间(IP、端口)和存储卷
- 原子管理:Pod 作为整体创建、销毁,容器间生命周期绑定
2. Pod 中容器的共享资源
| 资源 | 共享方式 |
|---|---|
| 网络 | 同一 IP 地址和端口空间,容器间通过 localhost 通信 |
| 存储 | 共享 Volume 挂载,可直接读写同一目录 |
| IPC | 共享进程间通信 |
| UTC | 共享主机名 |
注意:容器间不共享 PID 命名空间(默认隔离),文件系统也是各自独立的。
3. Pod 生命周期
1 | ┌──────────┐ |
| 状态 | 说明 |
|---|---|
Pending |
已创建,等待调度或拉取镜像 |
Running |
至少一个容器运行中 |
Succeeded |
所有容器正常退出,不会再重启 |
Failed |
至少一个容器异常退出 |
CrashLoopBackOff |
容器反复崩溃,kubelet 退避重启 |
4. Sidecar 模式
多容器 Pod 最常见的设计模式:主容器 + 辅助容器(Sidecar)。Sidecar 与主容器共享网络和存储,负责日志收集、监控代理等辅助工作,主容器专注业务逻辑。
5. Pod vs Deployment
实际生产中很少直接创建 Pod,而是用 Deployment 管理:
- Pod:一次性,挂了不会自动重建
- Deployment:管理 Pod 副本,自动恢复、滚动更新
6. Init 容器
Init 容器在主容器启动前按顺序运行,全部成功后才会启动主容器。常用于:
- 等待依赖服务就绪(如等数据库可用)
- 初始化配置文件或数据
- 注册服务到发现系统
与普通容器的区别:Init 容器必须成功退出才会继续下一个,失败会根据 Pod 的
restartPolicy决定是否重启。
资源计算:调度 Pod 时,kubelet 取以下两者的较大值作为资源需求:
- 所有 Init 容器的最大资源请求
- 所有普通容器的资源请求之和
1 | spec: |
上例中 init-db 会一直等待直到 db-service 可解析,成功退出后才启动 main-app。
7. 容器探针
探针是 kubelet 对容器定期执行的健康检查:
| 探针类型 | 作用 | 失败后果 |
|---|---|---|
livenessProbe |
容器是否存活 | 重启容器 |
readinessProbe |
容器是否就绪 | 从 Service 端点移除,不接流量 |
startupProbe |
容器是否已启动 | 禁用 liveness/readiness 检查直到成功 |
四种检测方式:exec(执行命令)、httpGet(HTTP 请求)、tcpSocket(TCP 连接)、grpc(gRPC 健康检查,1.24+ 稳定)。
探针配置字段:
| 字段 | 默认值 | 说明 |
|---|---|---|
initialDelaySeconds |
0 | 容器启动后首次探测的等待秒数 |
periodSeconds |
10 | 探测间隔 |
timeoutSeconds |
1 | 单次探测超时时间 |
successThreshold |
1 | 连续成功几次视为通过 |
failureThreshold |
3 | 连续失败几次视为失败 |
8. 资源请求与限制
1 | resources: |
| 字段 | 作用 | 超额后果 |
|---|---|---|
requests |
调度器据此选择节点 | 调度失败(Pending) |
limits.cpu |
CPU 上限 | CPU 节流(throttle),性能下降 |
limits.memory |
内存上限 | OOMKilled,容器被杀 |
生产建议:requests 和 limits 都设置,requests 用于调度,limits 防止嘈杂邻居。但 CPU limits 可能导致延迟敏感型应用性能下降,需权衡。
QoS 等级:Kubernetes 根据 requests/limits 配置自动为 Pod 分配 QoS 等级,决定节点资源不足时的驱逐顺序。
| QoS 等级 | 条件 | 驱逐优先级 |
|---|---|---|
Guaranteed |
每个容器 requests = limits(CPU 和内存都设置) | 最低(最后被驱逐) |
Burstable |
至少一个容器设置了 requests 或 limits,但不满足 Guaranteed | 中 |
BestEffort |
所有容器都未设置 requests 和 limits | 最高(最先被驱逐) |
节点资源紧张时,kubelet 按 BestEffort → Burstable → Guaranteed 顺序驱逐 Pod。生产环境建议设置为 Guaranteed。
9. Pod Condition
Pod 的状态通过 pod.status.conditions 字段以条件列表形式描述,每个条件记录 Pod 在某方面的状态:
| 条件类型 | 说明 |
|---|---|
PodScheduled |
Pod 已被调度到某节点 |
PodReadyToStartContainers |
Pod 沙箱已创建,可以启动容器(1.31+) |
Initialized |
所有 Init 容器已成功完成 |
ContainersReady |
所有普通容器已就绪 |
Ready |
Pod 可接收流量(PodScheduled + Initialized + ContainersReady 均为 True) |
DisruptionTarget |
Pod 即将被驱逐或中断 |
PodResizePending |
资源调整请求已提交但尚未处理 |
PodResizeInProgress |
资源调整正在处理中 |
1 | # 查看 Pod 条件 |
10. 原生 Sidecar 容器
Kubernetes 1.28+ 支持在 initContainers 中声明 restartPolicy: Always 的容器作为原生 Sidecar:
1 | spec: |
与普通 Sidecar 的区别:
| 特性 | 普通 Sidecar(containers 中) | 原生 Sidecar(initContainers + Always) |
|---|---|---|
| 启动顺序 | 与主容器同时启动,无顺序保证 | 先于主容器启动 |
| 停止顺序 | 无保证 | 主容器退出后才停止 |
| 依赖管理 | 需额外探针协调 | 启动顺序由 kubelet 保证 |
原生 Sidecar 解决了”Sidecar 必须先于主容器启动”的痛点,如日志代理需在主容器前就绪才能收集全部日志。
11. 临时容器(Ephemeral Containers)
临时容器是注入到运行中 Pod 的特殊容器,专用于运行时调试:
- 无资源限制:不设 ports、probes、resources
- 不可重启:没有
restartPolicy - 不参与调度:直接复用 Pod 所在节点
1 | # 向运行中的 Pod 注入临时调试容器 |
典型场景:Pod 因缺少调试工具(如 distroless 镜像)而无法
exec进去时,用kubectl debug注入一个带工具的临时容器排查问题。
12. Downward API
Downward API 将 Pod 和容器的元数据暴露给容器内部使用,有两种方式:
环境变量方式:
1 | spec: |
Volume 方式(适合暴露标签和注解):
1 | spec: |
可暴露的字段:
metadata.name、metadata.namespace、metadata.labels、metadata.annotations、limits.cpu、limits.memory、requests.cpu、requests.memory等。
13. 高级 Pod 配置
| 配置项 | 字段 | 作用 |
|---|---|---|
| 优先级 | priorityClassName |
引用 PriorityClass,决定调度和驱逐优先级 |
| 运行时 | runtimeClassName |
引用 RuntimeClass,选择容器运行时(如 gVisor、Kata Containers) |
| 安全上下文 | securityContext |
设置 runAsUser、runAsNonRoot、readOnlyRootFilesystem、capabilities 等 |
| 节点选择 | nodeSelector / affinity |
约束 Pod 调度到特定节点 |
| 容忍 | tolerations |
允许 Pod 调度到带污点的节点 |
| 运行开销 | overhead |
容器运行时额外开销(由 RuntimeClass 自动设置) |
1 | spec: |
生产建议:设置
securityContext最小权限原则,敏感工作负载用runtimeClassName选择沙箱运行时。
四、代码逻辑分析
Pod YAML 示例
1 | apiVersion: v1 |
关键字段解析
| 字段 | 作用 |
|---|---|
spec.containers |
定义 Pod 内的容器列表 |
resources.requests |
调度时的最小资源需求,决定调度到哪个节点 |
resources.limits |
资源上限,超过会被限制或 OOMKill |
volumes.emptyDir |
Pod 级别的临时共享目录,Pod 删除时清空 |
volumeMounts |
容器内挂载路径,多个容器可挂载同一 Volume |
查看 Pod
1 | # 查看所有 Pod |