k8s の複数 pod を横断してかつ「並列」でコマンドを実行する必要がある場合、どのような手段があるだろうか。例えばパフォーマンス測定のために jstat を複数 pod で実行したい場合、以下のように kubectl に pod を次々と「直列」で渡していっては、各 pod でコマンドの実行時間のズレが生じてしまう。何よりも jstat のように標準出力(stdout)を取られてしまうコマンドを kubectl に渡した場合、ひとつひとつ Ctrl+C していかなければならず、目的を果たすことができない。
複数 pod に「直列」でコマンドを実行する例
- pod リストを取得する
$ kubectl get pods -lapp=myapp -o jsonpath="{.items[*].metadata.name}" | xargs -n 1 echo myapp-78ccc84d99-2cr24 myapp-78ccc84d99-2pmp7 myapp-78ccc84d99-59f4g myapp-78ccc84d99-5bwkc myapp-78ccc84d99-5d8wc myapp-78ccc84d99-5fzsd myapp-78ccc84d99-67qkr
- 取得した pod リストを kubectl に渡して date コマンドを実行するものの、最初の pod と最後の pod で実行時間のズレが生じてしまう。ターミナルを pod 数分開いて「せーの」で実施すれば実行時間のズレはある程度是正できるものの、数十から数百 pod ある環境では現実的ではない。
$ while read p; do kubectl exec -it $p -c myapp -- date; done < <(kubectl get pods -lapp=myapp -o jsonpath="{.items[*].metadata.name}" | xargs -n 1 echo)
複数 pod に「並列」でコマンドを実行する例
- pod リストを取得する。parallel に渡すのに適したフォーマットにする。
$ kubectl get pods -lapp=myapp -o jsonpath="{.items[*].metadata.name}" myapp-78ccc84d99-2cr24 myapp-78ccc84d99-2pmp7 myapp-78ccc84d99-59f4g myapp-78ccc84d99-5bwkc myapp-78ccc84d99-5d8wc myapp-78ccc84d99-5fzsd myapp-78ccc84d99-67qkr myapp-78ccc84d99-6glcz myapp-78ccc84d99-6htmf myapp-78ccc84d99-7dchn
- parallel を使って並列でコマンドを流す。jstat は標準出力(stdout)に連続して出力しようとするので、ここでは標準出力を out ディレクトリ配下に吐き出すように指定する。
$ parallel --results out kubectl exec -it {} -c myapp -- /usr/bin/jstat -gcutil -t 1 1000 ::: $(kubectl get pods -lapp=myapp -o jsonpath="{.items[*].metadata.name}")
- 適当に時間が経過したところで Ctrl+C で jstat を中止する。out ディレクトリ配下を確認すると pod 名のディレクトリが自動作成され、jstat の標準出力が吐き出されていることが確認できる。
$ tree out/ out/ └── 1 ├── myapp-78ccc84d99-2cr24 │ ├── stderr │ └── stdout ├── myapp-78ccc84d99-2pmp7 │ ├── stderr │ └── stdout ├── myapp-78ccc84d99-59f4g │ ├── stderr │ └── stdout ├── myapp-78ccc84d99-5bwkc │ ├── stderr │ └── stdout ├── myapp-78ccc84d99-5d8wc │ ├── stderr │ └── stdout ├── myapp-78ccc84d99-5fzsd │ ├── stderr │ └── stdout ├── myapp-78ccc84d99-67qkr │ ├── stderr │ └── stdout ├── myapp-78ccc84d99-6glcz │ ├── stderr │ └── stdout └── myapp-78ccc84d99-6htmf ├── stderr └── stdout
$ cat out/1/myapp-78ccc84d99-*/stdout Timestamp S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 339412.0 36.71 0.00 33.87 85.15 97.85 96.46 112186 6009.403 232 25.555 6034.958 339413.1 36.71 0.00 62.38 85.15 97.85 96.46 112186 6009.403 232 25.555 6034.958 339414.1 36.71 0.00 89.70 85.15 97.85 96.46 112186 6009.403 232 25.555 6034.958 339415.1 0.00 37.42 24.00 85.20 97.85 96.46 112187 6009.455 232 25.555 6035.011 339416.1 0.00 37.42 61.76 85.20 97.85 96.46 112187 6009.455 232 25.555 6035.011 339417.1 0.00 37.42 89.42 85.20 97.85 96.46 112187 6009.455 232 25.555 6035.011 Timestamp S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 339551.1 0.00 39.96 68.38 46.40 97.99 95.55 107987 6136.845 238 49.173 6186.018 339552.1 0.00 39.96 93.15 46.40 97.99 95.55 107987 6136.845 238 49.173 6186.018 339553.1 44.37 0.00 32.62 46.43 97.99 95.55 107988 6136.903 238 49.173 6186.075 339554.1 44.37 0.00 88.96 46.43 97.99 95.55 107988 6136.903 238 49.173 6186.075 339555.1 0.00 41.82 17.52 46.49 97.99 95.55 107989 6136.963 238 49.173 6186.135 339556.1 0.00 41.82 64.14 46.49 97.99 95.55 107989 6136.963 238 49.173 6186.135 339557.1 39.57 0.00 4.16 46.59 97.99 95.55 107990 6137.027 238 49.173 6186.200 Timestamp S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 339522.0 0.00 35.20 92.33 45.48 97.82 96.47 112235 6360.675 236 25.843 6386.519 339523.0 37.73 0.00 34.98 45.53 97.82 96.47 112236 6360.728 236 25.843 6386.572 339524.0 37.73 0.00 79.99 45.53 97.82 96.47 112236 6360.728 236 25.843 6386.572 339525.0 0.00 36.40 20.69 45.58 97.82 96.47 112237 6360.781 236 25.843 6386.624 339526.0 0.00 36.40 64.99 45.58 97.82 96.47 112237 6360.781 236 25.843 6386.624 339527.0 35.51 0.00 10.36 45.64 97.82 96.47 112238 6360.835 236 25.843 6386.678 339528.0 35.51 0.00 55.57 45.64 97.82 96.47 112238 6360.835 236 25.843 6386.678 Timestamp S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 339454.0 38.18 0.00 38.61 44.10 97.78 95.53 114078 6133.794 236 23.938 6157.731 339455.1 38.18 0.00 82.87 44.10 97.78 95.53 114078 6133.794 236 23.938 6157.731 339456.1 0.00 41.97 17.91 44.16 97.78 95.53 114079 6133.854 236 23.938 6157.792 339457.1 0.00 41.97 51.55 44.16 97.78 95.53 114079 6133.854 236 23.938 6157.792 339458.1 0.00 41.97 82.24 44.16 97.78 95.53 114079 6133.854 236 23.938 6157.792 (... snip ...)
kubectl と parallel の組み合わせは相性がよいので組み合わせでいろいろなことができそう。(๑•̀ㅂ•́)و✧
※なお、複数 pod を横断してログを tail するには stern という素晴らしいツールがある。