在 Kubernetes 中,Pod 的创建是一个多组件协作的过程,涉及 API Server、调度器(Scheduler)、控制器管理器(Controller Manager)、kubelet 等核心组件。以下是 Pod 创建的详细流程:
1. 提交 Pod 创建请求
用户通过 kubectl
命令、API 调用(如 curl
调用 Kubernetes API)或通过控制器(如 Deployment、StatefulSet)提交 Pod 配置(通常是 YAML/JSON 格式)。
示例:kubectl create -f pod.yaml
请求首先发送到 API Server(kube-apiserver),API Server 是所有操作的统一入口,负责验证请求的合法性(如权限、配置格式)。
2. API Server 处理请求
- API Server 验证 Pod 配置的合法性(如必填字段是否存在、资源限制是否合理、用户是否有权限创建等)。
- 验证通过后,API Server 将 Pod 信息存储到 etcd(Kubernetes 的分布式数据库),此时 Pod 的状态为
Pending
(等待调度)。 - API Server 会通过 watch 机制通知其他组件(如调度器、kubelet)有新的 Pod 待处理。
3. 调度器(Scheduler)选择节点
- 调度器通过 Informer 监听 API Server,发现状态为
Pending
且未指定节点(nodeName
为空)的 Pod。 - 调度器执行调度算法,为 Pod 选择最合适的节点:
- 过滤(Filter):排除不满足 Pod 要求的节点(如资源不足、节点亲和性不匹配、污点与容忍度冲突等)。
- 打分(Score):对过滤后的节点进行评分(如资源剩余量、负载情况、距离其他服务的网络延迟等),选择分数最高的节点。
- 调度器通过 API Server 将选中的节点信息(
nodeName
字段)更新到 etcd 中的 Pod 配置。
4. kubelet 启动 Pod
- 目标节点上的 kubelet 进程通过 Informer 监听 API Server,发现分配给自己的 Pod(
nodeName
匹配自身节点名)。 - kubelet 执行以下操作启动 Pod:
- 创建 Pod 目录:在节点的
/var/lib/kubelet/pods/<PodUID>/
下创建目录,存储 Pod 相关文件(如配置、日志等)。 - 拉取镜像:根据 Pod 配置中的
image
字段,通过容器运行时(如 containerd、CRI-O)拉取所需镜像。 - 创建网络资源:调用网络插件(如 Calico、Flannel)为 Pod 创建网络命名空间、虚拟网卡(veth),并分配 IP 地址,确保 Pod 网络互通。
- 挂载存储:若 Pod 配置了 Volume(如 PersistentVolume、ConfigMap),kubelet 会挂载相应的存储卷到 Pod 中。
- 启动容器:通过容器运行时启动 Pod 中的初始化容器(Init Container)和应用容器(按顺序启动),并设置容器的资源限制、环境变量等。
- 创建 Pod 目录:在节点的
5. 更新 Pod 状态
- 容器启动后,kubelet 会定期检查容器状态(如运行状态、健康检查结果),并通过 API Server 更新 Pod 在 etcd 中的状态:
- 若所有容器正常运行,Pod 状态变为
Running
。 - 若启动失败(如镜像拉取失败、健康检查不通过),状态可能为
Error
或CrashLoopBackOff
。
- 若所有容器正常运行,Pod 状态变为
- 其他组件(如 kube-proxy)会根据 Pod 状态更新网络规则(如 Service 对应的负载均衡规则)。
总结:核心组件协作流程
用户请求 → API Server(验证+存etcd) → 调度器(选节点) → kubelet(启动容器) → 更新状态
整个过程中,API Server 作为“通信中枢”,etcd 作为“数据存储中心”,调度器负责“决策”,kubelet 负责“执行”,各组件通过 watch 机制实时同步状态,确保 Pod 按预期创建和运行。