たぶん役に立たない豆知識です。
ssh接続したリモートホストにファイルをコピーせずにシェルスクリプトを実行する方法を知っている方も多いと思います。
ssh $HOSTNAME bash -s <./main.sh
リモートホストで起動したbashに、ローカルホストのmain.sh
の内容が標準入力経由で渡されて実行されるテクニックになります。
単純にこのテクニックをコンテナでも使おうという話になります。
Dockerコンテナで実行する
オプションについての詳細は省きますが、runでもexecでも-i
オプションをつけて実行するだけです。
# run docker run --rm -i ubuntu:latest bash -s <./main.sh # exec docker exec -i $CONTAINER_NAME bash -s <./main.sh
この時気をつけることなんですが、-t
オプションをつけないことが重要です。
-t
オプションを付与すると、エラーが表示されます。(エラーが表示されているものの実行されていないかどうかは未確認)
$ docker run --rm -it ubuntu:latest bash -s <./main.sh the input device is not a TTY
こういったテクニックを使えば、ローカルにあるファイルをコピーやマウントせずとも、
標準入力経由でファイルの内容を渡して実行することができます。
例えばRubyスクリプトであれば、以下のように実行することができます。
docker run --rm -i ruby:3 ruby <./main.rb
他にも標準入力から受け取ることができるツールであれば、大体応用できます。(psqlなど)
Kubernetesのコンテナで実行する
さて、Dockerコンテナでもできたのであれば、コマンド体系が似ているKubernetesで動いているコンテナでもできるでしょうか?
答えは可能です。
kubectl exec -i $POD_NAME -- bash -s <./main.sh
kubectlの場合は、-t
をつけてもDockerと同様にエラーは表示されるものの、
スクリプト内のechoなどで出力した文字列も表示されているので実行されているようです。
まとめ
たぶん役に立たない「コンテナにファイルをコピーせずスクリプトを実行する」方法について紹介しました。
kubectl exec
に関しては賛否両論がありそうですが、docker run
に関してはファイルをコピーせずとも動作確認が気軽にできるので役立つ時が来るかもしれません。
気が向いたら、また役に立たなそうな豆知識を書くかもしれません。