【问题标题】:Ensure Kubernetes Deployment has completed and all pods are updated and available确保 Kubernetes 部署已完成并且所有 pod 都已更新且可用
【发布时间】:2016-05-25 22:00:22
【问题描述】:

The status of a deployment 表示您可以查看部署observedGenerationgeneration,当observedGeneration >= generation 时部署成功。没关系,但我很想知道新容器何时在我的 所有 pod 中实际运行,因此如果我点击服务,我肯定知道我正在点击代表最新部署的容器。

来自 K8S Slack 成员的另一个提示:

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

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

【问题讨论】:

    标签: bash kubernetes


    【解决方案1】:

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

    更新 #1:我已将我的答案转换为 script hosted on Github,目前已收到少量改进的 PR。

    原答案:

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

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

    获得可用副本的数量(第 5 列)

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

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

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

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

    这是我写的一个快速的 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="$1"
    
      kubectl get deployment "${deployment}" -o "jsonpath=${_jsonpath}"
    }
    
    if [[ $# != 1 ]]; then
      echo "usage: $(basename $0) <deployment>" >&2
      exit 1
    fi
    
    readonly deployment="$1"
    
    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."
    

    【讨论】:

    【解决方案2】:

    只需使用rollout status

    kubectl rollout status deployment/<deployment-name>
    

    这将在前台运行,它等待并显示状态,并在部署成功或失败时退出。 如果你正在编写一个 shell 脚本,那么在命令之后检查返回码,就像这样。

    kubectl rollout status deployment/<deployment-name>
    if [[ "$?" -ne 0 ]] then
        echo "deployment failed!"
        exit 1
    fi
    

    进一步自动化您的脚本:

    deployment_name=$(kubectl get deployment -n <your namespace> | awk '!/NAME/{print $1}')  
    kubectl rollout status deployment/"${deployment_name}" -n <your namespace>
    if [[ "$?" -ne 0 ]] then
        echo "deployment failed!"
        #exit 1
    else
        echo "deployment succeeded"
    fi
    

    如果您在默认命名空间中运行,则可以省略 -n 。 命令 awk '!/NAME/{print $1}') 提取第一个字段(部署名称),同时忽略作为标题的第一行(NAME READY UP-TO-DATE可用年龄)。 如果您有多个部署文件,那么您还可以向 awk 添加更多正则表达式或模式:例如awk '!/NAME//{print $1}')

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-18
      • 2021-12-24
      • 1970-01-01
      • 1970-01-01
      • 2019-08-10
      • 2021-09-21
      • 2022-08-14
      • 1970-01-01
      相关资源
      最近更新 更多