初めてのDockerのお勉強〜備忘録〜


はじめに

書いているうちに長くなってしまったので、ストック/LGTMしてお暇なときに読んでください。誤字・脱字はひっそりと直していると思います。

初めて Docker というものに触れるにあたって、一から勉強していくことにしました。ここでは、私が勉強した内容を、私なりに簡潔にまとめていくことを目指します。そこで、記事としては見づらくなることを承知の上で、敢えて勉強していく過程で直面した順(をベース)に話を進めていくことにします1

備忘録として残すことが主な目的ですが、経験を積むためにも投稿することにしました。極力間違いのないようにしていますが、理解不足などによる間違いが無いとも言い切れません2。その際は是非ご指摘頂けますと幸いです。

※ 本記事に書いてあることは、基本的にブログ記事3を参考にしてまとめているので、より詳細に知りたい場合にご参照下さい。

Dockerとは

まず、Dockerとはそもそも何者なのかについてまとめていきます。Dockerとは、簡単に一言で言うと、コンテナを扱うための便利なツールです。

Dockerを利用することで、誰かと共同作業する時に自慢の煩わしさを発揮する様々な環境整備(「環境整備」という言い回しの厳密性には触れませんがご容赦下さい)を高速・確実・楽にしてくれるようです。

コンテナとは

コンテナ(型仮想化)4は、1種の仮想化手法です。

Dockerを初めて勉強する人が「仮想化」と言われると、VirtualBoxParallels Desktopのように、仮想化用のソフトウェアをインストールして、その上でホストOS5とは異なるOS(ゲストOS)を利用する技術を思い浮かべるでしょう(私はそうでした)。

これに対して、コンテナでは、ホストOSのコマンドやライブラリから隔離された場所で、ホストOSのカーネルとコンテナ独自のコマンドやライブラリを利用して、あたかも別なOSが動いているように動作してくれます。そのため、コンテナは仮想化ソフトウェアやゲストOSを必要とせず、高速に動いてくれるのです。


仮想化とコンテナ(より良い図を描ける気がしないので 引用3)

上図のように、通常のプロセスではホストOSのコマンド・ライブラリを使用してホストOSのカーネルにアクセスします。

一方、コンテナはホストOSのコマンド・ライブラリから隔離されていて、コンテナ内のものを使用しますが、コンテナ内にはゲストOSが存在しないため、ホストOSのカーネルにアクセスします6

コンテナのOSについて
$ docker run -it centoOS:centoOS7 /bin/bash

(まだ下の基本的な使い方を見ていない方の実行はオススメしませんが、)このコマンドを実行することで、CentOS7の環境を作ってbashを起動できます。(-itは実行時のオプション指定です)
このOSのイメージは、Docker Hubという、インターネット上に公開されているリポジトリから取得されるそうです。

Docker を使う

前提

使用環境は下記の通りとします。

macOS Catalina バージョン10.15.7

この使用環境を前提に話を進めていきますが、ご了承ください。
他のOSなど、詳しくは、公式ドキュメント Docker docs の Supported platforms
から、ご自身の使用環境への対応をご確認ください。m(_ _)m

準備

Mac で Docker を使用するために、 Docker Desktop for Mac をインストールします。
インストールが完了したら、 Docker.dmg を実行してアプリケーションを追加します。
これで Docker がお手元の Mac で利用することができます。

チュートリアル(になってたら嬉しい)

コンテナの起動

Docker コンテナを起動するために以下のコマンドを実行します。

$ docker run --name tutorial centos:centos7 /bin/echo hoge

書式:
docker run --name [コンテナ名] [イメージ名]:[タグ名] [コンテナ起動直後に実行するコマンド]

実行結果:

hoge

hogeと出力されました。

コマンドの書式について
  • docker は、(筆者の経験上) Docker コマンドにはお決まりでくっついています。
  • run は、Docker コンテナを起動するための命令で、他にも起動中のコンテナを一覧で確認する ps など、様々な命令があります。
  • --name は、起動するコンテナに名前をつけるためのオプションです。上記のコマンドでは、tutorial という名前がつけられています。
  • centosは、Docker Hub 上での CentOS のOSを提供しているイメージの名前です。
  • centos7は、上で指定したイメージの中から、centos7というタグのつけられたバージョンのイメージを取得することを意味します。
  • /bin/echo hogeは、書式の通り、コンテナ起動直後に実行するコマンドです。今回の場合は、よく見る(?)echoコマンドで、実行結果のようにhogeを出力しています。/bin/echoはコマンドなので、実際にはホストOSのカーネルを利用しています。

※ 本来、イメージを取得するには、Docker pull centos:centos7というコマンドが使用されますが、Docker runコマンドでも、指定したイメージが取得されていなければ自動で取得してくれるみたいです。

コンテナの確認

コンテナの起動をしたら、次のコマンドを実行してコンテナの状況を確認してみましょう。

$ docker ps

実行結果:

CONTAINER ID   IMAGE         COMMAND                  CREATED      STATUS      PORTS                    NAMES

表の列名のようなものしか出てこない。。。?

docker psは、稼働中のコンテナの一覧を表示してくれます。
実は、コンテナは、起動した後、指定のコマンドを実行すると(内部で動作しているプロセスが終了すると)停止するようになっています。

では、停止中のコンテナも表示してくれるオプションをつけて再度確認してみましょう。

$ docker ps -a

実行結果:

CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS                      PORTS                    NAMES
53f4db7f38f4   centos:centos7   "/bin/echo hoge"         12 minutes ago   Exited (0) 12 minutes ago                            tutorial

各列の説明
  • CONTAINER_ID : 作成されたコンテナのID(上の例とは異なるはずです)
  • IMAGE : コンテナに用いられていたイメージとそのタグ
  • COMMAND : 起動直後に実行されたコマンド
  • CREATED : コンテナが作成された時間(上の例とは異なるはずです)
  • STATUS : コンテナの状態(時間の部分は、上の例とは異なるはずです)
  • PORTS : ポートの接続関係(詳細は割愛)
  • NAMES : コンテナの名前

確かに、tutorialという名前のコンテナがありますね。
STATUSExitedになっていることから、コンテナが稼働中ではないことがなんとなくわかると思います。

また、COMMANDを見ると、/bin/echo hogeとなっています。
初めにコンテナを起動したときに、実行されるコマンドが決まるんですね。

コンテナの削除

(気にならない人は、やり方だけ確認して飛ばしてもらっても結構です)
では、停止したまま残っているコンテナを一度削除してしまいましょう。

コンテナの削除には、次のコマンドを実行します。

$ docker rm tutorial

書式:
docker rm [コンテナ名 or コンテナID]

これで、先ほど作ったコンテナが削除されているはずです。docker ps -aで確認してみてください。

ちなみに、docker rm $(docker ps -aq)とすることで、停止している全てのコンテナを削除できます。
また、docker imagesでイメージの一覧表示、docker rmiで指定したイメージの削除もできます。

コンテナの起動(2)

それでは、改めてコンテナの起動をしてみましょう。
次は、起動してもすぐに停止することのないようなコンテナを作成します。

$ docker run -itd --name tutorial2 centos:centos7 /bin/bash

実行結果:

3e98ba03038860506113697a075c4d2ce9a9a2a730edd3db3c625a099acada31

実行結果では、何やら不思議な数字と文字の羅列が出力されていると思います。
docker psで確認してみると、

3e98ba030388   centos:centos7   "/bin/bash"              3 seconds ago   Up 3 seconds                            tutorial2

STATUSUptutorial2という名前のコンテナが出来ていると思います。

コマンドの中で、コンテナの起動の時と違う部分について説明します。

  • /bin/bash先ほどは、/bin/echo hogeとなっていました。これは、bashを起動することになります。今皆さんが使っているはずのものです。(mac なら bash だったり zsh だったり)
  • -itdはオプションです。オプションは繋げられるので-i -t -dでも同じです。
    • -i : interactive らしいです。インタラクティブシェルってことですね。ホストの標準入力をコンテナの標準入力にせつぞくしてくれるらしい。
    • -t : tty だそうです。どうやらコンテナ内の標準出力をホストの標準出力に繋いでくれるらしい。
    • -d : detach-mode らしい。バックグラウンドでコンテナが実行されます。

(run)コマンドのオプションについてはDocker公式のリファレンスなどを参照してみてください。

※ ちなみに、オプションについては、-id-tdでも同様の結果が得られました。これは、筆者自身、解釈に自信がないのですが、-dのみでは、バックグラウンドで実行された際に入出力プロセスが終了しているためにコンテナが停止してしまい、-i-tどちらかでも追加されることで、入出力のプロセスが生き残ってコンテナが稼働したままなのだと思っています。(偉い人教えてください。。)

コンテナにログイン

先ほどのコマンドを実行しただけでは、コンテナは稼働中でもコンテナを「使う」ことはできていないですよね。
オプションの説明でも描いたように、コンテナはバックグラウンドで動いています。
そこで、裏で待機してくれているコンテナに、下のコマンドでログインします。

$ docker exec -it tutorial2 /bin/bash

書式:
docker exec [オプション] [コンテナ名 or コンテナID] [コマンド]

実行結果:

[root@3e6c16e91968 /]#

上記のように、root@[コンテナID]という形でコンテナ内のbashに入れたと思います。
ここで、echo hogeを実行すると、期待通りhogeが出力されます。
コンテナを抜けるときは、exitコマンドを使用します(通常のターミナルのコマンドと同じですね)。

コンテナを抜けた後、もう一度docker psを実行すると、コンテナがちゃんと裏で待機してくれていることがわかります。

コンテナの停止

コンテナtutorial2は、バックグラウンドで稼働しているため、こちらから停止させる手段が欲しくなりますね。
そんなときには、次のコマンドを実行します。

$ docker stop tutorial2

実行結果:

tutorial2

シンプルですね。docker psdocker ps -aの出力を比較するとコンテナが停止していることをより実感できると思います。

コンテナの再起動

tutorial2コンテナを停止したけど、もう一度使いたい」という場合には、下のコマンドでコンテナを再起動してあげます。

$ docker restart tutorial2

書式:
docker restart [コンテナ名 or コンテナID]

これで、tutorial2コンテナを初めて起動した時と同じように、バックグラウンドで待機している状態になります。

最後に

これで、Dockerのインストール、イメージの取得、コンテナの作成・起動、停止、再起動、ログイン、削除ができると思います。
ひとまず、ここまでで今回のまとめは終わりにしたいと思います。

筆者自身まだまだ勉強中の身なので、これからも頑張っていきたいと思います。
結論:世のエンジニアは偉い(異論は認めません)


  1. 用語などの全ての説明を保証する記事ではありません。 

  2. 特に、表現の仕方などには曖昧な表現が多分に含まれている可能性があります。 

  3. 【連載】世界一わかりみが深いコンテナ&Docker入門 

  4. 「コンテナ」という概念自体はDockerに特有のものではなく、(例えば、プログラミングにおけるデータ構造やクラスなど)いくつかの種類を持っているようです。 

  5. 実際に使用しているマシンのOS 

  6. ホストOSのカーネルを利用するので、ホストOSのカーネルが対応していない操作はできないようです(ex : ホストが MacOS 系なのにコンテナ内では WindowsOS 系の操作を要求する場合)