今回はタイトルにあるように Pod が定義された YAML ファイルに任意の環境変数を追加して再度 YAML ファイルとして出力する。
満たしたい要件は
今回は下記の YAML を使用する。
# pod.yaml apiVersion: v1 kind: Pod metadata: name: apps spec: containers: - name: app-1 image: busybox - name: app-2 image: busybox
ゴールとしては下記のファイルが出力されることを目指す。
apiVersion: v1 kind: Pod metadata: name: apps spec: containers: - name: app-1 image: busybox - name: app-2 image: busybox env: - name: FOO value: BAR
yq
YAML ファイルの操作になるので真っ先に思いついたのが yq を使うことでした。
公式サイトを見ると Multiply (Merge) に今回のように環境変数を追加したい時に使える例が書いてあるので、これをベースに今回の要件を満たすように変更したコマンドが下記になります。
➜ idPath=".name" originalPath=".spec.containers[] | select(.name == \"app-2\") | .env" otherPath=".env" yq eval-all ' ( (( ((eval(strenv(originalPath)) // []) + eval(strenv(otherPath))) | .[] | {(eval(strenv(idPath))): .}) as $item ireduce ({}; . * $item )) as $uniqueMap | ( $uniqueMap | to_entries | .[]) as $item ireduce([]; . + $item.value) ) as $mergedArray | select(fi == 0) | (eval(strenv(originalPath))) = $mergedArray ' pod.yaml <(echo '{"env": [{"name": "FOO", "value": "BAR"}]}' | yq -P)
むずかしいですね。。。yq 慣れしてない私はパッと見ただけでは何が起きているのか分かりませんでした。
kubectl
次に試したのが kubectl です。今回は Kubernetes のリソースを扱うので kubectl で実現できないかと試しました。結果としてできたコマンドは下記になります。
cat pod.yaml | \ kubectl patch \ -f - \ --local \ -o yaml \ -p ' { "spec": { "containers": [ { "name": "app-2", "env": [ { "name": "FOO", "value": "BAR" } ] } ] } }'
今回は yq の時よりは分かりやすくなったのではないでしょうか。-p
で指定している JSON を使用して patch が行われ、spec.containers
内で name
を指定することによって特定のコンテナに環境変数が追加されます。
環境変数を追加するという目的であれば kubectl set env
も使えるのですが、これは変更がない場合には YAML ファイルを出力してくれなかったので、kubectl patch
を使用しています。
最後に
今回は Pod の YAML ファイルに env を追加して YAML ファイルを出力するために yq
と kubectl
を試し最終的にシンプルさから kubectl
を選択しました。 Kubernetes 周りの操作をする時は、まずは kubectl
で実現できないかをしていくと良さそう。