こたつ&&みかん&&でーたべーす

DB 関連の話を中心に技術っぽい記事を書きます。

kubectl wait コマンドの --for=condition=XXXX に指定できる値を調べる

お仕事で同僚のエンジニアから kubectl wait--for=condition=XXXX に指定できる値 (condition の種類) ってどこで確認できるの?的な質問をもらったのですが、自分も知らなかったので調べてみました。

先に結論

kubernetes/pkg/apis/ 配下の各 API (coreapps 等) のディレクトリ配下にある types.go というファイルで Condition の名前 (種類) が定義されているようです。

全てのリソースを確認した訳ではありませんが、例えば以下のような感じで各リソースの Condition が定義されているっぽいことが確認できました。

いろいろ調査

先に結論を書きましたが、自分用の備忘録も兼ねて調査の過程を残しておきます。興味がある方はご覧ください。

環境

今回は Kubernetes v1.26 をベースに調べました。

とりあえず --help を確認

まずは kubectl wait コマンドの help を見てみたのですが、「condition-name を指定する」と書いてあるのみで、この condition-name に「どのような値を指定できるのか」という情報は見当たりませんでした。

$ kubectl wait --help

(snip)

Options:

    (snip)

    --for='':
        The condition to wait on: [delete|condition=condition-name[=condition-value]|jsonpath='{JSONPath
        expression}'=JSONPath Condition]. The default condition-value is true.  Condition values are compared after
        Unicode simple case folding, which is a more general form of case-insensitivity.

kubectl wait のドキュメントを確認

kubectl wait--help では分からなかったので、Kubernetes の公式ドキュメント Kubectl Reference Docs を調べてみました。

しかし、こちらの --for の説明も以下のようになっており、「どのような値を指定できるのか」という情報は見当たりませんでした。

The condition to wait on: [delete|condition=condition-name]. The default status value of condition-name is true, you can set false with condition=condition-name=false

雑にググってみる

--help やリファレンスマニュアルでは情報が見つからなかったので、それっぽいキーワードでググってみたところ、Kubernetes の公式ドキュメント Pod Lifecycle に「Pod の Condition の一覧」が記載されていました。しかし、Deployment 等の 「Pod 以外のリソース」の Condition の一覧のような情報が記載されたドキュメントは (私が探した範囲では) なさそうでした。

また、上記 Pod Lifecycle を見ると、Pod の Condition は PodCondition という構造体で定義されているっぽいことが確認できました。

PodCondition から情報を探る

前述した Pod Lifecycle を見ると type の説明が "Name of this Pod condition." となっており、どうやらこの type の値が Condition の名前になっているようです。また、PodCondition 側の type の説明にも "Type is the type of the condition." と記載されていました。

そこで、このあたりから「Kubernetes のリソースの Condition の名前 (種類) がどこで定義されているか」を探ってみました。

この PodCondition は "Appears In: PodStatus [core/v1]" となっています。さらに、PodStatus は "Appears In: Pod [core/v1]" となっています。

ということで、Pod の Condition の値 (名前?) は Pod -> PodStatus -> PodCondition -> type で定義されていそう、ということがわかりました。

kubectl explain から情報を探る

なんとなく type (Condition の名前) が定義されていそうな場所が分かったので、kubectl explain コマンドで対応していそうなフィールドを探してみました。

まず、kubectl explain pod を実行すると pod.status というフィールドがあることが確認できました。

$ kubectl explain pod

(snip)

FIELDS:

   (snip)

   status       <Object>
     Most recently observed status of the pod. This data may not be up to date.
     Populated by the system. Read-only. More info:
     https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

次に、kubectl explain pod.status を実行すると pod.status.conditions というそれっぽい感じのフィールドが見つかりました。

$ kubectl explain pod.status

(snip)

FIELDS:
   conditions   <[]Object>
     Current service state of pod. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions

さらに、kubectl explain pod.status.conditions を実行してみると、pod.status.conditions.type というフィールドがありました。

$ kubectl explain pod.status.conditions

(snip)

FIELDS:

   (snip)

   type <string> -required-
     Type is the type of the condition. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions

最後に kubectl explain pod.status.conditions.type を実行すると、最初にググった際に見つかったドキュメントへの URL (Pod の Condition の一覧が記載されていたドキュメントの URL) が記載されていました。どうやら、この pod.status.conditions.type で Condition の名前 (種類) が定義されている、ということで間違いなさそうです。

$ kubectl explain pod.status.conditions.type
KIND:     Pod
VERSION:  v1

FIELD:    type <string>

DESCRIPTION:
     Type is the type of the condition. More info:
     https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions

他のリソースについても kubectl explain から情報を探ってみる

Pod の場合は pod.status.conditions.type で Condition の名前 (種類) が定義されていそうな感じだったので、試しに他のリソースについても同じフィールド (xxxx.status.conditions.type) が存在しているか確認してみました。すると、(全てのリソースを確認した訳ではないですが) 他のリソースにも同様のフィールドが存在しているようでした。

$ kubectl explain node.status.conditions.type
KIND:     Node
VERSION:  v1

FIELD:    type <string>

DESCRIPTION:
     Type of node condition.
$ kubectl explain deployment.status.conditions.type
KIND:     Deployment
VERSION:  apps/v1

FIELD:    type <string>

DESCRIPTION:
     Type of deployment condition.
$ kubectl explain replicaset.status.conditions.type
KIND:     ReplicaSet
VERSION:  apps/v1

FIELD:    type <string>

DESCRIPTION:
     Type of replica set condition.

しかし、どのリソースの DESCRIPTION にも "Type of XXXX condition." としか記載されておらず、具体的な Condition の名前 (種類) は確認できませんでした... (´・ω・`)

ソースコードを調べる

ドキュメントや kubectl explain コマンドではこれ以上詳細な情報が得られそうになかったので、ソースコードを調べました。ドキュメントから PodCondition という構造体が存在していそうなことが確認できていたので、この PodCondition というキーワードでソースコード内を検索したところ、以下の構造体が見つかりました。

https://github.com/kubernetes/kubernetes/blob/v1.26.4/pkg/apis/core/types.go#L2485-L2497

// PodCondition represents pod's condition
type PodCondition struct {
    Type   PodConditionType
    Status ConditionStatus
    // +optional
    LastProbeTime metav1.Time
    // +optional
    LastTransitionTime metav1.Time
    // +optional
    Reason string
    // +optional
    Message string
}

TypePodConditionType 型になっているようなので、この PodConditionType の定義を探してみると、すぐ隣に以下のような定義がありました。

https://github.com/kubernetes/kubernetes/blob/v1.26.4/pkg/apis/core/types.go#L2460-L2483

// PodConditionType defines the condition of pod
type PodConditionType string

// These are valid conditions of pod.
const (
    // PodScheduled represents status of the scheduling process for this pod.
    PodScheduled PodConditionType = "PodScheduled"
    // PodReady means the pod is able to service requests and should be added to the
    // load balancing pools of all matching services.
    PodReady PodConditionType = "Ready"
    // PodInitialized means that all init containers in the pod have started successfully.
    PodInitialized PodConditionType = "Initialized"
    // PodReasonUnschedulable reason in PodScheduled PodCondition means that the scheduler
    // can't schedule the pod right now, for example due to insufficient resources in the cluster.
    PodReasonUnschedulable = "Unschedulable"
    // PodReasonSchedulingGated reason in PodScheduled PodCondition means that the scheduler
    // skips scheduling the pod because one or more scheduling gates are still present.
    PodReasonSchedulingGated = "SchedulingGated"
    // ContainersReady indicates whether all containers in the pod are ready.
    ContainersReady PodConditionType = "ContainersReady"
    // DisruptionTarget indicates the pod is about to be terminated due to a
    // disruption (such as preemption, eviction API or garbage-collection).
    DisruptionTarget PodConditionType = "DisruptionTarget"
)

kubectl explain pod.status.conditions を実行した際に表示されていたドキュメント Pod conditions に記載されている Condition の内容ともだいたい一致しているようなので、Condition の名前 (種類) はここで定義されているようです。

ただ、ドキュメント Pod conditions とこのソースコード上の定義は厳密には合致していないようです... もしかしたらバージョンの違い (「ドキュメントが前提にしているバージョン」と「確認したソースコードのバージョン」が違う?) 等による差異があるのかもしれませんが、これ以上の詳細はよくわかりませんでした...

まとめ

ということで、kubectl wait--for=condition=XXXX に指定できる値を知るために、Kubernetes の各リソースの Condition がどこで定義されているかを探してみました。

再掲になりますが、kubernetes/pkg/apis/ 配下の各 API (coreapps 等) のディレクトリ配下にある types.go というファイルで Condition の名前 (種類) が定義されているようです。

最近、稀に Kubernetesソースコードを読むことがあるのですが、Kubernetes はコードの量が膨大でやばいですね (語彙力)。