Deployment 部署
Kubernetes 部署可以帮助每一个应用程序的生命都保持相同的一点:那就是变化。此外,只有挂掉的应用程序才会一尘不变,否则,新的需求会源源不断地涌现,更多代码会被开发出来、打包以及部署。这个过程中的每一步都有可能出错。
部署资源可以自动化应用程序从一版本升迁到另一版本的过程,并保证服务不间断,如果有意外发生,它可以让我们迅速回滚到前一个版本。
部署实践
现在我们有两个 Pod 和一个服务开放,而且它们之间有负载均衡(如图 19 所示)。我们提到过现有的 Pod 还远远不够完美。需要分开管理每一个 Pod(创建、更新、删除和监视他们的情况)。快速更新和迅速回滚根本不可能!这样是不行的,部署 Kubernetes 资源可以解决这里的每个问题。
图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 已更新了。
图20:绿色按钮
“RollingUpdate”背后的情况
在我们应用了新的部署后,Kubernetes 会将新状态与旧的相比。在我们的例子中,新状态需要两个
rinormaloku/sentiment-analysis-frontend:green 映像的 Pod。这与当前的运行状态不同,所以
Kubernetes 会执行 RollingUpdate。
图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,译者:弯月,责编:郭芮