Kekeの日記

エンジニア、読書なんでも

JsonPathを変幻自在に操るKubernetes使いになろう

JSONPathとは

何かしらCLIツールでコマンドを実行した時にフォーマットをするようなものである。

たとえば以下のように実行する

kubectl get pods -o json

すると生のJSONが返ってくるので、このjsonにpathを指定することになる。

これに対してjsonpathを指定することによって効率のよく必要な情報が集められたりする。

JSONPathの使い方

注意点

全体は''で囲んで、中では""を使うこと。

使える項目

1. Child Operator

子要素を取得するものである

以下のように直接指定する。

kubectl get nodes -o=jsonpath="{.kind}"

=> List

kubectl get nodes -o=jsonpath="{.metadata}"

=> map[selfLink: resourceVersion:]

2. Recursive descent

再帰的に合致するものも抽出するものである。

kubectl get nodes -o=jsonpath="{..name}"

=> gke-locust-cluster-default-pool-8eb6b5df-9hjh gke-locust-cluster-default-pool-8eb6b5df-ctb5

3. Wild card

すべてのオブジェクトを取得するものである。

kubectl get nodes -o=jsonpath="{.items[*].name}"

4. Current Object

以下のFilterのSectionでもあるが、@でそのレベルでのオブジェクトを取得できる。

kubectl get nodes -o=jsonpath="{@}"

ここでは@に対応するのはルートオブジェクトである。

5. Filter

条件にかけて抽出するものである。

()の中に条件を入れる。Go templateで構成されているので、わからなければGo templateを参照するのがいいかもしれない。

kubectl get nodes -o=jsonpath="{.users[?(@.name==“e2e”)].user.password}"

6. Range

以下のように特定のArrayを持つようなオブジェクトに対してfor文を行う。{end}も忘れずに。

kubectl get nodes -o=jsonpath="{range .items[*]}[{.metadata.name}, {.status.capacity}] {end}"

7. Union

,で配列などを定義できる。もちろんオブジェクトも可能である。

kubectl get nodes -o=jsonpath="{range .items[*]}[{.metadata.name}, {.status.capacity}] {end}"

ユースケース

特定のNodeをDrainする

公式ページにもあった使い道です。

一般的には

  1. Node名を確認する
kubectl get nodes
  1. ひとつひとつDrainする
kubectl drain --force --ignore-daemonsets --delete-local-data --grace-period=10 [NODE1]
kubectl drain --force --ignore-daemonsets --delete-local-data --grace-period=10 [NODE2]
kubectl drain --force --ignore-daemonsets --delete-local-data --grace-period=10 [NODE3]
....

これをjsonpathを使うと

for node in $(kubectl get nodes -l cloud.google.com/gke-nodepool=default-pool -o=name); do
  kubectl drain --force --ignore-daemonsets --delete-local-data --grace-period=10 "$node";
done

このようにすることでNode名を知らなくても一気にdrainすることができます。ここで-lを指定しているのはラベルを使うためです。

参考文献

kubernetes.io