07-K8S Basic-Pod控制器基础(ReplicaSet、Deployment )

一、Pod控制器

1.1、K8s资源介绍

  • Kubernetes
    • Control Plan 控制平面(Master)
      • API Server : 整个系统得GATEWAY ,操作整个集群都需要借助此接口,APIServer是一个REST Ful风格的系统,它把我们整个系统的所有的待管理目标统统抽象为资源。(Resouces → Objects),API Server为整个K8s数据管理提供了一个所谓的数据范式或者称为数据方案,所有能够存取再Api Server上的数据都必须遵循此规范,所以API Server就是整个K8S的数据库和数据接口并保存再etcd当中
      • etcd : 用于保存用户期望的状态对象标准
      • Controller : Controller用于去除etcd当中的用户期望的对象标准, 保存再etcd当中的数据要被实时的构建为能够运行再K8S之上的活动对象,用于管理活动对象的状态结果,且负责创建删除修改各个活动对象(live Objects),并且还要负责和解循环(Reconcilation Loops),确保正在运行的对象运行的状态要吻合用户期望的状态(status → spec)
        • kubernetes上的控制器 (status → spec)
          • 控制Pod的称为Pod控制器
          • 控制Service的称为Service控制器
          • 控制node节点的称为node控制器
          • 控制器本身也是标准的kubernetes资源类型,它们被实例化出具体的对象负责具体的任务,控制器资源自身也会存在响应的管理操作
      • Kube-Controller-Manager 控制器管理器
        • 内部打包k8s内建的40~50个原生的控制器守护进程,其内部有很多控制器运行,防止k8s上太多的控制器守护进程运行使得用户眼花缭乱。
        • 创建的任何类型的控制器都会在此的维护下确保控制器正常运转
    • Node 工作节点

1.2、k8s控制器资源介绍

  • 控制器本身也是标准的kubernetes资源类型,它们被实例化出具体的对象负责具体的任务,控制器资源自身也会存在响应的管理操作
  • Kube-Controller-Manager 控制器管理器
    • 控制器本身也是标准的kubernetes资源类型,它们可被实例化出具体的对象负责具体的任务
      • 例如匹配一个特定的Deployment控制器对象负责管理由标签选择器匹配到Pod资源对象
    • 控制器资源对象自身的建立、更新及伸出操作则由控制器进程负责,这些进程统一打包在了Kube-Controller-Manager之中
    • 而Kube-Controller-Manager自身的运行正常与否的状态则需要通过冗余的方式设置,可以选择集群中添加多个manager节点,但是仅能有一个Kube-Controller-Manager运行,当运行出问题时,就会将Manager中选举一个Kube-Controller-Manager运行
# Kube-Controller-Manager 本身也是一个pods
chapter4]# kubectl get pods -n kube-system
kube-controller-manager-k8s.master1   1/1     Running   0          29h
 
 
chapter4]# ls /etc/kubernetes/manifests/    # 启动controller-manager所需的配置清单
etcd.yaml  kube-apiserver.yaml  kube-controller-manager.yaml   kube-scheduler.yaml
 
 
# Kube-Controller-Manager默认管理其它资源的所有类型的Controller,但是有两个控制器不不被包含的,如果有需要则修改,修改完不需要apply,k8s会过会自动读取重建新容器
spec:
  containers:
  - command:
    - kube-controller-manager
    - --allocate-node-cidrs=true
    - --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
    - --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
    - --bind-address=127.0.0.1
    - --client-ca-file=/etc/kubernetes/pki/ca.crt
    - --cluster-cidr=10.244.0.0/16
    - --cluster-name=kubernetes
    - --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
    - --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
    - --controllers=*,bootstrapsigner,tokencleaner      # 两个控制器不不被包含的,如果要添加则使用逗号往后添加
    - --kubeconfig=/etc/kubernetes/controller-manager.conf
    - --leader-elect=true
    - --node-cidr-mask-size=24
    - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
    - --root-ca-file=/etc/kubernetes/pki/ca.crt
    - --service-account-private-key-file=/etc/kubernetes/pki/sa.key
    - --service-cluster-ip-range=10.96.0.0/12
    - --use-service-account-credentials=true
    image: registry.aliyuncs.com/google_containers/kube-controller-manager:v1.18.2

二、Pod控制器

2.1、Pod控制器介绍

  • Pod控制器是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试 进行重启,当根据重启策略无效,则会重新新建pod的资源。

    • pod是kubernetes的最小单元,自主式创建的pod删除就没有了,但是通过资源控制器创建的pod如果删除还会重建。pod控制器就是用于实现代替我们去管理pod的中间层,并帮我们确保每一个pod资源处于我们所定义或者所期望的目标状态,pod资源出现故障首先要重启容器,如果一直重启有问题的话会基于某种策略重新编排。自动适应期望pod数量。
  • 早期版本控制器仅有一个:ReplicationController

  • 控制器类型划分

    • 目前版本pod控制器有多种类型:
      • 应用程序可划分为多种类型的控制器
        • 守护进程型
          • 无状态 :
            • 非系统级别:Deployment 、ReplicaSet
            • 系统级别 :DaemonSet
          • 有状态 : StatefulSet
        • 非守护进程型 (作业-->用处不多)
          • Job
          • CronJob
pod控制器有多种类型:
 
ReplicaSet: 代用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。
ReplicaSet主要三个组件组成:
  (1)用户期望的pod副本数量
  (2)标签选择器,判断哪个pod归自己管理
  (3)当现存的pod数量不足,会根据pod资源模板进行新建
    帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制器,而是使用Deployment。
 
Deployment:工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能,还提供声明式配置。
 
DaemonSet:用于确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任务。比如ELK服务
    特性:服务是无状态的
    服务必须是守护进程
 
Job:只要完成就立即退出,不需要重启或重建。
 
Cronjob:周期性任务控制,不需要持续后台运行,
 
StatefulSet:管理有状态应用

2.2、ReplicaSet 无状态应用控制器(但是不应该直接rs去直接管理pods,正确的控制器使用为(Deployment→ ReplicaSet → Pods))

  • ReplicaSet: 用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。
  • ReplicaSet主要三个组件组成:
    • (1)用户期望的pod副本数量
    • (2)标签选择器,判断哪个pod归自己管理
    • (3)当现存的pod数量不足,会根据pod资源模板进行新建
  • 帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制器,而是使用Deployment

kubectl explain ReplicaSet

  • apiVersion : 标准资源 apps/v1
  • kind : 资源类型ReplicaSet
  • metadata : 元数据信息
  • spec : ReplicaSet的规格定义
    • replicas:  定义副本数量
    • selector: 标签选择器,定义匹配pod的标签
      • matchLabels : 指定标签匹配,默认与关系
      • matchExpressions :指定多个标签选择器,表达式的过滤条件
    • template: pod的模板定义
  • status
1、查看当前k8s 有哪些 ReplicaSet类型的控制器(默认名称空间)
    ~]# kubectl get rs    #kubectl get ReplicaSet
        NAME                      DESIRED   CURRENT   READY   AGE
        myapp-5c6976696c          2         2         2       3d
 
2、定义ReplicaSet类型的控制器资源YAML
chapter5]# cat rs-example.yaml
#标准资源api版本定义
apiVersion: apps/v1
#定义资源类型为ReplicaSet
kind: ReplicaSet
#定义元数据
metadata:
  #控制器名称
  name: myapp-rs
  #定义控制器所属的名称空间,事先名称空间是存在的
  namespace: prod
#ReplicaSet的规格定义
spec:
  #定义期望副本数量为2个
  replicas: 2
  #标签选择器,定义匹配pod的标签
  selector:
     #使用matchLabels来匹配,每一个pod被创建出来后匹配有app这个标签且值为myapp-pod的pod,直到匹配到ReplicaSet中定义的期望副本数量的pod
     matchLabels:
       app: myapp-pod
  #pod的模板定义:以下创建的每一个pod自动使用app: myapp-pod这个标签
  template:
    #pod元数据定义
    metadata:
      #pod的标签
      labels:
        app: myapp-pod
    #pod的规格定义
    spec:
      #容器定义
      containers:
      #pod中容器的名称
      - name: myapp
        #运行此容器使用的镜像
        image: ikubernetes/myapp:v1
        #容器暴漏的端口
        ports:
        - name: http
          containerPort: 80
 
3、创建ReplicaSet定义的pod
    chapter5]# kubectl apply -f rs-example.yaml
        replicaset.apps/myapp-rs created
 
4、查看prod民称空间下的ReplicaSet控制器
    chapter5]# kubectl get rs -n prod
                   #期望pod数量 / 当期已经运行的pod数量/已经就绪的pod数量/大概创建时间
        NAME       DESIRED     CURRENT   READY   AGE
        myapp-rs   2           2         2       109s
 
 
    chapter5]# kubectl get rs -n prod -o wide
        NAME       DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                 SELECTOR
        myapp-rs   2         2         2       24s   myapp        ikubernetes/myapp:v1   app=myapp-pod
 
 
 
5、查看ReplicaSet控制器详细信息
chapter5]# kubectl describe rs myapp-rs -n prod
#控制器名称
Name:         myapp-rs
#控制器所属的名称空间
Namespace:    prod
#选择器是选择那些拥有app标签值为myapp-pod的pod
Selector:     app=myapp-pod
#当前控制器的标签
Labels:       <none>
#使用apply时自动创建的信息
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"apps/v1","kind":"ReplicaSet","metadata":{"annotations":{},"name":"myapp-rs","namespace":"prod"},"spec":{"replicas":2,"selec...
#当前运行的pod数量和期望运行的pod数量
Replicas:     2 current / 2 desired
#旗下控制的pod的状态(相位)
Pods Status:  2 Running / 0 Waiting / 0 Succeeded / 0 Failed
#控制器旗下运行pod使用的模板信息
Pod Template:
  Labels:  app=myapp-pod
  Containers:
   myapp:
    Image:        ikubernetes/myapp:v1
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
#控制器创建pod时的创建过程
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  5m56s  replicaset-controller  Created pod: myapp-rs-hp4nj   #pod名称后面为随机字串
  Normal  SuccessfulCreate  5m56s  replicaset-controller  Created pod: myapp-rs-7dpv4
 
 
basic]# kubectl get pods -n prod
NAME             READY   STATUS    RESTARTS   AGE
myapp-rs-7dpv4   1/1     Running   0          26m
myapp-rs-hp4nj   1/1     Running   0          26m
 
basic]# kubectl get pods -n prod --show-labels
NAME             READY   STATUS    RESTARTS   AGE   LABELS
myapp-rs-7dpv4   1/1     Running   0          34m   app=myapp-pod
myapp-rs-hp4nj   1/1     Running   0          34m   app=myapp-pod
 
 
 
6、(注意)ReplicaSet控制器会根据的定义的Selector:    
    app=myapp-pod(选择器是选择那些拥有app标签值为myapp-pod的pod)自动管理同一名称空间下的pod资源,                                       
    这样就涉及到定义的期望运行的pod数量和存在满足控制器根据标签信息控制pod的数量发生冲突,很可能干掉之前运行的pod资源
        (如果认为手动干掉一个pod,也会启动一个pod,来满足replicase的数量)
 
 
#再次创建一个自主式pod,并打上满足控制器标签选择器所识别的pod标签,演示原有的Pod则会被干掉。
basic]# cat pod-demo-yaml
#pod所属的群组
apiVersion: v1
#资源的类型为pod
kind: Pod
#元数据
metadata:
  creationTimestamp: null
  name: pod-demo-rs
  #定义和上面控制器控制的pod在同一名称空间下的自主式pod
  namespace: prod
  #添加ReplicaSet控制器所能检测控制的标签
  labels:
    app: myapp-pod
#定义pod的属性
spec:
#容器
  containers:
  #这个容器使用的镜像文件
  - image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    #容器的名称
    name: myapp
    #定义这个容器期望和拥有所使用的资源
    resources: {}
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  priority: 0
  restartPolicy: Always
  #使用哪个调度器进行调度此pod
  schedulerName: default-scheduler
  #定义安全上下文
  securityContext: {}
 
7、使用声明式命令创建此pod,并观察pod状态
    basic]# kubectl apply -f pod-demo-yaml
        pod/pod-demo-test configured
    basic]# kubectl get pods -n prod     # 新创建的pod则未被创建因为,控制仅希望有2个pod资源运行
        NAME             READY   STATUS    RESTARTS   AGE
        myapp-rs-7dpv4   1/1     Running   0          27m
        myapp-rs-hp4nj   1/1     Running   0          27m
 
 
    # 如果手动删除一个pod,ReplicaSet控制器也会再次创建新的pod,以满足用户期望状态、数量的pod
 
8、修改pod的副本数量
    #方式一:修改etcd中的信息
    ~]# basic]# kubectl edit rs myapp-rs -n prod
        replicas: 5
     ~]# kubectl get rs -o wide -n prod
 
 
    # 方式二:使用声明式接口去修改之前定义的控制器的对象的YAML,修改replicas:
    chapter5]# cat rs-example.yaml
        #标准资源api版本定义
        apiVersion: apps/v1
        #定义资源类型为ReplicaSet
        kind: ReplicaSet
        #定义元数据
        metadata:
            #控制器名称
            name: myapp-rs
            #定义控制器所属的名称空间
            namespace: prod
        #ReplicaSet的规格定义
        spec:
        #定义副本数量为2个
        replicas: 6          ####增加期望pod运行数量
        #标签选择器,定义匹配pod的标签
        selector:
            #使用matchLabels来匹配,每一个pod被创建出来后匹配有app这个标签且值为myapp-pod的pod
            matchLabels:
            app: myapp-pod
        #pod的模板定义:以下创建的每一个pod自动使用app: myapp-pod这个标签
        template:
            #pod元数据定义
            metadata:
            #pod的标签
            labels:
                app: myapp-pod
            #pod的规格定义
            spec:
            #容器定义
            containers:
            #pod中容器的名称
            - name: myapp
                #运行此容器使用的镜像
                image: ikubernetes/myapp:v1
                #容器暴漏的端口
                ports:
                - name: http
                containerPort: 80
 
        chapter5]# kubectl apply -f rs-example.yaml
            replicaset.apps/myapp-rs configured
         
        chapter5]# kubectl get rs -n prod
            NAME       DESIRED   CURRENT   READY   AGE
            myapp-rs   6         6         6       16h
 
        chapter5]# kubectl get pods -n prod
            NAME             READY   STATUS    RESTARTS   AGE
            myapp-rs-7dpv4   1/1     Running   0          16h
            myapp-rs-ctdj4   1/1     Running   0          51s
            myapp-rs-hp4nj   1/1     Running   0          16h
            myapp-rs-mfvtq   1/1     Running   0          51s
            myapp-rs-mvjcv   1/1     Running   0          51s
            myapp-rs-sfxs4   1/1     Running   0          51s
 
9、也可以使用scale动态修改此控制器下的pod副本数量
    chapter5]# kubectl scale --replicas=3 rs myapp-rs -n prod
        replicaset.apps/myapp-rs scaled
 
 
    chapter5]# kubectl get pods -n prod
        NAME             READY   STATUS    RESTARTS   AGE
        myapp-rs-7dpv4   1/1     Running   0          16h
        myapp-rs-ctdj4   1/1     Running   0          4m38s
        myapp-rs-hp4nj   1/1     Running   0          16h
 
    chapter5]# kubectl get pods -n prod -o wide
        NAME             READY   STATUS    RESTARTS   AGE     IP              NODE            NOMINATED NODE   READINESS GATES
 
#代码更新
10、(不推荐手动去代码更新)修改pod的镜像版本
    #方式一:直接修改配置清单,修改image:
    chapter5]# cat rs-example.yaml
        #标准资源api版本定义
        apiVersion: apps/v1
        #定义资源类型为ReplicaSet
        kind: ReplicaSet
        #定义元数据
        metadata:
            #控制器名称
            name: myapp-rs
            #定义控制器所属的名称空间
            namespace: prod
        #ReplicaSet的规格定义
        spec:
        #定义副本数量为2个
        replicas: 6          ####增加期望pod运行数量
        #标签选择器,定义匹配pod的标签
        selector:
            #使用matchLabels来匹配,每一个pod被创建出来后匹配有app这个标签且值为myapp-pod的pod
            matchLabels:
            app: myapp-pod
        #pod的模板定义:以下创建的每一个pod自动使用app: myapp-pod这个标签
        template:
            #pod元数据定义
            metadata:
            #pod的标签
            labels:
                app: myapp-pod
            #pod的规格定义
            spec:
            #容器定义
            containers:
            #pod中容器的名称
            - name: myapp
                #运行此容器使用的镜像
                image: ikubernetes/myapp:v2
                #容器暴漏的端口
                ports:
                - name: http
                containerPort: 80  
             
        # 修改完配置清单重新使用声明式结构加载一次
        chapter5]# kubectl apply -f rs-example.yaml
            replicaset.apps/myapp-rs configured
        chapter5]# kubectl get rs -n prod -o wide
            NAME       DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                 SELECTOR
            myapp-rs   6         6         6       16h   myapp        ikubernetes/myapp:v2   app=myapp-pod
         
        #但是修改资源配置清单时会出现的现象,就是有些pod内部运行的image版本未更新,因为rs并不确保每一次更新操作都能反应其pod,仅有后续添加的pod才会使用新版本的镜像,之前创建的pod则使用的还是老的镜像
        chapter5]# kubectl get pods -n prod
            NAME             READY   STATUS    RESTARTS   AGE
            myapp-rs-2nx7f   1/1     Running   0          2m3s    #从时间看,老的pod则未更新创建时间、镜像
            myapp-rs-68shh   1/1     Running   0          2m3s
            myapp-rs-6q7j5   1/1     Running   0          2m3s
            myapp-rs-7dpv4   1/1     Running   0          16h
            myapp-rs-ctdj4   1/1     Running   0          14m
            myapp-rs-hp4nj   1/1     Running   0          16h
 
        # 查看新增的pod确实是新的启动镜像,但是老的pod却还是旧的镜像,可以使用describe查看pod的详细信息
        chapter5]# kubectl describe pods myapp-rs-64h6c -n prod 
 
        # 仅有后续添加的pod才会使用新版本的镜像,之前创建的pod则使用的还是老的镜像
        chapter5]# kubectl scale --replicas=6 rs myapp-rs -n prod
 
    # 方式二:
    ~]# kubectl edit rs myapp
        image: ikubernetes/myapp:v2  
    ~]# kubectl delete pods myapp-*** -n pord # 修改了pod镜像版本,pod需要重建才能达到最新版本
    ~]# kubectl apply  -f rs-example.yaml
 
 
ReplicaSet更新总结:
  1、rs 自己本身并不确保用户的每一次更新操作都能反应给需求,只有在后续新增的Pod的才会被更新。如果想更新之前已有的Pod,必须删除老的Pod并重新以新清单重建。
  2、但是此种更新有弊端,方式一,先增加新Pod,后减少老Pod,第二种,先减少Pod,但是如果无法满足客户端请求的处理需求呢?
  2、但是不应该直接rs去直接管理pods,正确的控制器使用为(Deployment→ ReplicaSets → Pods)

三、Deployment控制器Deployment→ ReplicaSets → Pods

3.1、Deployment控制器介绍

  • Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新。
  • 只需要在 Deployment 中描述想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。也可以定义一个全新的 Deployment 来创建 ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。

image

  • 典型的用例如下:
    • (1)使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失败。
    • (2)然后,通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
    • (3)如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision。
    • (4)扩容Deployment以满足更高的负载。
    • (5)暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
    • (6)根据Deployment 的状态判断上线是否hang住了。
    • (7)清除旧的不必要的 ReplicaSet。

3.2、Deployment控制器实战

  • 在定义Deployment时不需要定义ReplicaSet,它会在中间默认添加一级

3.2.1、Deployment控制器-镜像滚动更新规则为停止一个old_pod,启动一个new_pod直至达到用户期望运行数量(默认的更新滚动策略)

  • 查看一个nginx-deployment.yaml的例子:
1、创建Deployment→ ReplicaSets → Pods 资源清单
chapter5]# cat deploy-nginx-zhushi.yaml
#Deployment标准资源api版本定义
apiVersion: apps/v1
#定义资源的类型
kind: Deployment
#定义Deployment元数据信息
metadata:
  #Deployment名称
  name: myapp
  #指定Deployment所属的名称空间
  namespace: prod
#Deployment的规格定义
spec:
  #定义期望pod的运行的副本数量
  replicas: 3
  minReadySeconds: 10
 
#  strategy:
#    rollingUpdate:
#      maxSurge: 1
#      maxUnavailable: 1
#    type: RollingUpdate
  #标签选择器,定义匹配的pod
  selector:
    matchLabels:
      app: myapp
      rel: stable
  #pod的模板以下创建的每一个pod自动使用app:myapp , rel:stable这个标签
  template:
    metadata:
      labels:
        app: myapp
        rel: stable
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - containerPort: 80
          name: http
        #就绪状态探测
        readinessProbe:
          periodSeconds: 1
          httpGet:
            path: /
            port: http
 
2、删除prod名称空间下的所有资源   #kubectl delete all --all   删除默认名称空间下的所有资源
    chapter5]# kubectl delete all --all -n prod
        pod "myapp-6db964bf97-fvxww" deleted
        pod "myapp-6db964bf97-lr6bk" deleted
        pod "myapp-6db964bf97-z6t2x" deleted
        pod "myapp-rs-2nx7f" deleted
        pod "myapp-rs-68shh" deleted
        pod "myapp-rs-6q7j5" deleted
        pod "myapp-rs-7dpv4" deleted
        pod "myapp-rs-ctdj4" deleted
        pod "myapp-rs-hp4nj" deleted
        pod "pod-demo" deleted
        deployment.apps "myapp" deleted
        replicaset.apps "myapp-6db964bf97" deleted
        replicaset.apps "myapp-rs" deleted
     
 
3、使用声明式接口创建资源
    chapter5]# kubectl apply -f deploy-nginx-zhushi.yaml
        deployment.apps/myapp created
 
 
 
4、查看已经创建Deployment信息
    chapter5]# kubectl get deploy -n prod
    chapter5]# kubectl get deployment -n prod -o wide
        NAME    READY   UP-TO-DATE   AVAILABLE   AGE
        myapp   3/3     3            3           95s
 
    #Deployment会自动创建一个rs
    chapter5]# kubectl get rs -n prod
    chapter5]# kubectl get replicaset -n prod -o wide
        NAME               DESIRED   CURRENT   READY   AGE
        myapp-6db964bf97   3         3         3       3m15s   #myapp-6db964bf97 为pod模板/rs模板的hash值,后续所有的pod都会被此rs来管理
         
    #查看pods
    chapter5]# kubectl get pods -n prod
    chapter5]# kubectl get pods -n prod -o wide --show-labels
        NAME                     READY   STATUS    RESTARTS   AGE
        myapp-6db964bf97-6fdw8   1/1     Running   0          78s
        myapp-6db964bf97-cvvdv   1/1     Running   0          78s
        myapp-6db964bf97-j5m98   1/1     Running   0          78s
     
 
#更新(如果更新副本数量直接修改期望运行得pod副本数量,但是rs不会修改,如果更新pod镜像版本时,则会新生成一个新的rs)
5、pod镜像版本更新
    #方式一:修改配置清单的image: 执行更新的镜像文件
        chapter5]# cat deploy-nginx-zhushi.yaml
        #Deployment标准资源api版本定义
        apiVersion: apps/v1
        #定义资源的类型
        kind: Deployment
        #定义Deployment元数据信息
        metadata:
          #Deployment名称
          name: myapp
          #指定Deployment所属的名称空间
          namespace: prod
        #Deployment的规格定义
        spec:
          #定义期望pod的运行的副本数量
          replicas: 3
          minReadySeconds: 10
 
        #  strategy:
        #    rollingUpdate:
        #      maxSurge: 1
        #      maxUnavailable: 1
        #    type: RollingUpdate
          #标签选择器,定义匹配的pod
          selector:
            matchLabels:
              app: myapp
              rel: stable
          #pod的模板以下创建的每一个pod自动使用app:myapp , rel:stable这个标签
          template:
            metadata:
              labels:
                app: myapp
                rel: stable
            spec:
              containers:
              - name: myapp
                image: ikubernetes/myapp:v2    #对其进行更改
            ports:
                - containerPort: 80
                  name: http
                #就绪状态探测
                readinessProbe:
                  periodSeconds: 1
                  httpGet:
                    path: /
                    port: http
 
6、声明式更新Deployment→ Replica Sets → Pods 资源清单
    chapter5]# kubectl apply -f deploy-nginx-zhushi.yaml
        deployment.apps/myapp configured
 
7、然后使用-w选项持续观察pod状态 (会看到删掉一个旧的pod,然后启动一个新的pod,直到替换完所有的期望运行的pod数量全部更新为止)
    ]# kubectl get pods -n prod -w
        NAME                     READY   STATUS    RESTARTS   AGE
        myapp-56c8d75644-5df7v   1/1     Running   0          3m4s    #56c8d75644  : 已经更新到新的rs管控的pod资源 即bash值
        myapp-56c8d75644-8274x   1/1     Running   0          2m51s
        myapp-56c8d75644-lrhpj   1/1     Running   0          2m39s   
         
8、查看Deployment下的rs信息(新的和旧的都存在)
    kubectl get rs -n prod -o wide
        NAME               DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES                 SELECTOR
        myapp-56c8d75644   3         3         3       5m45s   myapp        ikubernetes/myapp:v2   app=myapp,pod-template-hash=56c8d75644,rel=stable    #新的rs则正在控制新镜像的pod
        myapp-6db964bf97   0         0         0       116m    myapp        ikubernetes/myapp:v1   app=myapp,pod-template-hash=6db964bf97,rel=stable   #旧的rs则不控制任何pod

3.2.2、Deployment控制器(strategy)→ 镜像滚动更新策略(指定更新策略)

  • .spec.strategy 指定新的Pod替换旧的Pod的策略。 .spec.strategy.type 可以是"Recreate"或者是 "RollingUpdate"。"RollingUpdate"是默认值。

  • kubectl explain deployment.spec.strategy
    • rollingUpdate
    • type
  • Recreate: 重建式更新,就是删一个建一个。类似于ReplicaSet的更新方式,即首先删除现有的Pod对象,然后由控制器基于新模板重新创建新版本资源对象。
  • rollingUpdate:滚动更新,简单定义 更新期间pod最多有几个等。可以指定maxUnavailable 和 maxSurge 来控制 rolling update 进程。

3.2.2.1、RollingUpdate滚动更新

kubectl explain deployment.spec.strategy.rollingUpdate

  • maxSurge:.spec.strategy.rollingUpdate.maxSurge 是可选配置项,用来指定可以超过期望的Pod数量的最大个数。该值可以是一个绝对值(例如5)或者是期望的Pod数量的百分比(例如10%)。当MaxUnavailable为0时该值不可以为0。通过百分比计算的绝对值向上取整。默认值是1。

    • 例如,该值设置成30%,启动rolling update后新的ReplicatSet将会立即扩容,新老Pod的总数不能超过期望的Pod数量的130%。旧的Pod被杀掉后,新的ReplicaSet将继续扩容,旧的ReplicaSet会进一步缩容,确保在升级的所有时刻所有的Pod数量和不会超过期望Pod数量的130%。
  • maxUnavailable:.spec.strategy.rollingUpdate.maxUnavailable 是可选配置项,用来指定在升级过程中不可用Pod的最大数量。该值可以是一个绝对值(例如5),也可以是期望Pod数量的百分比(例如10%)。通过计算百分比的绝对值向下取整。 如果.spec.strategy.rollingUpdate.maxSurge 为0时,这个值不可以为0。默认值是1。

    • 例如,该值设置成30%,启动rolling update后旧的ReplicatSet将会立即缩容到期望的Pod数量的70%。新的Pod ready后,随着新的ReplicaSet的扩容,旧的ReplicaSet会进一步缩容确保在升级的所有时刻可以用的Pod数量至少是期望Pod数量的70%。
  • 补充:

    • maxSurge和maxUnavailable的属性值不可同时为0,否则Pod对象的副本数量在符合用户期望的数量后无法做出合理变动以进行更新操作。
    • 在配置时,用户还可以使用Deployment控制器的spec.minReadySeconds属性来控制应用升级的速度。新旧更替过程中,新创建的Pod对象一旦成功响应就绪探测即被认为是可用状态,然后进行下一轮的替换。而spec.minReadySeconds能够定义在新的Pod对象创建后至少需要等待多长的时间才能会被认为其就绪,在该段时间内,更新操作会被阻塞。

image

3.2.2.1.1、查看默认的更新策略
~]# kubectl describe deploy myapp -n prod
Name:                   myapp
Namespace:              prod
CreationTimestamp:      Fri, 21 Feb 2020 11:32:57 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 2
                        kubectl.kubernetes.io/last-applied-configuration:
                          {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"myapp","namespace":"prod"},"spec":{"minReadySeconds":10,"...
Selector:               app=myapp,rel=stable
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate                              #默认使用滚动更新策略
MinReadySeconds:        10                                             
RollingUpdateStrategy:  25% max unavailable, 25% max surge         #允许最大百分比25% , 允许最小百分比 25%,不允许四舍五入,仅能少
3.2.2.1.2、自己定义滚动更新策略-更新镜像-版本回滚
#更新修改默认得滚动更新策略规则
1、创建Deployment→ Replica Sets → Pods 资源清单
chapter5]# cat deploy-nginx-zhushi.yaml
#Deployment标准资源api版本定义
apiVersion: apps/v1
#定义资源的类型
kind: Deployment
#定义Deployment元数据信息
metadata:
  #Deployment名称
  name: myapp
  #指定Deployment所属的名称空间
  namespace: prod
#Deployment的规格定义
spec:
  #定义期望pod的运行的副本数量
  replicas: 3
  minReadySeconds: 10
  #定义使用更新策略
  strategy:
    #定义滚动更新策略值
    rollingUpdate:
      #允许比用户期望值多一个
      maxSurge: 1
      #允许比用户期望值少一个
      maxUnavailable: 1
    #更新策略为滚动更新
    type: RollingUpdate
  #标签选择器,定义匹配的pod
  selector:
    matchLabels:
      app: myapp
      rel: stable
  #pod的模板以下创建的每一个pod自动使用app:myapp , rel:stable这个标签
  template:
    metadata:
      labels:
        app: myapp
        rel: stable
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v2
        ports:
        - containerPort: 80
          name: http
        #就绪状态探测
        readinessProbe:
          periodSeconds: 1
          httpGet:
            path: /
            port: http
 
 
 
2、使用声明式接口创建资源
    chapter5]# kubectl apply -f deploy-nginx-zhushi.yaml --recursive
        deployment.apps/myapp configured
 
3、查看已经更新得deploy控制器更新规则
~]# kubectl describe deploy myapp -n prod
Name:                   myapp
Namespace:              prod
CreationTimestamp:      Fri, 21 Feb 2020 11:32:57 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 2
                        kubectl.kubernetes.io/last-applied-configuration:
                          {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"myapp","namespace":"prod"},"spec":{"minReadySeconds":10,"...
Selector:               app=myapp,rel=stable
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        10
RollingUpdateStrategy:  1 max unavailable, 1 max surge
 
 
 
#更新容器镜像
4、测试控制得滚动更新策略,则测试修改pod内部容器运行的镜像版本  kubectl set image
                                 控制器、控制器名名称、容器名称=更新的镜像名称、-n名称空间
    chapter5]# kubectl set image deployment myapp myapp=ikubernetes/myapp:v3  -n prod
 
 
5、实时查看pod状态信息(上面设置的滚动更新策略生效,加一个减两个,加两个减一个)
    chapter5]# kubectl get pods -n prod -w
    NAME                     READY   STATUS    RESTARTS   AGE
    myapp-56c8d75644-5df7v   1/1     Running   0          5d11h
    myapp-56c8d75644-8274x   1/1     Running   0          5d11h
    myapp-66574f5b75-4vb4g   1/1     Running   0          9s
    myapp-66574f5b75-58lgn   1/1     Running   0          9s
    myapp-56c8d75644-5df7v   1/1     Terminating   0          5d11h
    myapp-56c8d75644-8274x   1/1     Terminating   0          5d11h
    myapp-66574f5b75-j26v7   0/1     Pending       0          0s
    myapp-66574f5b75-j26v7   0/1     Pending       0          0s
    myapp-66574f5b75-j26v7   0/1     ContainerCreating   0          0s
    myapp-56c8d75644-5df7v   0/1     Terminating         0          5d11h
    myapp-56c8d75644-8274x   0/1     Terminating         0          5d11h
    myapp-56c8d75644-5df7v   0/1     Terminating         0          5d11h
    myapp-56c8d75644-8274x   0/1     Terminating         0          5d11h
    myapp-56c8d75644-8274x   0/1     Terminating         0          5d11h
    myapp-56c8d75644-5df7v   0/1     Terminating         0          5d11h
    myapp-56c8d75644-5df7v   0/1     Terminating         0          5d11h
    myapp-66574f5b75-j26v7   0/1     ErrImagePull        0          17s
    myapp-66574f5b75-j26v7   0/1     ImagePullBackOff    0          32s
    myapp-66574f5b75-j26v7   0/1     Running             0          41s
    myapp-66574f5b75-j26v7   1/1     Running             0          42s
 
     
 6、查看Deployment下的rs信息(新的和旧的都存在)
    ~]# kubectl get rs -n prod -o wide
    NAME               DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES                 SELECTOR
    myapp-56c8d75644   0         0         0       5d11h   myapp        ikubernetes/myapp:v2   app=myapp,pod-template-hash=56c8d75644,rel=stable
    myapp-66574f5b75   3         3         3       9m33s   myapp        ikubernetes/myapp:v3   app=myapp,pod-template-hash=66574f5b75,rel=stable
    myapp-6db964bf97   0         0         0       5d13h   myapp        ikubernetes/myapp:v1   app=myapp,pod-template-hash=6db964bf97,rel=stable
 
    ~]# kubectl get deploy -n prod
        NAME    READY   UP-TO-DATE   AVAILABLE   AGE
        myapp   3/3     3            3           5d13h
    chapter5]# kubectl get deploy -n prod -o wide
        NAME    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                 SELECTOR
        myapp   3/3     3            3           82m   myapp        ikubernetes/myapp:v3   app=myapp,rel=stable
 
 
#回滚
7、kubectl rollout  -h
    #显示回滚的历史(指定控制、指定名称空间)
        ~]# kubectl rollout history deployment/myapp -n prod
            deployment.apps/myapp
            REVISION  CHANGE-CAUSE
            1         <none>
            2         <none>
            3         <none>
    #查看滚动版本的状态(指定控制、指定名称空间)
        ~]# kubectl rollout status deployment/myapp -n prod
            deployment "myapp" successfully rolled out
 
    #执行版本回滚操作  kubectl rollout status -h
        --to-reversion=0  默认为0,意思为前一个版本
        #回滚为上一版本
        ~]# kubectl rollout undo deployment/myapp -n prod
            deployment.apps/myapp rolled back
        ~]# kubectl rollout status deployment/myapp -n prod
            Waiting for deployment "myapp" rollout to finish: 2 of 3 updated replicas are available...   #显示已经从第三版滚回到第二版
            deployment "myapp" successfully rolled out
        ~]# kubectl rollout history deployment/myapp -n prod
            deployment.apps/myapp
            REVISION  CHANGE-CAUSE
            1         <none>
            3         <none>
            4         <none>
 
        #查看rs版本
        ~]# kubectl get rs -n prod -o wide
            NAME               DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES                 SELECTOR
            myapp-56c8d75644   3         3         3       5d12h   myapp        ikubernetes/myapp:v2   app=myapp,pod-template-hash=56c8d75644,rel=stable   #已经滚回了V2
            myapp-66574f5b75   0         0         0       54m     myapp        ikubernetes/myapp:v3   app=myapp,pod-template-hash=66574f5b75,rel=stable
            myapp-6db964bf97   0         0         0       5d14h   myapp        ikubernetes/myapp:v1   app=myapp,pod-template-hash=6db964bf97,rel=stable
3.2.2.1.3、kubectl rollout版本回滚
  • 默认情况下,kubernetes 会在系统中保存前两次的 Deployment 的 rollout 历史记录,以便可以随时回退(您可以修改revision history limit来更改保存的revision数)。
  • 注意: 只要 Deployment 的 rollout 被触发就会创建一个 revision。也就是说当且仅当 Deployment 的 Pod template(如.spec.template)被更改,例如更新template 中的 label 和容器镜像时,就会创建出一个新的 revision。
  • 其他的更新,比如扩容 Deployment 不会创建 revision——因此我们可以很方便的手动或者自动扩容。这意味着当您回退到历史 revision 时,只有 Deployment 中的 Pod template 部分才会回退。
#回滚
7、kubectl rollout  -h
    #显示回滚的历史(指定控制、指定名称空间)
 
        ~]# kubectl rollout history deployment/myapp -n prod     #检查Deployment升级记录
            deployment.apps/myapp
            REVISION  CHANGE-CAUSE
            1         <none>
            2         <none>
            3         <none>
    #查看滚动版本的状态(指定控制、指定名称空间)
        ~]# kubectl rollout status deployment/myapp -n prod
            deployment "myapp" successfully rolled out
 
    #执行版本回滚操作  kubectl rollout status -h
 
        --to-reversion=0  默认为0,意思为前一个版本
 
        #回滚为上一版本
 
        ~]# kubectl rollout undo deployment/myapp -n prod
 
            deployment.apps/myapp rolled back
        ~]# kubectl rollout status deployment/myapp -n prod
            Waiting for deployment "myapp" rollout to finish: 2 of 3 updated replicas are available...   #显示已经从第三版滚回到第二版
            deployment "myapp" successfully rolled out
        ~]# kubectl rollout history deployment/myapp -n prod
            deployment.apps/myapp
            REVISION  CHANGE-CAUSE
            1         <none>
            3         <none>
            4         <none>
 
        #查看rs版本
        ~]# kubectl get rs -n prod -o wide
            NAME               DESIRED   CURRENT   READY   AGE     CONTAINERS   IMAGES                 SELECTOR
            myapp-56c8d75644   3         3         3       5d12h   myapp        ikubernetes/myapp:v2   app=myapp,pod-template-hash=56c8d75644,rel=stable   #已经滚回了V2
            myapp-66574f5b75   0         0         0       54m     myapp        ikubernetes/myapp:v3   app=myapp,pod-template-hash=66574f5b75,rel=stable
            myapp-6db964bf97   0         0         0       5d14h   myapp        ikubernetes/myapp:v1   app=myapp,pod-template-hash=6db964bf97,rel=stable
  • deployment回滚补充:CHANGE-CAUSE参数注解
# 回退到上一个版本
kubectl rollout undo deployment/abc
 
# 回退到指定版本
kubectl rollout undo deployment/abc --to-revision=2
 
 
# 查看回滚历史
kubectl rollout history deployment/nginx-deployment
        ~]# kubectl rollout history deployment/myapp -n prod
            deployment.apps/myapp
            REVISION  CHANGE-CAUSE
            1         <none>
            3         <none>
            4         <none>
 
 
如上所示,第一列为版本序号,第二列为 CHANGE-CAUSE。
    可以通过一下三种方式,指定 CHANGE-CAUSE:
        1、使用命令 kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1",对 Deployment 进行注解;
        2、追加 --record 以保存正在更改资源的 kubectl 命令;例如,kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.161 --record=true
        3、手动编辑资源的清单;
3.2.2.1.4、kubectl rollout金丝雀发布
  • Deployment控制器支持自定义控制更新过程中的滚动节奏,如“暂停(pause)”或“继续(resume)”更新操作。比如等待第一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布(Canary Release),如下命令演示:
1、更新deployment的v3版本,并配置暂停deployment
    [root@k8s-master ~]# kubectl set image deployment myapp-deploy myapp=ikubernetes/myapp:v3 && kubectl rollout pause deployment myapp-deploy   
    deployment "myapp-deploy" image updated
    deployment "myapp-deploy" paused
    [root@k8s-master ~]# kubectl rollout status deployments myapp-deploy  #观察更新状态
 
2、监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为使用了pause暂停命令
    [root@k8s-master ~]# kubectl get pods -l app=myapp -w
    NAME                            READY     STATUS    RESTARTS   AGE
    myapp-deploy-869b888f66-dpwvk   1/1       Running   0          24m
    myapp-deploy-869b888f66-frspv   1/1       Running   0         24m
    myapp-deploy-869b888f66-sgsll   1/1       Running   0         24m
    myapp-deploy-7cbd5b69b9-5s4sq   0/1       Pending   0         0s
    myapp-deploy-7cbd5b69b9-5s4sq   0/1       Pending   0         0s
    myapp-deploy-7cbd5b69b9-5s4sq   0/1       ContainerCreating   0         1s
    myapp-deploy-7cbd5b69b9-5s4sq   0/1       ContainerCreating   0         2s
    myapp-deploy-7cbd5b69b9-5s4sq   1/1       Running   0         19s
 
3、确保更新的pod没问题了,继续更新
    [root@k8s-master ~]# kubectl rollout resume deploy  myapp-deploy
 
4、查看最后的更新情况
    [root@k8s-master ~]# kubectl get pods -l app=myapp -w
    NAME                            READY     STATUS    RESTARTS   AGE
    myapp-deploy-869b888f66-dpwvk   1/1       Running   0          24m
    myapp-deploy-869b888f66-frspv   1/1       Running   0         24m
    myapp-deploy-869b888f66-sgsll   1/1       Running   0         24m
    myapp-deploy-7cbd5b69b9-5s4sq   0/1       Pending   0         0s
    myapp-deploy-7cbd5b69b9-5s4sq   0/1       Pending   0         0s
    myapp-deploy-7cbd5b69b9-5s4sq   0/1       ContainerCreating   0         1s
    myapp-deploy-7cbd5b69b9-5s4sq   0/1       ContainerCreating   0         2s
    myapp-deploy-7cbd5b69b9-5s4sq   1/1       Running   0         19s
    myapp-deploy-869b888f66-dpwvk   1/1       Terminating   0         31m
    myapp-deploy-7cbd5b69b9-p6kzm   0/1       Pending   0         1s
    myapp-deploy-7cbd5b69b9-p6kzm   0/1       Pending   0         1s
    myapp-deploy-7cbd5b69b9-p6kzm   0/1       ContainerCreating   0         1s
    myapp-deploy-7cbd5b69b9-p6kzm   0/1       ContainerCreating   0         2s
    myapp-deploy-869b888f66-dpwvk   0/1       Terminating   0         31m
    myapp-deploy-869b888f66-dpwvk   0/1       Terminating   0         31m
    myapp-deploy-869b888f66-dpwvk   0/1       Terminating   0         31m
    myapp-deploy-7cbd5b69b9-p6kzm   1/1       Running   0         18s
    myapp-deploy-869b888f66-frspv   1/1       Terminating   0         31m
    myapp-deploy-7cbd5b69b9-q8mvs   0/1       Pending   0         0s
    myapp-deploy-7cbd5b69b9-q8mvs   0/1       Pending   0         0s
    myapp-deploy-7cbd5b69b9-q8mvs   0/1       ContainerCreating   0         0s
    myapp-deploy-7cbd5b69b9-q8mvs   0/1       ContainerCreating   0         1s
    myapp-deploy-869b888f66-frspv   0/1       Terminating   0         31m
    myapp-deploy-869b888f66-frspv   0/1       Terminating   0         31m
    myapp-deploy-869b888f66-frspv   0/1       Terminating   0         31m
    myapp-deploy-869b888f66-frspv   0/1       Terminating   0         31m
    ......
posted @ 2021-06-13 22:35  SRE运维充电站  阅读(0)  评论(0编辑  收藏  举报