zoukankan      html  css  js  c++  java
  • ASP.NET Core on K8S深入学习(5)Rolling Update

    本篇已加入《.NET Core on K8S学习实践系列文章索引》,可以点击查看更多容器化技术相关系列文章。

    一、什么是Rolling Update?

      为了服务升级过程中提供可持续的不中断的服务,K8S提供了Rolling Update机制,它可以使得服务近乎无缝地平滑升级,即在不停止对外服务的前提下完成应用的更新。滚动更新采用渐进的方式逐步替换旧版本Pod,如果更新不如预期,那么也可以通过回滚操作恢复到更新前的状态。

    滚动更新的最大好处在于零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性。

      为了实践滚动更新,我们先做一些准备工作:

      (1)准备一个ASP.NET Core WebAPI项目,具体项目代码参见这里

      项目代码里边有三个版本,如下图所示:

      

      他们之间的差别在于一个接口的返回JSON数据,比如V1.0版本中返回的是Version: 1.0,而V1.1版本中返回的是Version:1.1,那么V1.2版本则是返回Versioin:1.2。

        [Route("api/[controller]")]
        [ApiController]
        public class HomeController : ControllerBase
        {
            // GET api/home
            [HttpGet]
            public ActionResult<IEnumerable<string>> Get()
            {
                return new string[] {
                    "Hello, welcome to EDC's demo. Version: 1.0"
                };
            }
        }

      (2)将此项目各个版本根据Dockerfile打成镜像,分别是k8s-demo:1.0,1.1,1.2

      (3)将本地镜像push到远程镜像仓库,这里我传送到了docker hub的一个公共仓库里边:

    docker push edisonsaonian/k8s-demo:1.0
    docker push edisonsaonian/k8s-demo:1.1
    docker push edisonsaonian/k8s-demo:1.2

      

    二、更新实践

      首先,我们先创建一个1.0版本到K8S中,准备YAML配置文件(这次我们将Deployment和Service的资源定义写在了一起):

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: edc-webapi-deployment
      namespace: aspnetcore
    spec:
      replicas: 2
      selector:
        matchLabels:
          name: edc-webapi
      template:
        metadata:
          labels:
            name: edc-webapi
        spec:
          containers:
          - name: edc-webapi-container
            image: edisonsaonian/k8s-demo:1.0
            ports:
            - containerPort: 80
            imagePullPolicy: IfNotPresent
    
    ---
    
    apiVersion: v1
    kind: Service
    metadata:
      name: edc-webapi-service
      namespace: aspnetcore
    spec:
      type: NodePort
      ports:
        - nodePort: 31000 
          port: 8080
          targetPort: 80
      selector:
        name: edc-webapi

      然后,通过kubectl进行创建:

    kubectl apply -f k8s-demo.yaml

      通过kubectl进行验证:

      

       通过外部访问接口验证:

      

      假设1.0版本运行了一段时间,我们又做了一些优化准备发布1.1版本,那么这时我们可以借助Rolling Update进行滚动更新,只需要修改一下YAML配置文件:将镜像版本的Tag更改为1.1即可。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: edc-webapi-deployment
      namespace: aspnetcore
    spec:
      replicas: 2
      selector:
        matchLabels:
          name: edc-webapi
      template:
        metadata:
          labels:
            name: edc-webapi
        spec:
          containers:
          - name: edc-webapi-container
            image: edisonsaonian/k8s-demo:1.1
            ports:
            - containerPort: 80
            imagePullPolicy: IfNotPresent

      同样,再次通过kubectl进行创建即可完成实时更新:

    kubectl apply -f k8s-demo.yaml

      再次验证一下:镜像已经变成了1.1

      

       通过外部接口访问,返回数据也已经更新:

      

      按照上面的步骤,我们再次更新到1.2,最后的效果如下:

      

    三、回滚实践

      当我们通过kubectl每次更新应用时,K8S都会记录下当前的配置,保存为一个revision(版次),这样就可以回滚到某个特定的revision。回想一下,我们在版本管理工具类似于SVN,Git中,都可以方便的回滚到之前的某个revision中。

      默认配置下,K8S只会保留最近的几个revision,可以在Deployment配置文件中通过revisionHistoryLimit属性增加revision数量。例如下面的例子,将revision数量设置为10:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: edc-webapi-deployment
      namespace: aspnetcore
    spec:
      revisionHistoryLimit: 10
      ......

      下面,以上面的示例为例,我们发现V1.2版本中存在某些bug,需要回退到上一个V1.1版本:

    kubectl rollout undo deployment edc-webapi-deployment -n aspnetcore

      

       通过外部访问接口验证一下:已经回退到了1.1了。

      

       如果想要回退到更远的老版本呢?这时,就需要借助--record命令了。怎么弄呢?下面慢慢道来:

      (1)准备三个YAML配置文件,分别是:k8s-demo-v1.0.yaml,k8s-demo-v1.1.yaml及k8s-demo-v1.2.yaml。

      (2)通过kubectl apply部署并更新应用,需要注意的就是加上 --record。

      

      加上--record的作用在于将当前命令记录到revision(版次)记录中,这样可以方便我们在后面通过kubectl rollback时去指定revision。我们也可以通过以下命令去查看各个revision的记录:

    kubectl rollout history deployment edc-webapi-deployment -n aspnetcore

      

      这里可以通过CHANGE-CAUSE看到每个revision的具体含义,前提条件就是需要在kubectl apply时加上--record参数

      (3)这时我们再进行rollback时,可以指定具体revision号了:

    kubectl rollout undo deployment edc-webapi-deployment --to-revision=1 -n aspnetcore

      

       验证一下是否回退到了1.0版本:

      

       可以看到,已经从1.2回退到了1.0版本,符合预期!

    四、Rolling Update原理

      K8S中对于更Rolling Update的操作主要是针对ReplicaSet的操作,可以通过如下命令查看验证:

    kubectl get replicaset -n aspnetcore -o wide

      可以看到1.0的ReplicaSet edc-webapi-deployment-75977bbfdc创建之后然后被清理了,已经没有正在运行的Pod了。转而创建了新的ReplicaSet edc-webapi-deployment-797dd9b8f8,它有两个正在运行的Pod。

      

       具体过程我们还可以通过以下命令查看:

    kubectl describe deployment edc-webapi-deployment -n aspnetcore

      

       通过日志可以看到,在进行对ReplicaSet的伸缩过程中,ReplicaSet会随之增加或减少一个Pod,从而完成Pod的替换以实现滚动更新的结果。

    五、小结

      滚动更新的最大好处在于零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性。本文介绍了滚动更新的概念,然后通过更新和回滚一个ASP.NET Core应用演示了如何在K8S中进行滚动更新。

    参考资料

    (1)CloudMan,《每天5分钟玩转Kubernetes

    (2)李振良,《一天入门Kubernets教程

    (3)马哥(马永亮),《Kubernetes快速入门

    (4)go4it,《使用kubernetes的deployment进行RollingUpdate

  • 相关阅读:
    iOS 进阶 第一天(0323)
    iOS 基础 第五天(0811)
    iOS 基础 第四天(0809)
    iOS 基础 第三天(0808)
    iOS 基础 第三天(0807)
    iOS 基础 第二天(0805)
    iOS 基础 第一天(0804)
    Mac 启用http-dav功能(WebDAV服务器)
    【转】phpmyadmin万能密码漏洞
    关于python文件操作 (转载)
  • 原文地址:https://www.cnblogs.com/edisonchou/p/aspnet_core_on_k8s_deepstudy_part5.html
Copyright © 2011-2022 走看看