K8S Pod控制器讲解

目录

一、Pod控制器类别

1、ReplicaSet

2、Deployment

3、DaemonSet

4、Job

5、CronJob

6、StatufulSet

7、CDR

8、Helm

二、ReplicaSet资源清单

三、Deployment资源清单

1、strategy(Pod更新策略)

2、revisionHistoryLimit

3、paused

4、template

5、Deployment资源清单示例

5.1、更新操作

5.2、通过打补丁的方式更新资源清单配置

5.3、暂停Pod更新

5.4、恢复Pod更新

5.5、回滚操作

四、DaemonSet资源清单


一、Pod控制器类别

1、ReplicaSet

ReplicaSet控制器用来管理无状态的Pod资源,核心作用在于代用户创建指定数量的Pod副本,并确保Pod副本数量一直等于用户期望的数量。而且还支持Pod滚动更新、及自动扩缩容等机制;它被称新一代的ReplicationCtroller。

ReplicaSet主要有三个组件组成:

  1. 用户期望的Pod副本数量;
  2. 标签选择器,用来选定由自己管理或控制的Pod副本,如果通过标签选择器挑选到的Pod少于定义的Pod副本数量,则会利用Pod资源模版来创建Pod副本,以达到规定的Pod数量;
  3. Pod资源模版。

但是Kubernetes却不建议用户直接使用ReplicaSet,而是应该使用Deployment

2、Deployment

Deployment也是Pod控制器,但是它是工作在ReplicaSet之上的。Deployment是通过控制ReplicaSet,从而来控制Pod。Deployment能够提供比ReplicaSet更为强大的功能。比如:Pod版本回滚、声明式配置(声明式配置是已经创建的Pod可以随时更改配置并应用到Pod)。Deployment是目前管理无状态应用最好的控制器。

3、DaemonSet

DaemonSet用于确保集群中的每一个节点只运行一个特定的Pod副本,这种特定的Pod通常是用来实现系统级的后台任务。把这样的任务托管在Kubernetes之上的好处是:如果这个后台任务宕了以后,会由DaemonSet控制器自动重建一个Pod;新建一个Node节点,它也会在新节点上创建一个这样的Pod运行。

约束:我们也可以根据自己的需求,在K8S群集中的部分满足条件的节点上仅运行一个Pod副本。

总结: Deployment和DaemonSet管理的Pod中运行的服务都是无状态的,且是守护进程类的(必须始终持续运行在后台)。但是对于那种只希望运行一次就结束的任务,显然以上两种控制器是不能够使用的。例如:我们需要对数据库进行备份,备份结束后,任务就应该结束了,而不是让任务持续运行在后台。那么对于这种任务只运行一次,只要任务完成就正常退出,没有完成才会重建,这就应该选择使用Job这种控制器了。

4、Job

Job控制器控制只能执行一次作业的任务,它确保这个任务确实是正常完成而退出的,如果是异常退出,则Job控制器会重建任务再次执行直到任务正常完成。

那么对于周期性的任务呢?显然Job控制器也是无法胜任的。这就需要CronJob了。

5、CronJob

CronJob与Job类似,也是运行一次就退出。不同之处在于,Job是只运行一次,CronJob是周期性运行。但每次运行都会有正常退出的时间。如果前一次任务还没执行完成,又到了下一次任务执行的时间点了怎么办呢?CronJob也可以解决这种问题。

6、StatufulSet

StatufulSet控制器能够管理有状态的Pod副本,而且每一个Pod副本都是被单独管理的,它拥有自己独有的标志和独有的数据集。一旦这个副本故障了,在重建Pod之前会做许多初始化操作。

以Redis群集为例:如果Redis集群中三个节点中的某一个节点宕机了,为了确保每个节点宕机后数据不丢失,我们传统的做法就是对每个节点做主从复制,当主节点宕机后,需要人为的把从节点提升为主节点,想要恢复从节点,就需要很多运维操作了。

但是利用StatufulSet去定义管理Redis或Mysql或者Zookeeper,它们的配置是不一样的。例如:配置管理Redis主从复制和配置管理Mysql主从复制中间的操作步骤是不一样的。所以这样的配置没有任何规律可循。StatufulSet给我们提供了一个封装,用户把需要人为操作的复杂的执行逻辑定义成脚本,放置在StatufulSet的Pod模板中。这样在每次Pod节点故障后,能通过脚本自动恢复过来。

总结:真正想把有状态的应用托管在Kubernetes之上,还是有相当的难度。

7、CDR

Custom Defined Resources K8S 1.8+,用户自定义资源。

8、Helm

任何不把用户当傻瓜的应用,都难以取得成功。K8S资源清单定义起来,门槛过高,难度大。这就诞生了Helm,Helm对于Kubernetes来说,就相当于Linux系统中的yum。以后在再部署大型的应用,就可以用Helm直接安装部署。不过Helm到目前为止,诞生也不超过两年的时间。到目前为止,许多大型主流的应用,已经可以通过Helm去部署。

二、ReplicaSet资源清单

ReplicaSet资源清单定义时的一级字段:

apiVersion: apps/v1
kind: ReplicaSet
metadata: 
spec: 

spec下一级核心字段主要的有三个:

replicas    <integer>       # 定义Pod副本数量
selector    <Object>        # 选择器
template    <Object>        # 模板

template字段中嵌套的就是Pod资源清单定义的字段:

metadata    <Object>        # 这是定义Pod的元数据
spec        <Object>        # Pod的spec

接下来,我们来定义一个ReplicaSet的资源清单:rs-demo.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      name: myapp-pod
      labels:
        app: myapp
        release: canary
        environment: qa
    spec:
      containers:
      - name: myapp-container
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80

注意事项看下图:

利用上述清单创建一个名为myapp的ReplicaSet:

kubectl create -f rs-demo.yaml

查看创建成功的ReplicaSet:

ReplicaSet可以简写为rs。

值得注意的是,在Pod模板中定义的Pod名称(如上代码:name: myapp-pod)实际上是不起作用的。因为通过控制器清单文件创建的Pod名称是由按照 控制器名称-随机字符串这样的形式命名的。如下图:

获取创建的Pod:

更新Pod容器的镜像后,新版本Pod更新示意图:

三、Deployment资源清单

Deployment管理保留的ReplicaSet版本数量可以由用户自定义,默认保留10个历史版本。Deployment能够使用声明式配置,声明式配置是使用kubectl apply -f demo.yaml命令。对于声明式配置的资源,将来还可以在命令行使用patch子命令去打补丁实现配置修改更新。

Deployment在控制Pod滚动更新时,还可以配置Pod的滚动更新逻辑。

Deployment、ReplicaSet、Pod三者之间的关系:

Deployment可以简写为deploy
接下来看看Deployment资源清单一级字段:

apiVersion: apps/v1
kind: Deployment
metadata: 
spec:

Deployment的spec与ReplicaSet的spec区别不大。
Deployment中的spec字段:

replicas    <integer>   # Pod副本数量
selector    <Object>    # 标签选择器
template    <Object> -required-     # Pod模板
strategy    <Object>    # 定义Pod更新策略
paused      <boolean>
revisionHistoryLimit    <integer>

1、strategy(Pod更新策略)

spec:
  strategy:
    type:                     # <string>
    rollingUpdate:            # <Object>

strategy.type字段取值:

  • Recreate: 重建更新,就是删除一个Pod,再重建一个Pod。当typerecreate时,与type同级的rollingUpdate字段就失效了。当typerollingUpdate,与type同级的rollingUpdate字段定义滚动更新的策略。
  • RollingUpdate滚动更新

strategy.rollingUpdate字段:

  • maxSurgePod滚动更新时,最多能超出replicas定义的Pod副本数的个数。有两种取值方式:1. 直接指定一个数字(ex: 5);2. 指定一个百分比(ex: 10%)。
  • maxUnavailablePod滚动更新时,最多有几个不可用。假设replicas值为5,maxUnavailable值为1,那么可用的Pod数量至少为5-1=4个。此字段同样可以指定一个百分比做为值。

例如:Pod滚动更新时,多则只能多2个,少则只能少1个,则可以这样定义:

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1

2、revisionHistoryLimit

revisionHistoryLimit <integer>表示要保留以允许回滚的旧ReplicaSet的数量。默认是10个。如果值为0,表示不保存旧版本。

3、paused

paused <boolean> 表示部署Pod时是否暂停,通常情况下是不暂停的,执行命令后会立即部署Pod。

4、template

template <Object> -required- Pod模板与ReplicaSet中Pod模板定义一致。

5、Deployment资源清单示例

编辑yaml文件:deploy-demo.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary 
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80

这里我们用声明式创建:

[root@k8s-master manifests]# kubectl apply -f deploy-demo.yaml 
deployment.apps/myapp-deploy created

看一下创建的结果:

同时还会自动创建一个ReplicaSet,如下图:

自动创建的ReplicaSet命名规则:deploy名称-Pod模板hash值

查看创建的Pod,如下图:

Pod的命令规则:deploy名称-Pod模板hash值-随机字符串

这时我们想要改变Pod副本数量,可以直接vim deploy-demo.yaml修改replicas: 4,然后再执行kubectl apply -f deploy-demo.yaml

注意:声明式创建,相同的yaml文件可以多次执行kubectl apply。而kubectl create只能执行一次。

上述示例清单中,有很多字段我们都没有定义。Kubernetes会自动填充默认值。可以通过命令:kubectl get deploy myapp-deploy -o yaml查看。

5.1、更新操作

我们先修改deploy-demo.yaml,将容器的镜像版本修改为v2:
vim deploy-demo.yaml

再次部署:

[root@k8s-master manifests]# kubectl apply -f deploy-demo.yaml 
deployment.apps/myapp-deploy configured

访问新版本Pod,可以看到已经更新到v2版本了。

查看滚动历史记录:

[root@k8s-master manifests]# kubectl rollout history deployment myapp-deploy 
deployments "myapp-deploy"
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

5.2、通过打补丁的方式更新资源清单配置

[root@k8s-master manifests]# kubectl patch deployment myapp-deploy -p '{"spec": {"replicas": 5}}'
deployment.extensions/myapp-deploy patched

可以看到Pod副本个数立即更新到5个了。

通过打补丁的方式修改滚动更新策略:

[root@k8s-master manifests]# kubectl patch deployment myapp-deploy -p '{"spec": {"strategy": {"type": "RollingUpdate", "rollingUpdate": {"maxSurge": 1, "maxUnavailable": 0}}}}'
deployment.extensions/myapp-deploy patched

查看一下滚动更新策略,已经应用修改:

5.3、暂停Pod更新

为了做这个示例,我们可以先修改镜像版本,然后立即暂停滚动更新。
修改镜像版本除了使用vim命令直接编辑yaml文件或使用kubectl patch打补丁外,还可以使用kubectl set image直接修改镜像。示例:kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
命令如下:

[root@k8s-master ~]# kubectl set image deployment myapp-deploy myapp=ikubernetes/myapp:v3 && kubectl rollout pause deployment myapp-deploy 
deployment.extensions/myapp-deploy image updated
deployment.extensions/myapp-deploy paused

另开启一个终端,监控label为app=myapp的Pod:

通过上图可以看到,滚动更新暂停命令执行后,会先创建一个新Pod并运行,然后就暂停住了,旧Pod也没有删除一个。此时有6个Pod,如下图:

通过命令:kubectl rollout status deployment myapp-deploy可以看到滚动更新的状态,如下图:

图中提示信息告诉我们:等待部署“myapp-deploy”部署完成:5个新副本中的1个已更新...

接下来我们恢复Pod更新...

5.4、恢复Pod更新

恢复Pod更新使用命令:

[root@k8s-master ~]# kubectl rollout resume deployment myapp-deploy 
deployment.extensions/myapp-deploy resumed

查看一下滚动更新的状态:

从图中可以看出,滚动更新完成。

看一下ReplicaSet的状态:

从上图中可以看到镜像已经更新到v3版了,而且有5个Pod已经准备就绪了。

接下来执行回滚操作。。。

5.5、回滚操作

假如新版本的应用Pod有问题,想要回滚,就要使用命令:kubectl rollout undo

kubectl rollout undo deployment myapp-deploy --to-revision=1

--to-revision=1 表示回滚到第1版,如果不指定--to-revision选项,则默认是回滚到前一个版本。可以通过命令kubectl rollout history deployment myapp-deploy查看。

回滚后,原来的第1版变成第4版,所以第4版的前一版就是第3版了。如果在第4版的基础上向前回滚一个版本,就会回滚到第3版。

再来看看ReplicaSet状态:

从上图中可以看到,已经回滚到v1版了,v1版有5个Pod准备就绪了。而v3版的Pod数为0 。

四、DaemonSet资源清单

DaemonSet控制器能够在指定节点上运行能够实现系统级的管理功能的Pod,而且每个指定节点只运行一个这样的Pod副本。还可以把节点的目录挂载至Pod中,通过Pod实现某些管理功能。

DaemonSet定义资源清单时,不再需要用replicas字段指定副本数量了。

DaemonSet资源清单文件中spec字段包含的子字段:

revisionHistoryLimit    <integer>   # rs历史版本保存个数,与Deployment中的此字段意义相同。
selector    <Object>    # 标签选择器
template    <Object> -required-     # Pod模板
updateStrategy  <Object>            # Pod更新策略

更新策略:

spec
  updateStrategy:
    type: RollingUpdate
    rollingUpdate: 
      maxUnavailable: 2

DaemonSet的Pod更新策略有两种:"RollingUpdate""OnDelete",只有类型为RollingUpdate时,与type同级的字段rollingUpdate才生效。rollingUpdate字段下只有maxUnavailable一个字段。也就是说DaemonSet的Pod更新时,只能少,不能多。

DaemonSet资源清单示例:

apiVersion: apps/v1
kind: DaemonSet
metadata: 
  name: filebeat-ds
  namespace: default
spec: 
  selector:
    matchLabels:
      app: filebeat
      release: stable
  template:
    metadata: 
      labels:
        app: filebeat
        release: stable
    spec: 
      containers:
      - name: filebeat
        image: ikubernetes/filebeat:5.6.5-alpine
        env: 
        - name: REDIS_HOST
          value: redis-svc
        - name: REDIS_LOG_LEVEL
          value: info

DaemonSet资源清单定义时,不用再指定replicas了。

猜你喜欢

转载自blog.csdn.net/qq_41210783/article/details/104512081