Help us understand the problem. What is going on with this article?

Dockerfileを試す

More than 5 years have passed since last update.

Dockerの勉強用のメモです。
Dockerに関しては、先達のみなさんのblog、Qiita上の情報を参考に勉強していますが、今回はスポットで下記についての実行結果をアップします。

やりたいこと

  • CentOSのイメージを使って、簡単なコマンドを実行する
  • docker run…ではなくて、Dockerfileを使ってdocker buildしてみる。
    • うまくいったら、少しずつRUNさせることを増やしていく。
  • Dockerのイメージのリポジトリから、好きなもの使ってみたい。

ここまでの前提

  • 仮想環境にはVirtualBox + Vagrantを使う。
  • Vagrantを使って、Docker入りのUbuntuをインストールした。
  • 上記のUbuntuをベースにし、sshログイン。この中でdockerコマンドが実行できることを確認した。
  • Dockerのチュートリアルで、簡単に学習をした。
  • 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 でも一覧が取れます)

bash
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さんのイメージを利用したいので、検索して出て来たそのままの名前を入れてみました(この時点で、この指定でいいのか自信がありませんでした)。

bash
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の内容は、こんな感じです。

  1. 指定のimageを取ってくる
  2. 起動して"hi" をecho する
  3. OSのバージョンを表示する (redhat-releaseの記載を確認し、CentOS6.5になってるかどうか確認)

Build前の確認

実施前の確認です。imageは空っぽの状態。(Ubuntu向けにbaseというイメージもありましたが、いったんクリアしました)

bash
vagrant@precise64:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE

Buildしてみます

Dockerfileのあるディレクトリで、docker build . としてみます。

まずはdocker.ioからイメージをダウンロードするところから始まります。

親切なことに、Step1, Step2 と言った具合に、進行状況(過程)も表示してくれるんですね!

bash
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は表示されますが、イメージのダウンロードは行われない分、処理が早くなります。

bash
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 の結果が返ってきました。

bash
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 が追加されてます。

bash
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させてみます。

結果、そんなのは無いよ、と言われます。

bash
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)

bash
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されました!

bash
# 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の中に入って確認してみます。

bash
# 上記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回目の覚え書きでした。

akiko-pusu
コツコツと学習しながらのメモを書いています。Redmineのプラグイン開発に関連するものが多めです。記事にご興味を持っていただけたら嬉しいです!
https://daily-postit.hatenablog.com
infra-workshop
インフラ技術を勉強したい人たちのためのオンライン勉強会です
https://wp.infra-workshop.tech/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away