Pod控制器(一)ReplicaSet

 

目录

1、关于Pod控制器

1.1Pod控制器概述

1.2 控制器与Pod对象

1.3 ReplicaSet控制器

1.3.1  ReplicaSet概述

1.3.2  创建ReplicaSet

1.3.3 ReplicaSet管控下的Pod对象

1.3.4  更新ReplicaSet控制器

1.3.5   删除ReplicaSet控制器资源


 

1、关于Pod控制器

我们可以把API Server类比成一个存储对象的数据库系统,它向客户端提供了API,并负责存储由用户创建的各种资源对象,至于各对象的当前状态如何才能符合用户期望的状态,则需要交由另一类称为控制器的组件来负责完成。Kubernetes提供了众多的控制器来管理各种类型的资源,如Node Lifecycle ControllerNamespace ControllerService ControllerDeployment Controller等,它们的功用几乎可以做到见名知义。创建完成后,每一个控制器对象都可以通过内部的和解循环 reconciliation loop),不间断地监控着由其负责的所有资源并确保其处于或不断地逼近用户定义的目标状态。

尽管能够由kubelet为其提供自愈能力,但在节点宕机时,自主式Pod对象的重建式自愈机制则需要由Pod控制器对象负责提供,并且由它来负责实现生命周期中的各类自动管理行为,如创建及删除等。

1.1Pod控制器概述

Master的各组件中,API Server仅负责将资源存储于etcd中,并将其变动通知给各相关的客户端程序,如kubeletkube-schedulerkube-proxykube-controller-manager等,kube-scheduler监控到处于未绑定状态的Pod对象出现时遂启动调度器为其挑选适配的工作节点,然而, Kubernetes的核心功能之一还在于要确保各资源对象的当前状态 status)以匹配用户期望的状态(spec),使当前状态不断地向期望状和解reconciliation)来完成容器应用管理,而这些则是kube-controller-manager的任务。kube-controller-manager是一个独立的单体守护进程,然而它包含了众多功能不同的控制器类型分别用于各类和解任务,如图5-1所示。

提示 Kubernetes 可用的控制器有 attachdetach 、bootstrapsigner clusterrole-aggregation cronjob csrapproving csrcleaner csrsigning daemonset deployment disruption endpoint garbagecollector horizontalpodautoscaling job namespace node persistentvolume-binder persistentvolume-expander podgc pvc- protection replicaset replication- controller resourcequota route service serviceaccount serviceaccount-token statefulset tokencleaner ttl 等数十种。
 

创建为具体的控制器对象之后,每个控制器均通过API Server提供的接口持续监控相关资源对象的当前状态,并在因故障、更新或其他原因导致系统状态发生变化时,尝试让资源的当前状态向期望状态迁移和逼近。简单来说,每个控制器对象运行一个和解循环负责状态和解,并将目标资源对象的当前状态写入到其status字段中。控制器的和解循环如图5-2所示。

List-WatchKubernetes实现的核心机制之一,在资源对象的状态发生变动时,由API Server负责写入etcd并通过水平触发(level-triggered机制主动通知给相关的客户端程序以确保其不会错过任何一个事件。控制器通过API Serverwatch接口实时监控目标资源对象的变动并执行和解操作,但并不会与其他控制器进行任何交互,甚至彼此之间根本就意识不到对方的存在。

工作负载(workload)一类的控制器资源类型包括ReplicationControllerReplicaSetDeploymentDaemonSetStatefulSetJobCronJob等,它们分别代表了一种类型的Pod控制器资源,后面的篇幅主要介绍各控制器的特性及其应用,不过StatefulSet控制器依赖于存储卷资源,因此它将单独在存储卷之后的章节中给予介绍。

 

1.2 控制器与Pod对象

Pod 控制器资源通过持续性地监控集群中运行着的 Pod 资源对象来确保受其管控的资源严格符合用户期望的状态,例如资源副本的数量要精 确符合期望等。通常,一个 Pod 控制器资源至少应该包含三个基本的组 成部分。
  • 标签选择器:匹配并关联Pod资源对象,并据此完成受其管控的Pod资源计数。
  • 期望的副本数:期望在集群中精确运行着的Pod资源的对象数量。
  • Pod模板:用于新建Pod资源对象的Pod模板资源。

注意:DaemonSet用于确保集群中的每个工作节点或符合条件的每个节点上都运行着一个Pod副本,而不是某个精确的数量值,因此不具有上面组成部分中的第二项。

例如,一个如图 5-3 所示的 Deployment 控制器资源使用的标签选择器为 “role=be-eshop” ,它期望相关的 Pod 资源副本数量精确为 3 个,少于 此数量的缺失部分将由控制器通过 Pod 模板予以创建,而多出的副本也 将由控制器负责终止及删除。
 

1.3 ReplicaSet控制器

1.3.1  ReplicaSet概述

ReplicaSet(简称RS)是Pod控制器类型的一种实现,用于确保由其管控的Pod对象副本数在任一时刻都能精确满足期望的数量。如图5-4示,ReplicaSet控制器资源启动后会查找集群中匹配其标签选择器的Pod资源对象,当前活动对象的数量与期望的数量不吻合时,多则删除,少则通过Pod模板创建以补足,等Pod资源副本数量符合期望值后即进入下一轮和解循环。

ReplicaSet的副本数量、标签选择器甚至是Pod模板都可以随时按需进行修改,不过仅改动期望的副本数量会对现存的Pod副本产生直接影响。修改标签选择器可能会使得现有的Pod副本的标签变得不再匹配,此时ReplicaSet控制器要做的不过是不再计入它们而已。另外,在创建完成后,ReplicaSet也不会再关注Pod对象中的实际内容,因此Pod模板的改动也只会对后来新建的Pod副本产生影响。

相比较于手动创建和管理 Pod 资源来说, ReplicaSet 能够实现以下功能。
  • 确保Pod资源对象的数量精确反映期望值:ReplicaSet需要确保由其控制运行的Pod副本数量精确吻合配置中定义的期望值,否则就会自动补足所缺或终止所余。
  • 确保Pod健康运行:探测到由其管控的Pod对象因其所在的工作节点故障而不可用时,自动请求由调度器于其他工作节点创建缺失的Pod副本
  • 弹性伸缩:业务规模因各种原因时常存在明显波动,在波峰或波谷期间,可以通过ReplicaSet控制器动态调整相关Pod资源对象的数量。 此外,在必要时还可以通过HPAHroizontalPodAutoscaler)控制器实现Pod资源规模的自动伸缩。

1.3.2  创建ReplicaSet

类似于Pod资源,创建ReplicaSet控制器对象同样可以使用YAMLJSON格式的清单文件定义其配置,而后使用相关的创建命令来完成资源创建。它也由kindapiVersionmetadataspecstatus5个一级字段组成,其中status为只读字段,因此需要在清单文件中配置的仅为前4个字段。它的spec字段一般嵌套使用以下几个属性字段。

  • replicas<integer>:期望的
  • selector<Object>:当前控制器匹配Pod对象副本的标签选择器,支持matchLabelsmatchExpressions两种匹配机制。
  • template<Object>:用于补足Pod副本数量时使用的Pod模板资源。
  • minReadySecond<integer>s:新建的Pod对象,在启动后的多长时间内如果其容器未发生崩溃等异常情况即被视为就绪;默认为0秒,表示一旦就绪性探测成功,即被视作可用。

[root@master ~]# vim replicaSet.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: rs-example
spec:
  replicas: 2
  selector:
     matchLabels:
       app: rs-demo
  template:
    metadata:
      labels:
        app: rs-demo
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80

[root@master ~]# kubectl apply -f replicaSet.yaml
replicaset.apps/rs-example created

 

集群中当前没有标签为 “app rs-demo” Pod 资源存在,因此 rs-example 需要按照 replicas 字段的定义创建它们,名称以其所属的控制器 名称为前缀。这两个 Pod 资源一开始都处于 ContainerCreating 状态,即处于 容器创建过程中,待创建过程完成后,其状态即转为 Running Pod 也将 转变为 “READY”
[root@master ~]# kubectl get pods -l app=rs-demo
NAME               READY   STATUS    RESTARTS   AGE
rs-example-ms4ps   1/1     Running   0          113s
rs-example-t6w67   1/1     Running   0          113s
接下来可以使用 “kubectl get replicaset” 命令查看 ReplicaSet 控制器资源的相关状态。下面的命令结果显示出它已经根据清单中配置的 Pod 板创建了 2 Pod 资源,这时它们已创建完成

[root@master ~]# kubectl get replicaset rs-example -o wide
NAME         DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES                 SELECTOR
rs-example   2         2         2       4m59s   myapp        ikubernetes/myapp:v1   app=rs-demo

  • DESIRED:期望有几个pod
  • CURRENT:当前一共有几个pod
  • READY:有几个pod已经就绪了
  • AGE:什么时间创建的
经由控制器创建与用户自主创建的 Pod 对象的功能并无二致,但其自动和解的功能在很大程度上能为用户省去不少的管理精力,这也是使 Kubernetes 系统之上的应用程序变得拥有自愈能力的主要保障。

 

1.3.3 ReplicaSet管控下的Pod对象

上面创建的rc-example通过标签选择器将拥有“app=rs-demo”签的Pod资源收归于麾下,并确保其数量精确符合所期望的数目,使用标签选择器显示出的Pod资源列表也能验证这一点。然而,实际中存着不少可能导致Pod对象数目与期望值不符合的可能性,如Pod对象的意外删除、Pod对象标签的变动(已有的Pod资源变得不匹配控制器的标签选择器,或者外部的Pod资源标签变得匹配到了控制器的标签选择器)、控制器的标签选择器变动,甚至是工作节点故障等。ReplicaSet 控制器的和解循环过程能够实时监控到这类异常,并及时启动和解操作。

1.缺少Pod副本

任何原因导致的相关 Pod 对象丢失,都会由 ReplicaSet 控制器自动补足。例如,手动删除上面列出的一个 Pod 对象,命令如下:

[root@master ~]# kubectl delete pods rs-example-ms4ps
pod "rs-example-ms4ps" deleted

再次列出相关 Pod对象的信息,可以看到被删除的rs-example-t6w67 进入了终止过程,而新的 Pod对象rs-example-zcjmj  正在被rs-example创建
器创建:

[root@master ~]# kubectl get pods -l app=rs-demo -o wide
NAME               READY   STATUS        RESTARTS   AGE   IP            NODE    NOMINATED NODE   READINESS GATES
rs-example-cwxgh   1/1     Running       0          3s    10.244.1.11   node1   <none>           <none>
rs-example-t6w67   0/1     Terminating   0          14m   10.244.1.10   node1   <none>           <none>
rs-example-zcjmj   1/1     Running       0          3m    10.244.2.11   node2   <none>           <none>  

 另外,强行修改隶属于控制器rs-example的某Pod资源(匹配于标签控制器)的标签,会导致它不再被控制器作为副本计数,这也将触发控制器的Pod对象副本缺失补足机制。例如,将rs-example-p66nv的标签app的值置空:

[root@master ~]# kubectl label pods rs-example-cwxgh app=  --overwrite
pod/rs-example-cwxgh labeled
列出 rs-example 相关 Pod对象的信息,发现rs-example-cwxgh 已经消失不见,并且正在创建新的对象副本

[root@master ~]# kubectl get pods -l app=rs-demo
NAME               READY   STATUS    RESTARTS   AGE
rs-example-q494g   1/1     Running   0          38s
rs-example-zcjmj   1/1     Running   0          7m16s

由此可见,修改 Pod 资源的标签即可将其从控制器的管控之下移出,当然,修改后的标签如果又能被其他控制器资源的标签选择器所命 中,则此时它又成了隶属于另一控制器的副本。如果修改其标签后的 Pod 对象不再隶属于任何控制器,那么它就将成为自主式 Pod ,与此前手 动直接创建的 Pod 对象的特性相同,即误删除或所在的工作节点故障都 会造成其永久性的消失。
 
 

2.多出Pod副本

一旦被标签选择器匹配到的 Pod资源数量因任何原因超出期望值,多余的部分都将被控制器自动删除。例如,为mypod 手动为其添 加“app rs-demo” 标签:

[root@master ~]# kubectl label pods mypod app=rs-demo
pod/mypod labeled

 
 
列出 rs-example 相关Pod对象的信息,发现rs-example-q494g 已经消失不见,已创建新的对象副本mypod 

[root@master ~]# kubectl get pods -l app=rs-demo
NAME               READY   STATUS    RESTARTS   AGE
mypod              1/1     Running   0          6d23h
rs-example-zcjmj   1/1     Running   0          16m

这就意味着,任何自主式的或本隶属于其他控制器的 Pod 资源其标签变动的结果一旦匹配到了其他的副本数足额的控制器,就会导致这类 Pod 资源被删除。
 

3.查看Pod资源变动的相关事件

“kubectl describe replicasets” 命令可打印出 ReplicaSet 控制器的详细状态,从下面命令结果中 Events 一段也可以看出, rs-example 执行了 Pod 资源的创建和删除操作,为的就是确保其数量的精确性。

[root@master ~]# kubectl describe replicasets/rs-example
Name:         rs-example
Namespace:    default
Selector:     app=rs-demo
Labels:       <none>
Annotations:  <none>
Replicas:     2 current / 2 desired
Pods Status:  2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=rs-demo
  Containers:
   myapp:
    Image:        ikubernetes/myapp:v1
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  32m    replicaset-controller  Created pod: rs-example-ms4ps
  Normal  SuccessfulCreate  32m    replicaset-controller  Created pod: rs-example-t6w67
  Normal  SuccessfulCreate  20m    replicaset-controller  Created pod: rs-example-zcjmj
  Normal  SuccessfulCreate  17m    replicaset-controller  Created pod: rs-example-cwxgh
  Normal  SuccessfulCreate  14m    replicaset-controller  Created pod: rs-example-q494g
  Normal  SuccessfulDelete  4m48s  replicaset-controller  Deleted pod: rs-example-q494g

 
事实上, ReplicaSet 控制器能对 Pod 对象数目的异常及时做出响应,是因为它向 API Server 注册监听( watch )了相关资源及其列表的变动信 息,于是 API Server会在变动发生时立即通知给相关的监听客户端。 而因节点自身故障而导致的 Pod 对象丢失, ReplicaSet 控制器一样会 使用补足资源的方式进行处理。
 

1.3.4  更新ReplicaSet控制器

ReplicaSet 控制器的核心组成部分是标签选择器、副本数量及 Pod 模板,但更新操作一般是围绕 replicas template 两个字段值进行的,毕竟 改变标签选择器的需求几乎不存在。改动 Pod 模板的定义对已经创建完 成的活动对象无效,但在用户逐个手动关闭其旧版本的 Pod 资源后就能 以新代旧,实现控制器下应用版本的滚动升级。另外,修改副本的数量 也就意味着应用规模的扩展(提升期望的副本数量)或收缩(降低期望 的副本数量)。这两种操作也是系统运维人员日常维护工作的重要组成 部分。
 

1.更改Pod模板:升级应用

ReplicaSet 控制器的 Pod 模板可随时按需修改,但它仅影响这之后由其新建的 Pod 对象,对已有的副本不会产生作用。大多数情况下,用户 需要改变的通常是模板中的容器镜像文件及其相关的配置以实现应用的 版本升级。下面的示例清单文件片断(replicaSet-v2.yaml )中的内容与 之前版本(replicaSet.yaml )的唯一不同之处也仅在于镜像文件的改 动:

 

[root@master ~]# vim replicaSet-v2.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: rs-example
spec:
  replicas: 2
  selector:
     matchLabels:
       app: rs-demo
  template:
    metadata:
      labels:
        app: rs-demo
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        ports:
        - name: http
          containerPort: 80

对新版本的清单文件执行 “kubectl apply” “kubectl replace” 命令即可完成 rs-example 控制器资源的修改操作:

[root@master ~]# kubectl apply -f replicaSet-v2.yaml
replicaset.apps/rs-example configured

不过,控制器 rs-example 管控的现存 Pod 对象使用的仍然是原来版本中定义的镜像:

[root@master ~]# kubectl get pods -l app=rs-demo -o  custom-columns=Name:metadata.name,Image:spec.containers[0].image
Name               Image
mypod              ikubernetes/myapp:v1
rs-example-zcjmj   ikubernetes/myapp:v1

此时,手动删除控制器现有的 Pod 对象(或修改与其匹配的控制器标签选择器的标签),并由控制器基于新的 Pod 模板自动创建出足额的 Pod 副本,即可完成一次应用的升级。新旧更替的过程支持如下两类操 作方式。
 
  • 一次性删除控制器相关的所有Pod副本或更改相关的标签:剧烈更替,可能会导致Pod中的应用短时间不可访问(如图所示);生产实践中,此种做法不可取。
 
 
  • 分批次删除旧有的Pod副本或更改其标签(待控制器补足后再删除另一批):滚动更替,更替期间新旧版本共存(如图所示)。

 
例如,这里采用第一种方式进行操作,一次性删除 rs-example 相关的所有 Pod 副本:
 

[root@master ~]# kubectl delete pods -l app=rs-demo
pod "mypod" deleted
pod "rs-example-zcjmj" deleted

再次列出 rc-example 控制器相关的 Pod 及其容器镜像版本时可以发现,使用新版本镜像的 Pod 已经创建完成:

[root@master ~]# kubectl get pods -l app=rs-demo -o  custom-columns=Name:metadata.name,Image:spec.containers[0].image
Name               Image
rs-example-jdp8k   ikubernetes/myapp:v2
rs-example-zrm66   ikubernetes/myapp:v2

必要时,用户还可以将 Pod 模板改回旧的版本进行应用的 降级 回滚 ,它的操作过程与上述过程基本类似。事实上,修改 Pod 板时,不仅仅能替换镜像文件的版本,甚至还可以将其替换成其他正在 运行着的、完全不同应用的镜像,只不过此类需求并不多见。若同时改 动的还有 Pod 模板中的其他字段,那么在新旧更替的过程中,它们也将 随之被应用。
 
以上操作只为说明应用部署的方式,实际使用时还需要更为完善的机制。即便是仅执行了一到多次删除操作,手动执行更替操作也并非一 项轻松的任务,幸运的是,更高级别的 Pod 控制器 Deployment 能够自动 实现更完善的滚动更新和回滚,并为用户提供自定义更新策略的接口。 而且,经过精心组织的更新操作还可以实现诸如蓝绿部署( Blue/Green Deployment )、金丝雀部署( Canary Deployment )和灰度部署等,这些 内容将在后面章节中详细展开说明。
 

2.扩容和缩容

改动 ReplicaSet 控制器对象配置中期望的 Pod 副本数量( replicas 字段)会由控制器实时做出响应,从而实现应用规模的水平伸缩。 replicas 的修改及应用方式同 Pod 模板,不过, kubectl 还提供了一个专用的子命 scale 用于实现应用规模的伸缩,它支持从资源清单文件中获取新的目
标副本数量,也可以直接在命令行通过 “--replicas” 选项进行读取,例如 rs-example 控制器的 Pod 副本数量提升至 5 个:
[root@master ~]# kubectl scale replicasets rs-example --replicas=5
replicaset.apps/rs-example scaled
由下面显示的 rs-example 资源的状态可以看出,将其 Pod 资源副本数量扩展至 5 个的操作已经成功完成:

[root@master ~]# kubectl get replicasets rs-example
NAME         DESIRED   CURRENT   READY   AGE
rs-example   5         5         5       88m

收缩规模的方式与扩展相同,只需要明确指定目标副本数量即可。
例如:
[root@master ~]# kubectl scale replicasets rs-example --replicas=3
replicaset.apps/rs-example scaled
另外, kubectl scale 命令还支持在现有 Pod 副本数量符合指定的值时才执行扩展操作,这仅需要为命令使用 “--current-replicas” 选项即可。例 如,下面的命令表示如果 rs-example 目前的 Pod 副本数量为 2 ,就将其扩 展至 4 个:

[root@master ~]# kubectl scale replicasets rs-example --current-replicas=2 --replicas=4
error: Expected replicas to be 2, was 3

但由于 rs-example 控制器现存的副本数量是 3 个,因此上面的扩展操作未执行并返回了错误提示。
 
注意 如果 ReplicaSet 控制器管控的是有状态的应用,例如主 从架构的 Redis 集群,那么上述这些升级、降级、扩展和收缩的操作都 需要精心编排和参与才能进行,不过,这也在一定程度上降低了 Kubernetes 容器编排的价值和意义。好在,它提供了 StatefulSet 资源来应 对这种需求,因此 ReplicaSet 通常仅用于管理无状态的应用,如 HTTP 服务程序等。
 
 

1.3.5   删除ReplicaSet控制器资源

使用 kubectl delete 命令删除 ReplicaSet 对象时默认会一并删除其管控的各 Pod 对象。有时,考虑到这些 Pod 资源未必由其创建,或者即便由其 创建却也并非其自身的组成部分,故而可以为命令使用 “-- cascade=false” 选项,取消级联,删除相关的 Pod 对象,这在 Pod 资源后续 可能会再次用到时尤有用。例如,删除 rs 控制器 rs-example
[root@master ~]# kubectl delete replicasets rs-example --cascade=false
replicaset.apps "rs-example" deleted
删除操作完成后,此前由 rs-example 控制器管控的各 Pod 对象仍处于活动状态,但它们变成了自主式 Pod 资源,用户需要自行组织和维护好 它们。
尽管 ReplicaSet 控制器功能强大,但在实践中,它却并非是用户直接使用的控制器,而是要由比其更高一级抽象的 Deployment 控制器对象 来调用
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值