Skip to content

ReplicaSet

ReplicaSet

img

目录

[toc]

1、ReplicaSet

img

假如我们现在有一个 Pod 正在提供线上的服务,我们来想想一下我们可能会遇到的一些场景:

  • 某次运营活动非常成功,网站访问量突然暴增

  • 运行当前 Pod 的节点发生故障了,Pod 不能正常提供服务了

第一种情况,可能比较好应对,活动之前我们可以大概计算下会有多大的访问量,提前多启动几个 Pod 副本,活动结束后再把多余的 Pod 杀掉,虽然有点麻烦,但是还是能够应对这种情况的。

第二种情况,可能某天夜里收到大量报警说服务挂了,然后起来打开电脑在另外的节点上重新启动一个新的 Pod,问题可以解决。

但是如果我们都人工的去解决遇到的这些问题,似乎又回到了以前刀耕火种的时代了是吧?如果有一种工具能够来帮助我们自动管理 Pod 就好了,Pod 挂了自动帮我在合适的节点上重新启动一个 Pod,这样是不是遇到上面的问题我们都不需要手动去解决了。

而 ReplicaSet 这种资源对象就可以来帮助我们实现这个功能,**ReplicaSet(RS)**的主要作用就是维持一组 Pod 副本的运行,保证一定数量的 Pod 在集群中正常运行,ReplicaSet 控制器会持续监听它所控制的这些 Pod 的运行状态,在 Pod 发送故障数量减少或者增加时会触发调谐过程,始终保持副本数量一致。

💘 实战:ReplicaSet测试-2022.12.14(成功测试)

  • 实验环境
bash
1、win10,vmwrokstation虚机;2、k8s集群:3台centos7.61810虚机,2个master节点,1个node节点k8sversion:v1.20CONTAINER-RUNTIME:containerd:v1.6.10
  • 实验软件(无)

  • 编写资源清单

和 Pod 一样我们仍然还是通过 YAML 文件来描述我们的 ReplicaSet 资源对象,如下 YAML 文件是一个常见的 ReplicaSet 定义:

yaml
# nginx-rs.yamlapiVersion:apps/v1kind:ReplicaSetmetadata:name:nginx-rsnamespace:defaultspec:replicas:3# 期望的 Pod 副本数量,默认值为1selector:# Label Selector,必须匹配Pod模板中的标签。matchLabels:app:nginxtemplate:# Pod 模板metadata:#Pod名称会根据rs的name自动生成labels:app:nginx#一定要包含上面的 matchLabels里面的标签。spec:containers:- name:nginximage:nginx:latest# latest标签最好别用在线上ports:- containerPort:80

上面的 YAML 文件结构和我们之前定义的 Pod 看上去没太大两样,有常见的 apiVersion、kind、metadata,在 spec 下面描述 ReplicaSet 的基本信息,其中包含3个重要内容:

  • replias:表示期望的 Pod 的副本数量

  • selector:Label Selector,用来匹配要控制的 Pod 标签,需要和下面的 Pod 模板中的标签一致

  • template:Pod 模板,实际上就是以前我们定义的 Pod 内容,相当于把一个 Pod 的描述以模板的形式嵌入到了 ReplicaSet 中来。

Pod 模板这个概念非常重要,因为后面我们讲解到的大多数控制器,都会使用 Pod 模板来统一定义它所要管理的 Pod。更有意思的是,我们还会看到其他类型的对象模板,比如Volume 的模板等。

上面就是我们定义的一个普通的 ReplicaSet 资源清单文件,ReplicaSet 控制器会通过定义的 Label Selector 标签去查找集群中的 Pod 对象:

img

  • 我们直接来创建上面的资源对象:
bash
[root@master1 ~]#kubectl apply -f nginx-rs.yamlreplicaset.apps/nginx-rscreated[root@master1 ~]#kubectl get rsNAMEDESIREDCURRENTREADYAGEnginx-rs33346s

通过查看 RS 可以看到当前资源对象的描述信息,包括DESIREDCURRENTREADY的状态值。

  • 创建完成后,可以利用如下命令查看下 Pod 列表:
bash
[root@master1 ~]#kubectl get po -l app=nginxNAMEREADYSTATUSRESTARTSAGEnginx-rs-7btxg1/1Running082snginx-rs-gfhzx1/1Running082snginx-rs-v8rrb1/1Running082s
  • 可以看到现在有 3 个 Pod,这 3 个 Pod 就是我们在 RS 中声明的 3 个副本,比如我们删除其中一个 Pod:
bash
[root@master1 ~]#kubectl delete pod nginx-rs-v8rrbpod"nginx-rs-v8rrb"deleted

然后再查看 Pod 列表:

bash
[root@master1 ~]#kubectl get po -l app=nginxNAMEREADYSTATUSRESTARTSAGEnginx-rs-7btxg1/1Running02m28snginx-rs-gfhzx1/1Running02m28snginx-rs-xxplf1/1Running028s

可以看到又重新出现了一个 Pod,这个就是上面我们所说的 ReplicaSet 控制器为我们做的工作,我们在 YAML 文件中声明了 3 个副本,然后现在我们删除了一个副本,就变成了两个,这个时候 ReplicaSet 控制器监控到控制的 Pod 数量和期望的 3 不一致,所以就需要启动一个新的 Pod 来保持 3 个副本,这个过程上面我们说了就是调谐的过程。

  • 同样可以查看 RS 的描述信息来查看到相关的事件信息:
bash
[root@master1 ~]#kubectl describe rs nginx-rsName:nginx-rsNamespace:defaultSelector:app=nginxLabels:<none>Annotations:<none>Replicas:3current/3desiredPodsStatus:3Running/0Waiting/0Succeeded/0FailedPodTemplate:Labels:app=nginxContainers:nginx:Image:nginxPort:80/TCPHostPort:0/TCPEnvironment:<none>Mounts:<none>Volumes:<none>Events:TypeReasonAgeFromMessage-------------------------NormalSuccessfulCreate3m31sreplicaset-controllerCreatedpod:nginx-rs-v8rrbNormalSuccessfulCreate3m31sreplicaset-controllerCreatedpod:nginx-rs-7btxgNormalSuccessfulCreate3m31sreplicaset-controllerCreatedpod:nginx-rs-gfhzxNormalSuccessfulCreate91sreplicaset-controllerCreatedpod:nginx-rs-xxplf[root@master1 ~]#

可以发现最开始通过 ReplicaSet 控制器创建了 3 个 Pod,后面我们删除了 Pod 后, ReplicaSet 控制器又为我们创建了一个 Pod,和上面我们的描述是一致的。

  • 如果这个时候我们把 RS 资源对象的 Pod 副本更改为 2 spec.replicas=2,这个时候我们来更新下资源对象:
bash
[root@master1 ~]#vim nginx-rs.yaml……spec:8replicas:2#修改pod副本数为29selector:10matchLabels:11app:nginx……[root@master1 ~]#kubectl apply -f nginx-rs.yamlreplicaset.apps/nginx-rsconfigured[root@master1 ~]#[root@master1 ~]#kubectl get rsNAMEDESIREDCURRENTREADYAGEnginx-rs2225m38s[root@master1 ~]#kubectl describe rs nginx-rsName:nginx-rsNamespace:defaultSelector:app=nginxLabels:<none>Annotations:<none>Replicas:2current/2desiredPodsStatus:2Running/0Waiting/0Succeeded/0FailedPodTemplate:Labels:app=nginxContainers:nginx:Image:nginxPort:80/TCPHostPort:0/TCPEnvironment:<none>Mounts:<none>Volumes:<none>Events:TypeReasonAgeFromMessage-------------------------NormalSuccessfulCreate5m43sreplicaset-controllerCreatedpod:nginx-rs-v8rrbNormalSuccessfulCreate5m43sreplicaset-controllerCreatedpod:nginx-rs-7btxgNormalSuccessfulCreate5m43sreplicaset-controllerCreatedpod:nginx-rs-gfhzxNormalSuccessfulCreate3m43sreplicaset-controllerCreatedpod:nginx-rs-xxplfNormalSuccessfulDelete19sreplicaset-controllerDeletedpod:nginx-rs-xxplf[root@master1 ~]#

可以看到 Replicaset 控制器在发现我们的资源声明中副本数变更为 2 后,就主动去删除了一个 Pod,这样副本数就和期望的始终保持一致了:

bash
[root@master1 ~]#kubectl get po -l app=nginxNAMEREADYSTATUSRESTARTSAGEnginx-rs-7btxg1/1Running06m12snginx-rs-gfhzx1/1Running06m12s
  • 我们可以随便查看一个 Pod 的描述信息可以看到这个 Pod 的所属控制器信息:
bash
[root@master1 ~]#kubectl get po -l app=nginxNAMEREADYSTATUSRESTARTSAGEnginx-rs-7btxg1/1Running06m50snginx-rs-gfhzx1/1Running06m50s[root@master1 ~]#kubectl describe pod nginx-rs-gfhzxName:nginx-rs-gfhzxNamespace:defaultPriority:0Node:node2/172.29.9.53StartTime:Mon,08Nov202121:30:03+0800Labels:app=nginxAnnotations:<none>Status:RunningIP:10.244.2.13IPs:IP:10.244.2.13ControlledBy:ReplicaSet/nginx-rs#从这里可以看到,这个pod是被ReplicaSet/nginx-rs控制;……[root@master1 ~]#
  • 另外被 ReplicaSet 持有的 Pod 有一个**metadata.ownerReferences****指针指向当前的 ReplicaSet,表示当前 Pod 的所有者,这个引用主要会被集群中的垃圾收集器使用以清理失去所有者的 Pod 对象。**这个 ownerReferences和数据库中的外键是不是非常类似。可以通过将 Pod 资源描述信息导出查看:
yaml
[root@master1 ~]#kubectl get po -l app=nginxNAME READY STATUS RESTARTS AGEnginx-rs-7btxg 1/1 Running 0 8m48snginx-rs-gfhzx 1/1 Running 0 8m48s[root@master1 ~]#kubectl edit pod nginx-rs-gfhzx或者[root@master1 ~]#kubectl get po nginx-rs-gfhzx -oyamlownerReferences:- apiVersion:apps/v1blockOwnerDeletion:truecontroller:truekind:ReplicaSetname:nginx-rsuid:e1b9d63b-6be5-4a9f-b565-1d8eea92c727

我们可以看到 Pod 中有一个 metadata.ownerReferences的字段指向了 ReplicaSet 资源对象。如果要彻底删除 Pod,我们就只能删除 RS 对象:

bash
[root@master1 ~]#kubectl delete rs nginx-rsreplicaset.apps"nginx-rs"deleted[root@master1 ~]#kubectl get rs,podNoresourcesfoundindefaultnamespace.[root@master1 ~]#或者:执行kubectldelete-fnginx-rs.yaml或者:你如果想彻底删除pod,就需要把rs给删除掉或者把rs里的副本数改为0;

这就是 ReplicaSet 对象的基本使用。

  • 注意,我们直接修改nginx-rs.yaml里的镜像版本后,是没办法改变pod里的镜像版本的,即:RS不支持应用的更新操作
bash
# 查看当前应用镜像版本[root@master1 ~]#kubectl get po -l app=nginxNAMEREADYSTATUSRESTARTSAGEnginx-rs-dfkqr1/1Running038snginx-rs-ml7gc1/1Running038snginx-rs-p2p6q1/1Running038s[root@master1 ~]#kubectl get po ginx-rs-dfkqr -oyaml……spec:containers:-image:nginx:latest……[root@master1 ~]#kubectl get rs nginx-rs -oyaml……spec:containers:-image:nginx:latest……#来执行一次更新应用操作[root@master1 ~]#vim nginx-rs.yaml……spec:containers:-name:nginximage:nginx:1.7.9# 修改为1.7.9……然后执行apply操作:[root@master1 ~]#kubectl apply -f nginx-rs.yaml replicaset.apps/nginx-rsconfigured#观察效果#可以看到,pod并没有被重建,且其nginx镜像版本未发生变化[root@master1 ~]#kubectl get po -l app=nginxNAMEREADYSTATUSRESTARTSAGEnginx-rs-dfkqr1/1Running04m55snginx-rs-ml7gc1/1Running04m55snginx-rs-p2p6q1/1Running04m55s[root@master1 ~]#kubectl get po nginx-rs-dfkqr -oyaml……spec:containers:-image:nginx:latest……[root@master1 ~]#kubectl get rsNAMEDESIREDCURRENTREADYAGEnginx-rs3335m52s#rs导出的资源清单里pod模板里的惊险版本发生了变化。[root@master1 ~]#kubectl get rs -oyaml……spec:containers:-image:nginx:1.7.9……

实验到此结束。😘

Replication Controller(了解即可)

Replication Controller 简称 RC,实际上 RC 和 RS 的功能几乎一致,RS 算是对 RC 的改进,目前唯一的一个区别就是 RC 只支持基于等式的 selector(env=dev或environment!=qa),但 RS 还支持基于集合的 selector(version in (v1.0,v2.0)),这对复杂的运维管理就非常方便了。

比如上面资源对象如果我们要使用 RC 的话,对应的 selector 是这样的:

plain
selector:app:nginx

RC 只支持单个 Label 的等式,而 RS 中的 Label Selector 支持 matchLabelsmatchExpressions两种形式:

yaml
selector:matchLabels:app:nginx---selector:matchExpressions:# 该选择器要求 Pod 包含名为 app 的标签- key:appoperator:Invalues:# 并且标签的值必须是 nginx- nginx

img

总的来说 RS 是新一代的 RC,所以以后我们不使用 RC,直接使用 RS 即可,他们的功能都是一致的,**但是实际上在实际使用中我们也不会直接使用 RS,而是使用更上层的类似于 Deployment 这样的资源对象。**注意,一般,还是matchLabels用的多一些。

关于我

我的博客主旨:

  • 排版美观,语言精炼;
  • 文档即手册,步骤明细,拒绝埋坑,提供源码;
  • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

🍀 微信二维码

x2675263825 (舍得), qq:2675263825。

img

🍀 微信公众号

《云原生架构师实战》

img

🍀 语雀

https:

版权:此文章版权归 One 所有,如有转载,请注明出处!

链接:可点击右上角分享此页面复制文章链接

上次更新时间:

最近更新