おまえの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
- cron
- SSH(※必要であれば
CentOSとか他のLinuxディストリビューションを使うDockerコンテナも同じ?
同じ。
Dockerコンテナ内で動かすプロセスは1つにするべきでは?
システム稼働に必要なプロセスは複数あるので、難しい。 コンテナはコンポーネントごと(APサーバ、DBサーバ、PROXYサーバなどなど…)に分けるようにし、その中のプロセス数は意識しなくてもいい。
まとめと課題
開発環境でちょろっと起動する程度だと、コンテナ内のプロセス管理など考慮する必要がないかも知れません。
しかし、実稼働させるシステムだと話は別です。長期稼働が前提で、様々な負荷に耐えつつも正常に動作し続ける必要があります。
ぜひ、本稿の内容を意識してDockerライフを送りたいものですね🐳
参考文献
この記事は下記資料の内容に私の解釈を足して作成しました。
Githubに下書きを置いています。