ハンズオンで学ぶDocker入門 | 1. Dockerイメージ・コンテナ管理メカニズム

Dockerはシンプルで実用的な機能を提供し、軽量な仮想環境としてアプリケーションデプロイに活用され、急速に普及して利用されている。この資料は、Dockerに関心はあるもののまだ経験したことがない人に向けて、実際に手を動かしながらDockerを理解するための資料を提供する。今回の章では、Dockerの概要と、最も基本となるイメージおよびコンテナ管理の実際の操作方法を段階的に紹介する。

Docker実習

ここまでDocker自体について説明してきた。Dockerを正しく理解するには、実際に動かしてみるのが一番よい。ぜひ一度、ざっと実習してみることをおすすめする。

Hello Worldを表示してみよう

インストールができたら、プログラマーになじみのあるhello worldを試してみよう。

% docker run hello-world

docker run は、イメージからコンテナを起動するコマンドである。上のコマンドは、hello-world というイメージからコンテナを起動するという意味である。しかし、ローカルに hello-world イメージがないため、DockerデーモンがDocker Hub(Docker社が運営するPaaS型のDocker Registry)からhello-worldイメージをダウンロードし、そのイメージのコンテナを起動する。このコンテナは次のように標準出力を行い、終了する。

Unable to find image 'hello:latest' locally
docker: Error response from daemon: pull access denied for hello, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
See 'docker run --help'.
% docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:9f6ad537c5132bcce57f7a0a20e317228d382c3cd61edae14650eec68b2b345c
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

コンテナでLinuxを動作させてみよう

先ほどの hello-world の例では、コマンドラインからイメージ取得とコンテナ起動を簡単に行えることを確認した。

次はもう少し複雑な例として、Alpine Linux というコンテナ向けに開発された軽量Linuxディストリビューションのコンテナを操作する方法を紹介する。このチュートリアルを通じて、Dockerを使用するうえで最も基本となる次の事項を学べる。

  • イメージの取得(pull)
  • イメージの一覧表示(images)
  • コンテナのライフサイクル管理
    • 作成(create)
    • 開始(start)
    • 停止(stop)
    • 削除(rm)
  • コンテナの表示(ps)

まずalpineのイメージを取得しよう。イメージを取得するには pull コマンドを使用する。

% docker pull alpine
Using default tag: latest
latest: Pulling from library/alpine
5843afab3874: Pull complete
Digest: sha256:234cb88d3020898631af0ccbbcca9a66ae7306ecd30c9720690858c1b007d2a0
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest

images コマンドで取得したイメージ一覧を確認できる。先ほどのhello worldとalpineのイメージが表示されていることを確認できる。

% docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
alpine        latest    d4ff818577bc   26 hours ago   5.6MB
hello-world   latest    d1165f221234   3 months ago   13.3kB

それでは、次にalpineイメージからコンテナを起動してみよう。コンテナの起動には run コマンドを使用する。

コマンドの構文は次の通りである。

`docker run <イメージ名> <コンテナで起動するコマンド>`

run はコンテナを作成(create)し、そのコンテナを開始(start)するところまで行う。高度なオプションは Docker公式ドキュメント を参照してほしい。

% docker run alpine echo "hello from alpine"
hello from alpine

<コンテナで起動するコマンド> として echo コマンドを指定したため、コンテナを起動した直後に echo コマンドを実行し、コンテナは終了した。

ここまではコンテナ起動時に1つだけコマンドを実行し、すぐに終了した。コンテナで対話型のコマンド操作をしたい場合は、run コマンドに -it オプションを付けてコンテナへ接続してみよう。次の例では、コンテナを起動してシェルが実行されたため、コンテナ内でLinuxコマンドを使用できるようになった。

% docker run -it alpine bin/sh
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var

そしてもう1つターミナルを開き、ps コマンドを実行してみよう。ps コマンドは現在実行中のコンテナを確認するコマンドである。現在、もう一つのターミナルでalpineイメージからコンテナを起動し、bin/sh コマンドを実行していることがわかる。

% docker ps
CONTAINER ID   IMAGE     COMMAND    CREATED          STATUS          PORTS     NAMES
d0736179149d   alpine    "bin/sh"   56 seconds ago   Up 55 seconds             nifty_keller

ここで stop コマンドを実行すると、コンテナを停止できる。上でalpineコンテナを起動したターミナルを開き、コンテナが停止していることを確認できる。

% docker stop d0736179149d
d0736179149d

stop はコンテナを削除するのではなく、あくまで停止するだけである。停止したコンテナは start コマンドで再度開始できる。ps コマンドでコンテナが実際に開始されているか確認する。

% docker start d0736179149d
d0736179149d
% docker ps
CONTAINER ID   IMAGE     COMMAND    CREATED         STATUS          PORTS     NAMES
d0736179149d   alpine    "bin/sh"   5 minutes ago   Up 13 seconds             nifty_keller

しかし、このままでは再びコンテナを操作できない。ターミナルからコンテナに接続するには attach コマンドを使用する。引数はコンテナIDである。

% docker attach d0736179149d
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ #

コンテナを終了(停止 + 削除)するには、コンテナに接続した状態で exit コマンドを実行する。Windowsでは Ctrl+C でも可能である。

/ # exit

または、stop コマンドで停止し、rm コマンドでコンテナを削除できる。

% docker stop 30cf0829bee2
30cf0829bee2
% docker rm 30cf0829bee2
30cf0829bee2

一度コンテナを削除すると、そのコンテナを start コマンドで再起動することはできない。

% docker start 30cf0829bee2
Error response from daemon: No such container: 30cf0829bee2
Error: failed to start containers: 30cf0829bee2

コンテナでWebサーバーを動かしてみる

ここまで、Alpine Linuxのイメージを例に、イメージおよびコンテナ管理方法について説明した。

次は最後の例として、もう少し実用的にDockerによるWebサーバーのデプロイを紹介する。

ここでは seqvence/static-site という Docker Hub で公開されているイメージを使用する。このイメージのコンテナ内部にはNginx(Webサーバー)が含まれており、アクセス可能なWebブラウザにコンテナ内の静的Webページを提供する。Dockerはゲスト側のポートをホスト側へマッピングできるため、Webブラウザによるホストポートへのアクセスをゲストへ転送できる。こうしてDockerでWebサーバーを起動し、Webアプリケーションを提供できる。

まずコンテナを起動してみよう。Your Name の部分には適切な名前を入れる。

% docker run --name static-site -e AUTHOR="Docker" -d -p 80:80 seqvence/static-site
Unable to find image 'seqvence/static-site:latest' locally
latest: Pulling from seqvence/static-site
Image docker.io/seqvence/static-site:latest uses outdated schema1 manifest format. Please upgrade to a schema2 image for better future compatibility. More information at https://docs.docker.com/registry/spec/deprecated-schema-v1/
fdd5d7827f33: Pull complete
a3ed95caeb02: Pull complete
716f7a5f3082: Pull complete
7b10f03a0309: Pull complete
aff3ab7e9c39: Pull complete
Digest: sha256:41b286105f913fb7a5fbdce28d48bc80f1c77e3c4ce1b8280f28129ae0e94e9e
Status: Downloaded newer image for seqvence/static-site:latest
9277612d90a1c6eb434c976db6bd6f1e1c651b05c0c35b1cc053656f53544ba1

初めて起動すると上のようにイメージのダウンロードが進み、Dockerが実行されていることを次のように確認できる。

% docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS          PORTS                                        NAMES
9277612d90a1   seqvence/static-site   "/bin/sh -c 'cd /usr..."   54 seconds ago   Up 52 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp, 443/tcp   static-site

上のコマンドオプションは次の通りである。

オプション 意味
-name static-site コンテナ名として static-site を指定する。
-e AUTHOR=“Docker” コンテナに環境変数 Author として Docker を渡す。このコンテナは環境変数 Author をWebページ表示に使用している。
-d Detach mode(分離モード)で起動する。コンテナがデーモンとしてバックグラウンドで開始する。
-p 80:80 コンテナの公開ポート(80)をホストポート(80)に割り当てる。

上の場合、ゲストの80番ポートをホストの80番ポートに割り当てているため、ブラウザで80番ポートにアクセスすると、Dockerコンテナ内のWebアプリケーションが生成したWebページが表示される。

static-siteの実行結果

注: 使用するDocker EngineによってアクセスするURIが異なる。

  • Linux、Docker for Windows(Windows 10以上)、Docker for Mac(OS X 10.10 Yosemite以上)の場合、localhost:80 で結果を確認できる。
  • それ以外の場合は、docker-machine ip default でDockerデーモンのIPアドレスを確認する。

それでは、-p オプションを変更して、ホスト側の別のポートに割り当てることができる。次の場合は2つ目のコンテナを起動し、ゲスト側の80ポートをホストの8080ポートに割り当てる。したがって、Webブラウザで localhost:8080 にアクセスするとWebページを表示できる。

% docker run --name static-site2 -e AUTHOR="My second Docker" -d -p 8080:80 seqvence/static-site
8996b832b603037d37e7d32c456fdc259929fe0a9094968ad2762c0c9651db3b

これで、簡単な例を使ってホストからDockerコンテナのWebサーバーにアクセスできることを確認した。ファイアウォール設定(Linuxではiptables)を変更し、外部からホストのHTTPポートにアクセス可能にすれば、DockerのWebサーバーを外部へ公開できる。

これを応用してクラウドサーバーにDockerをインストールしておけば、Dockerコマンドでイメージ検索からコンテナのWebサーバー起動までを含むデプロイ作業を簡単に行える。また、Webページの内容を簡単に変更し、ホスト側で再び新しいDockerイメージを取得してコンテナを起動すればよいことも確認した。

まとめ

ここではDockerの概要、既存イメージおよびコンテナの操作方法について説明した。Webサーバーをデプロイする方法についても紹介した。今回の内容で、イメージおよびコンテナ管理は難しくなく、アプリケーションのデプロイも簡単にできることを理解できたと思う。しかし、実際にDockerでアプリケーションをデプロイするには、自分のイメージを作成してデプロイする必要がある。次回はイメージを作成する方法を紹介する。