如何 kubectl 等待 crd 创建?

How to kubectl wait for crd creation?

仅使用 kubectl 命令行在 运行 脚本之前检查自定义资源定义是否存在的最佳方法是什么?

我们有一个 yaml 文件,其中包含 NATS 集群 ServiceAccountRoleClusterRoleBindingDeployment 的定义。 Deployment 中使用的映像创建 crd,第二个脚本使用 crd 部署一组 pods。目前我们的 CI 管道需要 运行 第二个脚本几次,只有在 crd 完全创建后才能成功完成。我试过使用 kubectl wait 但无法弄清楚要使用什么条件才能完成 crd

以下是我最近的一次尝试,虽然完全错误,但这说明了我们想要的一般顺序。

kubectl wait --for=condition=complete kubectl apply -f 1.nats-cluster-operator.yaml kubectl apply -f 2.nats-cluster.yaml

CRD 的条件为 established:

kubectl -n <namespace-here> wait --for condition=established --timeout=60s crd/<crd-name-here>

您可能需要适当调整 --timeout

如果您想等待一个可能不存在的资源,您可以尝试这样的操作:

{ grep -q -m 1 "crontabs.stable.example.com"; kill $!; } < <(kubectl get crd -w)

{ sed -n /crontabs.stable.example.com/q; kill $!; } < <(kubectl get crd -w)

我知道这个问题更愿意只使用 kubectl,但是这个答案对我的情况有帮助。这种方法的缺点是必须以不同的方式设置超时,并且实际上不会检查条件本身。

为了更彻底地检查情况,我做了以下操作:

#!/bin/bash

condition-established() {
    local name="crontabs.stable.example.com"
    local condition="Established"

    jq --arg NAME $name --arg CONDITION $condition -n \
        'first(inputs | if (.metadata.name==$NAME) and (.status.conditions[]?.type==$CONDITION) then
            null | halt_error else empty end)' 

    # This is similar to the first, but the full condition is sent to stdout
    #jq --arg NAME $name --arg CONDITION $condition -n \
    #    'first(inputs | if (.metadata.name==$NAME) and (.status.conditions[]?.type==$CONDITION) then
    #        .status.conditions[] | select(.type==$CONDITION) else empty end)' 
}

{ condition-established; kill $!; } < <(kubectl get crd -w -o json)

echo Complete

为了解释发生了什么,$! 通过 bash 的进程替换引用了命令 运行。我不确定这在其他 shell 中的效果如何。

我使用官方 kubernetes 文档中的 CRD 进行了测试。