Dockerの基本操作をCentOS 7で確認 その1 

# Dockerの基本操作をCentOS 7で確認 その1  
お休みに入ったのでDockerの基本操作を改めて確認。VagrantでVirtualBox上に
CentOS 7.0の仮想環境を立ち上げ、Dockerを動かしながら確認します。

**前提**

- 以下の作業はMBPのターミナル上で実行しています
- インターネットに接続できること
- vagrant は install 済み

## Vagrantによる環境準備

### Vagrantfileの設定

適当なディレクトリを作ってその中に[bento](https://github.com/opscode/bento)からCentOS 7.0のboxを取得し
インストールするVagrantfileを置きます。

```
$ mkdir dockerenv && cd dockerenv
$ vagrant init
```

`init`により設置されたテンプレートをエディタで次の通り編集します。
**Vagrantfile**

```rb
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.require_version ">= 1.6.3", "< 1.9.9"
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.boot_timeout = 60
  config.vm.box = "centos-7.0"
  config.vm.box_url = "http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-7.0_chef-provisionerless.box"
  config.vm.hostname = "docker-centos7-01"
  config.vm.network "forwarded_port", guest: 80, host: 8888

end
```

### Dockerインストール
早速仮想環境を立ち上げてdockerをインストールします。

```bash
$ vagrant up
$ vagrant ssh
$ sudo yum install docker
```

## Dockerの利用
以降の作業はvagrantで立ち上げた仮想環境内で行います。

### Docker起動

dockerをdaemonとして起動します。

```
$ sudo systemctl enable docker.service
$ sudo systemctl start docker.service
```

確認

```
$ sudo systemctl status docker.service
```
このコマンドの結果に`Active: active (running)`と出ていれば起動に成功しています。

### 基本情報の確認

DockerはGo言語で実装されており、起動したdeamonへ`docker`コマンドで指示を送る
サーバクライアント方式で動作します。Go及び各コンポーネントのバージョンは次の通り
`docker version`で確認できます。

```
$ sudo docker version
Client version: 1.3.2
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 39fa2fa/1.3.2
OS/Arch (client): linux/amd64
Server version: 1.3.2
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 39fa2fa/1.3.2
```

また、`docker info`コマンドでコンテナ数やデータの保存先とサイズなど現在の利用状況が確認できます。

```
$ sudo docker info
Containers: 4
Images: 8
Storage Driver: devicemapper
 Pool Name: docker-253:1-134297046-pool
 Pool Blocksize: 65.54 kB
 Data file: /var/lib/docker/devicemapper/devicemapper/data
 Metadata file: /var/lib/docker/devicemapper/devicemapper/metadata
 Data Space Used: 860 MB
 Data Space Total: 107.4 GB
 Metadata Space Used: 1.368 MB
 Metadata Space Total: 2.147 GB
 Library Version: 1.02.84-RHEL7 (2014-03-26)
Execution Driver: native-0.2
Kernel Version: 3.10.0-123.el7.x86_64
Operating System: CentOS Linux 7 (Core)
```

### イメージ取得

Dockerはイメージという単位でコンテナ起動に必要なデータを保持します。
ここではCentOS 7.0上に Ubuntu 14.04 のイメージを取得します。
`docker pull`コマンドはデフォルトで[公式レジストリ](https://registry.hub.docker.com/)からイメージを取得します。

```
$ sudo docker pull ubuntu:14.04
```

確認
ダウンロードが完了したら`docker images`コマンドでダウンロードされたイメージを確認してみます。

```
$ sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              14.04.1             ed5a78b7b42b        2 days ago          192.7 MB
ubuntu              trusty              ed5a78b7b42b        2 days ago          192.7 MB
ubuntu              14.04               ed5a78b7b42b        2 days ago          192.7 MB
```

IMAGE IDがすべて同じことから、同じイメージに複数のTAGを付けられることがわかります。

### コンテナ起動

コンテナの起動は`docker run <オプション> <イメージ> <コマンド>`で行います。
まず最も簡単なechoを実行するだけのコンテナを起動してみます。

```
$ sudo docker run -i -t -h 'first_container' --rm ubuntu:14.04 hostname && echo 'Hello Docker!'
```

実行結果
`hostname`コマンドの結果としてオプションで設定したホスト名がちゃんと返ってきています。

```
first_container
Hello Docker!
```

主要な次の通りです。詳しくは`man docker-run`でご確認を。

| オプション | 説明
|:--- |:--- |
| -a, --attach  | 起動したコンテナのコンソール出力をホストのコンソールへ出力する。    |
| -d, --detach  | コンテナをバックグラウンドで起動する。|
| -h, --hostname| 起動したコンテナ内に設定されるホスト名を指定する。|
| -i, --interactive | attachしていなくても標準出力をオープンします。 |
| -m, --memory | メモリの使用量を制限します。 ex.) `-m 200m`なら200MBまで。|
| --name | 管理用の名前を設定します。ex.) --name 'my_server' |
| -p, --publish| ポートフォワーディングを設定する。ex.)コンテナのポート80を<br>ホストの8080に接続するには -p 8080:80 と指定する。|
| --rm   | コンテナの実行終了時にコンテナを削除する。 |
| -t, --tty | コンテナの標準出力をttyにattachする。主に`-i`と一緒に用いる。 |
| -v, --volume | マウントを設定する。主にホストの特定のディレクトリへ<br>コンテナ内から読み書きしたいときに用いる。 |

その他にもコンテナ内での環境変数設定やワーキングディレクトリの設定(デフォルトは/)を
`docker run`のオプションで設定することができます。

### bashを起動してコンテナ内部から操作する

通常はこういったことはあまり行いませんが、ここでは例としてbashでコンテナ内に入り
そこでWebサーバを立ててみます。

**手順**

1. 親ホストにコンテナから参照するファイルを設置。
2. bashコンテナ起動（オプションで親ホストへのマウントとポートフォワーディング）
3. コンテナ内でWebサーバを起動、ブラウザから確認。

#### 親ホストにコンテナから参照するファイルを設置
```
$ mkdir /tmp/docker
$ echo 'Test Server running inside a container.' > /tmp/docker/test.txt
```

#### bashコンテナ起動
`-v`オプションで親ホストへマウントを指定し、`-p`オプションでコンテナのポート8080を親ポートの80へ接続。

```
$ sudo docker run --rm -ti -v /tmp/docker:/opt -p 80:8080 ubuntu:14.04 /bin/bash
```

#### コンテナ内でWebServerを起動、ブラウザから確認
起動がうまくいけばコンテナ内のターミナルがrootで起動します。
そこで、次のようにrubyを使って簡易Webサーバを起動してみます。
参考：[ワンライナーWebサーバを集めてみた](http://qiita.com/sudahiroshi/items/e74d61d939f18779970d)

まずはrubyをインストール。

```
# sudo apt-get install ruby -y
```

続いてワンライナーでWebサーバを起動します。

```
# ruby -run -e httpd . -p 8080
[2014-12-31 10:02:35] INFO  WEBrick 1.3.1
[2014-12-31 10:02:35] INFO  ruby 1.9.3 (2013-11-22) [x86_64-linux]
[2014-12-31 10:02:35] WARN  TCPServer Error: Address already in use - bind(2)
[2014-12-31 10:02:35] INFO  WEBrick::HTTPServer#start: pid=2651 port=8080
```

ではブラウザを起動して確認しましょう。次の画像のように表示されれば成功です。
http://localhost:8888/opt/test.txt
＊ポート8888を指定しているのはVagrantfileでVMの80を8888へフォワーディングしているため。

![スクリーンショット 2014-12-31 19.08.26.png](https://qiita-image-store.s3.amazonaws.com/0/61318/71e7b9b3-8920-93af-15c5-95403c45e6eb.png)


## まとめ

- Dockerはサーバークライアント方式。`docker`コマンドでサーバへコマンドを送信する。
- Dockerはイメージを元にコンテナを起動する。
- Dockerのイメージはregistryからpull/push可能。
- 公式のregistryは https://registry.hub.docker.com/
- イメージには（複数の）タグを付けることが可能。
- コンテナの起動は`docker run`コマンドで行う。
 - マウントは`-v <親ホストのディレクトリ>:<コンテナ内ディレクトリ>`
 - ポートフォワーディングは`-p <親ホストポート>:<コンテナポート>`