本題の前に
位置付け・前提
本記事は、社内ワークショップ のために用意したものです。
複数回実施する予定で、下記も併せてご利用ください。
コンテナ技術 ハンズオン Vol.2 Dockerイメージ編
なお、次の前提で進めることをご理解ください。
本ハンズオンの目的
参加者が必要に併せて 自学できる入口に立つ ことを目的とします。
なお、本ハンズオンではコンテナ技術に関する知識は説明しません。また、本ハンズオンだけで、あらゆるコンテナ操作ができるようになるわけでもありません。
後日に「コンテナ」を扱おうとしたときに、自分で調べて理解でき、実際に扱えるようになることを目指します。
端的には、なんかこういうもんだ、という感じで軽く頭に残れば大丈夫と考えましょう。
ターゲットとなる参加者
下記のような基礎知識があるエンジニアを対象とします。
- Linuxなどでコマンドを扱えるインフラの基礎知識があるエンジニア
- OSやネットワークの基礎知識は持っていること
- WEBサーバなどのミドルウェアの基礎知識を持っていること
- nginx / WordPress / Ubuntu が何かわかること
参加者の前提知識
参加者は下記が説明できること。
- コンテナとイメージの違いが説明できる
- docker とdocker hub の違いが説明できる
- docker とdocker-compose / kubernetes の違いを説明できる
- コンテナとVMとの違いが説明できる
- docker の長所と短所が説明できる
もし分からないようであれば、下記を読み込んでおくこと。今回のハンズオン内では説明しません。
動画が良ければこちら。
※上記のうち、いずれか1つで良いと思います。
docker ハンズオン環境
今回は Play with Docker を活用してハンズオンを行います。
※要:Docker Hub アカウント
注意点として、この環境は4時間の制限があります。4時間経過すると環境が削除されてしまう点を注意して下さい。
もちろんローカル環境でも構いません。
ハンズオン
今回のゴール
- docker でイメージとコンテナを追加/確認/起動/停止/削除できること
- docker でコンテナの内部を操作できること
- dockerコンテナ同士を連携させること
今回やらないこと
- コンテナ/イメージを作ったり、変更したりはしません。
- kubernetes / docker-compose のようなオーケストレーションツールの使いません。
Docker ヘルプ
基本的には docker コマンドで操作します。こちらを読めば、コマンドのオプションを忘れても大丈夫。
docker --help
表示結果はこちら。
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/root/.docker")
-c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/root/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/root/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/root/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit
Management Commands:
builder Manage builds
checkpoint Manage checkpoints
config Manage Docker configs
container Manage containers
context Manage contexts
engine Manage the docker engine
image Manage images
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
Commands:
attach Attach local standard input, output, and error streams to a running container
build Build an image from a Dockerfile
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
deploy Deploy a new stack or update an existing stack
diff Inspect changes to files or directories on a container's filesystem
events Get real time events from the server
exec Run a command in a running container
export Export a container's filesystem as a tar archive
history Show the history of an image
images List images
import Import the contents from a tarball to create a filesystem image
info Display system-wide information
inspect Return low-level information on Docker objects
kill Kill one or more running containers
load Load an image from a tar archive or STDIN
login Log in to a Docker registry
logout Log out from a Docker registry
logs Fetch the logs of a container
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
ps List containers
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
rmi Remove one or more images
run Run a command in a new container
save Save one or more images to a tar archive (streamed to STDOUT by default)
search Search the Docker Hub for images
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
version Show the Docker version information
wait Block until one or more containers stop, then print their exit codes
Run 'docker COMMAND --help' for more information on a command.
困ったら長いけど、読めば使えます。
Docker 動作テスト
docker run hello-world
実行結果の例はこちら。
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:6540fc08ee6e6b7b63468dc3317e3303aae178cb8a45ed3123180328bcc1d20f
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/
docker イメージの操作
docker イメージの操作
ここでは、docker のイメージを操作していきます。コンテナの元になるイメージですから、様々な操作が必要です。
保有している docker イメージ一覧
保有している docker のイメージを一覧表示します。
docker images
さきほど実行した hello-world イメージだけが表示されるはず。
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest XXXXXXXXXXXX 7 months ago 1.84kB
これは先程の動作テストのコマンドで、「hello-world」イメージをダウンロードして保存していることを示します。
保有している Dockerイメージをコンテナとして起動する
先程のイメージ hello-world の IMAGE ID: XXXXXXXXXXXX を指定して起動します。
docker run XXXXXXXXXXXX
動作確認と同じメッセージが出ればOK.
保有している Dockerイメージを削除する
動作確認のためのイメージ hello-world を削除します。
docker rmi -f XXXXXXXXXXXX
または
docker image rm -f XXXXXXXXXXXX
どちらでも可能です。念のため、削除されてるかを下記のコマンドで確認しておきましょう。
docker images
docker コンテナの操作
今度は動作の実態となる コンテナ を操作します。
docker イメージを取得する
下記のコマンドでLinuxディストリビューションの「Ubuntu」のイメージを取得(ダウンロード)します。
docker pull ubuntu
実行すると、下記の実行結果が表示されます。
Using default tag: latest
latest: Pulling from library/ubuntu
35c102085707: Pull complete
251f5509d51d: Pull complete
8e829fe70a46: Pull complete
6001e1789921: Pull complete
Digest: sha256:d1d454df0f579c6be4d8161d227462d69e163a8ff9d20a847533989cf0c94d90
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
これはUbuntuの最新イメージがダウンロードされたことを意味します。
ちなみに、ダウンロード元はDocker Hubです。
キチンとダウンロードが成功したかは下記で確認します。
docker images
docker コンテナの状態を確認する
先程、取得したイメージからコンテナが起動できていないことを確認します。
docker ps
恐らく表示はこちらになるはずです。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
フィールド名の行だけ出力される状態です。つまり、コンテナは何も起動していません。
docker コンテナを開始する
取得したイメージからコンテナを起動します。
docker run -it ubuntu
実行した結果、このような感じになります。
root@d3eea44310fc:/#
これはコンテナ内にログインして、シェルが起動した状態です。通常のLinuxと同じコマンドが使えます。
この状態で Ctrl+P Ctrl+Q の順にキーを入力してみましょう。
ホストOSのシェルに戻れます。(この行為を dettach と呼ぶ)
また、コンテナ内のシェルで exit を入力すると、起動したコンテナが停止します。
docker コンテナの状態を確認する
コンテナのシェルから、ホストのシェルに戻った状態を下記のコマンドで確認してみましょう。
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d3eea44310fc ubuntu "/bin/bash" 3 minutes ago Up 3 minutes silly_galileo
STATUS が「UP」と表記されている状態は、コンテナが起動している状態を指します。
dockerコンテナにログインする
dockerコンテナにログインすることを attach(アタッチ) と呼びます。下記のコマンドで実行できます。
docker attach d3eea44310fc
実行した結果、このような感じになります。
root@d3eea44310fc:/#
ls コマンドやcdコマンドなどで色々移動してみると、ホントにコンテナのOSにログインしている事が分かります。
dockerコンテナにログアウトしつつ、停止する(exit)
そのまま、exit コマンドを実行してみます。
root@d3eea44310fc:/# exit
先に記載した通り、これでコンテナも停止します。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
コンテナが停止すると、何も表示されなくなります。
dockerコンテナを全て表示する
停止したコンテナも含めて、全て表示してみます。
docker ps -a
そうすると、こんな感じで表示されます。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d3eea44310fc ubuntu "/bin/bash" 8 minutes ago Exited (0) 49 seconds ago silly_galileo
95cb9df8ea3c fce289e99eb9 "/hello" 29 minutes ago Exited (0) 29 minutes ago keen_davinci
STATUS列の値が Exited になっておいます。この Exited は停止状態 を現します。
ちなみに、こちらでも同じように表示されます。使いやすい方を使って下さい。
docker container ls --all
docker コンテナを削除する
上記の CONTAINER ID が d3eea44310fc の ubutntuコンテナを削除してみます。
$ docker rm d3eea44310fc
d3eea44310fc
成功すると、コンテナIDだけが表示されます。その後、どうなったか確認しましょう。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
95cb9df8ea3c fce289e99eb9 "/hello" 29 minutes ago Exited (0) 29 minutes ago keen_davinci
ついでに、動作確認に使った hello コンテナも削除しておきましょう。
docker rm 95cb9df8ea3c
これでキレイになりました。
ちなみに、これまで実働する実態を「コンテナ」と呼んできました。しかし、一般的には「インスタンス」と呼ぶことも多いです。今後は インスタンス と呼ぶことにします。
複数の docker インスタンスを扱う
docker イメージの取得
いくつかサービス提供できるイメージを取得してみます。
Nginx インスタンス
Webサーバで定評のある nginx を取得して起動します。取得と起動を同時に行うには次のコマンドです。
docker run -p 80:80 nginx
これはインスタンス(コンテナ)の80番ポートをOSの80番ポートに紐付けて、起動するコマンドになります。これを実行してみると下記のようになります。
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
1ab2bdfe9778: Pull complete
a17e64cfe253: Pull complete
e1288088c7a8: Pull complete
Digest: sha256:53ddb41e46de3d63376579acf46f9a41a8d7de33645db47a486de9769201fec9
Status: Downloaded newer image for nginx:latest
イメージ取得後に上記のメッセージを表示して、何も表示されなくなります。
その上で、Play with Docker のコンソールを見ると下記のようにリンク表示されますので、確認しましょう。
リンクを辿った結果、下記のように表示されれば成功です。
コンソール上には、下記のようにアクセスログが表示されます。
その後、コンテナの状態を見てみましょう。とはいえ、この状態では Ctrl-P Ctrl-Qでnginxインスタンスからデタッチすることができません。一度、Ctrl+c で強制終了します。
Nginx インスタンス(バックグラウンド)
改めて、下記のコマンドでバックグラウンド実行をしましょう。
docker run -p 80:80 -d nginx
引数 -d を追加すると、起動後にデタッチした状態、つまりバックグラウンドでインスタンスを起動することができます。次のコマンドでインスタンスの起動状態が確認できます。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
084d96e489b8 nginx "nginx -g 'daemon of…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp condescending_morse
PORTS 列に注目すると、「0.0.0.0:80 つまりホストOSの80番ポートに、 80/TCP つまりインスタンスの80番ポートを紐付ける」設定で起動していることが分かります。
WordPress インスタンス
CMSとして有名なWordPressインスタンスを起動してみましょう。取得と起動に加え、先度と同じようにバックグラウンドでインスタンスを動作させます。
docker run -d -p 8080:80 --name wp-tmp wordpress
ちなみに、インスタンス(コンテナ)の80番ポートをOSの8080番ポートに紐付けて、起動するコマンドになります。インスタンスの名前も wp-tmp として付けています。
これを実行してみると下記のようになります。
$ docker run -d -p 8080:80 --name wp-tmp wordpress
Unable to find image 'wordpress:latest' locally
latest: Pulling from library/wordpress
1ab2bdfe9778: Already exists
1448c64389e0: Pull complete
4b8a4e62b444: Pull complete
9eb9d1e8e241: Pull complete
d20b2d19292c: Pull complete
023060ea5930: Pull complete
a7fa99bc84ac: Pull complete
138ec8da18f2: Pull complete
cd4dae5ac262: Pull complete
c90eff48869a: Pull complete
1bc49f4d3a43: Pull complete
e3bb2b10f58d: Pull complete
fd7b454ec570: Pull complete
f683ca4a731d: Pull complete
ddfc36999535: Pull complete
7fddf219f6ab: Pull complete
4f41fcb25817: Pull complete
42e4c7a4efc8: Pull complete
3db92b48316d: Pull complete
09fa84b4298a: Pull complete
Digest: sha256:c3c95ed75a85b024c07455b2722f5ecec78d4efb363aca02539f1b9057e713ac
Status: Downloaded newer image for wordpress:latest
4171518356b78f585a82522da48a2ca2ae522dcbffb1188e6b83266b25d716c8
イメージ取得後に上記のメッセージを表示して、シェルに戻ってきます。また、管理コンソールから8080ポートにアクセスすると下記の画面が表示されます。
この後進めると、実際にデータベースを設定する画面まで進められます。
実際には、MySQLが必要となります。
そのため、一度この WordPressインスタンスは停止および削除 してください。
docker stop wp-tmp
stop コマンドでインスタンスは停止することができます。もちろん、rm コマンドで削除しても構いません。
docker rm -f wp-tmp
引数 -r を付ければ、起動しているインスタンスごと強制的に削除可能です。
MySQL インスタンスの取得
RDBMSとして有名なMySQLインスタンスを起動してみましょう。取得と起動に加え、バックグラウンドでインスタンスを動作させる引数「-d」をつけ、さらにインスタンス名と環境変数を設定するコマンドです。ちょっと複雑。
docker run --name wp-mysql -e MYSQL_ROOT_PASSWORD=wppassword -e MYSQL_USER=wpuser1 -e MYSQL_PASSWORD=password -e MYSQL_DATABASE=wp -d mysql:5.7.27
ちなみに、ここでは動作条件に必要なMySQLのバージョン指定をしています。
これを実行してみると下記のようになります。
$ docker run --name wp-mysql -e MYSQL_ROOT_PASSWORD=wppassword -e MYSQL_USER=wpuser1 -e MYSQL_PASSWORD=password -e MYSQL_DATABASE=wp -d mysql:5.7.27
Unable to find image 'mysql:latest' locally
latest: Pulling from library/mysql
9fc222b64b0a: Pull complete
291e388076f0: Pull complete
d6634415290b: Pull complete
1f1e7d852ad4: Pull complete
125fc05f36e0: Pull complete
2aed16e5b02f: Pull complete
5fa9342b7235: Pull complete
6ce062d9949d: Pull complete
c5a4e96aaa50: Pull complete
60ca60d28457: Pull complete
e93ef9cc9bb0: Pull complete
9bc6d9fa3f72: Pull complete
Digest: sha256:01cf53f2538aa805bda591d83f107c394adca8d31f98eacd3654e282dada3193
Status: Downloaded newer image for mysql:latest
93e8eb78dc7d837b72ddba842fd1283eae0ab8c0c24805ca071a722993b23525
再び WordPressインスタンスの作成
この MySQL インスタンスにアクセスできるWordPressインスタンスを作成します。
docker run --name wp -p 8080:80 --link wp-mysql:mysql -d wordpress
既にイメージは取得済みなので、サクッと起動できるはずです。違いとしては、引数 --link を設定していまして、意味は下記の通りです。
docker run -link [dockerコンテナ名、もしくはID][:[エイリアス]]
このようにコンテナ間をリンクさせることで、1つのOSで動作しているのと同じように動きます。
先程と同様に管理コンソールから8080番ポートにWEBアクセスして、先程のWordPress設定画面まで進めます。
先程とは違って、データベースの接続設定画面が表示されません。つまり、MySQLの接続が成功し、わざわざ設定しなく済んでいることが分かります。
今度は、適切に設定して、「WordPressインストール」ボタンを押下します。
あとは先程設定したユーザー名やパスワードを入れればログインできる画面まで到達できます。
このとき、裏側では WordPress のコンテナと MySQL のコンテナが連携して動作しています。
このように同一ホスト上のコンテナの間で通信したい場合、接続したい相手のネットワーク情報を取得できるようにする仕組みを備えています。こちらも併せて読むと良いでしょう。
問題
下記を調べましょう。
- 起動しているコンテナはホストのどのディレクトリにあるでしょうか。
- dockerイメージはどこにあるでしょうか。
- dockerのプロセスはどれか。
また、1-3が完了した後は後始末をしましょう。
- 起動しているインスタンスをすべて停止してください。
- 起動しているインスタンスをすべて削除してください。
- 取得したイメージをすべて削除してください。
おわりに
今回は docker で1~数個のコンテナを扱う方法について、ハンズオンをしました。
しかし、dockerコンテナはそもそも誰かが作る必要がありますが、その手順は今後学んでいく必要があります。それはこちらで学習しましょう。
コンテナ技術 ハンズオン Vol.2 Dockerイメージ編
また、コンテナの真骨頂は大量のコンテナ操作や定型的な運用操作の効率化にあります。今後は、Docker-compose や Kubernetes といったツールを学んでいきましょう。
なお、もう少しハンズオンを独自にやりたい人はこちらもどうぞ。
Play with Docker Classroom(英語)
参考
本ハンズオン資料を作成する上で、下記のページを参考にさせていただきました。ありがとうございました。
- 入門 Docker
- Dockerでコンテナ作成/起動/停止/自分用Image作成
- Dockerコンテナの作成、起動〜停止まで
- Use the Docker command line | Docker Documentation
- Dockerのすべてが5分でわかるまとめ!(コマンド一覧付き) - paiza開発日誌
- 【Linux】Docker / Kubernetes 入門
- Dockerハンズオン基礎編:コンテナとイメージのライフサイクルを理解 - Qiita
- Dockerハンズオン資料 - Qiita
- Docker ハンズオン - 基本コマンド編 - Qiita
- こうしたいんだぜ! という時の逆引きdockerコマンド | 株式会社ビヨンド