ぺーぺーSEのブログ

備忘録・メモ用サイト。

Vagrant+Dockerをいじってみる

Dockerとは?
コピーオンライトなファイルシステム(AUFS:Another Union File System)とLinuxコンテナ技術(LXC:Linux Containers)を利用してアプリケーション配置を支援するツール

ハイパーバイザ型仮想化VMware、VirturlBox、KVM等)みたいにOS一式動かすのとは違って、コンテナ型仮想化(Docker)は1プロセスとして動くので軽い。

VagrantでDockerを使ってみる。
Vgarnt1.4からDocker Provionerなるものが入っていてVagrantfileをいじれば勝手にインストールされる。
Vagrantについてはここを参照。

環境構築

(1)boxの取得
ハイパーバイザはVirtualBoxでやった。
CentOSなら↓

> vagrant box add CentOS65 https://github.com/2creatives/vagrant-centos/releases/download/v6.5.1/centos65-x86_64-20131205.box

Ubuntuなら↓

> vagrant box add Ubuntu1204 http://files.vagrantup.com/precise64.box

(2)初期化

> vagrant init CentOS65
> vagrant init Ubuntu1204

(3)Vagrantfileの編集
Vagrantfileを下記のように編集。

# 〜省略〜
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# 〜省略〜
  # ここから追記↓
  config.vm.network :private_network, ip: "192.168.33.11"

  # プロキシ環境の場合は↓も追記 これを追記する場合は「vagrant-proxyconf」が必要
  if Vagrant.has_plugin?("vagrant-proxyconf")
    config.proxy.http     = "http://<username>:<password>@<proxy-host>:<proxy-port>"
    config.proxy.https    = "https://<username>:<password>@<proxy-host>:<proxy-port>"
    config.proxy.no_proxy = "localhost,127.0.0.1"
  end

  config.vm.provision "docker" do |d|
    d.pull_images "centos"             # Ubuntuなら「d.pull_images "ubuntu"」
    d.run "centos",                    # Ubuntuなら「d.run "ubuntu",」
      cmd: "echo 'hello world' > /tmp/hello"
  end
  # ここまで追記↑
end

(4)起動

> vagrant up

この段階でVagrantdocker provionerがゲストOSへDockerをインストールしてくれる。
もしインストールしてくれなかったら下記を叩いてみる。

> vagrant provision

また、プロキシ環境下ではVagrantfileでdockerのimageをpullする記述を書いているが失敗する。
vagrant up事態は成功するのでこのまま進めておk。

(5)ゲストOSへssh
TeraTermでもなんでもいいよ。

ssh 192.168.33.11

(6)Dockerの存在を確認

[vagrant@vagrant-centos65 ~]$ sudo -s
[root@vagrant-centos65 vagrant]# docker -v
Docker version 0.9.0, build 2b3fdf2/0.9.0

(7)プロキシ設定
プロキシ環境の場合はdocker用に設定が必要。(docker pullとかしてもimageをとってこれない)
CentOSなら/etc/sysconfig/dockerへ、
Ubuntuなら/etc/default/docker下記を追記。

export http_proxy=http://<username>:<password>@<proxy-host>:<proxy-port>
export https_proxy=https://<username>:<password>@<proxy-host>:<proxy-port>

(8)dockerを再起動

[root@vagrant-centos65 vagrant]# service docker restart
Stopping docker:                                           [  OK  ]
Starting docker:                                           [  OK  ]

これでdockerをいじる環境構築終了。
以降説明するコマンドで生成されたコンテナやらはCentOSUbuntu共に/var/lib/dockerあたりに入ってるっぽい。
また公式?のimageは↓にある。
https://index.docker.io/


dockerの基本操作

以降コマンド内でcentosとなっているところはUbuntuの場合、ubuntuに読み替える。
と思ったけど、utuntuのimageがdownloadできなかったからstackbrew/ubuntu(ガリガリのubuntu)で読み替える。

[root@vagrant-centos65 vagrant]# docker run -i -t centos /bin/bash
Unable to find image 'centos' locally
Pulling repository centos
539c0211cd76: Pulling image (latest) from centos, endpoint: https://cdn-registry539c0211cd76: Download complete
bash-4.1#

このコマンド(docker run -i -t centos /bin/bash)でCentOSのimageをダウンロードしてきて、このimageを元にコンテナを起動・ログインしている。
ファイルを作成して終了。

bash-4.1# cd /tmp
bash-4.1# touch hoge
bash-4.1# ls
hoge
bash-4.1# exit

もう一度コンテナを起動・ログインしてみる。

[root@vagrant-centos65 vagrant]# docker run -i -t centos /bin/bash
bash-4.1# cd /tmp
bash-4.1# ls
bash-4.1#

先ほどtouchしたhogeはなくなっている。
実は、このコマンド(docker run -i -t centos /bin/bash)は単純に真新しいcentosのイメージから新しいコンテナを起動しただけ
exitしてからdocker ps -aを実行すると停止したコンテナも含めた一覧が表示される。

[root@vagrant-centos65 vagrant]# docker ps -a
CONTAINER ID        IMAGE                    COMMAND             CREATED             STATUS              PORTS               NAMES
c613deef57b7        centos:6.4               /bin/bash           18 minutes ago      Exit 0                                  grave_pike
b69cfe01bef4        centos:6.4               /bin/bash           53 minutes ago      Exit 127                                suspicious_curie
d3eaf51d5c52        centos:6.4               /bin/bash           3 hours ago         Exit 0                                  silly_fermi
957f488ae1a1        centos:6.4               /bin/bash           4 hours ago         Exit 1                                  cranky_nobel

停止したコンテナを起動するには「docker start」、起動中のコンテナにログイン(attach)するには「docker attach」に「CONTAINER ID」を指定する。
また、コンテナログイン中にexitするとコンテナが停止してしまう。コンテナを停止せずにログオフ(detach)するには「Ctrl+p、Ctrl+q」する。
imageからログインせずにコンテナだけ起動する場合は「docker run -i -t -d centos /bin/bash」を実行する。(-dがついてる)
作業したコンテナからimageを作成する場合は、CONTAINER IDを指定して下記のように作成する。

[root@vagrant-centos65 vagrant]# docker commit b69cfe01bef4 hoge/centos

imageの一覧を表示すると作成されていることがわかる。

[root@vagrant-centos65 vagrant]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
hoge/centos         latest              b2dabb26c313        13 minutes ago      336.1 MB
centos              6.4                 539c0211cd76        12 months ago       300.6 MB
centos              latest              539c0211cd76        12 months ago       300.6 MB

タグの名前を付けなかったら"latest"という名前がつく。
このようにimageを育てていくと思いきや、imageの作成にはDockerfileを使用する。



■dockerコマンド一覧

コンテナ操作系コマンド 説明
docker run コンテナを作成
docker stop コンテナを停止
docker start コンテナを起動
docker restart コンテナを再起動
docker attach 起動中のコンテナに接続
docker rm コンテナを破棄
docker wait コンテナが停止するまでブロック
コンテナ情報表示系コマンド 説明
docker ps 起動中のコンテナを表示
docker ps -a 起動中と停止中のコンテナを表示
docker inspect コンテナの全情報を表示
docker logs コンテナのログを表示
docker events コンテナ内のイベントを表示
docker port コンテナのportを表示
docker top コンテナのプロセスを表示
ファイル授受系コマンド 説明
docker cp コンテナ内のファイルをホストにコピー
docker export コンテナのファイルシステムを出力
image操作系コマンド 説明
docker pull レジストリからimageもしくはリポジトリを取得
docker import ファイルシステムのtarballからイメージを取得
docker tag イメージにタグをつける
docker build Dockerfileからimageを作成
docker commit コンテナからimageを作成
docker rmi imageを削除
docker insert URLからimageにファイルを取り込む
docker load 標準入力としてtarファイルからリポジトリを取り込む
image情報表示系コマンド 説明
docker images 全イメージを表示
docker history イメージの履歴を表示


Dockerfile

基本構文

命令 引数


命令 説明 USAGE
FROM コンテナのbase imageを指定 FROM
FROM :
MAINTAINER Authorを指定 MAINTAINER
RUN ビルド中に実行されるコマンド RUN
/bin/sh -c」のコマンドとして実行される RUN ["executable", "param1", "param2"]
CMD コンテナ起動時のコマンド CMD ["executable","param1","param2"] (like an exec, preferred form)
Dockerfileに1つしか記載できない CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param (as a shell)
EXPOSE コンテナ内部からみたポートを解放 EXPOSE [...]
ENV 環境変数を設定 ENV
ADD コンテナ外のファイルをコンテナ内に配置 ADD
ENTRYPOINT 作成されたコンテナ起動時のコマンド ENTRYPOINT ["executable", "param1", "param2"] (like an exec, preferred form)
Dockerfileに1つしか記載できない ENTRYPOINT command param1 param2 (as a shell)
VOLUME 外部からボリュームとしてマウントする際のマウントポイント VOLUME ["/data"]
USER コンテナを起動する際のユーザー名またはUID USER daemon
WORKDIR CMDが実行されるカレントディレクトリ WORKDIR /path/to/workdir
ONBUILD ビルド完了後に実行される命令 ONBUILD [INSTRUCTION]

■Dockerfileの例 〜centosApacheをインストールしてテストページが見れるまで〜

FROM centos

# proxy環境下の場合にyumできるように
RUN echo 'exclude=kernel*' >> /etc/yum.conf
RUN echo 'proxy=http://[proxy_FQDN]:[port]' >> /etc/yum.conf
RUN echo 'proxy_username=[username]' >> /etc/yum.conf
RUN echo 'proxy_password=[password]' >> /etc/yum.conf

RUN yum -y install httpd
RUN echo 'Test Page' > /var/www/html/index.html
EXPOSE 80

ENTRYPOINT /etc/init.d/httpd start && /bin/bash

■Dockerfileの例 〜ubuntuApacheをインストールしてテストページが見れるまで〜

FROM stackbrew/ubuntu

# proxy環境下の場合にapt-getできるように
RUN touch /etc/apt/apt.conf.d/01proxy
RUN echo 'Acquire::http::Proxy "http://[username]:[password]@[proxy_FQDN]:[port]";' >> /etc/apt/apt.conf.d/01proxy
RUN echo 'Acquire::https::Proxy "https://[username]:[password]@[proxy_FQDN]:[port]";' >> /etc/apt/apt.conf.d/01proxy

RUN apt-get update
RUN apt-get -y install apache2
EXPOSE 80

ENTRYPOINT /etc/init.d/apache2 start && /bin/bash

参考:
http://docs.docker.io/en/latest/reference/builder/


Dockerfileのビルド

カレントディレクトリに上記のDockerfileを作成してdocker build --no-cache --rm -t httpd/centos .を実行。
Ubuntuのときはdocker build --no-cache --rm -t httpd-ubuntu .を実行。

[root@vagrant-centos65 tmp]# docker build --no-cache --rm -t httpd/centos .
Uploading context 3.072 kB
Uploading context
Step 0 : FROM centos
 ---> 539c0211cd76
Step 1 : RUN echo 'exclude=kernel*' >> /etc/yum.conf
 ---> Running in a715393fa751
 ---> 4abfb9e6e9c1
Step 2 : RUN echo 'proxy=http://[proxy_FQDN]:[port]' >> /etc/yum.conf
 ---> Running in fa26d9488c8c
 ---> 81f1359d9105
Step 3 : RUN echo 'proxy_username=[username]' >> /etc/yum.conf
 ---> Running in 163144c7b008
 ---> 2fea536adbed
Step 4 : RUN echo 'proxy_password=[password]' >> /etc/yum.conf
 ---> Running in b9f9dc7d44a5
 ---> f3f58e9c499d
Step 5 : RUN yum -y install httpd
 ---> Running in 92a432d1dcb2
Loaded plugins: fastestmirror
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.2.15-30.el6.centos will be installed
--> Processing Dependency: httpd-tools = 2.2.15-30.el6.centos for package: httpd-2.2.15-30.el6.centos.x86_64
--> Processing Dependency: system-logos >= 7.92.1-1 for package: httpd-2.2.15-30.el6.centos.x86_64
--> Processing Dependency: apr-util-ldap for package: httpd-2.2.15-30.el6.centos.x86_64
--> Processing Dependency: /etc/mime.types for package: httpd-2.2.15-30.el6.centos.x86_64
--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.15-30.el6.centos.x86_64
--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.15-30.el6.centos.x86_64
--> Running transaction check
---> Package apr.x86_64 0:1.3.9-5.el6_2 will be installed
---> Package apr-util.x86_64 0:1.3.9-3.el6_0.1 will be installed
---> Package apr-util-ldap.x86_64 0:1.3.9-3.el6_0.1 will be installed
---> Package httpd-tools.x86_64 0:2.2.15-30.el6.centos will be installed
--> Processing Dependency: libssl.so.10(libssl.so.10)(64bit) for package: httpd-tools-2.2.15-30.el6.centos.x86_64
--> Processing Dependency: libcrypto.so.10(libcrypto.so.10)(64bit) for package: httpd-tools-2.2.15-30.el6.centos.x86_64
---> Package mailcap.noarch 0:2.1.31-2.el6 will be installed
---> Package redhat-logos.noarch 0:60.0.14-12.el6.centos will be installed
--> Running transaction check
---> Package openssl.x86_64 0:1.0.0-27.el6_4.2 will be updated
---> Package openssl.x86_64 0:1.0.1e-16.el6_5.4 will be an update
--> Processing Dependency: make for package: openssl-1.0.1e-16.el6_5.4.x86_64
--> Running transaction check
---> Package make.x86_64 1:3.81-20.el6 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package            Arch        Version                      Repository    Size
================================================================================
Installing:
 httpd              x86_64      2.2.15-30.el6.centos         updates      821 k
Installing for dependencies:
 apr                x86_64      1.3.9-5.el6_2                base         123 k
 apr-util           x86_64      1.3.9-3.el6_0.1              base          87 k
 apr-util-ldap      x86_64      1.3.9-3.el6_0.1              base          15 k
 httpd-tools        x86_64      2.2.15-30.el6.centos         updates       73 k
 mailcap            noarch      2.1.31-2.el6                 base          27 k
 make               x86_64      1:3.81-20.el6                base         389 k
 redhat-logos       noarch      60.0.14-12.el6.centos        base          15 M
Updating for dependencies:
 openssl            x86_64      1.0.1e-16.el6_5.4            updates      1.5 M

Transaction Summary
================================================================================
Install       8 Package(s)
Upgrade       1 Package(s)

Total download size: 18 M
Downloading Packages:
--------------------------------------------------------------------------------
Total                                           1.6 MB/s |  18 MB     00:10
rpmts_HdrFromFdno: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Importing GPG key 0xC105B9DE:
 Userid : CentOS-6 Key (CentOS 6 Official Signing Key) <centos-6-key@centos.org>
 Package: centos-release-6-4.el6.centos.10.x86_64 (@febootstrap/$releasever)
 From   : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction

Installed:
  httpd.x86_64 0:2.2.15-30.el6.centos

Dependency Installed:
  apr.x86_64 0:1.3.9-5.el6_2
  apr-util.x86_64 0:1.3.9-3.el6_0.1
  apr-util-ldap.x86_64 0:1.3.9-3.el6_0.1
  httpd-tools.x86_64 0:2.2.15-30.el6.centos
  mailcap.noarch 0:2.1.31-2.el6
  make.x86_64 1:3.81-20.el6
  redhat-logos.noarch 0:60.0.14-12.el6.centos

Dependency Updated:
  openssl.x86_64 0:1.0.1e-16.el6_5.4

Complete!
 ---> ece59126ddfb
Step 6 : RUN echo 'Test Page' > /var/www/html/index.html
 ---> Running in ce64c84b3149
 ---> 0e9aba715b90
Step 7 : EXPOSE 80
 ---> Running in ea6fc7c6f879
 ---> 5040b79ac66c
Step 8 : CMD /bin/bash
 ---> Running in 48f38c087de8
 ---> 2dfb101187c6
Successfully built 2dfb101187c6
Removing intermediate container a715393fa751
Removing intermediate container fa26d9488c8c
Removing intermediate container 163144c7b008
Removing intermediate container b9f9dc7d44a5
Removing intermediate container 92a432d1dcb2
Removing intermediate container ce64c84b3149
Removing intermediate container ea6fc7c6f879
Removing intermediate container 48f38c087de8

image作成されたくさい。
確認。

[root@vagrant-centos65 tmp]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
httpd/centos        latest              2dfb101187c6        About a minute ago   369.2 MB
centos              6.4                 539c0211cd76        12 months ago        300.6 MB
centos              latest              539c0211cd76        12 months ago        300.6 MB

httpd/centosがある!(utuntuのときはhttpd-ubuntuがある!)
imageからコンテナ起動してapacheにアクセスしてみる!(※iptablesSELinuxの設定はしておいてね)
docker run -i -t -d -p 80:80 httpd/centos」を実行する。
DockerfileでENTRYPOINTを指定した場合は上記を実行する際、コマンド(/bin/bash)を指定する必要はない。

centosのとき

[root@vagrant-centos65 tmp]# docker run -i -t -d -p 80:80 httpd/centos
39ee65904bac15bb8adcd5e148fa9e6c69d99fdbc83a81c13073a4710bcc79d8
[root@vagrant-centos65 tmp]# docker ps
CONTAINER ID        IMAGE                 COMMAND                CREATED             STATUS              PORTS                NAMES
39ee65904bac        httpd/centos:latest   /bin/bash -c service   9 seconds ago       Up 8 seconds        0.0.0.0:80->80/tcp   nostalgic_brattain
[root@vagrant-centos65 tmp]# curl http://localhost/index.html
Test Page

ubuntuのとき

root@precise64:/tmp# docker run -i -t -d -p 80:80 httpd-ubuntu
1227159c99a21ceabc03aa25ac21f3ecabbb70cdb1466c3ef524479a242c7c00
root@precise64:/tmp# docker ps
CONTAINER ID        IMAGE                 COMMAND                CREATED             STATUS              PORTS                NAMES
1227159c99a2        httpd-ubuntu:latest   "/bin/bash -c 'servi   8 seconds ago       Up 7 seconds        0.0.0.0:80->80/tcp   nostalgic_elion
root@precise64:/tmp# curl http://localhost/index.html
<html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
</body></html>

なんか成功したくさいwww