Chapter 04

2部: Docker を理解するためのポイント

ほげさん
ほげさん
2022.03.21に更新

Docker の細かい話に入る前に、Docker を正しく、そして結果的には早く理解するために、まずはとても大切なポイントを4つ確認します。
( これは僕独自の分類で、あくまでこの本に限るものです )

  1. 基本の要素は3つ
  2. 基本のコマンドも3つ
  3. コマンドの形を意識する
  4. Docker と周辺ツールを分ける

Docker をコマンド一覧やオプション一覧から理解しようしても、やみくもに集めた知識は正しく活用できず基本が身につきません。

ただたくさんのコマンドを写経で実行して「ふーん...??」となるよりも、まずは ちょっとの時間を割いて基本を堅実におさえることが絶対に近道 です。

1. 基本の要素は3つ

Docker で開発環境を構築をする場合、実は出てくる要素はそんなに多くありません。
この本では次の3つを基本の要素として考えることにします。

  1. コンテナ
  2. イメージ
  3. Dockerfile

image

この本の後半では、コンテナのデータをホストマシンと共有するためにボリュームを作成したり、コンテナ同士で通信できるようにするためにネットワークを作成したりしますが、誤解を恐れずに言えば それらの要素は基本の要素を脚色するもの だと考えられます。

なのでまずはこの3つの基本の要素を1つずつ理解していきしましょう。

コンテナとは

コンテナは特定のコマンドを実行するために作られる ホストマシン上の隔離された領域 です。

Docker に不慣れな間はコンテナをホストマシン上で動いている仮想 OS のように感じるかもしれませんが、コンテナの実体は Linux の Namespace という機能によりほかと分離されたただの1プロセスでしかありません。
Linux の Namespace 自体はもう 20 年近く存在する技術であり、それをコンテナやイメージというものを用いて扱いやすくした技術が Docker ということになります。

image

ホストマシンにも各コンテナにも Process ID 1 のプロセスや /etc/hosts などのファイルがあり重複していますが、Namespace により隔離された領域をマッピングすることで衝突を回避しています。

この Namespace をイメージから作り出すことで異なる OS に見えるようにしてくれたり、Namespace を簡単に作ったり消したりできるようなコマンドを提供してくれたりするものが Docker と言えます。

そう考えると【 1部: 仮想化とは 】で説明した「コンテナ型仮想化には OS は含まれておらず、ホストマシンのカーネルを使っている」ということが理解しやすいはずです。
コンテナはあくまでホストマシンの1プロセスであり、仮想サーバではないのです。

コンテナには次のような特徴があります。

  1. コンテナはイメージをもとに作られる
  2. Docker の CLI や API を使って、生成や起動や停止を行うことができる
  3. 複数のコンテナは互いに独立していて影響できず、独自に動作する
  4. Docker Engine の上ならローカルマシンでも仮想マシンでもクラウド環境でも動かせる

image

イメージとは

イメージはコンテナの実行に必要なパッケージで、ファイルやメタ情報を集めたもの です。

イメージは複数のレイヤーというものからなる情報のことであり、ホストマシンのどこかに .img のような具体的な単一のファイルが存在するわけではありません。

イメージにはレイヤーによって次のような情報が含まれています。

  • ベースはなにか
  • なにをインストールしてあるか
  • 環境変数はどうなっているか
  • どういう設定ファイルを配置しているか
  • デフォルト命令はなにか

image

イメージは Docker Hub で公開されています。
( Docker Hub に公開されているのは Dockerfile ではありません。)

そのおかげで、たとえばチームで「php8.1 のイメージを使う」と決めておけば、同じ開発環境を構築することが容易にできます。

image

Dockerfile とは

Dockerfile は 既存のイメージにレイヤーをさらに積み重ねるためのテキストファイル です。

インターネット上に公開されているイメージではインストールしてあるコマンドが足りないなどの問題がある場合に、自分に都合の良いイメージを作るために Dockerfile を作成します。

image

イメージを作れと言われるととても難しそうですが、公開されているイメージに Dockerfile でレイヤーを乗せるだけなので、OS から構築したりする手間は不要でとても簡単です。

Dockerfile は GitHub などで共有するのが望ましいです。
( Git 管理するのはイメージではありません。)

それにより、たとえばチームで「php8.1 のイメージに git を入れたイメージを使う」という構成を共有することができます。

image

2. 基本のコマンドも3つ

3つの要素を軸に考えると、誤解を恐れなければコマンドの基本形も3つに分類できると考えられます。

  1. コンテナを起動する
  2. イメージを作る
  3. コンテナをどうにかする

図におこしたとしても、せいぜいこの程度しかありません。

image

この3つの基本のコマンドも1つずつ理解していきしましょう。
( それぞれの詳細は次以降のページで改めて解説します )

コンテナを起動する

container run というコマンドは、イメージ から コンテナを起動する コマンドです。

image

container run には非常に多くのオプションがあり、コンテナの用途に応じて多量のオプションを使い分ける必要があります。
が、基礎中の基礎である イメージからコンテナを1つ作るだけのコマンド という点を忘れないようにしましょう。

この本でもそれなりの数のオプションは解説しますが、オプションは本当に多いので無理に覚えようとせずに、自分に必要なものを自分のタイミングで1つずつ理解していけば十分です。

また、実は container run は次のコマンドを一気に行う便利コマンドなのですが、この本ではコマンド個別の解説は行わずに container run として解説します。

  • image pull
  • container create
  • container start

イメージを作成する

image build というコマンドは、Dockerfile から イメージを作成する コマンドです。

image

先ほど解説した通り、Dockerfile はベースとなるイメージを指定し、「コマンドのインストール」や「設定ファイルの配置」などのレイヤーを重ねて、新たなイメージを作るためのものです。

そうして自分で作成したイメージは、ほかのイメージと全く同様に container run で使うことができます。

image

コンテナを操作する

たとえば container execコンテナ命令を送る コマンドです。

対象がコンテナなので、必然的に container run のあとに使うコマンドになります。
イメージDockerfile に対しては命令できません。

image

container exec で「ログを見せろ」「コンパイルしろ」「テストを実行しろ」のような命令を送ることで、起動しているコンテナに様々な処理をさせることができます。

ほかにも container stop という コンテナ停止する コマンドなど、コンテナを対象になんらかを行うコマンドはたくさんあります。

3. コマンドの形を意識する

3つの基本の要素と3つの基本のコマンドを理解できたら、その基礎を最大限に活かすために「コマンドが なにどうする のか」を常に考える習慣を作ります。

初めは大変で辛く感じるかもしれませんが、やみくもにコマンドを覚えるのとこれを続けるのでは、理解の早さと深さが圧倒的に違います

この習慣を、頑張らずに楽に行えるようになったころが「Docker わかってきた気がする」という扉が開く瞬間のはずです。

「なに」を「どうする」か

3つの基本の要素と3つの基本のコマンドについて理解したところで、再度全体像を確認します。

image

矢印の先がコンテナなら container xxx で、矢印の先がイメージなら image xxx になっていることがわかるはずです。
それが なに の部分です。

そして runbuild の部分が どうする の部分です。

docker container rundocker image builddocker なに ( を ) どうする と読み替えられるということです。

コマンド1つを実行するたびに脳内で ( もちろん紙でも ) この図が描ければ、すぐ理解が深まるはずです。

新コマンドと旧コマンドについて

普段から Docker を利用されている方はお気付きでしょうが、この本では docker run ではなく docker container run を使っています。

実は Docker のコマンドは 2017 年 1 月にリリースされた v1.13 で大幅な変更が行われており、docker run が旧コマンド、docker container run が新コマンドとなっています。
これは docker rundocker build のような docker 直下のコマンドが増えすぎて なに がわかりづらくなってしまったためで、v1.13 からはそれぞれ対象を明示できるサブコマンド形式の方を使うことが推奨されています。

image

普段目にするコマンドはおそらく docker rundocker build などの旧コマンドが多いのではないかと思います。
僕自身も短くて楽なので普段は旧コマンドを使っていますが、この本では なに が明瞭な新コマンドを使って説明を行います。

タイプ数は多くなりますが、どちらが理解しやすいかは一目瞭然ですね。

旧コマンド 新コマンド
docker build docker image build
docker run docker container run
docker pull docker image pull
docker create docker container create
docker start docker container start
docker images docker image ls
docker ps docker container ls

4. Docker と周辺ツールを分ける

Docker を前提としたものがいくつかあるので、初学者のうちはそれを Docker そのものと混同しない ように気を付けると良いでしょう。

  1. Docker Compose
  2. Kubernetes

ここでは2つだけ、軽く紹介します。

Docker Compose

Docker Compose は Yaml ファイルを書くことにより、複数のコンテナをまとめて起動したりしてくれるツールです。

image

Docker Compose は Docker Desktop に含まれており、docker compose xxx のようなコマンド体系になっています。

Docker CLI のみで環境を構築しようとすると、多量の複雑なコマンドを誰でも何度でも同じく実行するためには Docker コマンドの手順書が必要 になります。
この問題を「Docker Compose を使い詳細な命令は 全部 Yaml に書いて GitHub で共有 する」という方法で解決することができるようになります。

image

Docker を使って開発環境を構築する ソフトウェアエンジニアにとって、Docker Compose は必須のスキルと言えるでしょう。

この本では「Docker を正しく理解する」→「Docker を使って環境構築をする」→「Docker Compose に置き換えて楽をする」という流れで導入し、最終的にはとても複雑な構成を compose up のみで即時起動できる状態を目指します。

Kubernetes

Kubernetes は Json ファイルや Yaml ファイルを書くことにより、同じコンテナを複数台起動してクラスタを構築したり、コンテナの監視やコンテナの自動再起動を簡単に行えるオーケストレーションソフトウェアです。

image

Kubernetes も Docker Desktop に含まれており、kubectl xxx のようなコマンド体系になっています。

開発環境を構築する場合、ロードバランサーを作って Web サーバを冗長構成にしたりアクセス増加時にコンテナを増やしたりする必要はないので、Kubernetes は使いません。

Docker 利用の主目的を開発環境の構築とするならば、Kubernetes はまだ学ばないと割り切ってしまってもよいでしょう。

この本では Kubernetes については解説を行いません。

まとめ

長くなってしまったので、簡潔にまとめます。

  1. 基本の要素
    • コンテナ はホストマシン上の隔離されたプロセス
    • イメージ はレイヤーというメタ情報の集積で、Docker Hub などで公開される
    • Dockerfile はイメージにレイヤーを重ねるテキストファイルで、GitHub などで共有する
  2. 基本のコマンド
    • コンテナ起動 する
    • イメージ作成 する
    • コンテナ操作 する
  3. コマンドの形
    • なにどうする かの意識が一番大事
    • 理解しやすい 新コマンド と、短くかける 旧コマンド がある
  4. Docker の周辺知識
    • Docker Compose はコンテナをまとめて起動するツールで、開発環境の構築に便利
    • Kubernetes はコンテナを運用するツールで、インフラ構築に便利

混乱してしまったときは立ち返ってみてください。