bash 确保 Kubernetes 部署已完成且所有 Pod 均已更新且可用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37448357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 14:40:57  来源:igfitidea点击:

Ensure Kubernetes Deployment has completed and all pods are updated and available

bashkubernetes

提问by devth

The status of a deploymentindicates that you can look at a deployments observedGenerationvs generationand when observedGeneration >= generationthen the deployment succeeded. That's fine, but I'm interested in knowing when the new container is actually running in allof my pods, so that if I hit a service I know for sure I'm hitting a server that represents the latest deployed container.

部署的状态表明,你可以看看一个部署observedGenerationVSgeneration并在observedGeneration >= generation随后的部署成功。这很好,但我想知道新容器何时在我的所有pod 中实际运行,因此如果我访问了一个服务,我肯定会访问一个代表最新部署的容器的服务器。

Another tip from a K8S Slack member:

K8S Slack 成员的另一个提示:

kubectl get deployments | grep <deployment-name> | sed 's/ /,/g' | cut -d ' ' -f 4

I deployed a bad image, resulting in ErrImagePull, yet the deployment still reported the correct number of 8 up-date-date replicas (available replicas was 7).

我部署了一个错误的映像,导致ErrImagePull,但部署仍然报告了正确数量的 8 个最新副本(可用副本为 7 个)。

回答by Timo Reimann

Update #2:Kubernetes 1.5 will ship with a much better version of kubectl rollout statusand improve even further in 1.6, possibly replacing my custom solution/script laid out below.

更新 #2:Kubernetes 1.5 将提供一个更好的版本,kubectl rollout status并在 1.6 中进一步改进,可能会取代我在下面列出的自定义解决方案/脚本。

Update #1:I have turned my answer into a script hosted on Githubwhich has received a small number of improving PRs by now.

更新 #1:我已将我的答案转换为托管在 Github 上脚本,脚本目前已收到少量改进的 PR。

Original answer:

原答案:

First of all, I believe the kubectlcommand you got is not correct: It replaces all white spaces by commas but then tries to get the 4th field after separating by white spaces.

首先,我相信kubectl您得到的命令不正确:它用逗号替换所有空格,然后尝试在用空格分隔后获取第 4 个字段。

In order to validate that a deployment (or upgrade thereof) made it to all pods, I think you should check whether the number of available replicas matches the number of desired replicas. That is, whether the AVAILABLEand DESIREDcolumns in the kubectloutput are equal. While you could get the number of available replicas (the 5th column) through

为了验证部署(或其升级)是否适用于所有 pod,我认为您应该检查可用副本的数量是否与所需的副本数量匹配。即输出中的AVAILABLEDESIRED列是否kubectl相等。虽然您可以通过以下方式获得可用副本的数量(第 5 列)

kubectl get deployment nginx | tail -n +2 | awk '{print $5}'

kubectl get deployment nginx | tail -n +2 | awk '{print $5}'

and the number of desired replicas (2nd column) through

以及所需副本的数量(第 2 列)到

kubectl get deployment nginx | tail -n +2 | awk '{print $2}'

kubectl get deployment nginx | tail -n +2 | awk '{print $2}'

a cleaner way is to use kubectl's jsonpath output, especially if you want to take the generation requirement that the official documentation mentions into account as well.

kubectl简洁的方法是使用的 jsonpath 输出,特别是如果您还想考虑官方文档中提到的生成要求。

Here's a quick bash script I wrote that expects to be given the deployment name on the command line, waits for the observed generation to become the specified one, and then waits for the available replicas to reach the number of the specified ones:

这是我编写的一个快速 bash 脚本,它期望在命令行上给出部署名称,等待观察到的生成成为指定的生成,然后等待可用副本达到指定的数量:

#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset

deployment=

get_generation() {
  get_deployment_jsonpath '{.metadata.generation}'
}

get_observed_generation() {
  get_deployment_jsonpath '{.status.observedGeneration}'
}

get_replicas() {
  get_deployment_jsonpath '{.spec.replicas}'
}

get_available_replicas() {
  get_deployment_jsonpath '{.status.availableReplicas}'
}

get_deployment_jsonpath() {
  local readonly _jsonpath=""

  kubectl get deployment "${deployment}" -o "jsonpath=${_jsonpath}"
}

if [[ $# != 1 ]]; then
  echo "usage: $(basename ##代码##) <deployment>" >&2
  exit 1
fi

readonly deployment=""

readonly generation=$(get_generation)
echo "waiting for specified generation ${generation} to be observed"
while [[ $(get_observed_generation) -lt ${generation} ]]; do
  sleep .5
done
echo "specified generation observed."

readonly replicas="$(get_replicas)"
echo "specified replicas: ${replicas}"

available=-1
while [[ ${available} -ne ${replicas} ]]; do
  sleep .5
  available=$(get_available_replicas)
  echo "available replicas: ${available}"
done

echo "deployment complete."