Kubernetes从零到精通(06-工作负载-Deployment)

工作负载        

        我们的应用以容器的形式在Kubernetes下的Pods中运行;但是,直接管理单个Pod的工作量将会非常繁琐(例如,一个Pod失败了,我们要挑选一个node节点再运行一个新的Pod来替换它,尤其是微服务框架下应用服务Pod数量非常大)。Kubernetes定义并实现了更高一层的抽象资源-工作负载。Kubernetes控制平面根据我们定义的工作负载对象规约自动管理Pod对象,其中最常见的就是Deployment。

Deployment用例

        首先我们看下ReplicaSet这个控制器,它直接管理Pod,确保指定数量的Pod副本始终处于运行状态,当Pod终止时,ReplicaSet会自动创建新的Pod实例以保持预设的副本数量。

        Deployment是一个更高级的抽象,提供了滚动更新和版本回滚功能,并且管理ReplicaSet。这意味着,我们可能永远不需要操作ReplicaSet对象,而是使用Deployment,并在spec部分定义我们的应用。

        当我们创建一个Deployment对象,也就自动创建了一个或多个ReplicaSet对象,然后自动创建一个或多个Pod及需要的副本。  

         以下是一个Deployment的示例,我们看一下参数的定义:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: example
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: nginx-demo
      namespace: example
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.1
        ports:
        - containerPort: 80

.spec.template就是上一节我们介绍的Pod定义的模版,被嵌套在Deployment模版中,这是常用做法(注意Pod被.spec.template.labels打上了标签,值为app: nginx);
.spec.selector字段定义创建的ReplicaSet如何查找要管理的Pod,这里通过.spec.selector.matchLabels匹配标签值为app: nginx的Pod;
.spec.replicas表示创建三个Pod副本(Pod副本根据默认规则和自定义的规则,可能分散在不同的node服务器上);
.metadata下是Deployment的一些基本定义:字段,名称,所在的命名空间,标签等;

        同样的,我们执行kubectl命名kubectl apply -f deployment-demo.yaml就可以一键部署:

kubectl apply -f deployment-demo.yaml

        每隔几秒执行一次kubectl get deployments -n example 可以看到副本数量的变化:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   0/3     0            0           1s

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/3     0            0           2s

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/3     0            0           2s

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           10s

        再查看Deployment创建的ReplicaSet(rs),运行kubectl get rs -n example 查看输出:

NAME                          DESIRED   CURRENT   READY   AGE
nginx-deployment-25455e5167   3         3         3       15s

        最后运行kubectl get pods -n example查看Pod的状态:

NAME                                READY     STATUS    RESTARTS   AGE     
nginx-deployment-25455e5167-1ac7i   1/1       Running   0          21s   
nginx-deployment-25455e5167-kssfz   1/1       Running   0          21s  
nginx-deployment-25455e5167-qmczt   1/1       Running   0          21s   

        从带哈希字符串的名称,也可以看到他们的关联关系:
nginx-deployment > nginx-deployment-25455e5167 > nginx-deployment-25455e5167-1ac7i

Deployment更新

常用操作

        当Deployment Pod模板(即 .spec.template)发生改变时(例如模板的标签或容器镜像被更新),会触发Deployment上线动作。其他更改(例如对Deployment执行扩缩容的操作)不会触发上线动作。
        我们以应用容器镜像版本为例(从nginx:1.14.1升级为nginx:1.14.2),介绍更新Deployment的几种方法如下:
1.编辑deployment-demo.yaml的内容,然后执行kubectl apply -f deployment-demo.yaml
2.执行命令行 kubectl set image deployment/nginx-deployment nginx=nginx:1.14.2
3.执行命令行 kubectl edit deployment/nginx-deployment 然后编辑内容,保存
        然后我们执行kubectl rollout status deployment/nginx-deployment查看上线状态,输出类似:

Waiting for rollout to finish: 1 out of 3 new replicas have been updated...

Waiting for rollout to finish: 2 out of 3 new replicas have been updated...

deployment "nginx-deployment" successfully rolled out

滚动更新机制

        Deployment确保在更新时仅关闭一定数量的Pod。默认情况下,它确保至少所需Pod的75%处于运行状态(最大不可用比例为25%),新版本的默认值有调整。
        更新Deployment时,Kubernetes创建了一个新的ReplicaSet(nginx-deployment-25455a9568),并将其扩容为1,等待其就绪;然后将旧ReplicaSet缩容到 2, 将新的ReplicaSet扩容到2以便至少有3个Pod可用且最多创建4个Pod。然后,使用相同的滚动更新策略继续对新的ReplicaSet扩容并对旧的ReplicaSet缩容。 最后,有3个可用的副本在新的ReplicaSet中,旧ReplicaSet将缩容到0。

Rollover机制

        实际使用过程中,可能出现的情况:当Deployment正在上线时又被更新。这种情况下,Deployment会针对更新创建一个新的ReplicaSet并开始对其扩容,之前正在被扩容的ReplicaSet会被Rollover,添加到旧ReplicaSet列表并开始缩容。
        例如,我正在更新一个Deployment以生成nginx:1.14.2的5个副本,但又有一个小伙伴更新Deployment要创建5个nginx:1.16.1的副本,此时只有3个nginx:1.14.2的副本已被创建。这种情况下,Deployment会立即开始杀死3个nginx:1.14.2的Pod,并开始创建nginx:1.16.1的Pod。它不会等待nginx:1.14.2的5个副本都创建完成后才开始执行变更动作。

回滚Rolling Back

        当我们部署的新版本出现问题,暂时无法修复的情况下,可以执行回滚操作(默认情况下,Deployment的所有上线版本记录都保留在系统中,以便可以随时回滚)。同样的,当Deployment Pod模板(即 .spec.template)发生改变时,Kubernetes才会记录新修订版本,Deployment的扩缩容操作不会创建Deployment上线版本。
        首先检查历史版本:

kubectl rollout history deployment/nginx-deployment

        输出结果类似:

deployments "nginx-deployment"
REVISION    CHANGE-CAUSE
1           kubectl apply --filename=deployment-demo.yaml
2           kubectl set image deployment/nginx-deployment nginx=nginx:1.14.1
3             kubectl set image deployment/nginx-deployment nginx=nginx:1.14.2
4           kubectl set image deployment/nginx-deployment nginx=nginx:heiheihei

        确认想要回滚的版本详细信息(可选)

kubectl rollout history deployment/nginx-deployment --revision=3 

        输出结果类似:

deployments "nginx-deployment" revision 3
  Labels:       app=nginx
          pod-template-hash=25455a9568
  Annotations:  kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.14.2
  Containers:
   nginx:
    Image:      nginx:1.14.2
    Port:       80/TCP
     QoS Tier:
        cpu:      BestEffort
        memory:   BestEffort
    Environment Variables:      <none>
  No volumes. 

        执行回滚操作:

kubectl rollout undo deployment/nginx-deployment --to-revision=3 

最后执行必要的检查。 

扩缩容

        关于扩缩容,会在HPA资源介绍的时候详细说明,下面通过命令行方式简单看一下:
手动扩缩容,副本数的目标是10个:

kubectl scale deployment/nginx-deployment --replicas=10

自动扩缩容,pod的cpu使用率不超过80%的情况下,自动保持副本数在10到15之间

kubectl autoscale deployment/nginx-deployment --min=10 --max=15 --cpu-percent=80 

暂停、恢复Deployment上线

        有时我们在上线时需要暂停更新,以便执行一些程序修补等,避免触发一些不必要的操作,执行如下命令即可:
        暂停

kubectl rollout pause deployment/nginx-deployment

        恢复

kubectl rollout resume deployment/nginx-deployment 

注意,暂停不是把Deployment和Pod的功能暂停了,应用是正常对外提供服务的,暂停的只是更新操作。

金丝雀部署Canary Deployment

        金丝雀部署是逐步发布新版本应用程序的策略。它允许我们在将新版本完全替换旧版本之前,先将新版本部署到一小部分用户,以便在真实环境中测试其稳定性和性能。

        而Kubernetes的Deployment更新默认是RollingUpdate滚动升级,或者手动修改为Recreate(在创建新 Pod 之前,所有现有的 Pod 会被杀死),更新策略都是针对副本数量的并且自动化的,无法满足金丝雀部署的需求。
        常用的方法举例:
1.准备新的Deployment,其中Pod标签labels也设置为相同的值,例如本文中的app: nginx,容器镜像版本是新版本nginx:1.8.0,副本数.spec.replicas是1;
2.前端有个Service的selector是app: nginx,所以经过这个Service网络流量会有一小部分转发到新的Pod上,大部分流量还是在旧的Pod上;
3.观察业务新版本的稳定性和性能,新的Deployment的副本数+1,旧的Deployment的副本数-1;
4.重复步骤3,直到新版本完全替换旧版本;

  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炸裂狸花猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值