本質的な仕組みを理解していると、探すだけ無駄な道を選択せずにすむ
仕事が早いエンジニアは何が違うのか。私のイメージでは話を構造的に整理し、技術的な原理を俯瞰して元から答えになり得ない場所は探さず、その道を強制されそうになった場合目的にあう代替案を提示できるそんな人物像です。
要するに本質が解っているから、探すだけ無駄な道を選択しないのでそれだけ早く終えられます。決して鬼のようにタイプが早い人ではありません。
できるエンジニアは話を構造的に整理し、技術的な原理を俯瞰して元から答えになり得ない場所は探さず、その道を強制されそうになった場合目的にあう代替案を提示できる人
さてコンテナを例に考えてみましょう。「イメージの削除を実行すると、イメージを削除できない」と言う相談を受けたとしましょう。
イメージの削除はそれを元にしているコンテナが稼働している限り削除できないと言うことを知っていて回答するのも良いですが、コンテナの構造を理解させた方が状況に応じた確認を行ってから問題解決できるようになるので今後の質問対応は少なくなるはずです。
さてDockerの「イメージ」とはそもそも何でしょう。一言で言えば、Docker imageは必要なソースコードやライブラリを含むimmutableなファイルです。
Docker Image は複数のDocker Image の積み重ねでできています。Dockerfileをビルドした後、docker historyとコマンドを実行すると複数のイメージを積み重ねて最終的に1つのイメージができていることが確認できます。積み重ねられたイメージを中間イメージと言います。
そして、コンテナ作成時、readonlyなimmutableなイメージをベースにwritebleなcontainer layerが追加されます。
プロセスはこのcontainer layerで動いています。このプロセスが他の環境から影響を受けないように隔離することを実現するため、イメージもコマンドに対して侵害を受けないように保護されます。これがコンテナのプロセスが動いているとイメージが削除できない理由です。
コンテナの本質が隔離できると言う性質から成り立っていることを理解していると、こう言うコマンドは受け付けないはずと瞬時に判るようになります。
コンテナの本質である「隔離できると言う性質」を成り立たせるためできる/できないが発生している
オブジェクト指向の言語のプログラムをやっている方ならイメージはクラス、コンテナはインスタンスといった関係性なので削除できないと理解するのも良いと思います。
Docker Image はDockerfileによって作成される特定の環境のスナップショットと言う特性も併せて持っています。
Dockerの理解ができた状態でKubernetesやAWS ECR/ECS/EKSの学習を始めると習熟度に差が出るでしょう。
隔離できるという性質と原理から操作の特性を理解する
コンテナの根幹は隔離できるという本質は、カーネルが含まれておらず独立しているためです。
イメージ化できるので複製でき持ち運べます。特性として移行が簡単と言えます。
Dockerのコマンドの基本構造を理解するために、以下にイメージ作成(build)するコマンドを記載します。
dockerコマンドの基本構造は「docker 何を(container, image, volume, network) どうする(create, start, stop, rm) どれに対して」の形式です
-tはタグのオプションです。イメージがコンテナで利用される際のタグ指定に対応します。キャッシュを無効にしたい場合はオプションに—no-cacheも追加します。
docker 上位コマンド(何を) 下位コマンド(どうする) オプション 対象 引数(どれに対して)
docker image build -t my-image/nginx:1.0. /User/myname/Documents/dockerfiles/
Dockerの技術はLinux OSの技術を利用して実現しているのでLinux用のソフトウェアしか対応しない点も留意する必要があります。
隔離できる性質を基本としているため、ストップ(docker stop)してからしか削除(docker rm)ができません。EC2と一緒ですね。
docker runは「docker pull」「docker create」「docker start」をまとめて実行するコマンドです。
上位コマンドはcontainer, image, volume, networkが基本ですがcontainerに関しては省略可能です。docker container runと書いてもdocker runと書いても動作します。
dockerコマンドの基本構造は「docker 何を(container, image, volume, network) どうする(create, start, stop, rm) どれに対して」の形式
次にそれぞれの系統のコマンドを見ていきましょう。コンテナの基本構造や原理から「このコマンドはないよな、このコマンドはあるよな」なんて頭の中で考えながら見ていくと理解が変わります。
docker container系
create, start, stop, rmなどが該当します。
docker attach <CONTAINER IDまたはNAME>
docker image系
build, ls, rm, pullなどが該当します。
docker volume系
create, inspect, ls, prune, rmなどが該当します。
docker network系
create, connect, disconnect, rm, lsなどが該当します。
この他のコマンドで知っておくと良いのはversionぐらいです。他はオーケストレーションを行うためのdocker Swarm関連のコマンドが多いです。
kubernetesとは別物ですが原理を理解するために勉強しておくのはありです。
実践編:wordpressを稼働させる
さて実践編ということでwordpressをdockerで準備して欲しいと依頼されたとしましょう。
wordpressを稼働させるにはMySQLのコンテナを稼働させコンテナのネットワークで接続する必要があります。
これを後ろから解決すればいいので、設定値を対応させながら以下の3つのコマンドを実行すれば良いと判ります。
docker network create wordpress2mysql
docker run --name testdb -dit --net=wordpress2mysql -e MYSQL_ROOT_PASSWORD=rootpw -e MYSQL_DATABESE=wpdb -e MYSQL_USER=wpuser -e MYSQL_PASSWORD =mypw mysql --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --default-authentication-plugin=mysql_native_password
docker run --name mywordpress -dit --net=wordpress2mysql -p 8081:80 -e WORDPRESS_HOST_NAME=testdb -e WORDPRESS_DB_NAME=wpdb -e WORDPRESS_DB_USER=wpuser -e WORDPRESS_DB_PASSWORD=mypw wordpress
docker psでrunで指定したnameのSTATUSがupになっていることを確認し、http://localhost:8081/にアクセスするとWordpressのセットアップ画面が出てくるはずです。
基本に立ち返りKubernetesやAWS ECR/ECS/EKSなどコンテナ技術を活用したツールやサービスを使い倒しましょう。
以上です。参考になれば幸いです。