• k8s-控制器模式


    前言

    我们开始使用配置文件创建 Deployment .例如:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
    
    

    控制器模型

    但我们使用 k8s 进行拓展或是收缩 pod 里面的 containers 的时候 , 这个过程使用到了 k8s 中的控制模型,可以这样子表述 :

    for {
      实际状态 := 获取集群中对象 X 的实际状态(Actual State)
      期望状态 := 获取集群中对象 X 的期望状态(Desired State)
      if 实际状态 == 期望状态{
        什么都不做
      } else {
        执行编排动作,将实际状态调整为期望状态
      }
    }
    

    1297993-20210524232247614-200112308.png

    我们看到我们的 yaml 文件的定义 , 控制器在扩张和收缩动作的时候会努力调整到期望值 .

    作业副本与水平扩展

    我们上面讲了控制器模型,现在我们看一下扩展和收缩是如何工作,又是如何运用了控制器模型的. 如果你更新了 Deployment 的 Pod 模板(比如,修改了容器的镜像),那么 Deployment 就需要遵循一种叫作“滚动更新”(rolling update)的方式,来升级现有的容器。而这个能力的实现,依赖的是 Kubernetes 项目中的一个非常重要的概念(API 对象):ReplicaSet。 ReplicaSet 的结构非常简单,我们可以通过这个 YAML 文件查看一下:

    apiVersion: apps/v1
    kind: ReplicaSet
    metadata:
      name: nginx-set
      labels:
        app: nginx
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
    
    从这个 YAML 文件中,我们可以看到,一个 ReplicaSet 对象,其实就是由副本数目的定义和一个 Pod 模板组成的。不难发现,它的定义其实是 Deployment 的一个子集。
    
    更重要的是,Deployment 控制器实际操纵的,正是这样的 ReplicaSet 对象,而不是 Pod 对象。
    

    我们来看一下 Deployment , ReplicaSet , pod 之间的关系 .

    1297993-20210525072814529-774868333.png

    可以看到管理 pod 实际是 ReplicaSet , 而 Deployment 只负责 ReplicaSet , 上面的 yaml 中, 我们创建了3个副本,假如我们对所部署的 pod 进行了修改. 例如修改的内容如下 :

        spec:
          containers:
          - name: nginx
            image: nginx:1.9.1 # 1.7.9 -> 1.9.1
            ports:
            - containerPort: 80
    

    使用的nginx版本号变了,那么我们那三台机器如何更新呢?有两种方法

    • 第一种 : 旧版本全部停止,新版本更新完再上线
    • 第二种 : 旧版本边停止,边更新, "滚动更新"
    • 第三种 : 旧版本不停止,等新的全部更新好了,旧版本全部停止
      我们可以看到上面几种更新方法都是以旧版本存在于更新过程中的数量作为依据, 每一种都是有优点和缺点. 而 k8s 默认是第二种,"滚动更新",边启动新版本的pod,边停止旧的 pod , 如下图所示 :

    1297993-20210525073753390-1022297801.png

    这种更新的策略实际上是可以指定的.在我们的 yaml 中如下指定 :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
    ...
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 1
    

    总结

    通过这些讲解,你应该了解到:Deployment 实际上是一个两层控制器。首先,它通过ReplicaSet 的个数来描述应用的版本;然后,它再通过ReplicaSet 的属性(比如 replicas 的值),来保证 Pod 的副本数量。
    
    备注:Deployment 控制 ReplicaSet(版本),ReplicaSet 控制 Pod(副本数)。这个两层控制关系一定要牢记。
    
    不过,相信你也能够感受到,Kubernetes 项目对 Deployment 的设计,实际上是代替我们完成了对“应用”的抽象,使得我们可以使用这个 Deployment 对象来描述应用,使用 kubectl rollout 命令控制应用的版本。
    
    可是,在实际使用场景中,应用发布的流程往往千差万别,也可能有很多的定制化需求。比如,我的应用可能有会话黏连(session sticky),这就意味着“滚动更新”的时候,哪个 Pod 能下线,是不能随便选择的。
    
    这种场景,光靠 Deployment 自己就很难应对了。对于这种需求,我在专栏后续文章中重点介绍的“自定义控制器”,就可以帮我们实现一个功能更加强大的 Deployment Controller。
    
    当然,Kubernetes 项目本身,也提供了另外一种抽象方式,帮我们应对其他一些用 Deployment 无法处理的应用编排场景。这个设计,就是对有状态应用的管理,也是我在下一篇文章中要重点讲解的内容。
    

    我们这一节的主要内容是介绍了 k8s 中的一种常见的 Controller , 该 Controller 运用在我们 pod 的水平拓展和容器更新中,这也引出了 pod 之间的关系是复杂的,我们在部署运维和更新等操作过程中,都需要注意他们的关系然后用合适的步骤来进行操作,对此 k8s 提供了多种模型用来描述 pod 之间的关系,我们也将通过后面的课程来了解其他 Controller .

    其他

    有了 Deployment 的能力之后,你可以非常轻松地用它来实现金丝雀发布、蓝绿发布,以及 A/B 测试等很多应用发布模式。这些问题的答案都在这个 GitHub 库,建议你在课后实践一下 , 地址 :  https://github.com/ContainerSolutions/k8s-deployment-strategies/tree/master/canary
    

    k8s 发布策略

    有以下几个发布策略 :

    • recreate (重新创建): 暂停旧的并且发布一个新的
    • ramped (滚动更新): 一个跟着一个滚动更新
    • blue/green (蓝绿发版): 发布一个新的和一个旧的 ,然后旧的直接切换过去新的
    • canary (金丝鸟发版): 发布新版本给一小部分用户,等ok了全部迁移过去
    • a/b testing (ab 测试): 提供指定的一小撮用户
    • shadow (影子测试): 创建一个新版本的应用,复制相同的流量到新版本中去,测试两者返回的响应 它们的优缺点 : 1297993-20210528223852980-742282859.png

    参考

    • https://jimmysong.io/kubernetes-handbook/usecases/service-mesh.html
    • https://github.com/ContainerSolutions/k8s-deployment-strategies/tree/master/canary
  • 相关阅读:
    go操作windows进程相关
    HTML5-格式化
    HTML5-属性
    关于sublime建立python工程的说明
    在Windows系统中安装matplotlib,需要注意的问题
    WPF combobox数据绑定和数据获取
    String的用法——其他功能
    String的用法——获取功能
    String的用法——判断功能
    String的用法——构造方法
  • 原文地址:https://www.cnblogs.com/Benjious/p/14824422.html
Copyright © 2020-2023  润新知