美文网首页
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