Kubernetesでliveness/readinessProbeのexec commandが実行される流れ

kubernetes

Kubernetesのliveness/readinessProbe はPodが生きているか/リクエストを受けられるかの判定で、 後者はアプリケーションの起動に時間がかかる場合などに使われる。 ヘルスチェックのようなエンドポイントを叩くのはhttpGetでできるが、任意のcommandを実行することもできる。

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
    httpHeaders:
    - name: X-Custom-Header
      value: Awesome

Manifestに書かれたProbeは、 各ノードで動いているkubeletPodが追加されたときにworkerを 作って runProbe()で実行させている。

if p.Exec != nil {
    glog.V(4).Infof("Exec-Probe Pod: %v, Container: %v, Command: %v", pod, container, p.Exec.Command)
    command := kubecontainer.ExpandContainerCommandOnlyStatic(p.Exec.Command, container.Env)
    return pb.exec.Probe(pb.newExecInContainer(container, containerID, command, timeout))
}

まずcommandに含まれる$( )で囲まれた文字列を Expand() で存在すればcontainerのenvの値に置き換える。

その後、 RunInContainer()で、 コンテナランタイムがK8s標準のCRI(Container Runtime Interface)に対応している場合はそのAPIの、 対応していない場合は~shimパッケージのExecSync()が呼ばれ、コンテナ内でcommandを実行させて結果を受け取り、終了コードが0でなければエラーとする。

$( )でenvの値が使えることを確認する。

$ kubectl config use-context docker-for-desktop
$ cat test.yaml
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: "test"
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: "test"
    spec:
      containers:
        - name: "test"
          image: "alpine"
          command: ["top"]
          env:
          - name: TEST
            value: "foobar"
          ports:
          - containerPort: 5000
            name: grpc
          readinessProbe:
            exec:
              command:
              - test
              - $(TEST)
              - =
              - foobar
            initialDelaySeconds: 0
            timeoutSeconds: 1

$ kubectl apply test.yaml
$ kubectl describe pod $(kubectl get pods -l app=test -o jsonpath='{.items[0].metadata.name}')
test-85994ddf4d-gpxpq       1/1       Running   0          9s