ちゃんなるぶろぐ

エンジニア5年生🧑‍💻 オライリーとにらめっこする毎日。

おまえのDockerコンテナは間違っている!!

どうも、ちゃんなるです🐻

今回はDockerコンテナの起動について🐳

Dockerへの愛を表現した

概要

おまえのDockerイメージ多分壊れてるよ、おまえの知らないところでな。

コンテナの正しい起動の仕方を知っといた方がいいよ。

Dockerイメージのビルドの際、勘違いしがちなこと

Dockerを学ぶとDockerfileが作りたくなる。

例えば、Ubuntu内で自作アプリを動かすものとか。

FROM ubuntu:20.04

RUN sudo apt-get install -y <必要なパッケージたち>
ADD my_app_local /my_app_container

CMD ["/my_app_container/start.sh"]

コンテナ内ではCMD命令で指定したプログラムしか動かない。(これがPID1のプロセスになる)

コンテナ内のOSを適切に稼働させるには、他にも様々なシステム(プロセスやサービス)を動かす必要がある。

OSがよしなにやってくれるんじゃないの?

コンテナ内でUbuntuを動かしてるから、Ubuntuがよしなにやってくれるんじゃないの?

出典:https://www.amazon.co.jp/違う、そうじゃない/dp/B00005G4XO

確かにコンテナ内でUbuntuは動いているけど、適切に動作しているわけじゃない。

コンテナ起動時はDockerfile内のCMD命令で指定したコマンドしか実行されないから、コンテナ内ではコマンドに紐づいたシステム(プロセスやサービス)しか動かない。

加えて、UbuntuはDockerの内部で実行されるように設計・最適化されているわけではない。

通常、Ubuntuのinitプロセス(PID1のプロセス)はUpstartやSystemd(最近主流)であり、これらは実際のハードウェアまたは仮想化されたハードウェア上で実行されることを想定している。

また、Dockerコンテナの内部では実行されない。(CMD命令で指定したものがPID1のプロセスとなるので)

要は、Dockerコンテナ内では、Ubuntuが想定するinitプロセス(Upstart/Systemd)の機能を持ち合わせないinitプロセス(CMD命令で指定したもの)が動いてしまうということ。

例えばどんなサービスが起動できてないの?

下記を動かしておくとよい。

  • 適切なinitプロセス(PID1のプロセス)
    • これが停止するとコンテナも停止する。
    • コンテナ内のプロセスを管理(起動や停止、終了)できるものがよい(そうしないと、コンテナ起動時間が長くなるほどコンテナ内にゾンビプロセスが溢れることに…)。

おそらくCMD命令で指定してるやつはこれを想定できてない!

  • syslog
    • Unixの標準ロギングサービスで、/var/log/syslogへ出力する。
    • warningやerrorを取得するために、syslog daemonは稼働が必須。
  • cron
  • SSH(※必要であれば
    • 時折、何かしらの理由でコンテナ内で作業したい場合が発生する(Ex. 挙動の変なアプリをデバッグしたい場合)。
      • docker execでコンテナ内に接続できるが、デメリットも多々。
        • 例えば、Docker daemonにアクセスする必要があるので、必然的にDockerホスト上のroot権限を持ってしまうこと。
        • 権限管理の一環としてSSHでコンテナにログインしてもらう方法があり、この場合はSSH デーモンプロセスの起動が必要になる。

docker execコマンドのメリデメ

CentOSとか他のLinuxディストリビューションを使うDockerコンテナも同じ?

同じ。

Dockerコンテナ内で動かすプロセスは1つにするべきでは?

システム稼働に必要なプロセスは複数あるので、難しい。 コンテナはコンポーネントごと(APサーバ、DBサーバ、PROXYサーバなどなど…)に分けるようにし、その中のプロセス数は意識しなくてもいい。

まとめと課題

開発環境でちょろっと起動する程度だと、コンテナ内のプロセス管理など考慮する必要がないかも知れません。

しかし、実稼働させるシステムだと話は別です。長期稼働が前提で、様々な負荷に耐えつつも正常に動作し続ける必要があります。

ぜひ、本稿の内容を意識してDockerライフを送りたいものですね🐳

参考文献

この記事は下記資料の内容に私の解釈を足して作成しました。

phusion.github.io

Githubに下書きを置いています。

github.com