ReplicationController
A ReplicationController ensures that a specified number of pod replicas are running at any one time. In other words, a ReplicationController makes sure that a pod or a homogeneous set of pods is always up and available.
How a ReplicationController works
If there are too many pods, the ReplicationController terminates the extra pods. If there are too few, the ReplicationController starts more pods. Unlike manually created pods, the pods maintained by a ReplicationController are automatically replaced if they fail, are deleted, or are terminated. For example, your pods are re-created on a node after disruptive maintenance such as a kernel upgrade. For this reason, you should use a ReplicationController even if your application requires only a single pod. A ReplicationController is similar to a process supervisor, but instead of supervising individual processes on a single node, the ReplicationController supervises multiple pods across multiple nodes.
ReplicationController is often abbreviated to "rc" in discussion, and as a shortcut in kubectl commands.
A simple case is to create one ReplicationController object to reliably run one instance of a Pod indefinitely. A more complex use case is to run several identical replicas of a replicated service, such as web servers.
Running an example ReplicationController
This example ReplicationController config runs three copies of the nginx web server.
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
Run the example job by downloading the example file and then running this command
kubectl apply -f https://k8s.io/examples/controllers/replication.yaml
The output is similar to this
replicationcontroller/nginx created
Check on the status of the ReplicationController using this command
kubectl describe replicationcontrollers/nginx
The output is similar to this
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
Here, three pods are created, but none is running yet, perhaps because the image is being pulled. A little later, the same command may show
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
To list all the pods that belong to the ReplicationController in a machine readable form, you can use a command like this
pods=$(kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name})
echo $pods
The output is similar to this
nginx-3ntk0 nginx-4ok8v nginx-qrm3m
Here, the selector is the same as the selector for the ReplicationController (seen in the kubectl describe
output), and in a different form in replication.yaml
. The --output=jsonpath
option specifies an expression with the name from each pod in the returned list.
Writing a ReplicationController Manifest
As with all other Kubernetes config, a ReplicationController needs apiVersion
, kind
, and metadata
fields.
When the control plane creates new Pods for a ReplicationController, the .metadata.name
of the ReplicationController is part of the basis for naming those Pods. The name of a ReplicationController must be a valid DNS subdomain value, but this can produce unexpected results for the Pod hostnames. For best compatibility, the name should follow the more restrictive rules for a DNS label.
For general information about working with configuration files, see object management.
A ReplicationController also needs a .spec
section.
Pod Template
The .spec.template
is the only required field of the .spec
.
The .spec.template
is a pod template. It has exactly the same schema as a Pod, except it is nested and does not have an apiVersion
or kind
.
In addition to required fields for a Pod, a pod template in a ReplicationController must specify appropriate labels and an appropriate restart policy. For labels, make sure not to overlap with other controllers. See pod selector.
Only a .spec.template.spec.restartPolicy
equal to Always
is allowed, which is the default if not specified.
For local container restarts, ReplicationControllers delegate to an agent on the node, for example the Kubelet.
Labels on the ReplicationController
The ReplicationController can itself have labels (.metadata.labels
). Typically, you would set these the same as the .spec.template.metadata.labels
; if .metadata.labels
is not specified then it defaults to .spec.template.metadata.labels
. However, they are allowed to be different, and the .metadata.labels
do not affect the behavior of the ReplicationController.
Pod Selector
The .spec.selector
field is a label selector. A ReplicationController manages all the pods with labels that match the selector. It does not distinguish between pods that it created or deleted and pods that another person or process created or deleted. This allows the ReplicationController to be replaced without affecting the running pods.
If specified, the .spec.template.metadata.labels
must be equal to the .spec.selector
, or it will be rejected by the API. If .spec.selector
is unspecified, it will be defaulted to .spec.template.metadata.labels
.
Also you should not normally create any pods whose labels match this selector, either directly, with another ReplicationController, or with another controller such as Job. If you do so, the ReplicationController thinks that it created the other pods. Kubernetes does not stop you from doing this.
If you do end up with multiple controllers that have overlapping selectors, you will have to manage the deletion yourself (see below).
Multiple Replicas
You can specify how many pods should run concurrently by setting .spec.replicas
to the number of pods you would like to have running concurrently. The number running at any time may be higher or lower, such as if the replicas were just increased or decreased, or if a pod is gracefully shutdown, and a replacement starts early.
If you do not specify .spec.replicas
, then it defaults to 1.
Working with ReplicationControllers
Deleting a ReplicationController and its Pods
To delete a ReplicationController and all its pods, use kubectl delete
. Kubectl will scale the ReplicationController to zero and wait for it to delete each pod before deleting the ReplicationController itself. If this kubectl command is interrupted, it can be restarted.
When using the REST API or client library, you need to do the steps explicitly (scale replicas to 0, wait for pod deletions, then delete the ReplicationController).
Deleting only a ReplicationController
You can delete a ReplicationController without affecting any of its pods.
Using kubectl, specify the --cascade=orphan
option to kubectl delete
.
When using the REST API or client library, you can delete the ReplicationController object.
Once the original is deleted, you can create a new ReplicationController to replace it. As long as the old and new .spec.selector
are the same, then the new one will adopt the old pods. However, it will not make any effort to make existing pods match a new, different pod template. To update pods to a new spec in a controlled way, use a rolling update.
Isolating pods from a ReplicationController
可以通过更改 Pod 的标签,将其从 ReplicationController 的目标集中移除。这种技术可用于将 Pod 从服务中移除,以便进行调试和数据恢复。以这种方式移除的 Pod 将被自动替换(假设副本数量没有同时更改)。
常见用法模式
重新调度
如上所述,无论您希望保持运行 1 个 Pod 还是 1000 个 Pod,即使在节点故障或 Pod 终止(例如,由于另一个控制代理的操作)的情况下,ReplicationController 都会确保指定数量的 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 与服务一起使用
多个 ReplicationController 可以位于单个服务之后,因此,例如,某些流量会发送到旧版本,而某些流量会发送到新版本。
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
ReplicaSet
是下一代 ReplicationController,它支持新的 基于集合的标签选择器。 它主要被 Deployment 用作编排 Pod 创建、删除和更新的机制。 请注意,我们建议使用 Deployment 而不是直接使用 Replica Set,除非您需要自定义更新编排或根本不需要更新。
Deployment(推荐)
Deployment
是一个更高级别的 API 对象,它更新其底层的 Replica Set 和它们的 Pod。 如果您想要滚动更新功能,建议使用 Deployment,因为它们是声明式的、服务器端的,并且具有其他功能。
裸 Pod
与用户直接创建 Pod 的情况不同,ReplicationController 会替换因任何原因而被删除或终止的 Pod,例如在节点故障或破坏性节点维护(如内核升级)的情况下。 因此,即使您的应用程序只需要一个 Pod,我们也建议您使用 ReplicationController。 将其视为类似于进程管理器,只是它在多个节点上而不是单个节点上的单个进程上管理多个 Pod。 ReplicationController 将本地容器重启委托给节点上的某个代理,例如 kubelet。
Job
对于预计会自行终止的 Pod(即批处理作业),请使用 Job
而不是 ReplicationController。
DaemonSet
对于提供机器级功能(如机器监控或机器日志记录)的 Pod,请使用 DaemonSet
而不是 ReplicationController。 这些 Pod 的生命周期与机器的生命周期相关联:Pod 需要在其他 Pod 启动之前在机器上运行,并且在机器准备好重新启动/关闭时可以安全终止。
下一步
- 了解有关 Pod 的信息。
- 了解有关 Deployment(ReplicationController 的替代方案)的信息。
ReplicationController
是 Kubernetes REST API 的一部分。 阅读 ReplicationController 对象定义,以了解复制控制器的 API。