Dockerの勉強用のメモです。
Dockerに関しては、先達のみなさんのblog、Qiita上の情報を参考に勉強していますが、今回はスポットで下記についての実行結果をアップします。
やりたいこと
- CentOSのイメージを使って、簡単なコマンドを実行する
- docker run…ではなくて、Dockerfileを使ってdocker buildしてみる。
- うまくいったら、少しずつRUNさせることを増やしていく。
- Dockerのイメージのリポジトリから、好きなもの使ってみたい。
ここまでの前提
- 仮想環境にはVirtualBox + Vagrantを使う。
- Vagrantを使って、Docker入りのUbuntuをインストールした。
- https://github.com/dotcloud/docker.git を利用 -> Vagrant upでUbuntuの環境を作成した。
- 上記のUbuntuをベースにし、sshログイン。この中でdockerコマンドが実行できることを確認した。
- Dockerのチュートリアルで、簡単に学習をした。
- http://www.docker.io/gettingstarted/# (オンラインで学習できます!)
- dockerコマンドで、最初にイメージをダウンロードし、コンテナ(Dockerで言う所の仮想環境)を起動できた。
- yum installなどで内部に変更が加わると、イメージのIDが変更していくことが分かった。
CentOSのイメージを選びます
docker search centos で検索
前提条件をもとに、ベースに使うCentOSを選びます。(実行の起点はUbuntuですが、dockerで利用するイメージはいろいろ選べます)
すでにCentOS6.5が出ているので、新しいほうがいいな..と思い、docker search で検索しました。
"TRUSTED"がOKになっているものは、公式なイメージなんでしょうか?
(https://index.docker.io/search?q=centos でも一覧が取れます)
vagrant@precise64:~$ docker search centos
NAME DESCRIPTION STARS OFFICIAL TRUSTED
dustin/centos Old CentOS is old. 0
chentoo/centos centos 5.6 x86_64 image 0
hnakamur/centos CentOS 6.5 x86_64 base image 0
tutum/centos CentOS Docker image with SSH access 5
blalor/centos Bare-bones base CentOS 6.5 image 0 [OK]
tianon/centos CentOS 5 and 6, created using rinse instea... 2
backjlack/centos This repository contains the following ima... 0
# --- 以下略
OfficalのものはCentOS6.4 なようなので、6.5は無いかなと思ったところ、hnakamurさんのエントリで、CentOS 6.5のbase imageを作成&登録したとの記述を発見!
こちらを利用させていただくことにしました。
Dockerfileを作ります
イメージを決めたので、次はDockerfileを用意します。場所はどこでも良いみたいなので、~/work 以下に置きました。
最低限、FROM(どのイメージを使うか)があれば良いみたいです。
今回は、hnakamuraさんのイメージを利用したいので、検索して出て来たそのままの名前を入れてみました(この時点で、この指定でいいのか自信がありませんでした)。
vagrant@precise64:~/work$ pwd
/home/vagrant/work
vagrant@precise64:~/work$ ls
Dockerfile
vagrant@precise64:~/work$ cat Dockerfile
#FROM centos
FROM hnakamur/centos
RUN /bin/echo hi
RUN /bin/cat /etc/redhat-release
Dockerfileの内容は、こんな感じです。
- 指定のimageを取ってくる
- 起動して"hi" をecho する
- OSのバージョンを表示する (redhat-releaseの記載を確認し、CentOS6.5になってるかどうか確認)
Build前の確認
実施前の確認です。imageは空っぽの状態。(Ubuntu向けにbaseというイメージもありましたが、いったんクリアしました)
vagrant@precise64:~$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
Buildしてみます
Dockerfileのあるディレクトリで、docker build . としてみます。
まずはdocker.ioからイメージをダウンロードするところから始まります。
親切なことに、Step1, Step2 と言った具合に、進行状況(過程)も表示してくれるんですね!
vagrant@precise64:~/work$ docker build .
Uploading context 10.24 kB
Step 1 : FROM hnakamur/centos
Pulling repository hnakamur/centos
a9f02140a1ee: Download complete
dfb97af77c51: Download complete
50d4926c934d: Download complete
---> dfb97af77c51
Step 2 : RUN /bin/echo hi
---> Running in d08b5b48f486
hi
---> 22d0bb5e5683
Step 3 : RUN /bin/cat /etc/redhat-release
---> Running in f832f6d77c12
CentOS release 6.5 (Final)
---> 9bd6f163b65a
Successfully built 9bd6f163b65a
結果を見ると、"hi" と "CentOS release 6.5 (Final)" という表示が出ているので、予想通りの結果となりました。
また、 built 9bd6f163b65a という結果になりました。
これが現在のIMAGE IDのようです。
https://index.docker.io/u/hnakamur/centos/ のダウンロード数もカウントアップされたようです。
2回目以降は?
Stepは表示されますが、イメージのダウンロードは行われない分、処理が早くなります。
vagrant@precise64:~/work$ time docker build .
Uploading context 10.24 kB
Step 1 : FROM hnakamur/centos
---> dfb97af77c51
Step 2 : RUN /bin/echo hi
---> Using cache
---> 22d0bb5e5683
Step 3 : RUN /bin/cat /etc/redhat-release
---> Using cache
---> 9bd6f163b65a
Successfully built 9bd6f163b65a
real 0m0.020s
user 0m0.008s
sys 0m0.000s
さて、echo, cat の内容はどうなったかと言うと、 Using cache という文字列が表示されているだけ。
どうなっちゃったんでしょう?
cacheということで、IMAGE IDは built 9bd6f163b65a という結果で、これは初回と同じ値です。
no cacheをつけてみる
まだよく分かっていないのですが、オプションにno cacheを付けてみます。こんどは、echo / cat の結果が返ってきました。
vagrant@precise64:~/work$ docker build -no-cache .
Uploading context 10.24 kB
Step 1 : FROM hnakamur/centos
---> dfb97af77c51
Step 2 : RUN /bin/echo hi
---> Running in 26955e584363
hi
---> fb53f74b6767
Step 3 : RUN /bin/cat /etc/redhat-release
---> Running in 95aba47597d6
CentOS release 6.5 (Final)
---> 45cdab64b614
Successfully built 45cdab64b614
イメージを確認すると built 45cdab64b614 が追加されてます。
vagrant@precise64:~/work$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
<none> <none> 45cdab64b614 2 minutes ago 309.9 MB
<none> <none> 9bd6f163b65a 14 minutes ago 309.9 MB
hnakamur/centos 6.5 a9f02140a1ee 2 weeks ago 309.9 MB
hnakamur/centos latest dfb97af77c51 2 weeks ago 309.9 MB
ファイルに何か書き込んでみます
echoするだけ、catするだけだと、書き込み(変更)が無いので、さらに ~/test.txt に書き込むテストをしてみます。
#FROM centos
FROM hnakamur/centos
RUN /bin/echo hi
RUN /bin/cat /etc/redhat-release
RUN /bin/echo "hoge" > ~/test.txt
RUN /bin/cat ~/test.txt
実行。~/test.txt の中身のcatもできたようです。
vagrant@precise64:~/work$ docker build .
Uploading context 10.24 kB
Step 1 : FROM hnakamur/centos
---> dfb97af77c51
Step 2 : RUN /bin/echo hi
---> Using cache
---> 22d0bb5e5683
Step 3 : RUN /bin/cat /etc/redhat-release
---> Using cache
---> 9bd6f163b65a
Step 4 : RUN /bin/echo "hoge" > ~/test.txt
---> Using cache
---> 699db1b2f739
Step 5 : RUN /bin/cat ~/test.txt
---> Running in c7eee58c120d
hoge
---> f20c50e138e4
Successfully built f20c50e138e4
状態をコミット
vagrant@precise64:~/work$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7eee58c120d 699db1b2f739 /bin/sh -c /bin/cat 2 minutes ago Exit 0 boring_pike
07e7be6ba1af 9bd6f163b65a /bin/sh -c /bin/echo 2 minutes ago Exit 0 boring_darwin
95aba47597d6 fb53f74b6767 /bin/sh -c /bin/cat 4 hours ago Exit 0 determined_turing
26955e584363 hnakamur/centos:latest /bin/sh -c /bin/echo 4 hours ago Exit 0 tender_euclide
f832f6d77c12 22d0bb5e5683 /bin/sh -c /bin/cat 4 hours ago Exit 0 prickly_ritchie
d08b5b48f486 hnakamur/centos:latest /bin/sh -c /bin/echo 4 hours ago Exit 0 romantic_turing
コミットには、CONTAINER IDが必要らしいので、一番最後に実行したものを引数にしてみます。
vagrant@precise64:~/work$ docker commit c7eee58c120d
9608087e8eb76cc16c40a842599f125861aadf7fd4afe78b6cf54ffbf64a89be
vagrant@precise64:~/work$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
<none> <none> 9608087e8eb7 3 seconds ago 309.9 MB
<none> <none> f20c50e138e4 2 minutes ago 309.9 MB
hnakamur/centos 6.5 a9f02140a1ee 2 weeks ago 309.9 MB
hnakamur/centos latest dfb97af77c51 2 weeks ago 309.9 MB
イメージ毎のテスト
test.txt を書き込む前の、ダウンロードした直後のイメージに対して、test.txt の中身をcatさせてみます。
結果、そんなのは無いよ、と言われます。
vagrant@precise64:~/work$ docker run a9f02140a1ee /bin/cat /test.txt
/bin/cat: /test.txt: No such file or directory
つぎに、コミットしたイメージに対して、test.txt の中身をcatさせてみます。(Image ID : f20c50e138e4)
vagrant@precise64:~/work$ docker run f20c50e138e4 /bin/cat /test.txt
hoge
こんどはちゃんと出力できたようです!
ファイルに書き込みテスト(2)をためします
同じ文字列"hoge" だけを書き込むと、キャッシュされるようなので、今度はdateコマンドの結果もくっつけて、Dockerfileを実行してみます。
Dockerfile
FROM hnakamur/centos
RUN /bin/echo hi
RUN /bin/cat /etc/redhat-release
RUN /bin/echo "hoge `date`" > ~/test.txt
RUN /bin/cat ~/test.txt
2回続けて実行
1回目。
"hoge Sun Jan 5 20:47:17 EST 2014" と出力されます。
vagrant@precise64:~/work$ docker build .
Uploading context 10.24 kB
Step 1 : FROM hnakamur/centos
---> dfb97af77c51
Step 2 : RUN /bin/echo hi
---> Using cache
---> 22d0bb5e5683
Step 3 : RUN /bin/cat /etc/redhat-release
---> Using cache
---> 9bd6f163b65a
Step 4 : RUN /bin/echo "hoge `date`" > ~/test.txt
---> Running in c5d97135393c
---> 6c44ddd7b236
Step 5 : RUN /bin/cat ~/test.txt
---> Running in 6126db4144b6
hoge Sun Jan 5 20:47:17 EST 2014
---> cf8c4153782b
Successfully built cf8c4153782b
2回目。
"hoge Sun Jan 5 20:47:29 EST 2014" と出力されます。
vagrant@precise64:~/work$ docker build .
Uploading context 10.24 kB
Step 1 : FROM hnakamur/centos
---> dfb97af77c51
Step 2 : RUN /bin/echo hi
---> Using cache
---> b8ecb1c6f4ca
Step 3 : RUN /bin/cat /etc/redhat-release
---> Using cache
---> 2cd2b4ee1d84
Step 4 : RUN /bin/echo "hoge `date`" > ~/test.txt
---> Running in a7d8417b6e95
---> b5aa2308d56a
Step 5 : RUN /bin/cat ~/test.txt
---> Running in aea88825dd7c
hoge Sun Jan 5 20:47:29 EST 2014
---> cce9c7c2d7cd
Successfully built cce9c7c2d7cd
imageを指定してテスト
ちゃんと異なるタイムスタンプ(時間)でcatされました!
# 1回目のimagewお指定
vagrant@precise64:~/work$ docker run cf8c4153782b /bin/cat /test.txt
hoge Sun Jan 5 20:47:17 EST 2014
# 2回目のimageを指定
vagrant@precise64:~/work$ docker run cce9c7c2d7cd /bin/cat /test.txt
hoge Sun Jan 5 20:47:29 EST 2014
ある時点のイメージに潜り込んでみます
Dockerで記録されるイメージは、IDを指定して呼び出すことができるのが分かりました。
では、今度は、その時点のOSの中に入って確認してみます。
# 上記1回目のimageを指定して、バックグラウンドで起動
vagrant@precise64:~/work$ docker run -i -t -d cf8c4153782b /bin/bash
0a0392a384d5a5a40e1ec87e88e2a2680eeec2603604ccd61bc200aae7bbf1c2
# アタッチします
vagrant@precise64:~/work$ docker attach 0a0392a384d5a5a40e1ec87e88e2a2680eeec2603604ccd61bc200aae7bbf1c2
# 中の世界に潜り込みました!
bash-4.1# cat /test.txt
hoge Sun Jan 5 20:47:17 EST 2014
bash-4.1#
ちゃんと、過去のある時点の世界に潜り込めました。(すごい!
exitすると、バックグラウンドで動いていたプロセスも停止します。
どうでもいいんですが、bashでなく、shにしたら、attachするとshでアクセスになりました。
vagrant@precise64:~/work$ docker run -i -t -d cf8c4153782b /bin/sh
152ad6c546c160cb3ab218d46f06907ecb9a8e41685739a435e444c8dcdbc0ed
vagrant@precise64:~/work$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
152ad6c546c1 cf8c4153782b /bin/sh 3 seconds ago Up 2 seconds cranky_morse
vagrant@precise64:~/work$ docker attach 152ad6c546c1
sh-4.1#
こんな気づきがありました!
実現方法に関しては、まだ良くわかっていないのですが、VirtualBox & Vagrant という組み合わせと違うな、というのが、とにかく任意の状態への遷移がしやすいことでした。
- 状態の管理がしやすい
- VirtualBoxのSnapshotでも、状態は記録できるけれど、復元するのに時間がかかる。(停止 -> スナップショットIDを指定して再起動)
- Dockerの場合は一瞬!(起動とか停止が気にならないくらい)
- Dockerfileだけ用意してチェックアウトしてJenkinsでビルドっていうのがホントに出来そう!
- ある時点、違う内容の『xxxxの世界』に、ほんの少しで移動出来る!(なんかディケイドっぽい!)
OSイメージに対する更新の歴史を垣間みる
また、docker.ioにもイメージがたくさん登録されているのですが、多分それをベースにすると、gitのリポジトリをcloneして来たときと同じように、そのイメージの歴史も一緒に見えるんじゃないかと思いました。
実際に、ruby2.1入りのCentOSのイメージをdocker.ioから取得して、historyを見てみると…。
vagrant@precise64:~/work$ docker history tmtk75/ruby-2.1.0p0
IMAGE CREATED CREATED BY SIZE
583b10f73f37 7 days ago /bin/sh -c gem install bundler --no-ri --no-r 8.675 MB
1b1fd68b6011 7 days ago /bin/sh -c cd /usr/local/ruby-2.1.0; ./config 345 MB
ebd5e5c243eb 7 days ago /bin/sh -c cd /usr/local; tar xfz ruby-2.1.0. 69.76 MB
bad9ee09833f 7 days ago /bin/sh -c cd /usr/local; curl -OL http://cac 15.08 MB
d6291e86618f 7 days ago /bin/sh -c yum install -y zlib-devel openssl- 27.27 MB
3ffa09187685 7 days ago /bin/sh -c yum install -y gcc 203.4 MB
539c0211cd76 9 months ago 300.6 MB
うーん、面白い。
しかも、先達のステップもきちんと見えてくるので、環境構築の手順に大変参考になります。
以上、全くプログラミングしてないので恐縮ですが、Dockerの1回目の覚え書きでした。