# Replication Controller（RC）

服务的扩容涉及资源分配（选择哪个节点进行扩容）、实例部署和启动等环节，在一个复杂的业务系统中，这两个问题基本上靠人工一步步操作才得以完成，费时费力又难以保证实施质量。&#x20;

在 Kubernetes 集群中，只需为需要扩容的 Service 关联的 Pod 创建一个 <mark style="color:blue;">**Replication Controller（简称 RC）**</mark>，则该 Service 的扩容以至于后来的 Service 升级等头疼问题都会迎刃而解。**RC 是 Kubernetes 系统中的核心概念之一，简单来说，它其实是**<mark style="color:blue;">**定义了一个期望的场景，即声明某种 Pod 的副本数量在任意时刻都符合某个预期值**</mark>，所以 **RC 的定义包括如下几个部分：**

* <mark style="color:blue;">**Pod 期待的副本数（replicas）**</mark>
* <mark style="color:blue;">**用于筛选目标 Pod 的 Label Selector**</mark>
* <mark style="color:blue;">**当 Pod 的副本数量小于预期数量的时候，用于创建新 Pod 的 Pod 模板（template）**</mark>

<mark style="color:blue;">**当我们定义了一个 RC 并提交到 Kubernetes 集群中以后，Master 节点上的**</mark> <mark style="color:blue;">**Controller Manager**</mark> <mark style="color:blue;">**组件就得到通知，定期巡检系统中当前存活的目标 Pod，并确保目标 Pod 实例的数量刚好等于此 RC 的期望值：**</mark>

* <mark style="color:blue;">**如果有过多的 Pod 副本在运行，系统就会停掉一些 Pod；**</mark>
* <mark style="color:blue;">**否则系统就会根据 RC 中定义的 Pod 模板来创建一个新的 Pod，然后将此 Pod 调度到合适的 Node 上启动运行，直到 Pod 实例的数量达到预定目标**</mark><mark style="color:blue;">。</mark>

通过 RC，Kubernetes 实现了用户应用集群的**高可用性**，并且大大减少了系统管理员在传统 IT 环境中需要完成的许多手工运维工作（如主机监控脚本、应用监控脚本、故障恢复脚本等）。

<details>

<summary><mark style="color:purple;"><strong>示例</strong></mark></summary>

```yaml
apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx-rc
spec:
  replicas: 2
  selector:
    app: nginx-rc
  template:
    metadata:
      name: nginx-rc
      labels:
        app: nginx-rc
    spec:
      containers:
        - name: nginx-rc
          image: nginx:1.14.2
          ports:
            - containerPort: 80
```

</details>

{% hint style="info" %}
**在运行时，可以通过修改 RC 的副本数量，来实现 Pod 的动态缩放（Scaling）功能，这可以通过执行 kubectl scale 命令来一键完成：**

```properties
kubectl scale rc redis-slave --replicas=3
```

{% endhint %}

{% hint style="warning" %} <mark style="color:orange;">**删除 RC 并不会影响通过该 RC 已创建好的 Pod**</mark><mark style="color:orange;">。</mark>为了删除所有 Pod，可以设置 replicas 的值为0，然后更新该 RC。

另外，**kubectl 提供了 stop 和 delete 命令来一次性删除 RC 和 RC 控制的全部 Pod。**
{% endhint %}

{% hint style="success" %} <mark style="background-color:green;">**滚动升级**</mark>

**应用升级时，通常会使用一个新的容器镜像版本替代旧版本**。如果希望系统进行平滑升级，比如在当前系统中有 10 个对应的旧版本的 Pod，则最佳的系统升级方式是旧版本的 Pod 每停止一个，就同时创建一个新版本的Pod，在整个升级过程中此消彼长，而运行中的 Pod 数量始终是 10 个，几分钟以后，当所有的 Pod 都已经是新版本时，系统升级完成。

通过 RC 机制，Kubernetes 很容易就实现了这种高级实用的特性，被称为<mark style="color:orange;">**“滚动升级”**</mark>（Rolling Update）。
{% endhint %}
