复制控制器

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

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

ReplicationController 如何工作

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

ReplicationController 在讨论中通常简写为 “rc”,在 kubectl 命令中也作为快捷方式使用。

一个简单的用例是创建一个 ReplicationController 对象,以可靠地无限期运行一个 Pod 实例。一个更复杂的用例是运行服务(如 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

通过下载示例文件,然后运行此命令来运行示例作业

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 清单

与其他所有 Kubernetes 配置一样,ReplicationController 需要 `apiVersion`、`kind` 和 `metadata` 字段。

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

有关配置文件的通用信息,请参阅 对象管理

ReplicationController 还需要一个 .spec 部分

Pod 模板

`.spec.template` 是 `.spec` 唯一必需的字段。

`.spec.template` 是一个 Pod 模板。它与 Pod 具有完全相同的模式,只是它被嵌套,并且没有 `apiVersion` 或 `kind`。

除了 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 正在优雅关闭,而替代 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 来替换它。只要新旧的 `。spec.selector` 相同,那么新的 ReplicationController 将采用旧的 Pod。但是,它不会努力使现有 Pod 与新的、不同的 Pod 模板匹配。要以受控方式将 Pod 更新为新的规范,请使用滚动更新

将 Pod 从 ReplicationController 中隔离

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

常见使用模式

重新调度

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

扩缩

ReplicationController 允许通过更新 `replicas` 字段来手动或通过自动扩缩控制代理,来向上或向下扩缩副本数量。

滚动更新

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

#1353 中所述,推荐的方法是创建一个具有 1 个副本的新 ReplicationController,逐个扩缩新控制器(+1)和旧控制器(-1),然后在旧控制器达到 0 个副本后将其删除。这可以预测地更新 Pod 集,无论发生何种意外故障。

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

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

多发布轨道

除了在滚动更新进行中时运行应用程序的多个版本之外,通常还会使用多个发布轨道在较长时间内,甚至持续运行多个版本。这些轨道将通过标签进行区分。

例如,一个服务可能针对所有带有 `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`。现在,该服务覆盖了金丝雀和非金丝雀 Pod。但您可以单独操作 ReplicationController 以测试事物、监控结果等。

将 ReplicationController 与 Service 一起使用

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

ReplicationController 绝不会自行终止,但它预计不会像服务那样长寿。服务可能由多个 ReplicationController 控制的 Pod 组成,并且预计在服务的生命周期内可能会创建和销毁许多 ReplicationController(例如,为了执行运行服务的 Pod 的更新)。服务本身及其客户端都应该对维护服务 Pod 的 ReplicationController 一无所知。

编写复制程序

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

ReplicationController 的职责

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

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

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

API 对象

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

ReplicationController 的替代方案

副本集

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

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

裸 Pod

与用户直接创建 Pod 的情况不同,ReplicationController 会替换因任何原因被删除或终止的 Pod,例如在节点故障或破坏性节点维护(如内核升级)的情况下。因此,即使您的应用程序只需要一个 Pod,我们也建议您使用 ReplicationController。将其视为类似于进程主管,只是它管理多个节点上的多个 Pod,而不是单个节点上的单个进程。ReplicationController 将本地容器重启委托给节点上的某个代理,例如 kubelet。

作业

对于预期自行终止的 Pod(即批处理作业),请使用 Job 而不是 ReplicationController。

DaemonSet

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

下一步

  • 了解Pod
  • 了解 Deployment,它是 ReplicationController 的替代品。
  • ReplicationController 是 Kubernetes REST API 的一部分。阅读 ReplicationController 对象定义以了解 ReplicationController 的 API。
最后修改时间:2024 年 3 月 14 日下午 2:28 PST:添加元数据以使用 API 参考链接机制 (c889d9b251)