【三小时学会Kubernetes!(四) 】Deployment实践

Deployment 部署

Kubernetes 部署可以帮助每一个应用程序的生命都保持相同的一点:那就是变化。此外,只有挂掉的应用程序才会一尘不变,否则,新的需求会源源不断地涌现,更多代码会被开发出来、打包以及部署。这个过程中的每一步都有可能出错。

部署资源可以自动化应用程序从一版本升迁到另一版本的过程,并保证服务不间断,如果有意外发生,它可以让我们迅速回滚到前一个版本。

部署实践

现在我们有两个 Pod 和一个服务开放,而且它们之间有负载均衡(如图 19 所示)。我们提到过现有的 Pod 还远远不够完美。需要分开管理每一个 Pod(创建、更新、删除和监视他们的情况)。快速更新和迅速回滚根本不可能!这样是不行的,部署 Kubernetes 资源可以解决这里的每个问题。
【三小时学会Kubernetes!(四) 】Deployment实践
图19:现状

在继续下面的内容之前,让我们复述下我们的目标,通过概述可以让我们更好的理解部署资源的清单文件的定义。我们想要的是:

  • 映像 rinormaloku/sentiment-analysis-frontend 的两个 Pod;
  • 部署期间服务不间断;
  • Pod 贴有标签 app: sa-frontend,所以我们可以通过 sa-frontend-lb 服务找到各个服务。

在下一节中,我们可以将这些需求反映到部署的定义中。

Deployment 部署的定义

如下资源定义的YAML文件可以达成以上所有提到的点:

apiVersion: extensions/v1beta1
kind: Deployment                                          # 1
metadata:
  name: sa-frontend
spec:
  replicas: 2                                             # 2
  minReadySeconds: 15
  strategy:
    type: RollingUpdate                                   # 3
    rollingUpdate:
      maxUnavailable: 1                                   # 4
      maxSurge: 1                                         # 5
  template:                                               # 6
    metadata:
      labels:
        app: sa-frontend                                  # 7
    spec:
      containers:
        - image: rinormaloku/sentiment-analysis-frontend
          imagePullPolicy: Always                         # 8
          name: sa-frontend
          ports:
            - containerPort: 80

#1 kind:部署;

#2 replicas:是部署 Spec 对象的一个属性,定义了我们想运行多少的 Pod。所以是 2;

#3 type:指定从当前版本升迁到下个版本的时候,部署使用的策略。此处的策略 RollingUpdate 可以保证部署期间服务不间断;

#4 maxUnavailable:是 RollingUpdate 对象的一个属性,定义了在升级的时候,最大允许停止的 Pod 数量(与希望的状态相比)。对我们的部署来说,我们有 2 个副本,这意味着在一个 Pod 停止后,我们还会有另外一个 Pod 运行,所以可以保证应用程序可访问;

#5 maxSurge:是 RollingUpdate 对象的另一个属性,定义了添加到部署的最大 Pod 数量(与希望的状态相比)。对我们的部署来说,这意味着在向新版本迁移的时候,我 们可以加一个 Pod,那么我们可以同时拥有个 3 个 Pod;

#6 template:指定 Pod 的模板,部署在创建新 Pod 的时候,会用到该模板。很可能这个非常相似的 Pod 会立即吸引你;

#7 app: sa-frontend:根据模板创建的 Pod 将被贴上该标签;

#8 imagePullPolicy:当设置成 Always 的时候,每一次新部署都会重新获取容器映像。

坦白来说,这一堆的文本让我更糊涂了,所以还是让我们来看个例子:

kubectl apply -f sa-frontend-deployment.yaml
deployment "sa-frontend" created

照例让我们确认是否一切如约履行了:

kubectl get pods
NAME                           READY     STATUS    RESTARTS   AGE
sa-frontend                    1/1       Running   0          2d
sa-frontend-5d5987746c-ml6m4   1/1       Running   0          1m
sa-frontend-5d5987746c-mzsgg   1/1       Running   0          1m
sa-frontend2                   1/1       Running   0          2d

现在我们有 4 个运行中的 Pod,两个是由部署创建的,而另外两个是我们手动创建的。通过 kubectl delete pod 命令删除其中一个手动创建的 Pod。

练习:删除其中一个部署创建的 Pod,看看结果怎样。在阅读如下的解释前,请先想想原因。

解释:删除一个 Pod 后,部署注意到当前的状态(只有 1 个 Pod 在运行)与希望的状态(2 个 Pod 处于运行状态),所以它会再启动一个 Pod。

那么,除了保持希望的状态外,使用部署还有什么好处?让我们先来看看好处。

好处 1:采用零停机时间部署(Zero-downtime)

产品经理带着新的需求来找我们,说客户想要在前端加一个绿色的按钮。开发者写好了代码后,只需提供给我们一样必须的东西,容器映像 rinormaloku/sentiment-analysis-frontend:green。然后就该我们了,我们需要采用零停机时间部署,这项工作很难吗?让我们试试看!

编辑 deploy-frontend-pods.yaml 文件,将容器映像改为新的映像:rinormaloku/sentiment-analysis-frontend:green。保存变更,并运行如下命令:

kubectl apply -f deploy-frontend-green-pods.yaml --record
deployment "sa-frontend" configured

让我们通过如下命令检查下上线的状态:

kubectl rollout status deployment sa-frontend
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 of 2 updated replicas are available...
deployment "sa-frontend" successfully rolled out

从部署上看来,上线已经成功。在这个过程中副本被逐个替换。意味着应用程序始终在线。在继续下面的内容前,先让我们来确认一下更新确实有效。

确认部署

让我们在浏览器中确认更新的结果。运行我们之前用到过的命令 minikube service sa-frontend-lb,它会打开浏览器。我们可以看到按钮 SEND 已更新了。
【三小时学会Kubernetes!(四) 】Deployment实践
图20:绿色按钮

“RollingUpdate”背后的情况

在我们应用了新的部署后,Kubernetes 会将新状态与旧的相比。在我们的例子中,新状态需要两个
rinormaloku/sentiment-analysis-frontend:green 映像的 Pod。这与当前的运行状态不同,所以
Kubernetes 会执行 RollingUpdate。

【三小时学会Kubernetes!(四) 】Deployment实践

图21:RollingUpdate 替换 Pod

这里的 RollingUpdate 会根据我们指定的规格执行,也就是“maxUnavailable: 1″和“maxSurge:
1″。这意味着部署需要终止一个 Pod,并且仅可以运行一个新的 Pod。这个过程会不断重复,一直到所有的 Pod被替换(如图 21 所示)。

我们继续介绍第二个好处。

声明:出于娱乐的目的,下面的部分我按照小说的形式来书写。

好处2:回滚到前一个状态

产品经理跑进办公室说,他遇到一个大麻烦!

产品经理大喊道:“产品环境中的应用程序有一个很关键的 bug!!需要马上回滚到前一个版本”。

你冷静地看着他,眼睛都没有眨一下,就转向了心爱的终端,然后开始敲:

kubectl rollout history deployment sa-frontend
deployments "sa-frontend"
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl.exe apply --filename=sa-frontend-deployment-green.yaml --record=true

你看了一眼前一个部署,然后问产品经理:“上个版本很多 bug,那前一个版本运行得很完美吗?”

产品经理吼道:“是啊,你没听见我说嘛?!”

你没理他,你知道该如何处理,于是你开始敲:

kubectl rollout undo deployment sa-frontend --to-revision=1
deployment "sa-frontend" rolled back

然后,你轻轻地刷新了页面,之前的修改全都不见了!

产品经理瞠目结舌地看着你。

你拯救了大家!

我知道……这是个很无聊的故事。在 Kubernetes 出现之前,这个故事挺好的,更加戏剧化,让人高度紧张,而且这种状态持续了很长时间。那段旧时光还是很美好的!

大多数的命令都自带说明,只是有一些细节你需要自己搞清楚。为什么第一个版本中字段 CHANGE-CAUSE 的值为 ,而同时第二次改版的时候,CHANGE-CAUSE 的值为“kubectl.exe apply –filename=sa-frontend-deployment-green.yaml –record=true”。

你应该可以发现这是因为在应用新的映像的时候,我们用到了标志符 --record。

在下一节中,我们将使用之前所有的概念,完成整个架构。

来自:CSDN(微信号:CSDNnews),作者:Rinor Maloku,译者:弯月,责编:郭芮

上一篇:Java——final代码块是否一定被执行---18.11.08


下一篇:flex三个对齐属性的记忆方式