kubectl exec
でコンテナ内でやや複雑な処理を実行させたい場合、ヒアドキュメントを使うと簡単だったのでメモ。コンテナ内にあらかじめスクリプトを配置しなくても済む。
やり方
以下のように書く。
コマンド
kubectl exec -i mypod bash <<'EOC'
echo hello
echo world
EOC
実行例
$ kubectl exec -i mypod bash <<'EOC'
> echo hello
> echo world
> EOC
hello
world
$
-
-t
オプションをつけるとUnable to use a TTY - input is not a terminal or the right kind of file
と警告がでるの-i
だけでよい - この例はコンテナ内に
bash
がある前提なので、ない場合はsh
を使う。
以下のようにもかけるが、ヒアドキュメントのほうが見やすい。
kubectl exec -i mypod -- bash -c "echo hello; echo world"
変数の展開
変数をコンテナの中に入る前に展開したい場合<<EOC
とする。コンテナの中で変数を使いたい場合は<<'EOC'
とする。
コンテナの外で変数を展開したい場合は以下。
コマンド
myworld="outer world"
kubectl exec -i mypod bash <<EOC
myworld="inner world"
echo hello
echo ${myworld}
EOC
実行例
$ kubectl exec -i mypod bash <<EOC
> myworld="inner world"
> echo hello
> echo ${myworld}
> EOC
hello
outer world
$
コンテナの中で変数を使いたい場合は以下。
コマンド
myworld="outer world"
kubectl exec -i mypod bash <<'EOC'
myworld="inner world"
echo hello
echo ${myworld}
EOC
実行例
$ kubectl exec -i mypod bash <<'EOC'
> myworld="inner world"
> echo hello
> echo ${myworld}
> EOC
hello
inner world
$
関数とかif文とか
関数とかif文とかも使える。リターンコードもとれる。
コマンド
kubectl exec -i mypod bash <<'EOC'
set -eu
set -o pipefail
myfunc () {
echo "hello world $1"
}
for i in `seq 1 10`; do
myfunc $i
if [ $i -eq 5 ]; then
exit 99
fi
done
EOC
実行例
$ kubectl exec -i mypod bash <<'EOC'
>
> set -eu
> set -o pipefail
>
> myfunc () {
> echo "hello world $1"
> }
>
> for i in `seq 1 10`; do
> myfunc $i
> if [ $i -eq 5 ]; then
> exit 99
> fi
> done
>
> EOC
hello world 1
hello world 2
hello world 3
hello world 4
hello world 5
command terminated with exit code 99
$ echo $?
99
$