Pod

Pod 是可以在 Kubernetes 中创建和管理的最小可部署计算单元。

Pod(就像鲸鱼群或豆荚一样)是一组一个或多个容器,它们共享存储和网络资源,并有一个运行容器的规范。Pod 的内容总是共同定位和共同调度,并在共享上下文中运行。Pod 建模了一个特定于应用的“逻辑主机”:它包含一个或多个相对紧密耦合的应用容器。在非云环境中,在同一物理机或虚拟机上执行的应用程序类似于在同一逻辑主机上执行的云应用程序。

除了应用容器,Pod 还可以包含在 Pod 启动期间运行的初始化容器。你还可以注入临时容器来调试正在运行的 Pod。

什么是 Pod?

Pod 的共享上下文是一组 Linux 命名空间、cgroups 以及可能还有其他隔离方面——与隔离容器的机制相同。在 Pod 的上下文中,各个应用程序可能会应用进一步的子隔离。

Pod 类似于一组共享命名空间和共享文件系统卷的容器。

Kubernetes 集群中的 Pod 主要有两种用途:

  • 运行单个容器的 Pod。“每个 Pod 一个容器”模型是最常见的 Kubernetes 用例;在这种情况下,你可以将 Pod 视为单个容器的包装器;Kubernetes 管理 Pod,而不是直接管理容器。

  • 运行多个需要协同工作的容器的 Pod。Pod 可以封装由多个共置容器组成的应用程序,这些容器紧密耦合并需要共享资源。这些共置容器构成一个单一的、内聚的单元。

    在单个 Pod 中对多个共置和共同管理的容器进行分组是一种相对高级的用例。你只应在容器紧密耦合的特定情况下使用此模式。

    你不需要运行多个容器来提供复制(为了弹性或容量);如果你需要多个副本,请参阅工作负载管理

使用 Pod

以下是一个 Pod 示例,它由一个运行 nginx:1.14.2 镜像的容器组成。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

要创建上面显示的 Pod,请运行以下命令:

kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml

Pod 通常不直接创建,而是使用工作负载资源创建。有关 Pod 如何与工作负载资源一起使用的更多信息,请参阅使用 Pod

用于管理 Pod 的工作负载资源

通常你不需要直接创建 Pod,即使是单例 Pod 也不需要。相反,请使用DeploymentJob等工作负载资源来创建它们。如果你的 Pod 需要跟踪状态,请考虑使用StatefulSet资源。

每个 Pod 都旨在运行给定应用程序的单个实例。如果你想水平扩展你的应用程序(通过运行更多实例来提供更多整体资源),你应该使用多个 Pod,每个实例一个。在 Kubernetes 中,这通常被称为复制。复制的 Pod 通常由工作负载资源及其控制器作为一组创建和管理。

有关 Kubernetes 如何使用工作负载资源及其控制器来实现应用程序扩缩和自动修复的更多信息,请参阅Pod 和控制器

Pod 为其组成容器原生提供两种共享资源:网络存储

使用 Pod

你很少直接在 Kubernetes 中创建单个 Pod,即使是单例 Pod 也很少。这是因为 Pod 被设计为相对短暂、可丢弃的实体。当一个 Pod 被创建时(由你直接或由控制器间接),新的 Pod 被调度到集群中的一个节点上运行。Pod 会一直保留在该节点上,直到 Pod 执行完成、Pod 对象被删除、Pod 因资源不足而被驱逐,或者节点发生故障。

Pod 的名称必须是有效的DNS 子域名值,但这可能会导致 Pod 主机名出现意想不到的结果。为了获得最佳兼容性,名称应遵循更严格的DNS 标签规则。

Pod 操作系统

特性状态: Kubernetes v1.25 [稳定]

你应该将 .spec.os.name 字段设置为 windowslinux,以指示你希望 Pod 运行的操作系统。这两个是 Kubernetes 目前支持的唯一操作系统。将来,此列表可能会扩展。

在 Kubernetes v1.34 中,.spec.os.name 的值不会影响 kube-scheduler 如何为 Pod 选择一个节点来运行。在任何有多个操作系统运行节点的集群中,你应该在每个节点上正确设置 kubernetes.io/os 标签,并使用基于操作系统标签的 nodeSelector 定义 Pod。kube-scheduler 根据其他标准将你的 Pod 分配给一个节点,并且可能成功也可能不成功地选择一个合适的节点位置,其中节点操作系统适合该 Pod 中的容器。Pod 安全标准也使用此字段来避免强制执行与操作系统无关的策略。

Pod 和控制器

你可以使用工作负载资源为你创建和管理多个 Pod。资源的控制器负责在 Pod 故障时进行复制、部署和自动修复。例如,如果一个节点发生故障,控制器会注意到该节点上的 Pod 已停止工作,并创建替代 Pod。调度器会将替代 Pod 放置到健康的节点上。

以下是一些管理一个或多个 Pod 的工作负载资源的示例:

Pod 模板

工作负载资源的控制器从Pod 模板创建 Pod,并代表你管理这些 Pod。

PodTemplate 是创建 Pod 的规范,并包含在诸如 DeploymentJobDaemonSet 等工作负载资源中。

每个工作负载资源的控制器都使用工作负载对象中的 PodTemplate 来创建实际的 Pod。PodTemplate 是你用于运行应用程序的任何工作负载资源的期望状态的一部分。

创建 Pod 时,你可以在 Pod 模板中包含环境变量,用于在 Pod 中运行的容器。

下面的示例是一个简单 Job 的清单,其中包含一个启动一个容器的 template。该 Pod 中的容器打印一条消息,然后暂停。

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    # This is the pod template
    spec:
      containers:
      - name: hello
        image: busybox:1.28
        command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
      restartPolicy: OnFailure
    # The pod template ends here

修改 Pod 模板或切换到新 Pod 模板对已存在的 Pod 没有直接影响。如果你更改了工作负载资源的 Pod 模板,该资源需要创建使用更新模板的替换 Pod。

例如,StatefulSet 控制器确保运行中的 Pod 与每个 StatefulSet 对象的当前 Pod 模板匹配。如果你编辑 StatefulSet 以更改其 Pod 模板,StatefulSet 将开始基于更新的模板创建新的 Pod。最终,所有旧 Pod 都将被新 Pod 替换,并且更新完成。

每个工作负载资源都实现了自己的 Pod 模板更改处理规则。如果你想了解更多关于 StatefulSet 的信息,请阅读 StatefulSet 基础教程中的更新策略

在节点上,kubelet 不直接观察或管理 Pod 模板和更新的任何细节;这些细节都被抽象掉了。这种抽象和关注点分离简化了系统语义,并使得在不更改现有代码的情况下扩展集群行为成为可能。

Pod 更新和替换

如上一节所述,当工作负载资源的 Pod 模板更改时,控制器会根据更新后的模板创建新的 Pod,而不是更新或修补现有 Pod。

Kubernetes 不会阻止你直接管理 Pod。可以直接更新正在运行的 Pod 的某些字段。但是,Pod 更新操作(如 patchreplace)有一些限制:

  • Pod 的大部分元数据是不可变的。例如,你不能更改 namespacenameuidcreationTimestamp 字段。

  • 如果设置了 metadata.deletionTimestamp,则不能向 metadata.finalizers 列表添加新条目。

  • Pod 更新不能更改 spec.containers[*].imagespec.initContainers[*].imagespec.activeDeadlineSecondsspec.terminationGracePeriodSecondsspec.tolerationsspec.schedulingGates 以外的字段。对于 spec.tolerations,你只能添加新条目。

  • 更新 spec.activeDeadlineSeconds 字段时,允许两种类型的更新:

    1. 将未分配的字段设置为正数;
    2. 将字段从正数更新为更小的非负数。

Pod 子资源

上述更新规则适用于常规 Pod 更新,但其他 Pod 字段可以通过子资源进行更新。

  • Resize: resize 子资源允许更新容器资源(spec.containers[*].resources)。有关更多详细信息,请参阅调整容器资源大小
  • Ephemeral Containers: ephemeralContainers 子资源允许将临时容器添加到 Pod 中。有关更多详细信息,请参阅临时容器
  • Status: status 子资源允许更新 Pod 状态。这通常仅由 Kubelet 和其他系统控制器使用。
  • Binding: binding 子资源允许通过 Binding 请求设置 Pod 的 spec.nodeName。这通常仅由调度器使用。

Pod Generation

  • metadata.generation 字段是唯一的。系统将自动设置它,使得新 Pod 的 metadata.generation 为 1,并且 Pod 规范中可变字段的每次更新都会将 metadata.generation 增加 1。
特性状态: Kubernetes v1.34 [beta] (默认启用:true)
  • observedGeneration 是一个在 Pod 对象的 status 部分中捕获的字段。如果启用了特性门 PodObservedGenerationTracking,Kubelet 会设置 status.observedGeneration 来跟踪 Pod 状态到当前 Pod 状态。Pod 的 status.observedGeneration 将反映报告 Pod 状态时 Pod 的 metadata.generation

不同的状态字段可能与当前同步循环的 metadata.generation 相关联,或者与上一个同步循环的 metadata.generation 相关联。关键区别在于 spec 中的更改是直接反映在 status 中,还是正在运行进程的间接结果。

直接状态更新

对于直接反映分配规范的状态字段,observedGeneration 将与当前 metadata.generation(N 代)相关联。

此行为适用于:

  • Resize Status:资源调整大小操作的状态。
  • Allocated Resources:调整大小后分配给 Pod 的资源。
  • Ephemeral Containers:当添加新的临时容器并且它处于 Waiting 状态时。

间接状态更新

对于作为运行规范的间接结果的状态字段,observedGeneration 将与上一个同步循环的 metadata.generation(N-1 代)相关联。

此行为适用于:

  • 容器镜像ContainerStatus.ImageID 反映前一代的镜像,直到拉取新镜像并更新容器。
  • 实际资源:在进行中的调整大小期间,实际使用的资源仍然属于前一代的请求。
  • 容器状态:在进行中的调整大小期间,需要重启策略反映前一代的请求。
  • activeDeadlineSeconds & terminationGracePeriodSeconds & deletionTimestamp:这些字段对 Pod 状态的影响是先前观察到的规范的结果。

资源共享和通信

Pod 允许其组成容器之间共享数据和通信。

Pod 中的存储

Pod 可以指定一组共享存储。Pod 中的所有容器都可以访问共享卷,从而允许这些容器共享数据。卷还允许 Pod 中的持久数据在一个容器需要重新启动时仍然存在。有关 Kubernetes 如何实现共享存储并使其可用于 Pod 的更多信息,请参阅存储

Pod 网络

每个 Pod 为每个地址族分配一个唯一的 IP 地址。Pod 中的每个容器共享网络命名空间,包括 IP 地址和网络端口。在 Pod 内部(在此情况下),属于 Pod 的容器可以使用 localhost 相互通信。当 Pod 中的容器与Pod 外部实体通信时,它们必须协调如何使用共享网络资源(例如端口)。在 Pod 内部,容器共享一个 IP 地址和端口空间,并且可以通过 localhost 相互查找。Pod 中的容器还可以使用标准进程间通信(如 SystemV 信号量或 POSIX 共享内存)相互通信。不同 Pod 中的容器具有不同的 IP 地址,并且在没有特殊配置的情况下无法通过 OS 级别 IPC 进行通信。希望与在不同 Pod 中运行的容器交互的容器可以使用 IP 网络进行通信。

Pod 内的容器将系统主机名视为与 Pod 的配置 name 相同。有关此内容的更多信息,请参阅网络部分。

Pod 安全设置

要在 Pod 和容器上设置安全限制,可以使用 Pod 规范中的 securityContext 字段。该字段让你能够精细控制 Pod 或单个容器可以执行的操作。例如:

  • 丢弃特定的 Linux 能力以避免 CVE 的影响。
  • 强制 Pod 中的所有进程以非 root 用户或特定的用户或组 ID 运行。
  • 设置特定的 seccomp 配置文件。
  • 设置 Windows 安全选项,例如容器是否作为 HostProcess 运行。

静态 Pod

静态 Pod 由特定节点上的 kubelet 守护进程直接管理,而API 服务器不观察它们。虽然大多数 Pod 由控制平面管理(例如,Deployment),但对于静态 Pod,kubelet 直接监督每个静态 Pod(并在其失败时重新启动)。

静态 Pod 始终绑定到特定节点上的一个 Kubelet。静态 Pod 的主要用途是运行自托管的控制平面:换句话说,使用 kubelet 监督各个控制平面组件

Kubelet 会自动尝试为每个静态 Pod 在 Kubernetes API 服务器上创建一个镜像 Pod。这意味着在节点上运行的 Pod 在 API 服务器上可见,但无法从那里控制。有关更多信息,请参阅指南创建静态 Pod

多容器 Pod

Pod 旨在支持多个协作进程(作为容器),它们构成一个有凝聚力的服务单元。Pod 中的容器会自动共置并共同调度到集群中的同一物理或虚拟机上。容器可以共享资源和依赖项,相互通信,并协调何时以及如何终止。

Kubernetes 集群中的 Pod 主要有两种用途:

  • 运行单个容器的 Pod。“每个 Pod 一个容器”模型是最常见的 Kubernetes 用例;在这种情况下,你可以将 Pod 视为单个容器的包装器;Kubernetes 管理 Pod,而不是直接管理容器。
  • 运行多个需要协同工作的容器的 Pod。Pod 可以封装由多个共置容器组成的应用程序,这些容器紧密耦合并需要共享资源。这些共置容器构成一个单一、有凝聚力的服务单元——例如,一个容器将共享卷中存储的数据提供给公众,而一个单独的Sidecar 容器刷新或更新这些文件。Pod 将这些容器、存储资源和临时的网络身份封装在一起,作为一个单一单元。

例如,你可能有一个容器作为共享卷中文件的 Web 服务器,以及一个单独的Sidecar 容器,它从远程源更新这些文件,如下图所示:

Pod creation diagram

有些 Pod 既有初始化容器,也有应用容器。默认情况下,初始化容器在应用容器启动之前运行并完成。

你还可以拥有Sidecar 容器,它们为主应用程序 Pod 提供辅助服务(例如:服务网格)。

特性状态: Kubernetes v1.33 [stable] (默认启用:true)

默认启用的 SidecarContainers 功能门控允许你为初始化容器指定 restartPolicy: Always。将 Always 重启策略设置为确保你设置它的容器被视为在 Pod 的整个生命周期内保持运行的Sidecar。你明确定义为 Sidecar 容器的容器在主应用程序 Pod 启动之前启动,并保持运行直到 Pod 关闭。

容器探针

探针是 kubelet 定期对容器执行的诊断。为了执行诊断,kubelet 可以调用不同的操作:

  • ExecAction(在容器运行时帮助下执行)
  • TCPSocketAction(由 kubelet 直接检查)
  • HTTPGetAction(由 kubelet 直接检查)

你可以在 Pod 生命周期文档中阅读有关探针的更多信息。

下一步

要了解 Kubernetes 将通用 Pod API 封装在其他资源(例如StatefulSetsDeployments)中的原因,你可以阅读相关的现有技术,包括:

上次修改时间:2025 年 7 月 28 日 晚上 11:59(太平洋标准时间):doc update issue#51195 -v3 (070dda9e4a)