【云原生】ReplicaSet控制器详解

avatar
作者
猴君
阅读量:0

ReplicaRet

文章目录

一、ReplicaSet介绍

1.1、介绍

  • ReplicaRet简称RS的目的是维护一组在任何时候都处于运行状态的Pod副本的稳定集合。因此,它通常用来保证给定数量的、完全相同的Pod的可用性。

1.2、ReplicaSet的工作原理

  • ReplicaSet是通过一组字段来定义的,包括一个用来识别可获得的Pod的集合选择标签、一个用来表明应该维护的副本个数的数值、一个用来指定应该创建新的Pod以满足副本个数条件时要使用的Pod的模板等等。每个ReplicaSet都通过根据需要创建和删除Pod以使得副本个数达到期望值,进而实现其存在价值。当ReplicaSet需要创建新的Pod 时,会使用所提供得Pod模板。
  • ReplicaSet通过Pod上的metadata.ownerReferences字段连接到附属Pod,该字段给出当前对象得属主资源。ReplicaSet所获得得Pod都在其ownerReferneces字段中包含了属主ReplicaSet的标识信息。正是通过这一连接,ReplicaSet知道它所维护的Pod的状态,并据此计划其操作行为。
  • ReplicaSet使用其选择标签来辨识要获得的Pod的集合。如果某个Pod没有OwnerReference或则其OwnerReference不是一个控制器,且其匹配到某个ReplicaSet的选择算符,则该Pod立即被此ReplicaSet获得。

1.3、何时使用ReplicaSet

  • ReplicaSet确保何时时间都有指定熟练的Pod副本在运行。然而,Deployment是一个更高级的概念,它管理ReplicaSet,并向Pod提供声明式的更新以及许多其他有用的功能。因此,我们建议使用Deployment而不是直接使用ReplicaSet,除非你需要自定义更新业务芮城或根据不需要更新。
  • 这实际上意味着,你可能永远不需要操作ReplicaSet对象:而是使用Deployment,并在spec部署定义你的引用。

二、实战

2.1、示例

[root@master ~]# cat rs.yaml  apiVersion: "v1" kind: Namespace metadata:   name: nginx-latest  ---  apiVersion: "apps/v1" kind: ReplicaSet metadata:   name: frontend   namespace: nginx-latest   labels:     app: guestbook     tier: frontend spec:   # 按照你的实际情况修改副本数   replicas: 3   # 定义标签选择:表示这个 ReplicaSet 将管理标签带有 tier=frontend 的Pod    # 可以通过 kubectl get pod -A l tier=frontend 查看带有此标签的Pod   selector:     matchLabels:       tier: frontend   # 定义容器模板   template:     metadata:       labels:         tier: frontend     spec:       # 只要容器退出就自动重启       restartPolicy: Always       containers:       - name: nginx-80         image: nginx:latest         # 定义拉取策略         imagePullPolicy: IfNotPresent 
  • 将此清单保存到rs.yaml中,并将其提交到kubernetes集群,就能创建yaml文件所定义的ReplicaSet及其管理的Pod
[root@master ~]# kubectl apply -f rs.yaml  
  • 你可以通过下面的命令查看被部署的ReplicaSet
[root@master ~]# kubectl get rs -n nginx-latest  NAME       DESIRED   CURRENT   READY   AGE frontend   3         3         3       65s 
  • 你也可以通过以下命令获取ReplicaSet的详细信息
[root@master ~]# kubectl describe rs -n nginx-latest  Name:         frontend Namespace:    nginx-latest Selector:     tier=frontend Labels:       app=guestbook               tier=frontend Annotations:  <none> Replicas:     3 current / 3 desired Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template:   Labels:  tier=frontend   Containers:    nginx-80:     Image:        nginx:latest     Port:         <none>     Host Port:    <none>     Environment:  <none>     Mounts:       <none>   Volumes:        <none> Events:   Type    Reason            Age    From                   Message   ----    ------            ----   ----                   -------   Normal  SuccessfulCreate  4m42s  replicaset-controller  Created pod: frontend-qb825   Normal  SuccessfulCreate  4m42s  replicaset-controller  Created pod: frontend-vb77t   Normal  SuccessfulCreate  4m42s  replicaset-controller  Created pod: frontend-ww8g9 
  • 最后可以查看启动了的Pod的集合
[root@master ~]# kubectl get pod -n nginx-latest  NAME             READY   STATUS    RESTARTS   AGE frontend-qb825   1/1     Running   0          5m27s frontend-vb77t   1/1     Running   0          5m27s frontend-ww8g9   1/1     Running   0          5m27s 
  • 你也可以通过以下命令以YAML格式输出Pod的详细信息,输出将类似这样,frontend ReplicaSet的信息被设置在metadata的ownerReferences字段中:
[root@master ~]# kubectl get pod frontend-qb825 -n nginx-latest -o yaml apiVersion: v1 kind: Pod metadata:   creationTimestamp: "2024-07-25T08:39:51Z"   generateName: frontend-   labels:     tier: frontend   name: frontend-qb825   namespace: nginx-latest ################################################################   ownerReferences:   - apiVersion: apps/v1     blockOwnerDeletion: true     controller: true     kind: ReplicaSet     name: frontend     uid: c0f64a9f-9032-470b-840e-17c93c392d3d ################################################################   resourceVersion: "5931"   uid: 2897d78c-1646-401f-bdc0-c5b146028645 spec:   containers:   - image: nginx:latest     imagePullPolicy: IfNotPresent     name: nginx-80     resources: {} ... 

三、非模板Po的获得

  • 尽管你完全可以直接创建裸的Pod,强烈建议你确保这些裸的Pod并不包含可能与你的某个ReplicaSet的选择算符匹配的标签。原因在于ReplicaSet并不仅限于拥有在其模板中设置的Pod,只要创建的裸Pod的标签和ReplicaSet标签一样,那么这个裸Pod将由ReplicaSet管理。

  • 在以下清单中指定这些裸Pod:

[root@master ~]# cat pod.yaml  apiVersion: "v1" kind: Pod  metadata:   name: pod1   namespace: nginx-latest   labels:     tier: frontend spec:   containers:   - name: hello1     image: nginx     # 容器十分钟后自动退出     command: ["/bin/sh","-c","sleep 600"]   ---  apiVersion: "v1" kind: Pod  metadata:   name: pod2   namespace: nginx-latest   labels:     tier: frontend spec:   containers:   - name: hello2     image: nginx      # 容器十分钟后自动退出     command: ["/bin/sh","-c","sleep 600"] 
  • 由于这些Pod没有控制器(Controller,或其他对象)作为其属主引用,并且其标签与frontend ReplicaSet的标签匹配,他们会立即被该ReplicaSet获取。
  • 假定你在frontend ReplicaSet已经被部署之后创建Pod,并且你已经在ReplicaSet中设置了其初始的Pod的腹板以满足其副本计数需要:
[root@master ~]# kubectl apply -f pod.yaml 
  • 新的Pod会被该ReplicaSet获取,并立即被ReplicaSet终止,因为它们的存在会使得ReplicaSet中Pod个数超出其期望值。
  • 取回Pod
  • 输出显示新的Pod或者已经被终止,或者处于终止过程中:
[root@master ~]# kubectl get pod -n nginx-latest  NAME             READY   STATUS        RESTARTS   AGE frontend-qb825   1/1     Running       0          24m frontend-vb77t   1/1     Running       0          24m frontend-ww8g9   1/1     Running       0          24m pod1             1/1     Terminating   0          35s pod2             1/1     Terminating   0          35s 
  • 如果你先创建Pod
# 先把之前创建的 ReplicaSet删除 # 提示:因为pod的标签和ReplicaSet的标签一样,所以删除ReplicaSet就将会删除Pod [root@master ~]# kubectl delete -f rs.yaml 
# Pod需要在顶部额外添加名称空间 [root@master ~]# cat pod.yaml  apiVersion: "v1" kind: Namespace metadata:   name: nginx-latest 
[root@master ~]# kubectl apply -f pod.yaml 
  • 之后再创建ReplicaSet
[root@master ~]# kubectl apply -f rs.yaml 
  • 你会看到ReplicaSet已经获得了该Pod,并仅根据其规约创建新的Pod,直到新的Pod和原来的Pod的总数达到其预期个数。这时取回Pod列表
[root@master ~]# kubectl get pod -n nginx-latest  NAME             READY   STATUS    RESTARTS   AGE frontend-zrj69   1/1     Running   0          67s pod1             1/1     Running   0          94s pod2             1/1     Running   0          94s 

四、编写ReplicaSet的清单注意事项

4.1、编写注意事项

  • 与所有其他Kubernetes API对象一样,ReplicaSet也需要apiVersionkind、和metadata字段。对于ReplicaSet而言,其kind始终是Replicaset
kind: ReplicaSet 
  • 当控制平台为ReplicaSet创建的新的Pod时,ReplicaSet的.metadata.name是命名这些Pod的部分基础。ReplicaSet的名称必须是一个合法的DNS 子域值,但这可能对Pod的主机名产生以外的结果。为获得最佳兼容性,名称应遵循更严格的DNS 标签规则。
  • ReplicaSet也需要.spec部分
metadata:   name: frontend 

4.2、Pod模板

  • .spec.template是一个Pod模板,要求设置标签。在rs.yaml示例中,我们指定了标签tier: frontend。注意不要将标签与其他控制器的选择标签重叠,否则那些控制器会尝试收养此Pod。
template:     metadata:       labels:         tier: frontend 
  • 对于模板的重启策略字段,.spec.template.spec.restartPolicy,唯一允许的取值是Always,这也是默认值。
spec:   template:     spec:       imagePullPolicy: IfNotPresent 

4.3、Pod选择标签

  • .spec.selector字段是一个标签选择算符。如前文中所讨论的,这些是用来标识要被获取的Pod的标签。在签名的rs.yaml示例中,选择算符为:
  • 在ReplicaSet中,.spec.template.metadata.labels的值必须与spec.selector值相匹配,是否该配置会被API拒绝
matchLabels:       tier: frontend                   metadata:       labels:         tier: frontend 

4.4、ReplicaSet扩缩容

  • 你可以通过设置.spec.replicas来指定要同时运行的Pod的个数。
  • ReplicaSet创建、删除Pod以与此值匹配
  • 如果你没有指定.spec.replicas,那么默认值为1,也就是容器1个Pod
spec:   # 按照你的实际情况修改副本数   replicas: 3 

4.5、删除ReplicaSet

[root@master ~]# kubectl delete -f rs.yaml 

4.6、只删除ReplicaSet

  • 你可以只删除ReplicaSet而不影响它的各个Pod,方法是使用kubectl delete命令并设置--cascade=orphan选项
[root@master ~]# kubectl delete rs frontend --cascade=orphan -n nginx-latest 
  • 查看ReplicaSet将看到如下内容
[root@master ~]# kubectl get rs -n nginx-latest  
  • 查看Pod是否被连着ReplicaSet一起删除
  • 由此可见,我们删除了ReplicaSet控制器,但是它所管理的Pod并没有被删除。
[root@master ~]# kubectl get pod -n nginx-latest  NAME             READY   STATUS    RESTARTS   AGE frontend-582rl   1/1     Running   0          3m22s frontend-rqw86   1/1     Running   0          3m22s frontend-xxcnh   1/1     Running   0          3m22s 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!