【小ネタ】Kubernetes でバッチアプリをデバッグしたいときに使える Pod の command の話 #Kubernetesリレー

この記事はなむゆの個人ブログにもマルチポストしています。

使いどころ

Kubernetes 上で動かすバッチアプリケーションを開発しているとき、コンテナ動作がおかしくてデバッグしたくなることがあるかと思います。
バッチでない、普段起動状態でとどまるようなアプリケーションなら kubectl exec コマンドを使ってコンテナに入り、各種デバッグ作業ができるのですが・・・
バッチのような、デプロイ後すぐに動作をはじめ、動作が終わるとすぐに停止してしまうようなアプリケーションの場合起動している時間が短すぎるのでコンテナに入ってもすぐに Pod が停止して締め出されてしまいます。
そういった時に、コンテナの生存時間を無理やり伸ばしてコンテナ内でデバッグするのに使える便利な小ネタの話です。

やり方

アプリケーションの展開に使うマニフェストを用意します。
マニフェストの中のコンテナの設定をしている箇所で、以下の 5 行目のような行を挟み込みます。

...<前略>  
  containers:  
  - name: <何かしらコンテナ名>  
    image: <何かしらのイメージ>  
    command: ["/bin/sh", "-c", "sleep 100000"]  
...<後略>  

その後、マニフェストをデプロイします。
すると、コンテナが処理を始めなくなるのでコンテナ内を歩き回って各種調査をすることができます。

詳細の話

これは、Kubernetes のマニフェストのcommandのパラメータを使用した小技です。
コンテナを作るときに書く Dockerfile には、起動後に実行するファイルを指定するためにENTRYPOINT命令を書きます。
例えばバッチアプリケーションを実行する場合はそのアプリケーションの実行ファイルを指定しておくことで、コンテナが起動後すぐにそのアプリケーションを実行できます。
一方で、今回指定した Kubernetes のマニフェストのcommandパラメータは、これを上書きする効果があります。
これによって本来は起動後に Dockerfile で指定したバッチ用アプリケーションを実行するはずが、今回はここで書いた bin/sh -c sleep 100000 のコマンドが実行され、100000 秒間 sleep します。
コンテナは sleep 実行中は等に何も問題が起きない限り起動し続けるので、sleep している間にkubectl execコマンドを使ってコンテナ内に入り、探索することができるということです。
同じような効果のものとして、Kubernetes を使う前のコンテナの段階では、コンテナ実行時に docker run --endpoint <各種コマンド> と書くことでも、コンテナ起動時にエンドポイントを上書きできます。
こちらはローカルの Docker で動作確認を行う時に使える方法です。
話は戻りまして、 commandパラメータは他にも、busybox などの小型で便利ツールだけが詰まったようなイメージにおいては各種シェルコマンドを使うことでアプリケーション実装要らずの小規模なバッチ処理を書くこともできたりするので何かと便利です。
困ったときの小手三寸として検討してみるといいかと思います。

おわりに

今回は、起動後すぐに処理を実行してその後すぐに終了してしまうようなバッチ系のアプリが入ったコンテナをデバッグする方法として、コンテナの ENTRYPOINT を上書きして起動状態を維持する方法について紹介しました。
しばらく方法を考えていくつか検索をかけたら誰かしら思いつきそうな気もする小ネタですが、最初に検索してこの記事に当たったあなたはちょっとラッキー(だといいな)ということで。

参考