美文网首页Kubernetes
十一、Kubernetes 进阶之部署方案篇

十一、Kubernetes 进阶之部署方案篇

作者: Suny____ | 来源:发表于2020-05-05 17:21 被阅读0次

    1、常用部署方案

    1.1 滚动更新

    滚动更新是一种自动化程度较高的发布方式,用户体验比较平滑,是目前成熟型技术组织所采用的主流发布方式。

    优势在于服务不会停止,但是pod会有新旧版本并存的情况。

    • 准备YAML文件

      • maxSurge 参数详解
        • 该值可以是绝对数(例如,5)或所需 Pods 的百分比(例如,10%)。如果 MaxUnavailable 0,则值不能为 0。默认值为 25%。
        • 定义除了 replicas 数量之外,在一次滚动更新过程中,Deployment还可以创建多少Pod
        • 若设置为30%,则是确保更新期间任何时间运行的 Pods 总数最多为所需 Pods 总数的130%。
      • maxUnavailable 参数详解
        • 定义在一次滚动更新过程中,Deployment最多可以删除多少Pod。如果maxSurge 为 0,则该值不能为 0。默认值为 25%。
        • 若设置为30%,确保可用的 Pods 总数在更新期间,任何时候都至少有 70% 所需的 Pods。
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: rollingupdate
      spec:
        strategy:                   # 策略
          rollingUpdate:            
            maxSurge: 1         # 滚动升级时会先启动1个pod
            maxUnavailable: 2       # 滚动升级时允许的最多不可用的 pod 个数
          type: RollingUpdate       # 滚动更新升级方式
        selector:
          matchLabels:
            app: rollingupdate
        replicas: 4
        template:
          metadata:
            labels:
              app: rollingupdate
          spec:
            containers:
            - name: rollingupdate
              image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v1.0   # 先使用v1.0版本
              ports:
              - containerPort: 8080  
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: rollingupdate
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 8080
        selector:
          app: rollingupdate
        type: ClusterIP
      
    • 创建资源

      [root@master-kubeadm-k8s project_deploy]# kubectl apply -f rollingupdate.yaml
      deployment.apps/rollingupdate created
      service/rollingupdate created
      
    • 查看资源

      [root@master-kubeadm-k8s project_deploy]# kubectl get pods
      NAME                             READY   STATUS      RESTARTS   AGE
      rollingupdate-67cd875cd6-fdxj2   1/1     Running     0          13s
      rollingupdate-67cd875cd6-r8z7l   1/1     Running     0          13s
      rollingupdate-67cd875cd6-vwq6b   1/1     Running     0          13s
      rollingupdate-67cd875cd6-zdfvr   1/1     Running     0          13s
      
      [root@master-kubeadm-k8s project_deploy]# kubectl get svc
      NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
      rollingupdate   ClusterIP   10.102.255.72  <none>        80/TCP    61s
      
    • 测试版本

      [root@master-kubeadm-k8s project_deploy]# curl 10.102.255.72/k8s
      hello K8S
      
    • 升级镜像

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: rollingupdate
      spec:
        strategy:
          rollingUpdate:            
            maxSurge: 1
            maxUnavailable: 2
          type: RollingUpdate
        selector:
          matchLabels:
            app: rollingupdate
        replicas: 4
        template:
          metadata:
            labels:
              app: rollingupdate
          spec:
            containers:
            - name: rollingupdate
              image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v2.0   # 使用v2.0版本
              ports:
              - containerPort: 8080  
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: rollingupdate
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 8080
        selector:
          app: rollingupdate
        type: ClusterIP
      
    • 滚动更新

      [root@master-kubeadm-k8s project_deploy]# kubectl apply -f rollingupdate.yaml
      deployment.apps/rollingupdate configured
      service/rollingupdate unchanged
      
    • 观察Pod创建过程

      image.png
    • 再次测试

      # 现在访问的就是新版本的了
      [root@master-kubeadm-k8s project_deploy]# curl 10.102.255.72/k8s
      hello K8S v2.0
      

    1.2 重新创建

    先停止旧的pod,然后再创建新的pod,但这个停止 到 创建新Pod的过程服务是会间断的。

    • 准备YAML

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: recreate
      spec:
        strategy:
          type: Recreate        # 重新创建
        selector:
          matchLabels:
            app: recreate
        replicas: 4
        template:
          metadata:
            labels:
              app: recreate
          spec:
            containers:
            - name: recreate
              image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v1.0
              ports:
              - containerPort: 8080
              livenessProbe:
                tcpSocket:
                  port: 8080
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: recreate
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 8080
        selector:
          app: recreate
        type: ClusterIP
      
      • 创建资源

        [root@master-kubeadm-k8s project_deploy]# kubectl apply -f recreate.yaml
        deployment.apps/recreate created
        service/recreate created
        
      • 查看资源

        [root@master-kubeadm-k8s project_deploy]# kubectl get pods
        NAME                        READY   STATUS    RESTARTS   AGE
        recreate-7b7dbf54cb-6zn2s   1/1     Running   2          118s
        recreate-7b7dbf54cb-86n84   1/1     Running   2          118s
        recreate-7b7dbf54cb-d4sw4   1/1     Running   1          118s
        recreate-7b7dbf54cb-t684d   1/1     Running   1          118s
        
        [root@master-kubeadm-k8s project_deploy]# kubectl get svc
        NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
        recreate     ClusterIP   10.107.31.94   <none>        80/TCP    2m2s
        
      • 测试版本

        [root@master-kubeadm-k8s project_deploy]# curl 10.107.31.94/k8s
        hello K8S
        
      • 升级镜像

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: recreate
        spec:
          strategy:
            type: Recreate
          selector:
            matchLabels:
              app: recreate
          replicas: 4
          template:
            metadata:
              labels:
                app: recreate
            spec:
              containers:
              - name: recreate
                image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v2.0     # 升级2.0版本
                ports:
                - containerPort: 8080
                livenessProbe:
                  tcpSocket:
                    port: 8080
        ---
        apiVersion: v1
        kind: Service
        metadata:
          name: recreate
        spec:
          ports:
          - port: 80
            protocol: TCP
            targetPort: 8080
          selector:
            app: recreate
          type: ClusterIP
        
      • 重新创建

        [root@master-kubeadm-k8s project_deploy]# kubectl apply -f recreate.yaml
        deployment.apps/recreate configured
        service/recreate unchanged
        
      • 观察Pod创建过程

        image.png
    • 再次测试

      # 升级成功
      [root@master-kubeadm-k8s project_deploy]# curl 10.107.31.94/k8s
      hello K8S v2.0
      

    1.3 蓝绿部署

    V1 版本称为蓝组,V2 版本称为绿组,发布时会一次性将流量从蓝组直接切换到绿组。

    蓝绿部署其实就是创建2组Pod同时运行,通过切换Service绑定的标签进行版本切换。无需停机,风险较小。

    1.3.1 实际部署流程

    • 部署v1的应用(一开始的状态)
      • 所有外部请求的流量都打到这个版本上
    • 部署v2的应用
      • v2的代码与v1不同(新功能、Bug修复等)
    • 将流量从v1切换到v2
    • 如v2测试正常,就删除v1正在使用的资源(例如实例),从此正式用v2
      • 一般不会直接删除v1,因为无法保证v2会在什么时候出现问题
      • 当版本升级到v3时,就可以删除v1

    1.3.2 开始部署

    • 准备YAML文件

      service的yaml要与Deployment的yaml分开,这样在升级时才不会修改service-ip

      • bluegreen.yaml

        #deploy
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: blue                # 这里的 blue 只是方便观察,实际没意义
        spec:
          strategy:         
            rollingUpdate:          # 同样是使用滚动更新的方式
              maxSurge: 1
              maxUnavailable: 2
            type: RollingUpdate
          selector:
            matchLabels:
              app: bluegreen
          replicas: 4
          template:
            metadata:
              labels:               # 关键点在于这里, 配置2个标签
                app: bluegreen      # 升级版本时这里不
                version: v1.0       # 升级版本时这里更新,Service选择标签也更新,就可以动态的切换到新版本
            spec:
              containers:
              - name: bluegreen
                image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v1.0
                ports:
                - containerPort: 8080
        
      • bluegreen-service.yaml

        apiVersion: v1
        kind: Service
        metadata:
          name: bluegreen-service
        spec:
          ports:
          - port: 80
            protocol: TCP
            targetPort: 8080
          selector:
            app: bluegreen
            version: v1.0       # 当版本升级时,修改版本即可动态升级版本,这样service-IP不会变
          type: ClusterIP
        
    • 创建资源

      [root@master-kubeadm-k8s project_deploy]# kubectl apply -f bluegreen.yaml
      deployment.apps/blue created
      
      [root@master-kubeadm-k8s project_deploy]# kubectl apply -f bluegreen-service.yaml
      service/bluegreen-service created
      
    • 查看资源

      [root@master-kubeadm-k8s project_deploy]# kubectl get pods
      NAME                    READY   STATUS    RESTARTS   AGE
      blue-8675d5c885-75shf   1/1     Running   0          2m43s
      blue-8675d5c885-j2qmm   1/1     Running   0          2m44s
      blue-8675d5c885-m9z2s   1/1     Running   0          2m44s
      blue-8675d5c885-x6ht4   1/1     Running   0          2m44s
      
      [root@master-kubeadm-k8s project_deploy]# kubectl get svc
      NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
      bluegreen-service   ClusterIP   10.111.118.191   <none>        80/TCP    2m44s
      
    • 测试版本

      [root@master-kubeadm-k8s project_deploy]# curl 10.111.118.191/k8s
      hello K8S
      
    • 升级镜像

      • bluegreen.yaml

        #deploy
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: green               # 修改名称为 green 只是方便观察,实际没意义
        spec:
          strategy:         
            rollingUpdate:
              maxSurge: 1
              maxUnavailable: 2
            type: RollingUpdate
          selector:
            matchLabels:
              app: bluegreen
          replicas: 4
          template:
            metadata:
              labels:
                app: bluegreen
                version: v2.0       # 升级版本
            spec:
              containers:
              - name: bluegreen
                image: registry.cn-hangzhou.aliyuncs.com/zhao_yang/springboot-demo-k8s:v2.0             # 升级镜像版本
                ports:
                - containerPort: 8080
        
      • bluegreen-service.yaml

        apiVersion: v1
        kind: Service
        metadata:
          name: bluegreen-service
        spec:
          ports:
          - port: 80
            protocol: TCP
            targetPort: 8080
          selector:
            app: bluegreen
            version: v2.0       # 选择新版本的Pod
          type: ClusterIP
        
    • 重新创建

      [root@master-kubeadm-k8s project_deploy]# kubectl apply -f bluegreen.yaml
      deployment.apps/green created
      
      [root@master-kubeadm-k8s project_deploy]# kubectl apply -f bluegreen-service.yaml
      service/bluegreen-service configured
      
    • 观察Pod

      image.png
    • 再次测试

      # 切换成功
      [root@master-kubeadm-k8s project_deploy]# curl 10.111.118.191/k8s
      hello K8S v2.0
      

    如果发现这个版本有问题,那么直接修改service中的标签选择器为 v1.0 版本即可

    1.4 金丝雀部署

    金丝雀部署也叫AB测试(国内称灰度发布),是指会有2个版本的代码存在,目的是先让一部分用户来测试新功能,若新功能没问题,再全部升级为新版本的功能。

    这里要使用的话可以直接使用上面的YAML文件,只需修改bluegreen-service.yaml文件中的标签选择器即可!

    • 修改service的YAML文件

      apiVersion: v1
      kind: Service
      metadata:
        name: bluegreen-service
      spec:
        ports:
        - port: 80
          protocol: TCP
          targetPort: 8080
        selector:
          app: bluegreen
          # version: v2.0  # 取消版本选择,让2个版本的Pod都运用起来
        type: ClusterIP
      
    • 更新资源

      [root@master-kubeadm-k8s project_deploy]# kubectl apply -f bluegreen-service.yaml
      service/bluegreen-service configured
      
    • 测试

      这样就达到了AB测试的功能,两个版本共存

      [root@master-kubeadm-k8s project_deploy]# while sleep 0.5; do curl 10.111.118.191/k8s; echo "";done
      hello K8S
      hello K8S
      hello K8S v2.0
      hello K8S
      hello K8S v2.0
      hello K8S
      hello K8S
      hello K8S v2.0
      hello K8S
      hello K8S
      hello K8S
      hello K8S v2.0
      hello K8S v2.0
      hello K8S v2.0
      hello K8S v2.0
      hello K8S v2.0
      
      # ...
      

    如果想要让更少部分用户体验新版的功能,那修改新版本的YAML文件时,可以将副本数改的少点就可以了

    相关文章

      网友评论

        本文标题:十一、Kubernetes 进阶之部署方案篇

        本文链接:https://www.haomeiwen.com/subject/yatvghtx.html