Kubernetes Pod 创建过程深度解析
概述
Pod 是 Kubernetes 中最小的可部署单元,理解 Pod 的创建过程对于深入掌握 Kubernetes 的工作原理至关重要。本文将详细解析从用户提交 Pod 创建请求到 Pod 成功运行的完整流程,帮助您深入理解 Kubernetes 的内部机制。
Pod 创建的核心组件
在深入了解创建过程之前,我们先来认识参与 Pod 创建的核心组件:
- API Server: Kubernetes 的控制中心,负责处理所有的 API 请求
- etcd: 分布式键值存储,保存集群的所有状态数据
- Scheduler: 调度器,负责将 Pod 分配到合适的节点
- kubelet: 运行在每个节点上的代理,负责管理节点上的 Pod
- Container Runtime: 容器运行时(如 containerd),负责实际的容器操作
Pod 创建的详细流程
1. 用户提交创建请求
用户通过 kubectl 命令行工具向 API Server 提交 Pod 创建请求。当然,其他控制器、REST API 或其他客户端也可以提交类似请求。
kubectl apply -f pod.yaml
2. API Server 处理请求
API Server 收到请求后,会进行以下操作:
- 验证请求的合法性(认证、授权)
- 验证 Pod 规格的有效性
- 将 Pod 对象写入 etcd 进行永久性存储
- 如果 etcd 写入成功,API Server 将成功信息返回给客户端
3. Scheduler 进行调度
Scheduler 通过 watch 机制监听到有新的 Pod 在 API Server 创建后:
- 首先检查该 Pod 是否已经被调度(
spec.nodeName是否为空) - 如果 Pod 尚未被调度,Scheduler 会根据预设的调度策略进行优选和打分,最后选出最优节点
- 考虑因素包括:资源需求、节点亲和性、Pod 亲和性/反亲和性、污点和容忍度等
- 将选中的节点主机名更新到
spec.nodeName字段,完成 Pod 的节点绑定
4. 持久化调度结果
Scheduler 将成功绑定的信息写回到 API Server,API Server 再将其写入 etcd 进行永久存储。
5. kubelet 接管 Pod 创建
运行在目标节点上的 kubelet 持续监听 API Server 中 Pod 资源的变化:
- 当发现有 Pod 被分配到自己所在的节点(节点名称和 Pod 的
spec.nodeName相等) - kubelet 开始 Pod 的创建流程
6. 存储卷准备
如果 Pod 定义了需要存储卷(PVC),kubelet 会首先进行存储卷的挂载:
- 通过 CSI 接口挂载存储卷到节点
- 将存储卷绑定到 Pod 的专用目录:
/var/lib/kubelet/pods/<pod-uid>/volumes/
7. 创建 Pod 沙箱
kubelet 创建 Pod 的基础运行环境:
- 检查 pause 镜像是否在本地存在(所有 Pod 都需要这个基础镜像)
- 通过 CRI 接口调用容器运行时创建 PodSandbox(pause 容器)
- pause 容器为 Pod 提供网络和 PID 命名空间
8. 网络配置
当 PodSandbox 创建成功后,kubelet 进行网络配置:
- 通过 CNI 接口调用网络插件为 Pod 配置网络
- 为 Pod 分配 IP 地址
- 配置网络路由和防火墙规则
- 将网络接口添加到 Pod 的网络命名空间
9. 准备容器镜像
网络配置完成后,kubelet 开始为 Pod 中的业务容器做准备:
- 检查容器镜像是否在本地存在
- 如果镜像不存在,通过 CRI 接口拉取镜像
- 从镜像仓库下载容器镜像到本地
10. 创建和启动业务容器
镜像准备就绪后:
- 通过 CRI 接口创建业务容器
- 容器运行时根据 Pod 规格配置容器参数(环境变量、挂载点等)
- 启动容器,容器开始执行其 ENTRYPOINT 和 CMD 指令
11. 状态更新
无论容器创建和启动是否成功:
- kubelet 都会将最新的容器状态更新到 Pod 对象的
Status字段中 - 这使得其他控制器能够监听到 Pod 对象的变化,从而采取相应的措施
Pod 创建流程图
sequenceDiagram
participant User as 用户/kubectl
participant API as API Server
participant etcd as etcd
participant Scheduler as Scheduler
participant kubelet as kubelet
participant CSI as CSI Driver
participant CRI as Container Runtime
participant CNI as CNI Plugin
User->>API: 1. 提交 Pod 创建请求
API->>API: 2. 验证请求合法性
API->>etcd: 3. 写入 Pod 对象
etcd-->>API: 4. 确认写入成功
API-->>User: 5. 返回创建成功响应
Scheduler->>API: 6. 监听新 Pod
Scheduler->>Scheduler: 7. 计算最优节点
Scheduler->>API: 8. 更新 spec.nodeName
API->>etcd: 9. 持久化调度结果
kubelet->>API: 10. 监听分配给本节点的 Pod
Note over kubelet,CSI: 第一步:存储卷准备(如果有PVC)
kubelet->>CSI: 11. 挂载存储卷到节点
Note over kubelet,CRI: 第二步:创建Pod沙箱
kubelet->>kubelet: 12. 检查 pause 镜像
kubelet->>CRI: 13. 创建 PodSandbox
Note over kubelet,CNI: 第三步:网络配置
kubelet->>CNI: 14. 配置Pod网络
Note over kubelet,CRI: 第四步:业务容器创建和启动
kubelet->>kubelet: 15. 检查容器镜像
kubelet->>CRI: 16. 拉取镜像(如需要)
kubelet->>CRI: 17. 创建业务容器
kubelet->>CRI: 18. 启动业务容器
kubelet->>API: 19. 更新 Pod 状态
API->>etcd: 20. 持久化状态更新
关键技术细节
pause 容器的作用
每个 Pod 都会创建一个 pause 容器,它的主要作用是:
- 持有 Pod 的网络命名空间和 PID 命名空间
- 为 Pod 中的其他容器提供共享的网络和存储
- 即使 Pod 中的应用容器重启,网络配置也会保持稳定
网络命名空间
- 每个 Pod 都有独立的网络命名空间
- 网络插件负责为 Pod 分配 IP 地址和配置网络路由
- 同一个 Pod 内的容器共享网络命名空间,可以通过 localhost 互相通信
常见问题和故障排查
Pod 停留在 Pending 状态
可能的原因:
- 没有合适的节点满足调度要求
- 镜像拉取失败
- 存储卷挂载失败
Pod 停留在 ContainerCreating 状态
可能的原因:
- 镜像拉取时间过长
- 网络配置失败
- 存储卷挂载超时
总结
Pod 的创建过程涉及 Kubernetes 集群中的多个核心组件协作。理解这个流程有助于:
- 故障排查: 当 Pod 创建失败时,可以根据流程定位问题环节
- 性能优化: 了解瓶颈所在,针对性地进行优化
- 架构设计: 更好地设计应用的部署策略和资源配置
通过深入理解 Pod 的创建过程,我们可以更好地利用 Kubernetes 的强大功能,构建稳定可靠的容器化应用。
浙公网安备 33010602011771号