美文网首页
Kubernetes-Deployment详解

Kubernetes-Deployment详解

作者: 12点前睡觉hhh | 来源:发表于2019-10-28 11:00 被阅读0次

    Deployment与控制器模型

    Deployment可以帮我们做什么

    • 定义一组Pod期望数量,Controller会维持Pod数量与期望数量一致
    • 配置Pod的发布方式,controller会按照给定的策略更新Pod,保证更新过程中不可用Pod维持在限定数量范围内
    • 如果发布有问题支持回滚

    实例

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

    控制器模型

    在Kubernetes架构中,有一个叫做kube-controller-manager的组件。这个组件,是一系列控制器的集合。

    其中每一个控制器,都以独有的方式负责某种编排功能。而Deployment正是这些控制器中的一种。它们都遵循Kubernetes中一个通用的编排模式,即:控制循环

    用一段go语言伪代码,描述这个控制循环

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

    在具体实现中,实际状态往往来自于Kubernetes集群本身。比如Kubelet通过心跳汇报的容器状态和节点状态,或者监控系统中保存的应用监控数据,或者控制器主动收集的它感兴趣的信息,这些都是常见的实际状态的来源;期望状态一般来自用户提交的YAML文件,这些信息都保存在Etcd中

    对于Deployment,它的控制器简单实现如下:

    1. Deployment Controller从Etcd中获取到所有携带 “app:nginx”标签的Pod,然后统计它们的数量,这就是实际状态
    2. Deployment对象的replicas的值就是期望状态
    3. Deployment Controller将两个状态做比较,然后根据比较结果,确定是创建Pod,还是删除已有Pod

    Deployment的滚动更新

    Deployment滚动更新的实现,依赖的是Kubernetes中的ReplicaSet

    Deployment控制器实际操纵的,就是Replicas对象,而不是Pod对象。对于Deployment、ReplicaSet、Pod它们的关系如下图:

    image.png

    ReplicaSet负责通过“控制器模式”,保证系统中Pod的个数永远等于指定的个数。这也正是Deployment只允许容器的restartPolicy=Always的主要原因:只有容器能保证自己始终是running状态的前提下,ReplicaSet调整Pod的个数才有意义。

    Deployment同样通过控制器模式,操作ReplicaSet的个数和属性,进而实现“水平扩展/收缩”和“滚动更新”两个编排动作

    对于“水平扩展/收缩”的实现,Deployment Controller只需要修改replicas的值即可。

    用户执行这个操作的指令如下:

    kubectl scale deployment nginx-deployment --replicas=4
    

    滚动更新的过程

    首先,创建上述Pod

    [root@host1 deployment]# kubectl create -f nginx-deployment.yaml --record #record参数可以记录每次操作所执行的命令,方便日后查看
    deployment.apps/nginx-deployment created
    [root@host1 deployment]# kubectl get deployments
    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   3/3     3            3           21s
    [root@host1 deployment]# kubectl get rs
    NAME                          DESIRED   CURRENT   READY   AGE
    nginx-deployment-76bf4969df   3         3         3       62s
    [root@host1 deployment]# kubectl get pods
    NAME                                READY   STATUS    RESTARTS   AGE
    nginx-deployment-76bf4969df-jq4tj   1/1     Running   0          70s
    nginx-deployment-76bf4969df-jsln9   1/1     Running   0          70s
    nginx-deployment-76bf4969df-nbl8j   1/1     Running   0          70s
    test-projected-volume               1/1     Running   0          19h
    [root@host1 deployment]# kubectl rollout status deployment/nginx-deployment  #通过该指令可以实时查看对象的状态变化
    deployment "nginx-deployment" successfully rolled out
    [root@host1 deployment]# kubectl edit deployment/nginx-deployment #修改etcd中的API对象
    deployment.extensions/nginx-deployment edited
    [root@host1 deployment]# kubectl rollout status deployment/nginx-deployment
    Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
    [root@host1 deployment]# kubectl describe deployment/nginx-deployment
    ....
    Events:
      Type    Reason             Age   From                   Message
      ----    ------             ----  ----                   -------
      Normal  ScalingReplicaSet  22m   deployment-controller  Scaled up replica set nginx-deployment-76bf4969df to 3
      Normal  ScalingReplicaSet  17m   deployment-controller  Scaled up replica set nginx-deployment-779fcd779f to 1
      Normal  ScalingReplicaSet  16m   deployment-controller  Scaled down replica set nginx-deployment-76bf4969df to 2
      Normal  ScalingReplicaSet  16m   deployment-controller  Scaled up replica set nginx-deployment-779fcd779f to 2
      Normal  ScalingReplicaSet  15m   deployment-controller  Scaled down replica set nginx-deployment-76bf4969df to 1
      Normal  ScalingReplicaSet  15m   deployment-controller  Scaled up replica set nginx-deployment-779fcd779f to 3
      Normal  ScalingReplicaSet  15m   deployment-controller  Scaled down replica set nginx-deployment-76bf4969df to 0
    
    

    首先,当你修改了Deployment中的Pod定义之后,Deployment Controller会使用这个修改后的Pod模板,创建一个新的ReplicaSet,这个ReplicaSet的初始Pod副本数是:0

    然后在17m的时候,Deployment Controller开始将这个新的ReplicaSet所控制的Pod副本数从0变为1,即水平扩展出与i个副本

    接着,在16m的时候,Deployment Controller将旧的ReplicaSet所控制的旧Pod副本数减少一个

    ....

    如此交替,就弯沉了一组Pod版本更新过程。

    [root@host1 deployment]# kubectl get rs
    NAME                          DESIRED   CURRENT   READY   AGE
    nginx-deployment-76bf4969df   0         0         0       26m
    nginx-deployment-779fcd779f   3         3         3       21m
    

    Deployment还会确保,在任何时间窗口内,只有指定比例的Pod处于离线状态,同时确保,在任何时间窗口内,只有指定比例的新Pod被创建出来,这两个值都可以配置,默认是25%

    这个策略,是Deployment对象的一个字段,叫做RollingUpdateStrategy,如下:

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

    maxSurge指定的是除了DESIRED数量之外,在一次滚动中,Deployment控制器还可以创建多少个新Pod;

    maxUnavailable指的是,在一次滚动中,Deployment控制器可以删除多少个旧Pod

    回滚

    首先我们使用kubeclt rollout history命令,查看每次Deployment变更对应的版本

    然后使用kubeclt rollout undo deployment/[deployment-name] --to-revision=[版本号]

    参考:阿里云大学云原生技术公开课 极客时间深入剖析Kubernetes

    相关文章

      网友评论

          本文标题:Kubernetes-Deployment详解

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