ReplicaSet

In Kubernetes, a controller is a control loop (in robotics and automation, a control loop is a non-terminating loop that regulates the state of a system) that watches the state of a cluster and makes or requests changes when needed. Each controller tries to move the current cluster state closer to the desired state.

A ReplicaSet is one of Kubernetes’ controllers. At any given time, a ReplicaSet maintains a stable set of replica Pods. It is typically used to guarantee the availability of a specified number of identical Pods.

ReplicaSets are the successors to ReplicationControllers. Both serve the same purpose and behave similarly. The difference is that ReplicationControllers do not support set-based selectors. For this reason, ReplicaSets are preferred over ReplicationControllers.

How to Create a ReplicaSet?

Below is an example ReplicaSet manifest. The source file is available at: https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/replica-set/web-server.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: web-server
spec:
replicas: 3 # 应该同时运行多少个pod,默认为1
selector: # label选择器
matchLabels:
tier: nginx
template: # pod 模板
metadata:
labels: # 必须有label,并且这个label必须匹配 spec.selector,否则将会被API拒绝
tier: nginx
spec:
containers:
- name: nginx
image: nginx

Run the following command to create a ReplicaSet:

1
kubectl apply -f https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/replica-set/web-server.yaml

The result is shown below:
example

When Should You Use a ReplicaSet?

A ReplicaSet ensures that a specified number of Pod replicas are running at any given time. However, a Deployment is a higher-level concept that manages ReplicaSets and provides declarative updates to Pods along with many other useful features. Therefore, unless you need custom update orchestration or no updates at all, it is recommended to use a Deployment instead of a ReplicaSet directly.

How Does a ReplicaSet Manage Pods?

A ReplicaSet uses a Pod template to create new Pods.

All Pods managed by a ReplicaSet have a metadata.ownerReferences field that records the identifying information of the ReplicaSet. This is the link from the ReplicaSet to its Pods — through this link, the ReplicaSet knows the state of the Pods it maintains and plans accordingly. In the example above, a ReplicaSet named web-server was created. Below is the metadata of one of the Pods created by that ReplicaSet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
metadata:
creationTimestamp: "2020-02-11T13:52:23Z"
generateName: web-server-
labels:
tier: nginx
name: web-server-jqxfq
namespace: default
ownerReferences:
- apiVersion: apps/v1
blockOwnerDeletion: true
controller: true
kind: ReplicaSet
name: web-server
uid: 330e32af-f027-48f4-a3c0-f2f16a661d3d
resourceVersion: "1468260"
selfLink: /api/v1/namespaces/default/pods/web-server-jqxfq
uid: 41fedd1a-1ed0-4fa6-a74a-fbbcb2ece16e

A ReplicaSet Acquires New Pods via Its Selector

If a new Pod has no ownerReferences, or its ownerReferences does not point to a controller, and it matches a ReplicaSet’s selector, it will be immediately acquired by that ReplicaSet.

First, create a Pod named nginx-pod with a label tier: nginx. Its manifest is as follows:

1
2
3
4
5
6
7
8
9
10
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
tier: nginx
spec:
containers:
- name: nginx
image: nginx
1
kubectl apply -f https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/replica-set/nginx-pod.yaml

Then create the web-server ReplicaSet from the example above:

1
kubectl apply -f https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/replica-set/web-server.yaml

The result is shown below:
example3

If we delete this ReplicaSet, will the previously created nginx-pod also be deleted?

1
kubectl delete rs web-server

The result is shown below:
delete-rs

When .spec.selector Is the Same but .spec.template.metadata.labels and .spec.template.spec Differ

In the example above, a ReplicaSet named web-server was created. Now let’s create a second ReplicaSet named web-server-2 with the following manifest:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: web-server-2
spec:
replicas: 3
selector:
matchLabels:
tier: nginx
template:
metadata:
labels:
app: nginx
tier: nginx
spec:
containers:
- name: nginx
image: nginx

Deploy the manifest:

1
kubectl apply -f https://raw.githubusercontent.com/chengqing-su/kubernetes-learning/master/replica-set/web-server-2.yaml

The result is shown below:
example2
Conclusion: When two ReplicaSets share the same .spec.selector but differ in .spec.template.metadata.labels and .spec.template.spec, each ReplicaSet will ignore the Pods created by the other.