0%

控制器 - ReplicaSet

控制器概述及控制器-ReplicaSet

控制器_概述

概述

Pod(容器组)是 Kubernetes 中最小的调度单元,可以通过 kubectl 直接创建一个 Pod。Pod 本身并不能自愈(self-healing)。如果一个 Pod 所在的 Node (节点)出现故障,或者调度程序自身出现故障,Pod 将被删除;同理,当因为节点资源不够或节点维护而驱逐 Pod 时,Pod 也将被删除。

Kubernetes 通过引入 Controller(控制器)的概念来管理 Pod 实例。在 Kubernetes 中,创建 Pod 始终应该用 Controller 来创建 Pod,而不是直接创建 Pod。

Pod控制器是用于实现管理 Pod 的中间层,确保 Pod 资源符合预期的状态,Pod 的资源出现故障时,会尝试进行重启,当根据重启策略无效,则会重新新建 Pod 的资源.。

控制器可以提供如下特性:

  • 水平扩展(运行 Pod 的多个副本)
  • rollout(版本更新)
  • self-healing(故障恢复) 例如:当一个节点出现故障,控制器可以自动地在另一个节点调度一个配置完全一样的 Pod,以替换故障节点上的 Pod。

控制器类型

  • 控制器-ReplicaSet: 代用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。
    ReplicaSet主要三个组件组成:
      (1)用户期望的pod副本数量
      (2)标签选择器,判断哪个pod归自己管理
      (3)当现存的pod数量不足,会根据pod资源模板进行新建
    帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制器,而是使用Deployment。
  • 控制器-Deployment: 工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能,还提供声明式配置。
  • 控制器-StatefulSet: 周期性任务控制,不需要持续后台运行。
  • 控制器-DaemonSet: 用于确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任务。比如ELK服务
    特性:服务是无状态的,服务必须是守护进程。
  • 控制器-Job: 只要完成就立即退出,不需要重启或重建。
  • 控制器CronJob: 周期性任务控制,不需要持续后台运行。

控制器 - ReplicaSet

Kubernetes 中,ReplicaSet 用来维护一个数量稳定的 Pod 副本集合,可以保证某种定义一样的 Pod 始终有指定数量的副本数在运行。

ReplicaSet的工作方式

ReplicaSet的定义中,包含:

  • selector: 用于指定哪些 Pod 属于该 ReplicaSet 的管辖范围
  • replicas: 副本数,用于指定该 ReplicaSet 应该维持多少个 Pod 副本
  • template: Pod模板,在 ReplicaSet 使用 Pod 模板的定义创建新的 Pod

ReplicaSet 控制器将通过创建或删除 Pod,以使得当前 Pod 数量达到 replicas 指定的期望值。ReplicaSet 创建的 Pod 中,都有一个字段 metadata.ownerReferences 用于标识该 Pod 从属于哪一个 ReplicaSet。

ReplicaSet 通过 selector 字段的定义,识别哪些 Pod 应该由其管理。如果 Pod 没有 ownerReference 字段,或者 ownerReference 字段指向的对象不是一个控制器,且该 Pod 匹配了 ReplicaSet 的 selector,则该 Pod 的 ownerReference 将被修改为 该 ReplicaSet 的引用。

何时使用 ReplicaSet

ReplicaSet 用来维护一个数量稳定的 Pod 副本集合。Deployment 可以管理 ReplicaSet,并提供声明式的更新等。因此,推荐用户总是使用 Deployment,而不是直接使用 ReplicaSet,除非需要一些自定义的更新应用程序的方式,或者完全不更新应用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# modify replicas according to your case
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: nginx
image: nginx

ReplicaSet 副本集的主要几个字段有:

  • selector 确定哪些 Pod 属于该副本集
  • replicas 副本集应该维护几个 Pod 副本(实例)
  • template Pod 的定义

副本集将通过创建、删除 Pod 容器组来确保符合 selector 选择器的 Pod 数量等于 replicas 指定的数量。当符合 selector 选择器的 Pod 数量不够时,副本集通过使用 template 中的定义来创建 Pod。

执行命令以创建该 YAML 对应的 ReplicaSet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[root@k8s-master k8s-yamls]# kubectl apply -f rs.yaml 
replicaset.apps/frontend created
[root@k8s-master k8s-yamls]# kubectl get rs
NAME DESIRED CURRENT READY AGE
frontend 3 3 1 10s


[root@k8s-master k8s-yamls]# kubectl describe rs/frontend
Name: frontend
Namespace: default
Selector: tier=frontend
Labels: app=guestbook
tier=frontend
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"ReplicaSet","metadata":{"annotations":{},"labels":{"app":"guestbook","tier":"frontend"},"name":"frontend",...
Replicas: 3 current / 3 desired
Pods Status: 2 Running / 1 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: tier=frontend
Containers:
nginx:
Image: nginx
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message

---- ------ ---- ---- -------

Normal SuccessfulCreate 2m58s replicaset-controller Created pod: frontend-fsfrx
Normal SuccessfulCreate 2m58s replicaset-controller Created pod: frontend-72vr4
Normal SuccessfulCreate 2m58s replicaset-controller Created pod: frontend-zp2k8

ReplicaSet的定义

与其他 Kubernetes 对象一样,ReplicaSet需要的字段有:

  • apiVersion:apps/v1
  • kind:始终为 ReplicaSet
  • metadata
  • spec: ReplicaSet 的详细定义

PodTemplate

.spec.template 字段是一个 Pod Template,为必填字段,且其中必须定义 .spec.template.metadata.labels 字段。在前面的ReplicaSet例子中,定义了 label 为 tier: frontend。请小心该字段不要与其他控制器的 selector 重合,以免这些控制器尝试接管该 Pod。

1
.spec.template.spec.restartPolicy` 的默认值为 `Always

Pod Selector

.spec.selector 字段为一个标签选择器,用于识别可以接管哪些 Pod。在前面的例子中,标签选择器为:

1
2
matchLabels:
tier: frontend

在 ReplicaSet 中, .spec.template.metadata.labels 必须与 .spec.selector 匹配,否则将不能成功创建 ReplicaSet。

如果两个 ReplicaSet 指定了相同的 .spec.selector 但是不同的 .spec.template.metadata.labels 和不同的 .spec.tempalte.spec 字段,两个 ReplicaSet 都将忽略另外一个 ReplicaSet 创建的 Pod

Replicas

.spec.replicas 字段用于指定同时运行的 Pod 的副本数。ReplicaSet 将创建或者删除由其管理的 Pod,以便使副本数与该字段指定的值匹配。

如果不指定,默认值为 1

使用 ReplicaSet

删除ReplicaSet及其Pod

使用 kubectl delete 可删除 ReplicaSet, Garbage Collector将自动删除该 ReplicaSet 所有从属的 Pod。

只删除ReplicaSet

使用 kubectl delete --cascade=false 命令,可以删除 ReplicaSet,但是仍然保留其 Pod。

一旦原来的 ReplicaSet 被删除,可以创建新的 ReplicaSet 作为替代。只要新 ReplicaSet 的 .spec.selector 字段与旧 ReplicaSet 的 .spec.selector 字段相同,则新的 ReplicaSet 将接管旧 ReplicaSet 遗留下来的 Pod。但是,新的 ReplicaSet 中定义的 .spec.template 对遗留下来的 Pod 不会产生任何影响。

将Pod从ReplicaSet中隔离

修改 Pod 的标签,可以使 Pod 脱离 ReplicaSet 的管理。这个小技巧在如下场景可能非常有用:

  • 将 Pod 从 Service 中移除,以便 Debug 或者做数据恢复

通过这种方式从 ReplicaSet 移除了 Pod 之后,ReplicaSet 将立刻自动创建一个新的 Pod 以维持其指定的 replicas 副本数。

ReplicaSet的自动伸缩

可以使用 Horizontal Pod Autoscalers(HPA) 对 ReplicaSet 执行自动的水平伸缩。下面例子中的 HPA 可以用来对前面例子中的 ReplicaSet 执行自动的水平伸缩:

1
2
3
4
5
6
7
8
9
10
11
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: frontend-scaler
spec:
scaleTargetRef:
kind: ReplicaSet
name: frontend
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 50

此外,也可以使用 kubectl autoscale 命令达到相同的效果:

1
kubectl autoscale rs frontend --max=10