コンテナが起動しない場合の対処法

dockerやk8sのコンテナ運用をしていると、諸般の事情でイメージ更新後にコンテナが起動しないケースに遭遇します。
原因を追求しようにも、コンテナが死んでしまうので追跡できない……という状況で、コマンドを差し替えてひとまず起動させる手があります。

dockerコンテナが起動しない場合

dockerは、ビルド時にCMDENTRYPOINTで指定した起動コマンドのプロセスが終了するとコンテナも停止します。(CMDとENTRYPOINTの挙動の違いは、 Understanding Docker’s CMD and ENTRYPOINT Instructionsが参考になります)

実行時に起動コマンドをtail -f /dev/nullなどに置き換えることで、実行予定のコマンドの影響を受けずにコンテナを起動できます。

$ docker run -d --name testcontainer original_image tail -f /dev/null

コンテナを起動したあとは、 docker execでコンテナに接続して調査できます。この状態では、起動したかったプロセスが異常停止した場合でもコンテナの動作は継続しているためログを取得するなど、一般的な原因調査の手順をとれます。

docker-composeのYAML設定ファイルにも、以下のようにcommandディレクティブを指定することで上書き可能です(抜粋)。

version: 2
services:
  testcontainer:
    image: original_image
	command: "tail -f /dev/null"

なおコンテナ終了には、docker killなどの一般の手順を利用します。

kubernetesの起動コマンド指定方法

コンテナにdockerを活用しているkubernetesやGoogle Container Engineも同様にDeploymentの定義で起動コマンドを指定できます。

以下のように、コンテナのスペックテンプレートのcommandargsディレクティブを利用します(抜粋)。

spec:
  templagte:
    spec:
      containers:
        - image: original_image
          command: ["tail"]
          args: ["-f", "/dev/null"]

kubernetesのdeployment起動オプションの詳細については 公式ドキュメントが参考になります。

マルチコンテナ構成で起動しないケース

kubernetesでは1つのpod内で複数のコンテナを動作させられますが、構成によっては起動しないケースがあります。
podは1つのホストであるため、たとえば同一ポートを用いるマルチコンテナは起動せず、後から起動したコンテナがCrashLoop状態になります。

1つのコンテナ内に複数のデーモンを起動させていると、ポートを占有していることに気づきにくくなるので注意が必要です。

中馬崇尋
Chuma Takahiro