Docker まとめ Chaos

# 概要
dockerについて書いていきます。現在適宜トピックを追加しており、書いていること精査はできていません。カオスです。

# 基本

## Hello Worldを表示

とりあえず実行。実行したらプロセスは終了します。

``` shell
### CentOS6のイメージをダウンロード
$ sudo docker pull centos:centos6

### ダウンロードしたイメージの確認
$ sudo docker images
================================================
REPOSITORY                    TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker.io/centos              6                   e133ccd15399        2 weeks ago         194.6 MB
================================================

### Hello Worldを表示する
$ sudo docker run centos:centos6 /bin/echo "Hello, World"
================================================
Hello, World
================================================
```

## 端末を取得する

``` shell
### 端末を取得する
$ sudo docker run -i -t centos:centos6 /bin/bash
[root@1ef66e4c763c /]# cat /etc/redhat-release
================================================
CentOS release 6.8 (Final)
================================================

* -i (--interactive) : 標準入力を開いてコンテナに接続
* -t (--tty) : 擬似端末を割り当てる
    * まとめて「-it」で指定可能
```

## 端末から抜ける

``` shell
### exitで抜けるとプロセスが終了する
[root@1ef66e4c763c /]# exit
================================================
exit
================================================

$ sudo docker ps -a
================================================
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS                      PORTS                                     NAMES
1ef66e4c763c        centos:6                   "/bin/bash"              3 minutes ago       Exited (0) 21 seconds ago                                             angry_bhabha
0c5ace85fc20        centos:6                   "/bin/echo 'Hello, Wo"   13 minutes ago      Exited (0) 13 minutes ago                                             clever_curie
================================================

### Ctrl+p, Ctrl+qで抜けるとプロセスを終了させずにコンテナから抜ける
[root@1ef66e4c763c /]# $
$ sudo docker ps
================================================
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                                     NAMES
1ef66e4c763c        centos:6                   "/bin/bash"              12 minutes ago      Up 2 minutes                                                  angry_bhabha
================================================
```

## 起動中のコンテナの端末を取得する

``` shell
### プロセスが起動している場合はdocker attachで取得できる
$ sudo docker attach 1ef66e4c763c
================================================
[root@1ef66e4c763c /]#
================================================

### プロセスが終了している場合はdocker startで起動してからdocker attachを実行
$ sudo docker start 1ef66e4c763c
================================================
1ef66e4c763c
================================================

$ sudo docker attach 1ef66e4c763c
================================================
[root@1ef66e4c763c /]#
================================================
```

## コンテナを停止、削除する

``` shell
### コンテナを停止する
$ sudo docker ps
================================================
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
858a5dc9c979        centos:6            "/bin/bash"         44 minutes ago      Up 26 seconds                           grave_fermat
================================================

$ sudo docker stop 858a5dc9c979
================================================
858a5dc9c979
================================================

$ sudo docker ps -a
================================================
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
858a5dc9c979        centos:6            "/bin/bash"              43 minutes ago      Exited (0) 42 minutes ago                       grave_fermat
================================================

### コンテナを削除する
$ sudo docker rm 858a5dc9c979
================================================
858a5dc9c979
================================================

$ sudo docker ps -a
================================================
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
================================================
```

## 確認

``` shell
### コンテナの情報をJSON形式で取得
$ sudo docker inspect ba675033b178
================================================
[
{
    "Id": "ba675033b178a601ff146f73bbd8db7be38582634c2e967c0ddcdbc8adf8a33c",
    "Created": "2016-06-21T06:52:36.310085146Z",
    "Path": "/bin/bash",
    "Args": [],
    "State": {
        "Status": "running",
        "Running": true,
        "Paused": false,
        "Restarting": false,
...
================================================

### 実行中の出力確認
$ sudo docker logs ba675033b178
================================================
[root@ba675033b178 /]# exit
[root@ba675033b178 /]#
[root@ba675033b178 /]# echo hoge
hoge
[root@ba675033b178 /]# exit
exit
※ コンテナ内で実行したコマンドの履歴が表示されている
================================================

### コンテナのリソース消費状況を確認できる
$ sudo docker stats
================================================
CONTAINER           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O               BLOCK I/O
072b59797f9f        0.07%               1.046 GB / 8.372 GB   12.49%              20.84 MB / 9.031 MB   6.169 MB / 998.9 kB
2617e11afa05        0.13%               484.9 MB / 8.372 GB   5.79%               182.9 MB / 5.004 MB   20.96 MB / 348.2 MB
41fb37bfefea        0.05%               1.205 GB / 8.372 GB   14.39%              100 MB / 2.666 MB     17.39 MB / 1.77 GB
52c967c9c029        0.02%               211.8 MB / 8.372 GB   2.53%               83.17 MB / 2.775 MB   29.17 MB / 93.9 MB
e4f552ef6cc1        0.00%               16.78 MB / 8.372 GB   0.20%               648 B / 648 B         4.948 MB / 7.893 MB
f0d2a676c12c        0.00%               536.6 kB / 2.147 GB   0.02%               0 B / 648 B           294.9 kB / 0 B
================================================
```

## イメージ

### イメージの作成

``` shell
### コンテナの表示
$ sudo docker ps -a
================================================
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS                        PORTS                  NAMES
92578f8c5428        centos:centos6      "/bin/bash --login"   24 minutes ago      Exited (137) 13 minutes ago                          db_server
================================================

### イメージの作成
### docker commit <CONTAINER ID> <イメージのREPOSITORY名>[:<イメージのTAG名>]
$ sudo docker commit 92578f8c5428  db_server:installed
================================================
de44c26fb2fdb55fcbc6fa7b7aeb9b2773eab1cf1e1ada4fd41e400b81cacf70
================================================

### イメージの確認
$ sudo docker images
================================================
REPOSITORY              TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
db_server               installed           de44c26fb2fd        47 seconds ago      1.376 GB
docker.io/centos        centos6             ae5fb3aecc1c        3 days ago          194.6 MB
================================================
```

### イメージのタグ操作

``` shell
### イメージを表示する
$ sudo docker images
================================================
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
ubuntu               latest              0f192147631d        5 days ago          132.8 MB
redmine              latest              927abfd6c25e        5 days ago          616.6 MB
================================================


### イメージにタグを付ける
$ sudo docker tag 927abfd6c25e localhost:5000/redmine
$ sudo docker images
================================================
ubuntu                   latest              0f192147631d        5 days ago          132.8 MB
localhost:5000/redmine   latest              927abfd6c25e        5 days ago          616.6 MB
redmine                  latest              927abfd6c25e        5 days ago          616.6 MB
================================================

### tagを消す(イメージを消す操作と同じ)
$ sudo docker rmi localhost:5000/redmine
================================================
Untagged: localhost:5000/redmine:latest
================================================

### tagが<none>のものを削除
sudo docker rmi $(sudo docker images | grep '<none>' | awk '{print$3}')
================================================
Deleted: 4001f1d879977298e47bc5ffa710ed6c08451c390fe89bd874f4255419c379c7
Deleted: 9f93b810dd1dec1ca00882e6693a9ce0de280f32521bd71c10803c676f37903d
Deleted: 44f284a0be62861092943802d0c1ad46697dfc1e553d9438d54278fe9defdcc0
Deleted: 9d056d89b0b6fdd83056cbed900701c29728ea1505634fe1dc8b3c4665426a0a
================================================
```

# dockerの設定情報確認

## パターン1

* dockerホストの/home/vagrant/shareをコンテナの/mntでマウント
* exposeで3306を指定

``` shell
### docker run 
$ sudo docker run -it -v /home/vagrant/share/:/mnt --expose=3306 docker.io/mysql /bin/bash

### docker ps
$ sudo docker ps
================================================
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
15f4e8a4c581        docker.io/mysql     "docker-entrypoint.sh"   2 hours ago         Up 16 minutes       3306/tcp               suspicious_yalow
================================================

### dockerホストの領域をマウントしている
$ sudo docker inspect -f '{{ .HostConfig.Binds }}' 15f4e8a4c581
================================================
[/home/vagrant/share/:/mnt]
================================================

### dockerホストのポートのbindingは無し
$ sudo docker inspect -f '{{ .HostConfig.PortBindings }}' 15f4e8a4c581
================================================
map[]
================================================

### 3306が開いている
$ sudo docker inspect -f '{{ .Config.ExposedPorts }}' 15f4e8a4c581
================================================
map[3306/tcp:{}]
================================================

### 3306は開いているが、dockerホストから接続するための設定は無し(null)
$ sudo docker inspect -f '{{ .NetworkSettings.Ports }}' 15f4e8a4c581
================================================
map[3306/tcp:[]]
================================================
```

## パターン2

* dockerホストの8080に接続するとコンテナの80にフォワードされる

``` shell
### docker run
$ sudo docker run -it -p 8080:80 centos6:web_server /bin/bash

### docker ps
$ sudo docker ps
================================================
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
916d31be2edb        centos:6            "/bin/bash --login"      44 hours ago        Up About a minute   0.0.0.0:8080->80/tcp   web_server
================================================

### dockerホストの領域をマウントしていない
$ sudo docker inspect -f '{{ .HostConfig.Binds }}' 916d31be2edb
================================================
[]
================================================

### dockerホストのポート8080がコンテナの80にバインディング
$ sudo docker inspect -f '{{ .HostConfig.PortBindings }}' 916d31be2edb
================================================
map[80/tcp:[{ 8080}]]
================================================

### 80が開いている
$ sudo docker inspect -f '{{ .Config.ExposedPorts }}' 916d31be2edb
================================================
map[80/tcp:{}]
================================================

### コンテナ側の80が開いており、dockerホストから8080で接続可能
$ sudo docker inspect -f '{{ .NetworkSettings.Ports }}' 916d31be2edb
================================================
map[80/tcp:[{0.0.0.0 8080}]]
================================================
```

## パターン3

* web_serverからdb_serverに--linkオプションでmysqlに接続できるように起動

``` shell
### docker run
$ sudo docker run -it -d --expose=3306 --name=db_server centos6:db_server
$ sudo docker run -it -p 8081:80 --link db_server:db --name=web_server centos6:web_server

### docker ps
$ sudo docker ps
================================================
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
d1c37406f095        centos6:web_server            "/bin/bash --login"      43 hours ago        Up 3 minutes                     0.0.0.0:8081->80/tcp   web_server
9568ca4b4219        centos6:db_server             "/bin/bash --login"      43 hours ago        Up 3 minutes                     3306/tcp               db_server
================================================


### dockerホストのポート8081からweb_serverの80に接続可能
$ sudo docker inspect -f '{{ .HostConfig.PortBindings }}' d1c37406f095
================================================
map[80/tcp:[{ 8081}]]
================================================
$ sudo docker inspect -f '{{ .HostConfig.PortBindings }}' 9568ca4b4219
================================================
map[]
================================================

### web_serverの80、db_serverの3306が開いている
$ sudo docker inspect -f '{{ .Config.ExposedPorts }}' d1c37406f095
================================================
map[80/tcp:{}]
================================================
$ sudo docker inspect -f '{{ .Config.ExposedPorts }}' 9568ca4b4219
================================================
map[3306/tcp:{}]
================================================

### web_serverの80が開いており、ホスト側から8081で接続可能、またdb_serverの3306が開いている
$ sudo docker inspect -f '{{ .NetworkSettings.Ports }}' d1c37406f095
================================================
map[80/tcp:[{0.0.0.0 8081}]]
================================================
$ sudo docker inspect -f '{{ .NetworkSettings.Ports }}' 9568ca4b4219
================================================
map[3306/tcp:[]]
================================================

### web_server側でLinkの設定がされている
$ sudo docker inspect -f '{{ .HostConfig.Links }}' d1c37406f095
================================================
[/db_server:/web_server/db]     ### db_serverコンテナとweb_serverコンテナでリンクのエイリアス名dbが設定されている
================================================
$ sudo docker inspect -f '{{ .HostConfig.Links }}' 9568ca4b4219
================================================
[]
================================================
```



# docker逆引き

## Apacheをインストールしてdockerホスト外からアクセスする

``` shell
### コンテナ内に入ってApacheをインストール
[root@ba675033b178 /]# yum install httpd
================================================
Loaded plugins: fastestmirror, ovl
Setting up Install Process
...
================================================

### Apache起動
[root@ba675033b178 /]# service httpd start
================================================
Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2 for ServerName
                                                           [  OK  ]
================================================

### curlで確認
[root@ba675033b178 /]# curl http://172.17.0.2 | head
================================================
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
101  4961  101  4961    0     0  6187k      0 --:--:-- --:--:-- --:--:-- 4844k
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
        <head>
                <title>Apache HTTP Server Test Page powered by CentOS</title>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                <style type="text/css">
                        body {
                                background-color: #fff;
                                color: #000;
                                font-size: 0.9em;
                                font-family: sans-serif,helvetica;
================================================

### コンテナから出る
[root@ba675033b178 /]# exit

### イメージの作成
$ sudo docker commit ba675033b178 centos:6/httpd
================================================
b6aa81a5ec25397dfb3a7cdee73886798f8ea16044cc7d4c5a87a5a6ffd434f3
================================================

### イメージが作成されたことの確認
$ sudo docker images
================================================
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos:6/httpd      latest              b6aa81a5ec25        45 seconds ago      285.2 MB
docker.io/centos    6                   e133ccd15399        2 weeks ago         194.6 MB
================================================

### ポートフォワードするように起動
$ docker run -i -t -p 8080:80 centos:6/httpd /bin/bash

### httpdの起動
[root@be9e201e55e9 /]# service httpd start
================================================
Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2 for ServerName
                                                           [  OK  ]
================================================

### コンテナを起動したまま抜ける
(Ctrl+p,Ctrl+q)

### プロセスの確認。dockerホストの8080ポートに接続するとコンテナの80番ポートにfowardされる
$ sudo docker ps
================================================
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS                  NAMES
be9e201e55e9        centos:6/httpd      "/bin/bash"         About a minute ago   Up About a minute   0.0.0.0:8080->80/tcp   naughty_varahamihira
================================================

### dockerホストのIP確認
$ ip a | grep inet
================================================
    inet 127.0.0.1/8 scope host lo
    inet 192.168.33.11/24 brd 192.168.33.255 scope global ens160
    inet 172.17.0.1/16 scope global docker0
================================================

### dockerホストの外のホストからcurlを実行
$ curl http://192.168.33.11:8080 | head
================================================
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
101  4961  101  4961    0     0  1241k      0 --:--:-- --:--:-- --:--:-- 4844k
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
        <head>
                <title>Apache HTTP Server Test Page powered by CentOS</title>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                <style type="text/css">
                        body {
                                background-color: #fff;
                                color: #000;
                                font-size: 0.9em;
                                font-family: sans-serif,helvetica;
================================================
```


## dockerホストとコンテナ間でファイルをやり取りする

### docker cpでファイルを移動

``` shell
### コンテナの確認
$ sudo docker ps
================================================
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
832cb94859c7        centos:6            "/bin/bash"         6 hours ago         Up 3 seconds                            hungry_hypatia
================================================

### dockerホスト ⇒ コンテナ
$ ls hoge.csv
================================================
hoge.csv
================================================

### docker cp <ファイル> <CONTAINER ID>:<転送先のPATH>
$ sudo docker cp hoge.csv 832cb94859c7:/tmp

### ファイルの確認
$ sudo docker attach 832cb94859c7
# ls /tmp/hoge.csv
================================================
/tmp/hoge.csv
================================================

### コンテナ ⇒ dockerホスト
# mv /tmp/hoge.csv /tmp/fuga.csv
(Ctrl+p,Ctrl+q)
$ sudo docker cp 832cb94859c7:/tmp/fuga.csv .
$ diff hoge.csv fuga.csv
================================================
(差分無し)
================================================
```

### 

## コンテナのスナップショットを取る

### [検証中] コンテナのファイル出力と読み込み

``` shell
### コンテナの確認
$ sudo docker ps -a
================================================
CONTAINER ID        IMAGE                             COMMAND             CREATED             STATUS                      PORTS                  NAMES
c3203cf47e19        docker.io/tensorflow/tensorflow   "/bin/bash"         6 minutes ago       Up 6 minutes                6006/tcp, 8888/tcp     cranky_pasteur
================================================

### コンテナをtarファイルに出力
$ sudo docker export --output="tensorflow.tar" c3203cf47e19
$ ls -lh tensorflow.tar
================================================
-rw-r--r-- 1 root root 682M  6月 24 08:38 tensorflow.tar
================================================

### tarファイルからイメージを作成
$ sudo docker import tensorflow.tar
================================================
cb80634d7b8c44237e21d3d491034817eac9a0ac13f44ea83d22b67a5f61bf95
================================================

### イメージの確認
$ sudo docker images
================================================
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
<none>                            <none>              cb80634d7b8c        44 seconds ago      686.9 MB
docker.io/tensorflow/tensorflow   latest              d1df24ec6a40        9 weeks ago         714.1 MB
================================================

### イメージに名前とTAGをつける
$ sudo docker tag  cb80634d7b8c docker.io/tensorflow/tensorflow:sample
$ sudo docker images
================================================
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker.io/tensorflow/tensorflow   sample              cb80634d7b8c        4 minutes ago       686.9 MB
docker.io/tensorflow/tensorflow   latest              d1df24ec6a40        9 weeks ago         714.1 MB
================================================

### コンテナ起動
$ sudo docker run -i -t cb80634d7b8c /bin/bash
```

コンテナをtarファイルで保存

### イメージを作成し、適宜コンテナを作成
コンテナそのもののスナップショットを取るというのではなくdocker commitでイメージを作成し、適宜イメージからコンテナを作成するというやり方。コンテナ起動中でもイメージを作成できるが、例えばhttpdを起動した状態でイメージ化し、それを立ち上げるとpidファイルは存在しているがhttpdは落ちているという状態になる。mysqlなど停めずにイメージ化すると壊れるサービスもありそう。

``` shell
### コンテナの確認
$ sudo docker ps -a
================================================
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS                   NAMES
388ec677301d        centos:6/https      "/bin/bash"         2 hours ago         Up 2 hours               0.0.0.0:4433->443/tcp   determined_hugle
================================================

### イメージの作成
### docker commit <CONTAINER ID> <イメージのREPOSITORY名>[:<イメージのTAG名>]
$ sudo docker commit 388ec677301d centos6:ssl_check
================================================
0cc0e3bfc374500c8ce96b6f6a9ae0689ca1095b5d50e1eb972c8bcbeeb166d0
================================================

### イメージの確認
$ sudo docker images
================================================
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos6             ssl_check           0cc0e3bfc374        7 minutes ago       288 MB
================================================

### イメージを使いポートフォワードするように起動
$ sudo docker run -i -t -p 4433:443 centos6:ssl_check /bin/bash
(Ctrl+p,Ctrl+q)
$ sudo docker ps -a
================================================
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS                   NAMES
388ec677301d        centos6:ssl_check      "/bin/bash"         2 hours ago         Up 2 hours               0.0.0.0:4433->443/tcp   determined_hugle
================================================
```
## イメージを他のdockerホストで利用する

### イメージをファイルで移動

``` shell
### イメージの確認
$ sudo docker images
================================================
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos6             ssl_check           0cc0e3bfc374        24 minutes ago      288 MB
================================================

### イメージファイルを出力
### sudo docker save <IMAGE ID名> > <ファイル名>.tar
$ sudo docker save 0cc0e3bfc374 > centos6_ssl_check.tar

### ファイルを別のdockerホストに移動

### イメージファイルを取り込む
$ sudo docker load --input centos6_ssl_check.tar

### 確認
$ sudo docker ps -a
================================================
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
<none>              <none>              0cc0e3bfc374        32 minutes ago      288 MB
================================================

### REPOSITORY名とTAG名を付与
### docker tag <IMAGE ID> <REPOSITORY><[:TAG]>
$ sudo docker tag 0cc0e3bfc374 centos6:ssl_check
$ sudo docker ps -a
================================================
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
centos6             ssl_check           0cc0e3bfc374        37 minutes ago      288 MB
================================================
```

### 公のイメージを検索して使う

TensorFlowの例

``` shell
### イメージの検索
$ sudo docker search tensorflow
================================================
INDEX       NAME                                                          DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
docker.io   docker.io/tensorflow/tensorflow                               Official docker images for deep learning f...   90
docker.io   docker.io/xblaster/tensorflow-jupyter                         Dockerized Jupyter with tensorflow              22                   [OK]
docker.io   docker.io/drunkar/anaconda-tensorflow-gpu                     anaconda-tensorflow-gpu                         7                    [OK]
docker.io   docker.io/satoshun/tensorflow-notebook                        Jupyter with Tensorflow                         5                    [OK]
...
================================================

### イメージの取得
$ sudo docker pull docker.io/tensorflow/tensorflow
================================================
Using default tag: latest
Trying to pull repository docker.io/tensorflow/tensorflow ... latest: Pulling from tensorflow/tensorflow
140d9fb3c81c: Downloading [==>                                                ] 3.227 MB/65.69 MB
74a2c71e6050: Download complete
================================================

### イメージの確認
$ sudo docker images
================================================
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
docker.io/tensorflow/tensorflow   latest              d1df24ec6a40        9 weeks ago         714.1 MB
================================================

### コンテナを作成して利用
$ sudo docker run -i -t docker.io/tensorflow/tensorflow /bin/bash
================================================
root@c3203cf47e19:/notebooks#
================================================

### サンプルコードを実行
# mkdir tensorflow
# cd tensorflow
# vi sample.py
================================================
# http://qiita.com/icoxfog417/items/fb5c24e35a849f8e2c5d#%E6%BC%94%E7%AE%97
import tensorflow as tf

def x2_plus_b(x, b):
    _x = tf.constant(x)
    _b = tf.constant(b)
    result = tf.square(_x)
    result = tf.add(result, _b)
    return result

with tf.Session() as sess:
    result = sess.run([x2_plus_b(2., 3.)])
    print result
================================================

# python sample.py
================================================
[7.0]
================================================
```

## レジストリサーバをたてる

### ローカルのdockerホストで利用

* [Docker Registryでプライベートなリポジトリを立てる](http://tanksuzuki.com/post/private-docker-registry/)

``` shell
### ディレクトリの作成
$ mkdir -p /home/${USER}/work/docker/containers/registry

### Registryコンテナを起動
$ sudo docker run -p 5000:5000 -d -v /home/${USER}/work/docker/containers/registry:/tmp/registry registry

### docker registryにpushするためにイメージにtagをつける
$ sudo docker tag 0f192147631d localhost:5000/ubuntu
$ sudo docker images
================================================
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
docker.io/ubuntu        16.04               0f192147631d        4 days ago          132.7 MB
localhost:5000/ubuntu   latest              0f192147631d        4 days ago          132.7 MB  ※ tagがついた
================================================

### pushする
$ sudo docker push localhost:5000/ubuntu
================================================
The push refers to a repository [localhost:5000/ubuntu]
0738910e0455: Image successfully pushed
21df36b5c775: Image successfully pushed
315fe8388056: Image successfully pushed
7f4734de8e3d: Image successfully pushed
Pushing tag for rev [0f192147631d] on {http://localhost:5000/v1/repositories/ubuntu/tags/latest}
================================================

### イメージの確認
$ ls /home/jsd/work/docker/containers/registry
================================================
images  repositories
================================================
$ ls /home/jsd/work/docker/containers/registry/repositories/library
================================================
ubuntu
================================================

### 他のdockerホストにアクセス。ubuntuのイメージ無し
$ sudo docker images
================================================
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
================================================

### docker registryからイメージをpull
$ sudo docker pull localhost:5000/ubuntu
```

### リモートのdockerホストから利用

デフォルトではローカルのdockerホストからの利用に制限されている。sshポートフォワーディングを利用してローカルから実行しているように見せかけることでコンテナ側の設定を変えずにregistryを利用する。

* registryのあるdockerホスト : 192.168.56.180
* registryを利用するdockerホスト : 192.168.56.181

``` shell
[192.168.56.180]
### ターゲットイメージ
$ sudo docker images
================================================
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
localhost:5000/ubuntu   latest              bbe1a03dc746        4 days ago          132.7 MB
================================================

[192.168.56.181]
### 以下コマンドを実行してターミナルはそのままにしておく
$ ssh -L 4001:localhost:5000 vagrant@192.168.56.180
================================================
vagrant@192.168.56.180's password:
bind: Cannot assign requested address
Last login: Mon Jul  4 13:23:53 2016 from 10.136.12.6
================================================

[192.168.56.181]
### 別ターミナルでdocker pullを実行
$ sudo docker pull localhost:4001/ubuntu
================================================
Using default tag: latest
0f192147631d: Download complete
7f4734de8e3d: Download complete
6d31e1827ca8: Download complete
89e9f76552fd: Download complete
Status: Downloaded newer image for localhost:4001/ubuntu:latest
localhost:4001/ubuntu: this image was pulled from a legacy registry.  Important:                                                                                                       This registry version will not be supported in future versions of docker.
================================================

[192.168.56.181]
### イメージの確認
$ sudo docker images
================================================
REPOSITORY                        TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
localhost:4001/ubuntu             latest              0f192147631d        4 days ago          132.7 MB
================================================
```

※ sshに-vオプションをつけるとデバッグモードになる

## コンテナ間連携

* [Docker container間の連携について](http://qiita.com/taka4sato/items/b1bf33941a1ec8b69fd2)
* [Dockerコンテナ間のlink，database.ymlの書き方](http://deeeet.com/writing/2014/03/20/docker-link-container/)
    * 後で読む

以下MySQLのdb_serverとRailsのweb_serverのイメージができている想定。


``` shell
### DBサーバ側起動
$ sudo docker run -it --name=db_server centos6:db_server
$ sudo docker ps 
================================================
CONTAINER ID        IMAGE                             COMMAND               CREATED             STATUS                  PORTS                  NAMES
9568ca4b4219        centos6:db_server             "/bin/bash --login"   44 seconds ago      Up 43 seconds           3306/tcp               db_server

※ PORTSの「3306/tcp」はイメージ化する元のコンテナで、docker runで立ち上げたときに-pオプションで指定したコンテナ側のポート番号
  例) 「sudo docker run -it -p 33066:3306 centos:6 /bin/bash」の「3306」
================================================

### mysqld起動
# service mysqld start
(Ctrl+p,Ctrl+q)

### Webサーバ起動
$ sudo docker run -it -p 8080:80 --link db_server:db --name=web_server centos6:web_server

### 環境変数の確認
# env | grep DB
================================================
DB_NAME=/web_server/db
DB_PORT=tcp://172.17.0.3:3306
DB_PORT_3306_TCP_PORT=3306
DB_PORT_3306_TCP_PROTO=tcp
DB_PORT_3306_TCP_ADDR=172.17.0.3
DB_PORT_3306_TCP=tcp://172.17.0.3:3306
================================================

### database.ymlの編集
# cd /var/share/webmail/config
# vi database.yml
================================================
production:
  adapter : mysql
  database: mysql_db
  username: mysql_user
  password: mysql_pass
  timeout : 5000
  encoding: utf8
  host: 172.17.0.3
  port: 3306
================================================

### Apache再起動
# service httpd restart

### ブラウザでアクセス 192.168.33.11はdockerホストのアドレス
http://192.168.33.11:8080


### docker psは以下のようになっている
CONTAINER ID        IMAGE                    COMMAND               CREATED             STATUS              PORTS                  NAMES
d1c37406f095        centos6:web_server   "/bin/bash --login"   5 minutes ago       Up 5 minutes        0.0.0.0:8080->80/tcp   web_server
9568ca4b4219        centos6:db_server    "/bin/bash --login"   6 minutes ago       Up 6 minutes        3306/tcp               db_server
```

### 一般ユーザが環境変数を使う

* 通常ではコンテナ起動時に接続するユーザにしか環境変数が設定できない
    * docker run実行時に/etc/profile.d/docker_env.shを作成して一般ユーザがログイン時に読み込むようにする
        * dockerの仕組みをちゃんと理解したら他の方法があるかも。。

``` shell
$ sudo docker run -it -d \
                -p 8081:80 \
                --link db_server:db \
                --name web_server \
                web_server:init \
                sh -c 'service httpd start && env | grep DB_ | sed -e "s/^/export /" > /etc/profile.d/docker_env.sh && /bin/bash --login'

※ sh実行ユーザのDB_～という環境変数を頭にexportをつけて/etc/profile.d/docker_env.shに書き込んでいる
※ --loginをつけないと環境変数が読み込まれない
```

### Apacheが環境変数を使う

* /etc/httpd/conf.d/docker.confを作成してSetEnvで設定

``` shell
$ sudo docker run -it -d \
                -p 8081:80 \
                --link db_server:db \
                --name web_server \
                web_server:init \
                sh -c 'service httpd start && env | grep DB_ | sed -e "s/^/SetEnv /" -e "s/=/ /" > /etc/httpd/conf.d/docker.conf && /bin/bash --login'
```

## コンテナからdockerホスト外のサーバにアクセス(作成中)

* [IT Automation Part I: Ansible “Hello World” Example using Ansible on Docker](https://oliverveits.wordpress.com/2015/11/09/it-automation-a-hello-world-example-using-ansible-on-docker/)
    * コンテナ内から外部のサーバにAnsibleを実行する設定
    * -> コンテナを作成したら、コンテナ内から普通に外部のサーバにsshできた


## NFSを利用する

* [Docker の Volume plugin で NFS や Glusterfs を利用する](http://qiita.com/rerofumi/items/579571c1453e7e6f2bd8)
* [DockerコンテナにNFSボリュームをマウントする---Netshare Pluginを使ってみる](http://qiita.com/kjtanaka/items/45c0e809e2632adde93b)

# トラブルシューティング

## Couldn't find an alternative telinit implementation to spawn.

docker-composeで ` command: sh -c '/usr/sbin/init && systemctl restart sshd.service' ` のように設定して起動しようとするとエラーが出て立ち上がらなくなった

``` shell
$ docker-compose -f hoge.yml up
================================================
Recreating hoge
Attaching to hoge
hoge | Couldn't find an alternative telinit implementation to spawn.
hoge exited with code 1
================================================
```

頭にexecをつけて` command: sh -c 'exec /usr/sbin/init && systemctl restart sshd.service' `
 で起動するとエラーとならず、一分後くらいにsshも受け付けるようになる。

``` shell
$ docker-compose hoge.yml up -d
================================================
Creating openldap_edu
================================================

$ docker exec -it (コンテナID) /bin/bash --login
# ssh localhost
================================================
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ECDSA key fingerprint is fb:76:9d:73:50:ab:fc:d4:84:44:5a:c9:72:79:0d:50.
================================================
```

-dをつけずにupのみで起動するとERRORが出ているので何かあるかもしれないが、とりあえず使えているのでよしとする。

``` shell
$ docker-compose hoge.yml up
Creating hoge
Attaching to hoge
================================================
ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running?

If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
================================================
```

## docker-storage-setup: ERROR: Docker has been previously configured for use with devicemapper graph driver. 

このメッセージが出てdockerが起動できない

``` shell
### /var/log/messages
docker-storage-setup: ERROR: Docker has been previously configured for use with devicemapper graph driver. 
Not creating a new thin pool as existing docker metadata will fail to work with it. Manual cleanup is required before this will succeed.
```

/var/lib/dockerを全部消したら起動した。 **イメージ全部消えます**

``` shell
$ sudo rm -rf /var/lib/docker
$ sudo systemctl start docker.service
```

## データが壊れることがある

    * 前にldconfig.serviceも同じようになっていた事がある
    * docker registryからpullしてきたもので壊れることがあるような気がする
        * -vオプションでホストと領域を共有しているのが原因か？
        * -> mysqlとかも-vオプション使って領域がこわれたことがあった。

``` shell
### 正常な状態
# ls -lh ldap/ | grep __db
================================================
-rw------- 1 ldap ldap  24K  7月  7 10:42 2016 __db.001
-rw------- 1 ldap ldap 137M  7月  7 10:48 2016 __db.002
-rw------- 1 ldap ldap 4.0G  7月  7 10:48 2016 __db.003
-rw------- 1 ldap ldap 1.3G  7月  7 10:47 2016 __db.004
-rw------- 1 ldap ldap 736K  7月  7 10:48 2016 __db.005
-rw------- 1 ldap ldap  32K  7月  7 10:47 2016 __db.006
================================================

### ldap起動失敗
# service slapd start
================================================
slapd を起動中:
SLAPD_PIDFILE: /var/run/openldap/slapd.pid
PIDFILE: /var/run/slapd.pid
PROG: slapd
SLAPD: /usr/sbin/slapd
HARG: ldap://*:389/ ldap:/// ldapi:///
USER: ldap
OPTIONS:
SLAPD_OPTIONS:
DAEMON: daemon --pidfile=/var/run/slapd.pid --check=slapd /usr/sbin/slapd -u ldap -f /etc/openldap/slapd.conf -h ldap://*:389/
                                                           [失敗]
================================================

### ファイルが壊れた
# ls -l /var/lib/ldap/ | grep __db
================================================
ls: cannot access ldap/__db.004: そのようなファイルやディレクトリはありません
ls: cannot access ldap/__db.005: そのようなファイルやディレクトリはありません
ls: cannot access ldap/__db.006: そのようなファイルやディレクトリはありません
-rw------- 1 ldap ldap  24K  7月  7 11:47 2016 __db.001
-rw------- 1 ldap ldap 137M  7月  7 11:47 2016 __db.002
-rw------- 1 ldap ldap 4.0G  7月  7 10:48 2016 __db.003
?????????? ? ?    ?       ?                  ? __db.004
?????????? ? ?    ?       ?                  ? __db.005
?????????? ? ?    ?       ?                  ? __db.006
================================================
```

## CentOS7でsystemctlを使うと「Failed to get D-Bus connection: No connection to service manager.」

* [CentOS 7のDockerコンテナ内でsystemdを使ってサービスを起動する](http://qiita.com/yunano/items/9637ee21a71eba197345)

``` shell
### docker runは /bin/bashではなく /sbin/initで立ち上げる
$ sudo docker run --privileged -d centos:centos7 /sbin/init

### イメージにログインするときはattachではなくexecで入る。 --loginで環境変数が読み込まれる。
$ sudo docker exec -it (コンテナID) /bin/bash --login
```

## docker run時に「... failed: iptables: No chain/target/match by that name..」

* エラーメッセージ

``` shell
docker: Error response from daemon: failed to create endpoint berserk_leakey on network bridge: 
COMMAND_FAILED: '/sbin/iptables -w2 -t nat -A DOCKER -p tcp -d 0/0 --dport 44333 -j DNAT --to-destination 172.17.0.5:3443 ! -i docker0' 
failed: iptables: No chain/target/match by that name..
```

* 対処法

``` shell
### Docker 管理のネットワークファイルの再構成する
### ※ dockerをリスタートするのでコンテナが全部落ちます

$ sudo mv /var/lib/docker/network/files /tmp
$ sudo systemctl restart docker
```

* [docker run実行時のiptablesエラー](http://qiita.com/witamo/items/9770a2a757d3f5e369a4)

## /var/log 配下にログが出力されない

* rsyslogが止まっているので起動する
    * docker runのオプションに service rsyslog startを入れておいても良い

``` shell
# service rsyslog status
================================================
rsyslogd は停止しています
================================================

# service rsyslog start
================================================
システムロガーを起動中:                                    [  OK  ]
================================================

```

## pstfix起動時に「master が停止していますが PID ファイルが残っています」が出る

* masterというプロセスがデバイスにアクセスする権限が無いことによる
    * docker run時に --privileged をつけて起動

``` shell
### masterがデバイスにアクセスする権限が無い
# lsof -c master
================================================
COMMAND PID USER   FD      TYPE DEVICE SIZE/OFF NODE NAME
master  125 root  cwd   unknown                      /proc/125/cwd (readlink: Permission denied)
master  125 root  rtd   unknown                      /proc/125/root (readlink: Permission denied)
master  125 root  txt   unknown                      /proc/125/exe (readlink: Permission denied)
master  125 root    0   unknown                      /proc/125/fd/0 (readlink: Permission denied)
...
================================================

### --privileged をつけて起動した後
# lsof -c master
================================================
COMMAND PID USER   FD   TYPE             DEVICE SIZE/OFF      NODE NAME
master  125 root  cwd    DIR              253,5     4096 503382647 /var/spool/postfix
master  125 root  rtd    DIR              253,5     4096       259 /
master  125 root  txt    REG              253,5   155976  67194114 /usr/libexec/postfix/master
master  125 root  mem    REG              253,5    65960 167772530 /lib64/libnss_files-2.12.so
...
================================================
```

## postfixで/var/log/maillogに「sSMTP[841]: Unable to locate mail、sSMTP[841]: Cannot open mail:25」

* /etc/ssmtp/ssmtp.confの「mailhub」にSMTPホスト名を設定
    * dockerというよりpostfixの設定かな

``` shell
### エラーメッセージ
# cat /var/log/maillog
================================================
Jul  6 11:30:43 581ca1c3fa51 sSMTP[841]: Unable to locate mail
Jul  6 11:30:43 581ca1c3fa51 sSMTP[841]: Cannot open mail:25
================================================

### 設定を変更してpostfixをrestart
# vi /etc/ssmtp/ssmtp.conf
================================================
mailhub=581ca1c3fa51   # ホスト名
================================================

# service postfix restart
```

## postfixで/var/log/maillogに「fatal: open database /etc/aliases.db: No such file or directory」

* /etc/aliases.db を作り直す

``` shell
# postalias /etc/aliases
# ls /etc/aliases.db
================================================
/etc/aliases.db
================================================
```

# 参考
* [2016年版、Dockerのすべてが5分でわかるまとめ!(コマンド一覧付き)](http://paiza.hatenablog.com/entry/docker_intro)
* AnsibleとDocker
    * [ansible/ansible-container](https://github.com/ansible/ansible-container)
        * playbookだけでdocker containerのイメージ作成、実行まで行う
        * inventoryは自動作成
        * sshではなくdocker connectionを使う
* [CentOS7 で Docker を使ってみる](http://blog.amedama.jp/entry/2015/09/24/222040)
* [Docker Hello World (SlideShare)](http://www.slideshare.net/Ftakao2007/docker-hello-world)
    * [NODE-Setagaya#11](http://node-setagaya.connpass.com/event/6795/)という勉強会でSlideShareにあげた資料のリンクです
* [Railsアプリケーション開発を完全にDocker化する](http://tech.degica.com/ja/2016/06/14/dockerized-rails-development/)