Dockerについて
Dockerサイト → https://docs.docker.com
参考 → https://employment.en-japan.com/engineerhub/entry/2017/09/28/110000
2013年に Docker社が開発しオープンソース化した仮想化環境の一つ。
コンテナと呼ばれる技術を使って軽量で容易に仮想化環境を構築できます。
インストール
開発環境に合わせてパッケージがあるのでインストールします。
→ https://store.docker.com/search?type=edition&offering=community
うちの開発環境は MacOSX なので Mac用をダウンロードしてインストールしました。
#Docker Hub にアクセスするために?ログインを聞いてくるので初めての場合はアカウント作成してログインします。
インストールが完了したら Terminal を開いて確認します。
$ docker --version
Docker version 17.09.0-ce, build afdb6d4
$ docker-compose --version
docker-compose version 1.16.1, build 6d1ac21
$ docker-machine --version
docker-machine version 0.12.2, build 9371605
動作確認
試しに次のコマンドを実行します。
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
5b0f327be733: Pull complete
Digest: sha256:175735360662078abd70dacb73c5518d5b3ae7c1ed069d22def5da57c3e917d6
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.
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://cloud.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/
なんか正常に動作したみたいですね(^^
Dockerイメージ
Docker は イメージと呼ばれる動作の塊みたいなものを Docker hub から取ってくるか或いは自分で作るかして、それをコンテナ上で実行する、というイメージです。
docker run <image>
は image をコンテナ上で走らす、というコマンドで、前項の docker run hello-world
は 'Hello from Docker!' と説明文を表示する動作の塊(hello-worldイメージ)を(手元になければ取ってきて)コンテナを作成して実行する、というコマンドでした。
で、イメージですが、自分で一から作ってもいいみたいですが、多くの方が既にたくさんのイメージを作って公開されているので、それを利用させてもらいます。
自分のやろうとしていることに近いイメージを取得して、それを改造して利用するといういやりかたが一番スマートなのかもしれません。
nginx が走る Dockerイメージ を作ってみる
その前に、まずは Docker ではなくて普通に仮想マシンで nginx が走るようにする場合を考えます。
- 仮想マシンの作成(OSインストール、ネットワーク設定)
- nginx のパッケージをインストールするかソースコードを取得してコンパイル
- nginx の設定
- 実行
以上だと思いますが、OSインストールからとなると、少し面倒ですw
Docker を使った場合も流れは同じですが、仮想マシンを作成する必要がないため、比較的すぐに nginx のインストールから始めることができます。
debian のイメージを pull する
ここでは OS は debian を利用します。もちろん ubuntu とか centos でも大丈夫。
$ docker pull debian
docker hub に登録されている debian の最新版を取得します。
バージョン(タグ)指定とかもできるみたいです。例えば 8.7 を取得したい場合は
docker pull debian:8.7
どんなタグがあるのかはAPIで確認できるみたいです。
$ curl -s https://registry.hub.docker.com/v1/repositories/debian/tags
[{"layer": "", "name": "latest"}, {"layer": "", "name": "6"}, {"layer": "", "name": "6.0"}, {"layer": "", "name": "6.0.10"}, {"layer": "", "name": "6.0.8"}, {"layer": "", "name": "6.0.9"}, {"layer": "", "name": "7"}, {"layer": "", "name": "7.10"}, {"layer": "", "name": "7.11"}, {"layer": "", "name": "7.3"}, {"layer": "", "name": "7.4"}, {"layer": "", "name": "7.5"}, {"layer": "", "name": "7.6"}, {"layer": "", "name": "7.7"}, {"layer": "", "name": "7.8"}, {"layer": "", "name": "7.9"}, {"layer": "", "name": "8"}, {"layer": "", "name": "8.0"}, {"layer": "", "name": "8.1"}, {"layer": "", "name": "8.2"}, {"layer": "", "name": "8.3"}, {"layer": "", "name": "8.4"}, {"layer": "", "name": "8.5"}, {"layer": "", "name": "8.6"}, {"layer": "", "name": "8.7"}, ...
ダウンロードしたイメージを走らせる
$ docker run -it --name docker_nginx debian /bin/bash
root@37aa52782342:/#
んでコンテナ上で走っている debian 最新版にログインできました。
-it
は interactive + tty でコンソールにログインしてごにょごにょできるオプションです。
あと、イメージ名だけだとすぐに終了するのでシェルを走らせるコマンドをつけておきます。→ /bin/bash
それから、--name
でイメージに名前を付けることができます。これを付けておくとあとでいろいろと便利なので、付けておきましょう。
これで OS のインストール?は完了です。
次に nginx をインストールします。
nginx のインストール
普通にインストールして実行してみます。
# apt-get update
# apt-get install nginx
# /etc/init.d/nginx start
で、確認したいのですが、取得した debian イメージは最低限のものしかないので、確認するものをインストールします。
curl をインストールしてみます。
# apt-get install curl
# curl http://localhost
HTMLが表示されたら成功です。
終了は
# exit
です。
コンテナの終了
前項で、インストールと実行が確認できたのですが、docker は基本的にイメージは上書き禁止になっています。
ではどうやってインストールしていたのかというと、レイヤーという方法で実現しているみたいです。
ベースとなるイメージとの差分を重ねていくことで実現しているみたいです。
なので終了して破棄すると先ほどの nginx のインストール はなかったことになってしまいます。
終了しているかどうかは docker ps -a
で調べることができます。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2d93a23033af debian "/bin/bash" 7 hours ago Exited (0) 3 seconds ago docker_nginx
STATUS が Exited (0) 3 seconds ago になってます。3秒前に終了した、という状態ですね。
この状態ではまだイメージは残っています。
再度アクセスしたい場合は docker start -i docker_nginx
と入力します。
イメージは明示的に破棄しなければ残ります。
ちなみに明示的な破棄の方法は二つあって、一つは docker run 時に --rm
オプションを付けるか、もう一つは docker rm
で削除するかです。
新しいイメージの作成
せっかく変更を加えたイメージなので、このイメージを新しい名前で保存します。#ベースイメージに変更を加えたものをコミットします。
$ docker commit -m 'add nginx' docker_nginx ysomei/nginx
sha256:d6168451070dc61a8173f6dde790c0fe7b532dd3e5c9618f1009355f5d25d988
-m はコメント記入で docker_nginx は run するときに --name で付けた名前。
ysomei/nginx は新しいイメージの名前になります。#ユーザー名/イメージ名 みたいです。
試しに docker images
を実行すると
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ysomei/nginx latest d6168451070d 6 minutes ago 193MB
となって、新しくイメージが作成されているのがわかります。
続きを作業したい場合は、
$ docker run -it --name ysomei_nginx ysomei/nginx /bin/bash
とするとコンソールでごにょごにょできます。
コンテナとホストをつなぐ
前項までで nginx のコンテナを起動するところまでできました。しかしながらこのままでは外部からアクセスすることができませんので繋げてあげる必要があります。
基本的には docker run の -p
オプションでホスト上のポートにコンテナ上のポートをフォワードすれば良いです。
$ docker run -p 8086:80 ysomei/nginx /etc/init.d/nginx start
ですが、docker run は一通り処理をしたら自動的に終了するようになっているので、少し細工が必要になります。
終わらない細工を入れる
コンテナに入って以下をします。
$ docker run -it --name ysomei_nginx ysomei/nginx /bin/bash
# cd /usr/local/sbin
# vi run.sh
vi が入ってなければ apt-get install vim
をします。
#エディターは自分の使いやすいのでいいですよ。
#!/bin/bash
/etc/init.d/nginx start
tail -f /dev/null
で、chmod +x run.sh
で実行権限を追加しておきます。
ポイントは最後の tail -f /dev/null
です。
無限に空デバイスを表示させることで終了しないコンテナが出来上がります :)
そしたら、一旦終了してイメージを更新します。
$ docker commit -m 'add run.sh' ysomei_nginx ysomei/nginx
sha256:d099d6d777549a20a1a26b47c5b8adf38d2c40e48b0d04e085e81bf75510b759
nginxコンテナ起動!
終わらない細工をしたのでコンテナを起動させます。
$ docker run -d -p 8086:80 --name ysomei_nginx ysomei/nginx /usr/local/sbin/run.sh
f2814017ed405393c5d79968c958e3c061466652b0bb3396e834cb606be28d5d
オプションの -d
はデーモンとして起動です。
-p 8086:80
で、コンテナ上の 80ポートをホストの 8086ポートにフォワードします。
では確認してみましょう。まずはプロセス確認。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2814017ed40 ysomei/nginx "/usr/local/sbin/r..." 2 minutes ago Up 2 minutes 0.0.0.0:8086->80/tcp ysomei_nginx
STATUS が Exited じゃなくて Up 2 minutes になってますね。起動して 2分ということです。
では 8086ポートにアクセスしてみましょう。
$ curl http://localhost:8086/
HTMLが流れたら成功です。ブラウザでも確認してみてください。
まとめ
とまあこんな感じです。
仮想環境へのインストールになるので、実環境が汚れなくていいかなぁなんて思います。
また、イメージができたらこれを持ち運ぶことで Docker の動く他の環境でもコンテナを起動して実行できるようになります。
$ docker save -o ysomei_nginx.tar ysomei/nginx
でイメージがファイルに出力されました。
読み込みは
$ docker load -i ysomei_nginx.tar
fba06a98a658: Loading layer 94.5MB/94.5MB
65b3667d0d44: Loading layer 33.02MB/33.02MB
Loaded image: ysomei/nginx:latest
です。
とりあえず今回はここまで。