2. Kubernetes资源模型基础:Pod、Container、Volume等核心资源对象的定义与抽象
Kubernetes 的资源模型是其声明式管理范式的基石。该模型将集群中的所有能力抽象为资源对象,并通过 API Server 提供统一的增删改查接口。理解 Pod、Container、Volume 等核心对象的定义与抽象层次,是掌握容器运行时控制面集成的第一步。
2.1 资源模型的三层抽象
Kubernetes 资源模型并非扁平结构,而是遵循从基础设施到应用负载再到策略控制的三层抽象体系。下表总结了各层的核心对象及其职责:
| 抽象层 | 核心对象 | 主要职责 | 与CRI的关联 |
|---|---|---|---|
| 基础设施层 | Node、Volume、Namespace | 提供计算、存储、网络与隔离边界 | CRI 负责 Node 上的容器生命周期 |
| 应用负载层 | Pod、Container、Service、Deployment | 定义应用的运行单元、编排与暴露 | Pod 是 CRI 调度的最小单元 |
| 策略控制层 | LimitRange、ResourceQuota、NetworkPolicy | 实施资源约束、安全与网络策略 | 影响 CRI 创建容器的资源参数 |
2.2 Pod:原子调度单元
Pod 是 Kubernetes 中可创建、调度和管理的最小部署单元。一个 Pod 封装一个或多个容器,共享同一网络命名空间、存储卷以及资源约束。Pod 的设计体现了“进程组”的概念——多个容器协同工作,共享生命周期。
Pod 的核心字段定义如下:
- metadata:名称、命名空间、标签、注解等标识信息。
- spec.containers:容器列表,每个容器包含镜像、命令、端口、资源请求与限制。
- spec.volumes:存储卷定义,支持 emptyDir、hostPath、PVC、ConfigMap 等多种类型。
- spec.nodeName:调度结果,由调度器写入,Kubelet 据此执行。
- status:Pod 当前阶段(Pending/Running/Succeeded/Failed/Unknown)与容器状态。
- 共享网络:Pod 内所有容器共享同一个 IP 地址和端口空间,通过 localhost 通信。
- 共享存储:Pod 级别的 Volume 可被所有容器挂载,实现数据交换。
- 原子调度:Pod 要么全部调度到同一节点,要么不调度。
- 临时性:Pod 被视为“可抛弃的”,其 IP 和身份不持久。
2.3 Container:运行时进程封装
Container 是 Pod 内最核心的字段,它定义了单个容器的完整运行时规范。Kubelet 在调用 CRI 创建容器时,会将 Container 结构体中的字段映射为 CreateContainerRequest 参数。
Container 定义的关键字段及其 CRI 映射关系如下:
| Container 字段 | 类型 | CRI 对应参数 | 说明 |
|---|---|---|---|
image |
string | ImageSpec.Image |
容器镜像名称与标签 |
command |
[]string | Command |
覆盖 Dockerfile 的 ENTRYPOINT |
args |
[]string | Args |
覆盖 Dockerfile 的 CMD |
ports |
[]ContainerPort | PortMapping |
容器暴露的端口列表 |
resources.limits |
ResourceList | LinuxContainerResources |
CPU/内存硬限制(Cgroup) |
resources.requests |
ResourceList | LinuxContainerResources |
CPU/内存预留(调度依据) |
volumeMounts |
[]VolumeMount | Mount |
存储卷挂载路径与权限 |
env |
[]EnvVar | KeyValue |
环境变量注入 |
securityContext |
SecurityContext | LinuxContainerSecurityContext |
Capabilities、Seccomp、RunAsUser |
resources.requests 主要用于调度决策,而 resources.limits 才是 CRI 传递给运行时的实际 Cgroup 限制。如果只设置 requests 不设置 limits,容器可能超卖节点资源。
2.4 Volume:存储抽象与生命周期
Volume 是 Kubernetes 中存储资源的抽象层,它解决了容器文件系统临时性的问题。Volume 的生命周期与 Pod 绑定——Pod 存在则 Volume 存在,Pod 删除则 Volume 销毁(持久卷类型除外)。
常见的 Volume 类型及其适用场景:
- emptyDir:Pod 启动时创建的空目录,用于容器间临时数据交换,Pod 删除后数据丢失。
- hostPath:挂载节点文件系统的目录或文件,用于访问宿主机资源(如 Docker Socket)。
- PersistentVolumeClaim (PVC):用户对持久化存储的请求,由集群动态供给或绑定已有 PV。
- ConfigMap / Secret:将配置数据或敏感信息以文件或环境变量形式注入容器。
- CSI (Container Storage Interface):通过标准接口对接外部存储系统,如 AWS EBS、NFS、Ceph。
2.5 从资源对象到 CRI 调用的映射路径
理解资源对象的定义后,需要掌握 Kubernetes 如何将 Pod 定义转化为 CRI 调用。Kubelet 内部的 Pod Worker 循环执行以下步骤:
- Pod 同步:从 API Server 监听 Pod 变更,或从本地缓存读取。
- Sandbox 管理:调用
RunPodSandbox创建 Pod 级别的隔离环境(网络命名空间、Cgroup 父目录)。 - 容器创建:遍历 Pod.Spec.Containers,依次调用
CreateContainer+StartContainer。 - Volume 挂载:在容器启动前,由 Volume Manager 执行挂载操作,并将挂载路径传入 CRI 的 Mount 参数。
- 状态上报:通过
PodSandboxStatus和ContainerStatus获取运行时状态,更新 Pod Status。
- Pod 的
SecurityContext中的RunAsUser、SeccompProfile、Capabilities直接映射到LinuxContainerSecurityContext。 - Pod 的
Resources.Limits中的 CPU 和内存值被转换为LinuxContainerResources.CpuPeriod、CpuQuota、MemoryLimitInBytes。 - Pod 的
Volumes中的 ConfigMap/Secret 在容器启动前由 Kubelet 负责写入临时文件系统,CRI 只感知最终的挂载路径。
2.6 资源对象的版本化与 API 演进
Kubernetes 资源模型通过 API 版本化 机制支持渐进式演进。每个资源对象都有 apiVersion 字段,例如 v1、apps/v1、batch/v1。CRI 接口同样遵循版本化原则,但 CRI 的版本与 Kubernetes API 版本相互独立。
| 资源对象 | 稳定 API 版本 | CRI 版本 | 备注 |
|---|---|---|---|
| Pod | v1 |
v1alpha2 / v1 | PodSpec 字段持续扩展,CRI 需向后兼容 |
| Container | 内嵌于 PodSpec | v1 | CRI 的 ContainerConfig 与 PodSpec.Container 字段对应 |
| Volume | v1 |
Mount 结构体 | CSI 驱动通过 CRI 的 Mount 传递卷信息 |
| RuntimeClass | node.k8s.io/v1 |
v1alpha2+ | 用于选择不同的容器运行时(如 gVisor、Kata) |
v1 版本的 CRI 接口,并关注 RuntimeClass 的引入,它允许同一个集群中混用多种运行时,而无需修改 Pod 定义。
2.7 本章小结
Kubernetes 资源模型通过 Pod、Container、Volume 等核心对象,构建了一套从应用描述到运行时实例化的完整抽象链。Pod 作为原子调度单元,封装了共享网络与存储的容器组;Container 定义了单个进程的运行时参数;Volume 解耦了存储的生命周期与容器生命周期。这些资源对象通过 Kubelet 的 Pod Worker 循环,被精确地翻译为 CRI 调用,最终由容器运行时在宿主机上创建出符合预期的隔离环境。理解这一映射关系,是后续深入 CRI 集成与运行时控制面优化的前提。