zaki work log

作業ログやら生活ログやらなんやら

[kubectl / oc] jsonpathフィルター芸

前の記事でjsonpathを使って特定のカラムのみをピックアップする指定について説明したけど、条件を指定するフィルターも使えます。

zaki-hmkc.hatenablog.com

kubernetes.io

使用するのは?()という書式。

全体

[zaki@codeready ~]$ oc get pod -o wide
NAME                  READY   STATUS      RESTARTS   AGE   IP             NODE                 NOMINATED NODE   READINESS GATES
json-sock             1/1     Running     0          26m   10.128.0.227   crc-k4zmd-master-0   <none>           <none>
memoapp-db-1-deploy   0/1     Completed   0          52m   10.128.0.225   crc-k4zmd-master-0   <none>           <none>
memoapp-db-1-m9cxl    1/1     Running     0          52m   10.128.0.226   crc-k4zmd-master-0   <none>           <none>
sockserv-1-build      0/1     Completed   0          59m   10.128.0.222   crc-k4zmd-master-0   <none>           <none>
sockserv-1-cdgzf      1/1     Running     0          55m   10.128.0.224   crc-k4zmd-master-0   <none>           <none>
sockserv-1-deploy     0/1     Completed   0          55m   10.128.0.223   crc-k4zmd-master-0   <none>           <none>

条件なしで出力するとこんな感じのpod状態で確認。

例1 コンテナ名が"mysql"のpod名を出力

jsonpath='{.items[?(@.spec.containers[*].name=="mysql")].metadata.name}{"\n"}'

[zaki@codeready ~]$ oc get pod -o jsonpath='{.items[?(@.spec.containers[*].name=="mysql")].metadata.name}{"\n"}'
memoapp-db-1-m9cxl

例2 statusがCompletedのpodをrange使って1行ずつ

jsonpath='{range .items[?(@.status.containerStatuses[0].state.terminated.reason=="Completed")]}{.metadata.name}{"\n"}{end}'

[zaki@codeready ~]$ oc get pod -o jsonpath='{range .items[?(@.status.containerStatuses[0].state.terminated.reason=="Completed")]}{.metadata.name}{"\n"}{end}'
memoapp-db-1-deploy
sockserv-1-build
sockserv-1-deploy

例3 runningのpodとそのIPアドレスとノード名をtab区切り

jsonpath='{range .items[?(@.status.phase=="Running")]}{.metadata.name}{"\t"}{.status.podIP}{"\t"}{.spec.nodeName}{"\n"}{end}'

[zaki@codeready ~]$ oc get pod -o jsonpath='{range .items[?(@.status.phase=="Running")]}{.metadata.name}{"\t"}{.status.podIP}{"\t"}{.spec.nodeName}{"\n"}{end}'
json-sock       10.128.0.227    crc-k4zmd-master-0
memoapp-db-1-m9cxl      10.128.0.226    crc-k4zmd-master-0
sockserv-1-cdgzf        10.128.0.224    crc-k4zmd-master-0

例4 作成日時が2020.01.26 11:35(GMT)以降のpod

'{range .items[?(@.metadata.creationTimestamp>"2020-01-26T11:35")]}{.metadata.name}{"\t"}{.metadata.creationTimestamp}{"\n"}{end}'
これは文字列比較してるだけだけど、運用で使いたい人はいるのかも。

[zaki@codeready ~]$ oc get pod -o jsonpath='{range .items[?(@.metadata.creationTimestamp>"2020-01-26T11:35")]}{.metadata.name}{"\t"}{.metadata.creationTimestamp}{"\n"}{end}'
json-sock       2020-01-26T12:04:39Z
memoapp-db-1-deploy     2020-01-26T11:37:54Z
memoapp-db-1-m9cxl      2020-01-26T11:38:03Z
sockserv-1-cdgzf        2020-01-26T11:35:18Z
sockserv-1-deploy       2020-01-26T11:35:00Z

ちなみに無条件に出力するとこんな感じ。

[zaki@codeready ~]$ oc get pod -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.creationTimestamp}{"\n"}{end}'
json-sock       2020-01-26T12:04:39Z
memoapp-db-1-deploy     2020-01-26T11:37:54Z
memoapp-db-1-m9cxl      2020-01-26T11:38:03Z
sockserv-1-build        2020-01-26T11:31:29Z
sockserv-1-cdgzf        2020-01-26T11:35:18Z
sockserv-1-deploy       2020-01-26T11:35:00Z

kubectlでももちろん使用可能。

…とはいえここまで書くとぶっちゃけメンテ困難なので、JSONをparseできて辞書型&配列操作できるオブジェクトとして処理できるプログラミング言語で処理した方がよさげ。