【云原生】ReplicaSet控制器详解

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、示例

bash 复制代码
[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
bash 复制代码
[root@master ~]# kubectl apply -f rs.yaml 
  • 你可以通过下面的命令查看被部署的ReplicaSet
bash 复制代码
[root@master ~]# kubectl get rs -n nginx-latest 
NAME       DESIRED   CURRENT   READY   AGE
frontend   3         3         3       65s
  • 你也可以通过以下命令获取ReplicaSet的详细信息
bash 复制代码
[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的集合
bash 复制代码
[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字段中:
bash 复制代码
[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:

bash 复制代码
[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的腹板以满足其副本计数需要:
bash 复制代码
[root@master ~]# kubectl apply -f pod.yaml
  • 新的Pod会被该ReplicaSet获取,并立即被ReplicaSet终止,因为它们的存在会使得ReplicaSet中Pod个数超出其期望值。
  • 取回Pod
  • 输出显示新的Pod或者已经被终止,或者处于终止过程中:
bash 复制代码
[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
bash 复制代码
# 先把之前创建的 ReplicaSet删除
# 提示:因为pod的标签和ReplicaSet的标签一样,所以删除ReplicaSet就将会删除Pod
[root@master ~]# kubectl delete -f rs.yaml
bash 复制代码
# Pod需要在顶部额外添加名称空间
[root@master ~]# cat pod.yaml 
apiVersion: "v1"
kind: Namespace
metadata:
  name: nginx-latest
bash 复制代码
[root@master ~]# kubectl apply -f pod.yaml
  • 之后再创建ReplicaSet
bash 复制代码
[root@master ~]# kubectl apply -f rs.yaml
  • 你会看到ReplicaSet已经获得了该Pod,并仅根据其规约创建新的Pod,直到新的Pod和原来的Pod的总数达到其预期个数。这时取回Pod列表
bash 复制代码
[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
bash 复制代码
kind: ReplicaSet
  • 当控制平台为ReplicaSet创建的新的Pod时,ReplicaSet的.metadata.name是命名这些Pod的部分基础。ReplicaSet的名称必须是一个合法的DNS 子域值,但这可能对Pod的主机名产生以外的结果。为获得最佳兼容性,名称应遵循更严格的DNS 标签规则。
  • ReplicaSet也需要.spec部分
bash 复制代码
metadata:
  name: frontend

4.2、Pod模板

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

4.3、Pod选择标签

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

4.4、ReplicaSet扩缩容

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

4.5、删除ReplicaSet

bash 复制代码
[root@master ~]# kubectl delete -f rs.yaml

4.6、只删除ReplicaSet

  • 你可以只删除ReplicaSet而不影响它的各个Pod,方法是使用kubectl delete命令并设置--cascade=orphan选项
bash 复制代码
[root@master ~]# kubectl delete rs frontend --cascade=orphan -n nginx-latest
  • 查看ReplicaSet将看到如下内容
bash 复制代码
[root@master ~]# kubectl get rs -n nginx-latest 
  • 查看Pod是否被连着ReplicaSet一起删除
  • 由此可见,我们删除了ReplicaSet控制器,但是它所管理的Pod并没有被删除。
bash 复制代码
[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
相关推荐
魏 无羡6 小时前
linux CentOS系统上卸载docker
linux·kubernetes·centos
Karoku0667 小时前
【k8s集群应用】kubeadm1.20高可用部署(3master)
运维·docker·云原生·容器·kubernetes
木子Linux7 小时前
【Linux打怪升级记 | 问题01】安装Linux系统忘记设置时区怎么办?3个方法教你回到东八区
linux·运维·服务器·centos·云计算
凌虚8 小时前
Kubernetes APF(API 优先级和公平调度)简介
后端·程序员·kubernetes
探索云原生12 小时前
在 K8S 中创建 Pod 是如何使用到 GPU 的: nvidia device plugin 源码分析
ai·云原生·kubernetes·go·gpu
启明真纳12 小时前
elasticache备份
运维·elasticsearch·云原生·kubernetes
橙子家13 小时前
关于 K8s 的一些基础概念整理-补充【k8s系列之五】
k8s
jwolf214 小时前
基于K8S的微服务:一、服务发现,负载均衡测试(附calico网络问题解决)
微服务·kubernetes·服务发现
nangonghen14 小时前
在华为云通过operator部署Doris v2.1集群
kubernetes·华为云·doris·operator
会飞的土拨鼠呀16 小时前
chart文件结构
运维·云原生·kubernetes