Dockerに入門してみた

「Docker入門」を購入したので、`docker`に入門したいと思います。

参考資料：
「Docker入門」
[Docker 0.9.0 for CentOS6.5](http://qiita.com/mykysyk@github/items/d19d07fc5af70ecccdce)

# 環境
| 項目 | 値 |
|:-----|:---------|
| ホストOS | Windows 7 Professional 64bit |
| プロバイダ | VirtualBox 4.3.8 |
| ゲストOS | CentOS 6 |
| Docker | docker-io-0.9.0-3.el6.x86_64 |
| Image | centos |

# インストール手順
http://docs.docker.io/installation/fedora/

今回はepelからパッケージインストールにて構築。

```rb:Vagrantfile
（中略）

docker.vm.provision "chef_solo" do |chef|
  chef.cookbooks_path = ["cookbooks/", "site-cookbooks/"]
  chef.add_recipe "base::yumupdate"
  chef.add_recipe "docker::default"
  chef.add_recipe "docker::centos"
end

（中略）
```

```rb:Berksfile
site :opscode

cookbook 'yum-epel'
```

```rb:site-cookbooks/base/recipes/yumupdate.rb
execute "yum update" do
  command "yum update -y"
end
```

```rb:site-cookbooks/docker/recipes/default.rb
include_recipe 'yum-epel::default'

package "docker-io"

service "docker" do
  action [:enable, :start]
end
```

```rb:site-cookbooks/docker/recipes/centos.rb
execute "pull centos" do
  command "docker pull centos"
end
```

＜2014/05/21追記＞
32bitの`epel`には`docker-io`パッケージがないので、上記のレシピではインストールできません。
別環境の32bit機で実行して見事にこけました。。。


# コマンドリファレンス

## Dockerの情報を取得：`docker info`

```bash
[vagrant@localhost ~]$ sudo docker info
Containers: 0
Images: 26
Driver: devicemapper
 Pool Name: docker-253:0-263291-pool
 Data file: /var/lib/docker/devicemapper/devicemapper/data
 Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
 Data Space Used: 2333.3 Mb
 Data Space Total: 102400.0 Mb
 Metadata Space Used: 2.5 Mb
 Metadata Space Total: 2048.0 Mb
```

## Dockerイメージの取得：`docker pull`
イメージはデフォルトだとDockerの公開している[docker index](https://index.docker.io/)から検索する。

```bash
# centosのイメージを取得
[vagrant@localhost ~]$ sudo docker pull centos
0b443ba03958: Download complete
539c0211cd76: Download complete
511136ea3c5a: Download complete
7064731afe90: Download complete
```

## 対話的にコンテナを実行：`docker run -i -t ＜イメージ名＞ /bin/bash`

```bash
# -hはホスト名を指定
# docker run -i -t -h ＜ホスト名＞ ＜イメージ名＞ /bin/bash
[vagrant@localhost ~]$ sudo docker run -i -t -h test centos /bin/bash
bash-4.1# hostname
test
```

## バックグラウンドでコンテナを実行：`docker run -d`

```bash
[vagrant@localhost ~]$ sudo docker run -d centos /bin/sh -c "while true; do echo Hello; sleep 10; done"
d95c283fb002c9ceae9f85f9d56df77b006af6a6b290c243ce19a731a9af1626
```

## 稼働中のコンテナの実行状態を確認：`docker ps`

```bash
[vagrant@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED   STATUS              PORTS               NAMES
d95c283fb002        centos:centos6      /bin/sh -c while tru   9 hours ago   Up 9 hours                              insane_ritchie

# 稼働中のコンテナのIDのみを取得：-q
[vagrant@localhost ~]$ sudo docker ps -q
d95c283fb002

# 停止中のコンテナも含めて取得：-a
[vagrant@localhost ~]$ sudo docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED   STATUS                      PORTS               NAMES
6a3a913b0f8f        centos:centos6      /bin/sh -c 'while tr   5 minutes ago   Up 3 minutes                                    pensive_wozniak
68bd42d503c1        centos:centos6      /bin/bash              6 minutes ago   Exited (0) 6 minutes ago                        insane_carson
00daefab7cc5        centos:centos6      /bin/bash              12 minutes ago   Exited (0) 12 minutes ago                       ecstatic_fermi
9d3e11b7bedc        centos:centos6      /bin/bash              12 minutes ago   Exited (0) 12 minutes ago                       angry_goldstine
```

## コンテナの標準出力を確認：`docker logs -f ＜CONTAINER ID＞`

```bash
[vagrant@localhost ~]$ sudo docker logs -f d95c283fb002
Hello
Hello
Hello
Hello
Hello
Hello
```

## コンテナの停止：`docker stop ＜CONTAINER ID＞`

```bash
# コンテナの停止
[vagrant@localhost ~]$ sudo docker stop d95c283fb002
d95c283fb002

# 稼働中の全てのコンテナを停止
[vagrant@localhost ~]$ sudo docker ps -q | sudo xargs docker stop
d95c283fb002
```

## コンテナの再実行：`docker start ＜CONTAINER ID＞`、`docker restart ＜CONTAINER ID＞`

```bash
# 停止中のコンテナを確認
[vagrant@localhost ~]$ sudo docker ps -a | grep Exit | awk '{ print $1 }'
d95c283fb002
5d9e80c64382
582a23bf9161
0c5a68e78a70

# d95c283fb002を実行
[vagrant@localhost ~]$ sudo docker start d95c283fb002
d95c283fb002

# 最初の1件を実行
[vagrant@localhost ~]$ sudo docker ps -a | grep Exit | head -1 | awk '{ print $1 }' | sudo xargs docker start
d95c283fb002

# restartで実行
[vagrant@localhost ~]$ sudo docker restart d95c283fb002
d95c283fb002
```

## バックグラウンド実行中のコンテナにアタッチ：`docker attach <CONTAINER ID>`

```bash
# バックグラウンド実行しているプロセスがある状態でアタッチ
[vagrant@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED   STATUS              PORTS               NAMES
d95c283fb002        centos:centos6      /bin/sh -c while tru   3 days ago   Up 13 hours                             insane_ritchie

[vagrant@localhost ~]$ sudo docker attach d95c283fb002
Hello
Hello
Hello
```
## コンテナの強制終了：`docker kill <CONTAINER ID>`

```bash
[vagrant@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED   STATUS              PORTS               NAMES
d95c283fb002        centos:centos6      /bin/sh -c while tru   3 days ago   Up 13 hours                             insane_ritchie

# 起動中のコンテナを強制終了
[vagrant@localhost ~]$ sudo docker kill d95c283fb002
d95c283fb002

[vagrant@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED STATUS              PORTS               NAMES
```

## コンテナ内のプロセスの監視：`docker top <CONTAINER ID>`

```bash
[vagrant@localhost ~]$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED   STATUS              PORTS               NAMES
d95c283fb002        centos:centos6      /bin/sh -c while tru   3 days ago   Up 4 seconds                            insane_ritchie

[vagrant@localhost ~]$ sudo docker top d95c283fb002
UID                 PID                 PPID                C
STIME               TTY                 TIME                CMD
root                3822                3817                0
12:15               ?                   00:00:00            /bin/sh -c while true; do echo Hello; sleep 10; done
root                3884                3822                0
12:15               ?                   00:00:00            sleep 10
```

## コンテナの詳細な情報を取得：`docker inspect [<CONTAINER ID>|<IMAGE>]`

```bash
[vagrant@localhost ~]$ sudo docker inspect d95c283fb002
[{
    "ID": "d95c283fb002c9ceae9f85f9d56df77b006af6a6b290c243ce19a731a9af1626",
    "Created": "2014-05-13T14:31:54.284329622Z",
    "Path": "/bin/sh",
    "Args": [
        "-c",
        "while true; do echo Hello; sleep 10; done"
    ],
    "Config": {
        "Hostname": "d95c283fb002",
        "Domainname": "",
（省略）
```

## コンテナのコミット：`docker commit -a "作者" -m "コミットメッセージ" <CONTAINER ID>`

```bash
[vagrant@localhost ~]$ sudo docker commit -a "author" -m "test" d95c283fb002
ccfe0e061be58bc1ff8b3694e06ed9179899be12d76c7b0a68c57a322e0aeb08

[vagrant@localhost ~]$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED VIRTUAL SIZE
<none>              <none>              ccfe0e061be5        32 seconds ago  297.6 MB
```

## コンテナの削除：`docker rm <CONTAINER ID> [<CONTAINER ID>]`

```bash
# 稼働中のコンテナは削除できない（`-f`オプションをつければ削除できる）
[vagrant@localhost ~]$ sudo docker ps -q | xargs sudo docker rm
Error: Impossible to remove a running container, please stop it first or use -f
2014/05/17 20:08:37 Error: failed to remove one or more containers

# 稼動していないコンテナの一覧を表示
[vagrant@localhost ~]$ sudo docker ps -a | grep Exit
582a23bf9161        centos:centos6      /bin/bash              3 days ago   Exit 130                                furious_hawking
0c5a68e78a70        centos:centos6      /bin/bash              3 days ago   Exit 0                                  hopeful_brattain

# 0c5a68e78a70を削除
[vagrant@localhost ~]$ sudo docker rm 0c5a68e78a70
0c5a68e78a70
```

## イメージの削除：`docker rmi <IMAGE ID> [<IMAGE ID>]`

```bash
# イメージの一覧を表示
[vagrant@localhost ~]$ sudo docker images | awk '{ print $1,$2,$3 }'
REPOSITORY TAG IMAGE
<none> <none> ccfe0e061be5
ubuntu 13.10 5e019ab7bf6d
ubuntu saucy 5e019ab7bf6d
ubuntu 12.04 74fe38d11401
（省略）
centos centos6 0b443ba03958
centos latest 0b443ba03958
centos 6.4 539c0211cd76

# ubuntu 13.10のイメージを削除
[vagrant@localhost ~]$ sudo docker rmi 5e019ab7bf6d
Untagged: ubuntu:13.10
Untagged: ubuntu:saucy
Deleted: 5e019ab7bf6deb75b211411ef7257d1e76bf7edee31d9da62a392df98d0529d6
Deleted: 2209cbf9dcd35615211a2fdc6762bb5e651b5c847537359f05b9ab1bc9a74614
Deleted: f0ee64c4df74c766a16faebfb5123e2b67192eff4a82aa70d0d2081681200a79
Deleted: e2aa6665d37109cd6d196eec32c98d8f4412325cb2dc1588e5eb27cae4beb836
```

`Vagrant 1.6`からはVagrantでもDockerを扱えるようですし、`AWS Beanstalk`がDockerをサポートするなど、Dockerが盛り上がってきてますね。
`Dockerfile`を触った後に`Vagrant`でのDocker操作に着手したいなと思います。

# プロキシ環境における`Docker`利用の注意点

## イメージをダウンロードできない

外部接続にプロキシの必要な環境の場合、`yum`等を実行する際には環境変数`http_proxy`や`https_proxy`にプロキシ情報を設定しますが、
上記環境変数を設定しても`docker pull`の実行に失敗します。

```bash
[vagrant@localhost ~]$ sudo docker pull centos
Pulling repository centos
2014/05/23 16:58:36 Get https://index.docker.io/v1/repositories/centos/images: dial tcp: lookup index.docker.io on ***.***.***.***:53: no answer from server
```

　プロキシ環境でイメージをダウンロードする場合、`/etc/sysconfig/docker`にプロキシ情報を設定する必要があります。
　また、`docker`を起動済みの場合は`service docker restart`を実行するなどして、`docker`を再起動する必要があります。

```bash:/etc/sysconfig/docker
export http_proxy=http://<ユーザ名>:<パスワード>@<プロキシサーバ>:<ポート>
export https_proxy=http://<ユーザ名>:<パスワード>@<プロキシサーバ>:<ポート>
```