ReplicationController

用于管理可水平扩展工作负载的传统 API。已被 Deployment 和 ReplicaSet API 取代。

ReplicationController 确保在任何时刻都有指定数量的 Pod 副本正在运行。换句话说,ReplicationController 确保一个 Pod 或一组同质的 Pod 始终处于可用状态。

ReplicationController 的工作原理

如果 Pod 数量过多,ReplicationController 会终止多余的 Pod。如果 Pod 数量过少,ReplicationController 会启动更多 Pod。与手动创建的 Pod 不同,ReplicationController 维护的 Pod 在失败、被删除或终止后会自动替换。例如,在中断性维护(例如内核升级)后,你的 Pod 会在节点上重新创建。因此,即使你的应用只需要一个 Pod,也应该使用 ReplicationController。ReplicationController 类似于进程监控器,但它监控的是跨多个节点的多个 Pod,而不是单个节点上的单个进程。

在讨论中,ReplicationController 通常缩写为 "rc",在 kubectl 命令中也可作为快捷方式。

一个简单的用例是创建单个 ReplicationController 对象,以便可靠地无限期运行一个 Pod 实例。一个更复杂的用例是运行 Service 的多个相同副本,例如 Web 服务器。

运行示例 ReplicationController

此示例 ReplicationController 配置运行三个 nginx Web 服务器副本。

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

下载示例文件并运行此命令来运行示例 Job

kubectl apply -f https://k8s.io/examples/controllers/replication.yaml

输出类似于:

replicationcontroller/nginx created

使用此命令检查 ReplicationController 的状态

kubectl describe replicationcontrollers/nginx

输出类似于:

Name:        nginx
Namespace:   default
Selector:    app=nginx
Labels:      app=nginx
Annotations:    <none>
Replicas:    3 current / 3 desired
Pods Status: 0 Running / 3 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:       app=nginx
  Containers:
   nginx:
    Image:              nginx
    Port:               80/TCP
    Environment:        <none>
    Mounts:             <none>
  Volumes:              <none>
Events:
  FirstSeen       LastSeen     Count    From                        SubobjectPath    Type      Reason              Message
  ---------       --------     -----    ----                        -------------    ----      ------              -------
  20s             20s          1        {replication-controller }                    Normal    SuccessfulCreate    Created pod: nginx-qrm3m
  20s             20s          1        {replication-controller }                    Normal    SuccessfulCreate    Created pod: nginx-3ntk0
  20s             20s          1        {replication-controller }                    Normal    SuccessfulCreate    Created pod: nginx-4ok8v

此处创建了三个 Pod,但没有一个正在运行,可能是因为正在拉取镜像。稍后,相同的命令可能会显示:

Pods Status:    3 Running / 0 Waiting / 0 Succeeded / 0 Failed

要以机器可读的格式列出属于 ReplicationController 的所有 Pod,可以使用以下命令:

pods=$(kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name})
echo $pods

输出类似于:

nginx-3ntk0 nginx-4ok8v nginx-qrm3m

此处,选择器与 ReplicationController 的选择器(在 kubectl describe 输出中看到)相同,并且在 replication.yaml 中形式不同。--output=jsonpath 选项指定一个表达式,其中包含返回列表中每个 Pod 的名称。

编写 ReplicationController Manifest

与所有其他 Kubernetes 配置一样,ReplicationController 需要 apiVersionkindmetadata 字段。

当控制平面为 ReplicationController 创建新的 Pod 时,ReplicationController 的 .metadata.name 是命名这些 Pod 的基础之一。ReplicationController 的名称必须是有效的 DNS 子域名 值,但这可能会导致 Pod 主机名出现意外结果。为了获得最佳兼容性,名称应遵循更严格的 DNS 标签 规则。

有关使用配置文件的一般信息,请参见对象管理

ReplicationController 还需要 .spec

Pod 模板

.spec.template.spec 中唯一必需的字段。

.spec.template 是一个 Pod 模板。它与 Pod 具有完全相同的 Schema,除了它是嵌套的并且没有 apiVersionkind

除了 Pod 的必需字段外,ReplicationController 中的 Pod 模板必须指定适当的标签和适当的重启策略。对于标签,请确保不与其他控制器重叠。参见 Pod 选择器

只允许 .spec.template.spec.restartPolicy 等于 Always,如果未指定,则默认为此值。

对于本地容器重启,ReplicationController 会委托给节点上的代理,例如 Kubelet

ReplicationController 的标签

ReplicationController 本身可以有标签(.metadata.labels)。通常,你会将这些标签设置为与 .spec.template.metadata.labels 相同;如果未指定 .metadata.labels,则默认为 .spec.template.metadata.labels。但是,它们允许不同,并且 .metadata.labels 不影响 ReplicationController 的行为。

Pod 选择器

.spec.selector 字段是一个 标签选择器。ReplicationController 管理所有标签与选择器匹配的 Pod。它不区分由它创建或删除的 Pod 与由其他人或进程创建或删除的 Pod。这使得可以在不影响正在运行的 Pod 的情况下替换 ReplicationController。

如果指定了 .spec.template.metadata.labels,则必须等于 .spec.selector,否则将被 API 拒绝。如果未指定 .spec.selector,则默认为 .spec.template.metadata.labels

此外,通常不应直接、通过另一个 ReplicationController 或通过另一个控制器(例如 Job)创建任何标签与此选择器匹配的 Pod。如果这样做,ReplicationController 会认为它创建了其他 Pod。Kubernetes 并不会阻止你这样做。

如果你最终出现多个控制器具有重叠选择器的情况,则需要自己管理删除(参见下文)。

多个副本

通过将 .spec.replicas 设置为你希望同时运行的 Pod 数量,可以指定同时运行的 Pod 数量。任何时候正在运行的数量可能会更高或更低,例如刚增加或减少副本时,或者 Pod 优雅关闭且替换 Pod 提前启动时。

如果未指定 .spec.replicas,则默认为 1。

使用 ReplicationController

删除 ReplicationController 及其 Pod

要删除 ReplicationController 及其所有 Pod,请使用 kubectl delete。Kubectl 会将 ReplicationController 副本数缩减至零,并等待它删除每个 Pod,然后再删除 ReplicationController 本身。如果此 kubectl 命令中断,可以重新启动。

使用 REST API 或 客户端库 时,你需要显式执行这些步骤(将副本数缩减到 0,等待 Pod 删除,然后删除 ReplicationController)。

仅删除 ReplicationController

你可以删除 ReplicationController 而不影响其任何 Pod。

使用 kubectl,为 kubectl delete 指定 --cascade=orphan 选项。

使用 REST API 或 客户端库 时,你可以删除 ReplicationController 对象。

原始的 ReplicationController 删除后,你可以创建新的 ReplicationController 来替换它。只要新旧 ReplicationController 的 .spec.selector 相同,新的 ReplicationController 就会接管旧的 Pod。但是,它不会努力使现有 Pod 与新的、不同的 Pod 模板匹配。要以受控方式将 Pod 更新到新的 Spec,请使用滚动更新

将 Pod 与 ReplicationController 隔离

通过更改 Pod 的标签,可以将其从 ReplicationController 的目标集中移除。此技术可用于将 Pod 从 Service 中移除以便进行调试和数据恢复。以这种方式移除的 Pod 将自动被替换(假设副本数量未同时更改)。

常见使用模式

重新调度

如前所述,无论你希望运行 1 个 Pod 还是 1000 个,ReplicationController 都会确保指定数量的 Pod 存在,即使在节点故障或 Pod 终止(例如,由于另一个控制代理的操作)的情况下也是如此。

扩缩容

ReplicationController 通过更新 replicas 字段,可以手动或通过自动扩缩容控制代理来实现副本数量的扩缩容。

滚动更新

ReplicationController 旨在通过逐个替换 Pod 来促进对 Service 的滚动更新。

#1353 中解释的,推荐的方法是创建一个新的 ReplicationController,副本数为 1,然后逐个扩缩容新的(+1)和旧的(-1)控制器,并在旧控制器达到 0 副本后将其删除。无论出现何种意外故障,此方法都能可预测地更新 Pod 集。

理想情况下,滚动更新控制器应考虑应用的就绪状态,并确保在任何给定时间都有足够数量的 Pod 正在提供服务。

这两个 ReplicationController 需要创建带有至少一个区分性标签的 Pod,例如 Pod 主容器的镜像标签,因为通常是镜像更新促使进行滚动更新。

多个发布轨道

除了在进行滚动更新时运行应用的多个版本外,使用多个发布轨道长时间甚至持续运行多个版本也很常见。这些轨道通过标签区分。

例如,Service 可能面向所有带有标签 tier in (frontend), environment in (prod) 的 Pod。假设你有 10 个组成此层级的副本 Pod。但你希望能够“金丝雀发布”此组件的新版本。你可以设置一个 ReplicationController,将 replicas 设置为 9,用于大部分副本,标签为 tier=frontend, environment=prod, track=stable,再设置另一个 ReplicationController,将 replicas 设置为 1,用于金丝雀版本,标签为 tier=frontend, environment=prod, track=canary。现在该 Service 涵盖了金丝雀和非金丝雀 Pod。但你可以单独调整 ReplicationController 进行测试、监控结果等。

将 ReplicationController 与 Service 一起使用

多个 ReplicationController 可以位于单个 Service 之后,这样,例如,一部分流量流向旧版本,一部分流量流向新版本。

ReplicationController 绝不会自行终止,但预计它不像 Service 那样长期存在。Service 可能由多个 ReplicationController 控制的 Pod 组成,预计在 Service 的生命周期内会创建和销毁许多 ReplicationController(例如,用于对运行该 Service 的 Pod 进行更新)。Service 本身及其客户端都应不关心维护 Service 的 Pod 的 ReplicationController。

编写复制程序

ReplicationController 创建的 Pod 旨在是可互换且语义上相同的,尽管它们的配置可能会随时间变得异构。这显然适合复制的无状态服务器,但 ReplicationController 也可用于维护主选、分片和工作池应用的可用性。此类应用应使用动态工作分配机制,例如 RabbitMQ 工作队列,而不是对每个 Pod 的配置进行静态/一次性定制(这被认为是反模式)。执行的任何 Pod 定制,例如资源的垂直自动扩缩(例如,cpu 或 memory),都应由另一个在线控制器进程执行,与 ReplicationController 本身类似。

ReplicationController 的职责

ReplicationController 确保期望数量的 Pod 与其标签选择器匹配且正在运行。目前,只有已终止的 Pod 不计入其计数。将来,可能会考虑就绪状态和系统提供的其他信息,我们可能会增加对替换策略的更多控制,并且我们计划发出可供外部客户端用于实现任意复杂替换和/或缩容策略的事件。

ReplicationController 始终局限于这种狭窄的职责。它本身不会执行就绪或存活探针。它不执行自动扩缩,而是旨在由外部自动扩缩器控制(如 #492 中讨论的),该自动扩缩器将更改其 replicas 字段。我们不会向 ReplicationController 添加调度策略(例如,分散)。它也不应验证受控的 Pod 是否与当前指定的模板匹配,因为这会阻碍自动调整大小和其他自动化过程。同样,完成期限、排序依赖关系、配置扩展和其他功能属于其他地方。我们甚至计划剥离批量创建 Pod 的机制(#170)。

ReplicationController 旨在成为一个可组合的基础构建块。我们期望将来在其之上以及其他补充原语之上构建更高级别的 API 和/或工具,以方便用户。目前 kubectl 支持的“宏”操作(run、scale)就是这一点的概念验证示例。例如,我们可以想象类似 Asgard 的东西管理 ReplicationController、自动扩缩器、Service、调度策略、金丝雀等。

API 对象

ReplicationController 是 Kubernetes REST API 中的顶级资源。有关 API 对象的更多详细信息,请参见:ReplicationController API 对象

ReplicationController 的替代方案

ReplicaSet

ReplicaSet 是下一代 ReplicationController,支持新的基于集合的标签选择器。它主要由 Deployment 用作协调 Pod 创建、删除和更新的机制。请注意,我们推荐使用 Deployment,而不是直接使用 ReplicaSet,除非你需要自定义更新编排或根本不需要更新。

Deployment 是一个更高级别的 API 对象,它更新其底层的 ReplicaSet 及其 Pod。如果你想要滚动更新功能,推荐使用 Deployment,因为它们是声明式的、服务器端的,并且具有附加功能。

裸 Pod

与用户直接创建 Pod 的情况不同,ReplicationController 会替换因任何原因被删除或终止的 Pod,例如节点故障或中断性节点维护(如内核升级)的情况。因此,即使你的应用只需要一个 Pod,我们也建议你使用 ReplicationController。可以将其类比为进程监控器,只不过它监控的是跨多个节点的多个 Pod,而不是单个节点上的单个进程。ReplicationController 将本地容器重启委托给节点上的某些代理,例如 kubelet。

Job

对于预期自行终止的 Pod(即批处理 Job),请使用 Job 代替 ReplicationController。

DaemonSet

对于提供机器级别功能(例如机器监控或机器日志记录)的 Pod,请使用 DaemonSet 代替 ReplicationController。这些 Pod 的生命周期与机器生命周期绑定:Pod 需要在其他 Pod 启动之前在机器上运行,并且在机器准备好重启/关闭时可以安全终止。

接下来

  • 了解 Pod
  • 了解 Deployment,它是 ReplicationController 的替代方案。
  • ReplicationController 是 Kubernetes REST API 的一部分。阅读ReplicationController 对象定义以了解复制控制器 API。
上次修改时间:2024 年 3 月 14 日 下午 2:28 PST:添加 metadata 以使用 API 参考链接机制 (c889d9b251)