目次
新卒研修でやった内容を軽くまとめたもの
コンテナ
- VM とコンテナの違い
- VM:OS (カーネル、OS のコア機能) から仮想化
- オーバーヘッドが大きい
- イメージサイズも大きい、起動も遅い
- コンテナ:プロセス (1 つの処理単位) から仮想化
- ホスト OS とカーネルを共有する、起動は早い
- OS 機能も含めて完全に同じ環境を再現することはしていない
- VM:OS (カーネル、OS のコア機能) から仮想化
- コンテナの実現するための技術
- Linux のカーネルには互換性があるため、カーネルを共有できる
- Linux namespace
- プロセスに対して、PID、ネットワーク、ユーザー、ホスト名などのリソースを分離する
- cgroups
- プロセスに対して、CPU やメモリなどのリソースを制限・隔離する
- Linux capability
- スーパーユーザーとしての機能を制限するための機能
- Docker コンテナへホスト OS の root ユーザーの権限を制限するなど
- スーパーユーザーとしての機能を制限するための機能
- Mac や Win はどうしている...?
- Mac や Win の場合は、
HyperKit
などを使って 軽量な Linux VM をたてて動かしている
- Mac や Win の場合は、
Docker の各要素
- image
- 環境のスナップショット
- container
- スナップショットを元に起動したプロセス
- コンテナ内のプロセスは、ホストマシンや他のコンテナと隔離されている
CMD
で定義されたプロセスは、どのコンテナ内でもプロセス ID に 1 が割り当てられる (PID=1)- PID=1 は、init プロセスと呼ばれ、他の全てのプロセスの親となっている
kill -s TERM 1
しても落とせない場合があるので注意- シグナルを送ることは制限されている
- Node.js とかが良い例 (参考記事が詳しい)
- volume
- コンテナが利用するデータを永続化する仕組み
- コンテナを終了しても volume は消えない
- ロギングをしたい場合などでよく使う
- -v VOLUME_NAME:CONTAINER_PATH
docker volume ls
で永続化されている volume を確認できる
- -v HOST_PATH:CONTAINER_PATH
- こっちの方がよく使う
- ホストのファイルをコンテナに同期させる
- network
- 複数プロセスを協調して動かす必要がある時は、ネットワークで通信する
- プロセス間のやりとりのための bridge を作るのが一般的
Docker ベストプラクティス
- Root ユーザーは使わない
- 一般ユーザーの作り方は、参考記事を見ると良い
- 野良イメージは使わない
- Docker Official Images は安全
.dockerignore
をちゃんと使う.env
、.git
、node_modules
などは、ちゃんと ignore するべき
- 小さいベースイメージを使う
distroless
やXXXX-slim
みたいなのが良い
- レイヤーを作りすぎない
- レイヤーが少ないほど、イメージサイズも小さくなる
- ADD・COPY の使い分け
- COPY が推奨、ADD は予期せぬ挙動をすることがある
- ENTRYPOINT/CMD の使い分け
- ENTRYPOINT
- コンテナ起動時のコマンドを変更する必要がない場合に使う
- CMD
- コンテナ起動時のコマンドを色々変更したい場合に使う
docker run
時の引数で上書きできる
- ENTRYPOINT
- multi stage build を使う
- ビルド用と実行用のステージで分離して記述できる
- 実行用のステージでは、ビルド用のツールなどがいらなくなり、イメージサイズが小さくなる
- Python や Node.js でもできる
- Dockerfile には Lint ツールを使う
- ヘルスチェックの仕組みを用意する
- コンテナの死活管理ができる
- Web API を用意するのが一般的、
HEALTHCHECK
も使える (Docker HEALTHCHECK)
- ログは標準出力 or 標準エラー出力に出す
docker logs -f
で確認できる