一、先理解 RC 和 RS 的定位

ReplicationController,简称 RC,是 Kubernetes 早期用来维护 Pod 副本数的控制器;ReplicaSet,简称 RS,则是它的增强版。两者的核心目标都很明确:让集群里始终保持期望数量的 Pod 在运行。

它们最重要的价值有两点:

  • 当副本数少于期望值时,自动补齐 Pod
  • 当副本数多于期望值时,自动删除多余 Pod

也就是说,手工创建的 Pod 被删掉就真的没了,而被 RC 或 RS 管理的 Pod 被删掉后,控制器会继续拉起新的实例。

二、ReplicationController 如何保证副本数

1.1 工作机制

RC 会持续监听与自身 selector 匹配的 Pod 数量。数量不够就创建,数量超了就回收,因此它非常适合演示“声明式副本控制”这件事。

一个最小可用的 RC 示例可以写成这样:

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 create -f rc.yml
kubectl describe replicationcontroller/nginx
kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name}

这里最关键的是 selectortemplate.metadata.labels 必须能对应上,否则控制器找不到自己要维护的 Pod。

1.2 RC 的局限

RC 今天已经很少在生产环境直接使用,原因不是它不能工作,而是它的能力已经被更现代的对象替代。尤其是在选择器能力、与发布控制器协同、版本演进等方面,RC 都显得偏旧。

三、ReplicaSet 比 RC 强在哪里

ReplicaSet 本质上是 RC 的下一代实现,它保留了“副本数控制”的核心能力,同时把标签选择器做得更强。除了简单的 matchLabels,它还支持更灵活的集合式选择逻辑,因此更适合被更高层对象复用。

一个常见的 RS 示例:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3

创建后可以直接观察 Pod:

kubectl create -f rs.yml
kubectl get pods

ReplicaSet 还有两个容易忽略的点:

  • 它会通过 Pod 的 ownerReferences 建立归属关系
  • 如果发现一个没有控制器归属、但又命中自己 selector 的 Pod,ReplicaSet 可能会“接管”它

这也是为什么在生产环境里,selector 设计一定要谨慎,避免错误接管。

四、为什么生产里更多看到 Deployment

虽然 RC 和 RS 都能直接用,但在真实业务里,更常见的做法是让 Deployment 去管理 ReplicaSet,再由 ReplicaSet 去管理 Pod。这样一来,副本控制、滚动更新、版本历史和回滚能力就被串起来了。

可以把三者理解成这样:

  • RC:早期副本控制器,了解即可
  • RS:现代副本控制器,通常作为 Deployment 的底层实现
  • Deployment:面向无状态应用的主流发布对象

五、什么时候还需要直接接触 ReplicaSet

大多数时候你不会手写 ReplicaSet,但你依然需要认识它,因为:

  • kubectl get rs 是排查 Deployment 发布问题时的重要视角
  • rollout 期间新旧版本的切换,本质上就是新旧 ReplicaSet 的交替
  • 看懂 ReplicaSet,才能真正看懂 Deployment 的工作方式

一句话总结:RC 是历史概念,RS 是底层控制器,而 Deployment 才是你在无状态应用发布中最应该熟练掌握的入口。