Dockerを使ってみる

コンテナ管理ツールDockerを使うと、gitのような差分バージョン管理のもとでLXCのようなLinuxコンテナを扱うことができる(実際にはLXCではなくlibcontainerが使われる)。 ここではDockerを使い、UbuntuCentOSのコンテナを作ってみる。

環境

Ubuntu 14.04.1 LTS 64bit版

$ uname -a
Linux vm-ubuntu64 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.1 LTS
Release:        14.04
Codename:       trusty

Docker Engineをインストールする

インストールガイドに従い、Ubuntuリポジトリからインストールする。

$ sudo apt-get update
$ sudo apt-get install docker.io
$ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
$ sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io

とりあえず、Ubuntu 14.04のイメージを取得し、起動してみる。

$ sudo docker run -i -t ubuntu:14.04 /bin/bash
Unable to find image 'ubuntu:14.04' locally
Pulling repository ubuntu
6b4e8a7373fe: Download complete
511136ea3c5a: Download complete
b18d0a2076a1: Download complete
67b66f26d423: Download complete
25c4824a5268: Download complete
8b1c48305638: Download complete
c900195dcbf3: Download complete
root@81b67cfd5e57:/# id
uid=0(root) gid=0(root) groups=0(root)
root@81b67cfd5e57:/# exit

Dockerfileからイメージを作成する

上で作成したUbuntu 14.04コンテナには最低限のパッケージしか入っていない。 そこでDockerfileを書き、必要なパッケージがインストールされた状態のイメージを作成する。 ここでは、gccなどのビルドツール一式とgit、pythonがインストールされたイメージを作ってみる。

$ mkdir -p docker/ubuntu1404
$ cd docker/ubuntu1404
$ vi Dockerfile

Dockerfileは作成するイメージを定義するファイルで、ここでは次のような内容を書く。

FROM ubuntu:14.04
RUN apt-get update && apt-get -y upgrade
RUN apt-get -y install build-essential
RUN apt-get -y install git
RUN apt-get -y install python

リポジトリ名をuser/ubuntu、タグに14.04を指定してイメージを作成する。

$ sudo docker build -t 'user/ubuntu:14.04' .
Sending build context to Docker daemon 3.584 kB
Sending build context to Docker daemon
Step 0 : FROM ubuntu:14.04
 ---> 6b4e8a7373fe
Step 1 : RUN apt-get update && apt-get -y upgrade
 ---> Running in 186a40066a41
(snip)
 ---> d6f65fed15bd
Removing intermediate container 186a40066a41
Step 2 : RUN apt-get -y install build-essential
 ---> Running in 25f00944f334
(snip)
 ---> a06e509772fa
Removing intermediate container 25f00944f334
Step 3 : RUN apt-get -y install git
 ---> Running in 6e11265bcc6a
(snip)
 ---> 9ca42741f503
Removing intermediate container 6e11265bcc6a
Step 4 : RUN apt-get -y install python
 ---> Running in 9bb6a5103414
(snip)
 ---> 5b15f1fdbaeb
Removing intermediate container 9bb6a5103414
Successfully built 5b15f1fdbaeb

$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
user/ubuntu         14.04               5b15f1fdbaeb        5 minutes ago       386.8 MB
ubuntu              14.04               6b4e8a7373fe        5 days ago          194.9 MB

コンテナを使う

作成したイメージをもとに、コンテナを作る。

$ sudo docker run --name ubuntu -i -t user/ubuntu:14.04 /bin/bash
root@c927a98a222e:/# gcc --version
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

root@c927a98a222e:/# exit

イメージ作成時にインストールしたgccが存在していることが確認できる。

作ったコンテナを確認し、再度起動してみる。

$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
c927a98a222e        user/ubuntu:14.04   /bin/bash           31 seconds ago      Exited (0) 16 seconds ago                       ubuntu
81b67cfd5e57        ubuntu:14.04        /bin/bash           22 minutes ago      Exited (0) 11 minutes ago                       mad_curie

$ sudo docker start -a -i ubuntu
root@c927a98a222e:/# history
    1  gcc --version
    2  history
root@c927a98a222e:/#

historyコマンドの結果から、過去に行った作業が残っていることがわかる。

なお、不要になったコンテナは次のようにして削除できる。

$ sudo docker rm mad_curie

$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                      PORTS               NAMES
c927a98a222e        user/ubuntu:14.04   /bin/bash           About a minute ago   Exited (0) 19 seconds ago                       ubuntu

CentOS環境も用意する

CentOSのイメージを利用し、Ubuntuと同じようにしてCentOS環境も作ってみる。

$ mkdir -p docker/centos7
$ cd docker/centos7
$ vi Dockerfile

DockerfileにてDevelopment Tools一式をインストールしたイメージを定義する。

FROM centos:centos7
RUN yum -y update
RUN yum -y groupinstall "Development Tools"

イメージを作成する。

$ sudo docker build -t 'user/centos:centos7' .
Sending build context to Docker daemon 3.584 kB
Sending build context to Docker daemon
Step 0 : FROM centos:centos7
Pulling repository centos
87e5b6b3ccc1: Download complete
511136ea3c5a: Download complete
5b12ef8fd570: Download complete
 ---> 87e5b6b3ccc1
Step 1 : RUN yum -y update
 ---> Running in 27b9c0462fc6
(snip)
 ---> dadb2aec97c6
Removing intermediate container 27b9c0462fc6
Step 2 : RUN yum -y groupinstall "Development Tools"
 ---> Running in 822e7c375333
(snip)
 ---> 03f8772df1ed
Removing intermediate container 822e7c375333
Successfully built 03f8772df1ed

$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
user/centos         centos7             03f8772df1ed        5 minutes ago       910.2 MB
user/ubuntu         14.04               5b15f1fdbaeb        17 minutes ago      386.8 MB
centos              centos7             87e5b6b3ccc1        5 days ago          224 MB
ubuntu              14.04               6b4e8a7373fe        5 days ago          194.9 MB

イメージをもとに、コンテナを作る。

$ sudo docker run --name centos -i -t user/centos:centos7 /bin/bash
bash-4.2# gcc --version
gcc (GCC) 4.8.2 20140120 (Red Hat 4.8.2-16)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

bash-4.2# exit

コンテナができていることを確認した後、再度起動し作業履歴が残っていることを確認してみる。

$ sudo docker ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS                      PORTS               NAMES
38f9a589db06        user/centos:centos7   /bin/bash           27 seconds ago      Exited (0) 17 seconds ago                       centos
c927a98a222e        user/ubuntu:14.04     /bin/bash           12 minutes ago      Exited (0) 11 minutes ago                       ubuntu

$ sudo docker start -a -i centos
bash-4.2# history
    1  gcc --version
    2  history
bash-4.2#

コンテナをexitしないで抜ける(デタッチ)

上の手順ではシェルを終了するとコンテナも停止してしまうが、Ctrl+P Ctrl+Q を押すことで起動した状態のままコンテナから抜けることができる。

$ sudo docker start -a -i ubuntu
root@c927a98a222e:/#
[CTRL+P CTRL+Q]

$ sudo docker ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS                          PORTS               NAMES
38f9a589db06        user/centos:centos7   /bin/bash           2 minutes ago       Exited (0) About a minute ago                       centos
c927a98a222e        user/ubuntu:14.04     /bin/bash           13 minutes ago      Up 52 seconds                                       ubuntu

起動中のコンテナにアタッチするには次のようにする。

$ sudo docker attach ubuntu
^C
root@c927a98a222e:/# exit

今度はシェルを終了したので、コンテナも停止している。

$ sudo docker ps -a
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS                          PORTS               NAMES
38f9a589db06        user/centos:centos7   /bin/bash           3 minutes ago       Exited (0) 2 minutes ago                            centos
c927a98a222e        user/ubuntu:14.04     /bin/bash           14 minutes ago      Exited (0) About a minute ago                       ubuntu

コンテナと通信する

コンテナには起動するたびに172.17.0.0/16のIPが振られるので、コンテナ間あるいはホスト・コンテナ間であればこのIPを使って通信できる。

$ sudo docker start -a -i ubuntu
root@c927a98a222e:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 2a:80:63:2e:dc:34
          inet addr:172.17.0.61  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::2880:63ff:fe2e:dc34/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:5 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:418 (418.0 B)  TX bytes:508 (508.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

Ctrl+P Ctrl+Q でデタッチした後、ホストからpingを打ってみる。

root@c927a98a222e:/#
[CTRL+P CTRL+Q]

$ ping 172.17.0.61
PING 172.17.0.61 (172.17.0.61) 56(84) bytes of data.
64 bytes from 172.17.0.61: icmp_seq=1 ttl=64 time=0.190 ms
64 bytes from 172.17.0.61: icmp_seq=2 ttl=64 time=0.126 ms
64 bytes from 172.17.0.61: icmp_seq=3 ttl=64 time=0.071 ms
64 bytes from 172.17.0.61: icmp_seq=4 ttl=64 time=0.105 ms
^C
--- 172.17.0.61 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 0.071/0.123/0.190/0.043 ms

関連リンク