Pod

本页面介绍 Kubernetes 的 Pod 对象及其在 Google Kubernetes Engine 中的用法。

什么是 Pod?

Pod 是 Kubernetes 中可部署的最小、最基本对象。一个 Pod 代表集群中正在运行的单个进程实例。

Pod 包含一个或多个容器,例如 Docker 容器。当 Pod 运行多个容器时,这些容器将作为一个实体进行管理并共用 Pod 的资源。通常,在单个 Pod 中运行多个容器是一种高级使用场景。

Pod 还包含其容器的共享网络和存储资源:

  • 网络:系统会自动为 Pod 分配独一无二的 IP 地址。各 Pod 容器共用同一网络命名空间,包括 IP 地址和网络端口。Pod 中的各容器在 Pod 内通过 localhost 彼此通信。
  • 存储:Pod 可以指定一组可在各容器之间共用的共享存储卷。

您可以将 Pod 视为一个自成一体的独立“逻辑主机”,其中包含该 Pod 所服务于的应用的系统需求。

Pod 的用途是在集群上运行应用的单个实例。 但是,建议不要直接创建单个 Pod。最好创建一组相同 Pod(称为副本)来运行您的应用。这组副本 Pod 由控制器(如 Deployment)创建和管理。控制器可以管理其组成 Pod 的生命周期,还可以执行横向扩缩,根据需要更改 Pod 的数量。

您偶尔可以直接与 Pod 互动来对其进行调试、问题排查或检查,但强烈建议您使用控制器来管理您的 Pod。

Pod 在集群的节点上运行。Pod 在创建后将保留在其节点上,除非对应进程完成、该 Pod 被删除、Pod 因资源不足而被逐出节点,或者节点发生故障。如果某节点出现故障,系统会自动安排将该节点上的 Pod 删除。

Pod 生命周期

Pod 是临时性的。它们不能永久运行;Pod 一旦终止,便无法再恢复。一般来说,Pod 只有在被用户或控制器删除后才会消失。

Pod 不会自我“修复”。例如,如果某 Pod 被安排到的对应节点之后发生了故障,则该 Pod 会被删除。同样,如果某 Pod 由于任何原因被逐出节点,则该 Pod 不会自行替换。

每个 Pod 都有一个 PodStatus API 对象,该对象由 Pod 的 status 字段表示。Pod 会将其阶段发布到 status: phase 字段。Pod 所处的阶段是对 Pod 当前状态的简要说明。

如果您运行 kubectl get pod 来检查集群上运行的 Pod,Pod 可能处于以下某一阶段:

  • 待处理:Pod 已创建完毕并已被集群接受,但它的一个或多个容器尚未运行。此阶段包括 Pod 被安排到节点以及下载映像所花费的时间。
  • 正在运行:Pod 已绑定到节点,并且所有容器均已创建完毕。至少有一个容器正在运行、正在启动或正在重新启动。
  • 成功:Pod 中的所有容器都已成功终止。 已终止的 Pod 不会重新启动。
  • 失败:Pod 中的所有容器都已终止,并且至少有一个容器是由于故障而终止。如果某容器以非零状态退出,则表示该容器发生“故障”。
  • 未知:无法确定 Pod 的状态。

此外,PodStatus 包含一个名为 PodConditions 的数组,该数组在 Pod 清单中表示为 conditions。该字段包含typestatus 字段。conditions 更具体地指出了导致 Pod 处于当前状态的 Pod 内部条件。

type 字段可以包含 PodScheduledReadyInitializedUnschedulablestatus 字段与 type 字段相对应,可以包含 TrueFalseUnknown

创建 Pod

由于 Pod 是临时性的,因此不必直接创建 Pod。 同样,由于 Pod 无法自行修复或替换,因此建议不要直接创建 Pod。

您可以使用控制器(例如 Deployment)来为您创建和管理 Pod。控制器还有助于发布更新(例如更改容器中运行的应用版本),因为控制器会为您管理整个更新流程。

Pod 请求

Pod 开始运行时,会请求一定数量的 CPU 和内存。这有助于 Kubernetes 将 Pod 安排到适当的节点上来运行工作负载。Pod 不会被安排到没有资源来接受 Pod 请求的节点上。请求是 Kubernetes 保证向 Pod 提供的最低 CPU 或内存量。

您可以根据应用所需的资源为 Pod 配置 CPU 和内存请求。您还可以为 Pod 中运行的各个容器指定请求。请注意以下几点:

  • 默认 CPU 请求数为 1 亿。对于许多应用而言,此数量太少,并且可能比节点上的可用 CPU 量要少得多。
  • 无默认内存请求。无默认内存请求的 Pod 可能会被安排到没有足够内存的节点上来运行该 Pod 的工作负载。
  • 如果为 CPU 或内存请求设置的值太小,可能会导致将过多 Pod 或优化不足的 Pod 组合安排到指定节点上并降低性能。
  • 设置过大的 CPU 或内存请求值可能会导致系统无法安排 Pod,并且会增加集群资源的费用。
  • 除了设置 Pod 的资源外,您还可以为 Pod 中运行的各个容器指定资源,或者两者同时指定。如果您仅为容器指定资源,则 Pod 的请求数是为容器指定的请求数总和。如果两者同时指定,则所有容器的请求总和不得超过 Pod 请求数。

强烈建议您根据实际工作负载需求为 Pod 配置请求。如需了解详情,请参阅 Google Cloud 博客中的 Kubernetes 最佳做法:资源请求和限制

Pod 限制

默认情况下,Pod 可在节点上使用的 CPU 或内存量没有上限。您可以设置限制来控制 Pod 可在节点上使用的 CPU 或内存量。限制是 Kubernetes 保证向 Pod 提供的最大 CPU 或内存量。

除了设置 Pod 的限制外,您还可以为 Pod 中运行的各个容器指定限制,或者两者同时指定。如果您仅为容器指定限制,则 Pod 的限制是为容器指定的限制总和。但是,每个容器可以访问的资源不能超出其上限,因此,如果您选择仅指定针对容器的限制,则必须为每个容器指定限制。如果这两者同时指定,则所有容器的限制总和不得超过 Pod 限制。

在安排 Pod 时不考虑限制,但考虑限制可以防止同一节点上的 Pod 之间发生资源争用,并且可通过使底层操作系统资源匮乏来防止 Pod 导致节点上的系统不稳定。

强烈建议您根据实际工作负载需求为 Pod 配置限制。如需了解详情,请参阅 Google Cloud 博客中的 Kubernetes 最佳做法:资源请求和限制

Pod 模板

控制器对象(如 Deployment 和 StatefulSet)包含 Pod 模板字段。Pod 模板包含 Pod 规范,该规范决定了每个 Pod 应如何运行,具体包括应在 Pod 中运行哪些容器以及 Pod 应装载哪些卷。

控制器对象使用 Pod 模板创建 Pod,并管理其在集群内的“所需状态”。Pod 模板更改后,所有未来 Pod 都会反映新模板,但所有现有 Pod 则不会。

如需详细了解 Pod 模板的工作原理,请参阅 Kubernetes 文档中的创建 Deployment 部分。

控制 Pod 在哪些节点上运行

默认情况下,Pod 在集群默认节点池中的节点上运行。您可以配置 Pod 显式或隐式选择的节点池:

  • 您可以通过在 Pod 清单中设置 nodeSelector,明确地强制将 Pod 部署到特定节点池。这会强制 Pod 仅在该节点池中的节点上运行。

  • 您可以为所运行的容器指定资源请求。Pod 将仅在满足资源请求的节点上运行。例如,如果 Pod 定义包含需要四个 CPU 的容器,则 Service 将不会选择在具有两个 CPU 的节点上运行的 Pod。

Pod 使用模式

Pod 主要有两种使用方式:

  • 使用 Pod 运行单个容器。最简单且最常用的 Pod 模式是每个 Pod 一个容器,其中,单个容器代表整个应用。在这种情况下,您可以将 Pod 视为封装容器。
  • 使用 Pod 运行多个需要协同工作的容器。具有多个容器的 Pod 主要用于支持存储于同一位置的需要共享资源和联合管理的程序。这些存储于同一位置的容器可能构成一个整合式的服务单元,即一个容器用于从共享卷传送文件,而另一个容器用于刷新或更新这些文件。Pod 将这些容器和存储资源作为单个可管理实体封装在一起。

每个 Pod 的用途是运行给定应用的单个实例。如果要运行多个实例,建议对应用的每个实例使用一个 Pod。这通常称为复制。副本 Pod 由控制器(例如 Deployment)创建并作为一个组管理。

Pod 终止

Pod 会在其进程完成后正常终止。Kubernetes 规定的默认正常终止时间段为 30 秒。删除 Pod 时,您可以替换此宽限期,方法是将 --grace-period 标志设置为强制终止 Pod 之前等待 Pod 终止的秒数。

后续步骤