Kubernetesでliveness/readinessProbeのexec commandが実行される流れ
kubernetesKubernetesのliveness/readinessProbe はPodが生きているか/リクエストを受けられるかの判定で、 後者はアプリケーションの起動に時間がかかる場合などに使われる。 ヘルスチェックのようなエンドポイントを叩くのはhttpGetでできるが、任意のcommandを実行することもできる。
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
Manifestに書かれたProbeは、 各ノードで動いているkubeletが Podが追加されたときに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