跳到主要内容

15、Kubernetes 实战 - Pod控制器ReplicaSet和Deployment详解

前言

pod控制器

第一节 Pod控制器

在kubernetes中,按照pod的创建方式可以将其分为两类

  • 自主式pod: kubernetes直接创建出来的pod,这种pod删除后就没有了,也不会重建.
  • 控制器创建的pod: 通过控制器创建的pod, 这种pod删除了之后还会自动重建

什么是pod控制器
Pod控制器是管理pod的中间层,使用了pod控制器之后,我们只需要告诉pod控制器,想要多少个什么样的pod就可以了,它就会创建出满足条件的pod并确保每一个pod处于用户期望的状态,如果pod在运行中出现故障,控制器会基于指定策略重启或者重建pod。

在kubernetes中,有很多类型的pod控制器,每个都有自己的适合的场景,常见的有下面这些:

  • ReplicationController
    比较原始的pod控制器,已经被废弃,由ReplicatSet替代
  • ReplicaSet
    保证指定数量的pod运行,并支持pod数量变更,镜像版本变更
  • Deployment
    通过空值ReplicaSet来空值pod,并支持滚动升级,版本回退
  • Horizontal Pod Autoscaler
    可以根据集群负载自动调整pod的数量,实现消峰填谷
  • DaemonSet
    在集群中的指定Node上都运行一个副本,一般用于守护进行类的任务
  • Job
    它创建出来的pod只要完成任务就立即退出,用于执行一次性任务
  • Cronjob
    它创建的pod会周期性的执行,用于执行周期性任务
  • StatefulSet
    管理有状态应用

第二节 ReplicaSet(RS)

1. 概念和资源清单

ReplicaSet的主要作用是保证一定数量的pod能够正常运行,它会持续监听这些pod的运行状态,一旦pod发生故障,就会重启或重建。同时它还支持pod数量。同时它还支持对pod数量的扩缩容和版本镜像的升级。
 
ReplicaSet的资源清单文件:

apiVersion: apps/v1  版本号
kind: ReplicaSet   类型
metadata:  元数据
  name: pc-replicaset   rs名称
  namespace: dev  所属命名空间
  labels: 标签
     controller: rs
spec: 详情
  replicas: 3副本数量3
  selector:选择器,通过它指定该控制器管理哪些pod
    matchLabels:labels匹配规则,用于匹配template
      app: nginx-pod
    matchExpressions: Expressions匹配规则
      - {
   
     key: app,operator: In ,values:[nginx-pod]}
  template: 模板,当副本数量不足时,会根据模板创建pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1
          ports:
            - containerPort: 80

在这里,需要新了解的配置项就是spec下面的几个属性

  • replicas: 指定副本数量,其实就是当前rs创建出来的pod的数量,默认1
  • selector: 选择器,它的作用是建立pod控制器与pod之间的关联关系,采用Label Selector机制在在pod模板上定义label,在控制器上定义选择器,就可以表明当前控制器能管理哪些pod了
  • template: 模板,就是当前控制器创建pod所使用的模板,就是前面的pod定义
     

2. 创建ReplicaSet

创建pc-replicaset.yaml文件,内容如下

apiVersion: apps/v1  版本号
kind: ReplicaSet   类型
metadata:  元数据
  name: pc-replicaset   rs名称
  namespace: dev  所属命名空间
  labels: 标签
     controller: rs
spec: 详情
  replicas: 3副本数量3
  selector:选择器,通过它指定该控制器管理哪些pod
    matchLabels:labels匹配规则,用于匹配template
      app: nginx-pod
  template: 模板,当副本数量不足时,会根据模板创建pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1

创建rs

kubectl create -f pc-replicaset.yaml

查看rs

kubectl get rs pc-replicaset -n dev -o wide

DESIRED: 期望副本数量
CURRENT: 当前副本数量
READY: 已准备好的副本数

 
可以看到它创建了3个pod,pod的名称是控制器的名称+一个随机字符串。
 

3. 扩缩容

3.1 方法一:直接编辑rs

kubectl edit rs pc-replicaset -n dev

 

 

3.2方法二 :命令扩缩容

kubectl scale rs pc-replicaset --replicas=2 -n dev

replicas=n,kubernetes会根据当前pod数量自动增加或者减少到n个pod
 

4. 镜像升级/降级

4.1 方法一: 直接编辑rs

kubectl edit rs pc-replicaset -n dev

修改版本并退出
 
查看rs

kubectl get rs pc-replicaset -n dev -o wide

 

4.2 方法二 :命令升级

kubectl set image rs pc-replicaset nginx=nginx:1.17.1 -n dev

 

5. 删除ReplicaSet

5.1 命令删除

使用kubectl delete 命令会删除此RS以及它管理的Pod
在kubernetes删除之前,会将RS的replicascaler调整为0,等地所有的Pod被删除后,在执行RS对象的删除

kubectl delete rs pc-replicaset -n dev
kubectl get pod -n dev -o wide

5.2 非级联删除

如果希望只删除RS对象(保留Pod),可以使用kubectl delete 命令后添加 --cascade=false选项(不推荐)

#只删除RS,不级联删除pod,不推荐此操作
kubectl delete rs pc-replicaset -n dev  --cascade=false

5.3 yaml删除

直接使用yaml删除(推荐)

kubectl delete -f pc-replicaset.yaml

 

第三节 Deployment(Deploy)

1. 概念和资源清单

为了更好的解决服务编排的问题,kubernetes在v1.2版本开始,引入了Deployment控制器。值得一提的是,这种控制器并不直接管理pod,而是通过管理ReplicasSet来间接管理Pod,即Deployment管理ReplicaSet,ReplicaSet管理Pod。所以Deployment比ReplicaSet功能更加强大。
 
Deployment主要功能有下面几个

  • 支持ReplicaSet的所有功能
  • 支持发布的停止、继续
  • 支持版本滚动更新和版本回退

Deployment的资源清单

apiVersion: apps/v1  版本号
kind: Deployment   类型
metadata:  元数据
  name: pc-deployment   rs名称
  namespace: dev  所属命名空间
  labels: 标签
     controller: deploy
spec: 详情
  replicas: 3副本数量3
  revisionHistoryLimit: 3保留历史版本,默认10
  paused: false暂停部署,默认是false
  progressDeadlineSeconds: 600部署超时时间(s),默认600
  strategy: 策略
    type: RollingUpdate滚动更新策略
    rollingUpdate:
      maxSurge: 30%最大额外可以存在的副本数,可以为百分比,也可以是整数
      maxUnavailable: 30%最大不可用状态的Pod的最大值,可以为百分比,也可以是整数
  selector:选择器,通过它指定该控制器管理哪些pod
    matchLabels:labels匹配规则,用于匹配template
      app: nginx-pod
    matchExpressions: Expressions匹配规则
      - {
   
     key: app,operator: In ,values:[nginx-pod]}
  template: 模板,当副本数量不足时,会根据模板创建pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1
          ports:
            - containerPort: 80

2. 创建Deployment

创建pc-deployment.yaml,内容如下

apiVersion: apps/v1  版本号
kind: Deployment   类型
metadata:  元数据
  name: pc-deployment   rs名称
  namespace: dev  所属命名空间
  labels: 标签
    controller: rs
spec: 详情
  replicas: 3副本数量3
  selector:选择器,通过它指定该控制器管理哪些pod
    matchLabels:labels匹配规则,用于匹配template
      app: nginx-pod
  template: 模板,当副本数量不足时,会根据模板创建pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1

创建deployment

kubectl create -f pc-deployment.yaml --record=true

 
查看deployment
UP-TO-DATE 最新版本的pod的数量
AVAILABLE 当前可用的pod的数量
 

名称规则
 

2. 扩缩容

2.1 方法一: 命令方式

将副本数量变成5

kubectl scale deploy pc-deployment --replicas=5 -n dev

查看deployment

kubectl get deploy pc-deployment -n dev

查看pod

kubectl get pod -n dev

 

2.2 方法二 : 直接编辑rs

编辑deployment的副本数量,修改spec.replicas:3

kubectl edit deploy pc-deployment -n dev

查看pod

kubectl get pod -n dev

 

 

3. 升级策略

Deployment支持两种镜像更新的策略: 重建更新和滚动更新(默认),可以通过strategy选项进行配置。

strategy: 指定新的pod替换旧的Pod的策略,支持两个属性
  type: 指定策略类型,支持两种策略
    Recreate: 在创建出新的Pod之前会先杀死所有已存在的Pod
    RollingUpdate: 滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本Pod
  rollingUpdate: 当type为RollingUpdate时生效,用于为RollingUpdate设置参数,支持两个属性
    maxUnavailable: 用来指定在升级过程中不可用Pod的最大数量,默认为25%
    maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%

3.1 重建更新

重建更新是将旧pod全部删除,重建创建新的pod

1、 编辑pc-deployment.yaml,在spec节点下添加更新策略;

apiVersion: apps/v1  版本号
kind: Deployment   类型
metadata:  元数据
  name: pc-deployment   rs名称
  namespace: dev  所属命名空间
  labels: 标签
    controller: rs
spec: 详情
  strategy:
    type: Recreate重建更新策略
  replicas: 3副本数量3
  selector:选择器,通过它指定该控制器管理哪些pod
    matchLabels:labels匹配规则,用于匹配template
      app: nginx-pod
  template: 模板,当副本数量不足时,会根据模板创建pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1

 

kubectl apply -f pc-deployment.yaml

1、 创建deploy进行验证;
变更镜像

kubectl set image deployment pc-deployment nginx=nginx:1.17.2 -n dev

 

观察升级过程

kubectl get pod -n dev -w 

一次性把所有的pod都停止了,然后重建创建
 

3.2 滚动更新

1、 编辑pc-deployment.yaml文件,在spec下添加更新策略;

apiVersion: apps/v1  版本号
kind: Deployment   类型
metadata:  元数据
  name: pc-deployment   rs名称
  namespace: dev  所属命名空间
  labels: 标签
    controller: rs
spec: 详情
  strategy:
    type: RollingUpdate滚动更新
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  replicas: 3副本数量3
  selector:选择器,通过它指定该控制器管理哪些pod
    matchLabels:labels匹配规则,用于匹配template
      app: nginx-pod
  template: 模板,当副本数量不足时,会根据模板创建pod副本
    metadata:
      labels:
        app: nginx-pod
    spec:
      containers:
        - name: nginx
          image: nginx:1.17.1

 
 

kubectl apply -f pc-deployment.yaml

1、 创建deploy进行验证;
变更镜像

kubectl set image deployment pc-deployment nginx=nginx:1.17.3 -n dev

 

观察升级过程

kubectl get pod -n dev -w 

可以看到它是按照25%比例进行创建新版本pod,再停止旧版本pod,这样滚动升级
 

4. 版本回退

deployment支持版本升级过程中的暂停、继续功能以及版本回退等诸多功能,下面具体来看
kubectl rollout 版本升级相关功能,支持下面选项

  • status 显示当前升级状态
  • history 显示升级历史记录
  • pause 暂停版本升级过程
  • resume 继续已经暂停的版本升级过程
  • restart 重启版本升级
  • undo 回滚到上一级版本(可以使用–to-revision回滚到指定版本)

(1)演示版本升级前,我们需要先进行一次升级,查看一下升级过程
删除掉之前的pc-deployment,重新create 一个rs

#创建rs
kubectl create -f pc-deployment.yaml --record
#查看deploy,rs,pod内容
kubectl get deploy,rs,pod -n dev

进行版本升级前,先打开两个标签窗口,分别查看rs和pod信息

kubectl get pod -n dev -w
kubectl get rs -n dev -w

#进行版本升级
kubectl set image deploy pc-deployment nginx=nginx:1.17.2 -n dev

 
 

 

升级保留了原来的rs,创建了新的rs,新rs上的pod增加,旧的rs上pod被删除。即使升级完了,旧的rs依然被保留。
 
(2)版本回退
查看当前升级版本的状态

kubectl rollout status deploy pc-deployment -n dev 

 
查看历史升级信息

kubectl rollout history deploy pc-deployment -n dev

 

注意,kubectl create 时需要添加–record ,否则可能显示为空

 

 

回退版本

#回退到版本1
kubectl rollout undo deploy pc-deployment --to-revision=1 -n dev

可以看到第一个rs上面拥有3个pod,而第三个则没有了。
 
再次查看历史升级信息,可以看到1版本消失了。
 

5. 金丝雀发布

Deployment 支持更新过程中的空值,如暂停(pause)或继续(resume)更新操作
比如有一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新的版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是金丝雀发布。

更新deployment 的版本,并配置暂停deployment

kubectl set image deploy pc-deployment nginx=nginx:1.17.4 -n dev && kubectl rollout pause deployment pc-deployment -n dev

监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为使用了pause暂停命令

kubectl get rs -n dev -o wide

 
观察更新状态

kubectl rollout status deploy pc-deployment -n dev

可以看到有一个pod创建,并且finish,三个副本等待更新。
 
确保更新的pod没问题之后,继续更新

kubectl rollout resume deploy pc-deployment -n dev

 
稍等一下就更新完成了。
 
 

6. 终止金丝雀发布

请见:k8s金丝雀发布终止