Docker ノウハウ集

  • 31
    いいね
  • 0
    コメント

1. ホスト版数、Docker版数

[root@master1 ~]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)

[root@master1 ~]# docker -v
Docker version 1.10.3, build cb079f6-unsupported

2. 基本編

2.1 Dockerコマンドのヘルプの使い方

dockerコマンドに--helpを指定する。attach等のサブコマンド一覧が表示される。
[root@master1 ~]# docker --help
-中略-
Commands:
    attach    Attach to a running container
    build     Build an image from a Dockerfile
以下、略


サブコマンドに--helpを指定する。
[root@master1 ~]# docker attach --help

Usage:  docker attach [OPTIONS] CONTAINER

Attach to a running container

  --detach-keys       Override the key sequence for detaching a container
  --help              Print usage
  --no-stdin          Do not attach STDIN
  --sig-proxy=true    Proxy all received signals to the process
[root@master1 ~]#

networkサブコマンドは、networkサブコマンドの下に、さらにサブコマンドがある。
[root@master1 ~]# docker network ls --help

Usage:  docker network ls [OPTIONS]

Lists networks

  -f, --filter=[]    Filter output based on conditions provided
  --help             Print usage
  --no-trunc         Do not truncate the output
  -q, --quiet        Only display numeric IDs
[root@master1 ~]#

3. 応用編

3.1 Dockerレジストリを使う(イメージのアップロード/ダウンロード)


------------------------------------------------------
1. 設定ファイル編集(/etc/sysconfig/docker)
------------------------------------------------------
定義ファイルを編集する。
[root@master1 ~]# vi /etc/sysconfig/docker

【変更前】
INSECURE_REGISTRY='--insecure-registry'

【変更後】
INSECURE_REGISTRY='--insecure-registry master1:12345'

  --insecure-registry <ホスト名>:<TCPポート番号>

   ホスト名:dockerデーモンが動作しているホスト名を指定する。
             /etc/hostsに定義されている名前を指定する。
   ポート番号:ホストのTCPポート番号を指定する。
              既存ポート番号と重複しないように選択する。


設定変更したらdockerを再起動する。
[root@master1 ~]# systemctl restart docker


------------------------------------------------------
2. Dockerレジストリを準備する
------------------------------------------------------
Dockerレジストリのイメージをダウンロードする。
[root@master1 ~]# docker pull registry:2.4.1
Trying to pull repository docker.io/library/registry ...
2.4.1: Pulling from docker.io/library/registry
-以下、略-

Dockerレジストリを起動する。
[root@master1 ~]# docker run -d -p 12345:5000 --name test-registry registry:2.4.1
894bcb0a2a4830013991ac827315ff7287d623d1031dc32e1d4848ccf93f013f

Dockerレジストリの状態を確認する。
[root@master1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
894bcb0a2a48        registry:2.4.1      "/bin/registry serve "   7 seconds ago       Up 4 seconds        0.0.0.0:12345->5000/tcp   test-registry


------------------------------------------------------
3. Dockerレジストにイメージをアップロードする
------------------------------------------------------
テスト用イメージをダウンロードする。イメージサイズが小さいbusyboxを使う。
[root@master1 ~]# docker pull busybox
Using default tag: latest
Trying to pull repository docker.io/library/busybox ...
-以下、略-

イメージにtag付けをする
[root@master1 ~]# docker tag busybox master1:12345/hana_shin/busybox:ver1

イメージを確認する。
[root@master1 ~]# docker images |grep busybox
docker.io/busybox                            latest            e02e811dd08f        8 weeks ago         1.093 MB
master1:12345/hana_shin/busybox              ver1              e02e811dd08f        8 weeks ago         1.093 MB

イメージをアップロードする。
[root@master1 ~]# docker push master1:12345/hana_shin/busybox:ver1
The push refers to a repository [master1:12345/hana_shin/busybox]
e88b3f82283b: Pushed
ver1: digest: sha256:9393222c6789842b16bcf7306b6eb4b486d81a48d3b8b8f206589b5d1d5a6101 size: 505


-------------------------------------------------------------
4. アップロードしたイメージを確認する。
-------------------------------------------------------------
Dockerレジストリに登録したイメージを確認する。
[root@master1 ~]# curl http://localhost:12345/v2/_catalog
{"repositories":["hana_shin/busybox"]}

tagを取得する。
[root@master1 ~]# curl http://localhost:12345/v2/hana_shin/busybox/tags/list
{"name":"hana_shin/busybox","tags":["ver1"]}


-------------------------------------------------------------
5. Dockerレジストリからイメージをダウンロードする。
-------------------------------------------------------------
ホスト側のイメージを削除する。
[root@master1 ~]# docker images |grep busybox
docker.io/busybox                                     latest                             e02e811dd08f        8 weeks ago         1.093 MB
master1:12345/hana_shin/busybox                       ver1                               e02e811dd08f        8 weeks ago         1.093 MB
[root@master1 ~]# docker rmi -f e02e811dd08f
Untagged: docker.io/busybox:latest
Untagged: master1:12345/hana_shin/busybox:ver1
Deleted: sha256:e02e811dd08fd49e7f6032625495118e63f597eb150403d02e3238af1df240ba
Deleted: sha256:e88b3f82283bc59d5e0df427c824e9f95557e661fcb0ea15fb0fb6f97760f9d9

busyboxのイメージを確認する。削除できたことがわかる。
[root@master1 ~]# docker images |grep busybox
[root@master1 ~]#

Dockerレジストリからイメージをダウンロードする。
[root@master1 ~]# docker pull master1:12345/hana_shin/busybox:ver1
Trying to pull repository master1:12345/hana_shin/busybox ...
ver1: Pulling from master1:12345/hana_shin/busybox
56bec22e3559: Pull complete
Digest: sha256:9393222c6789842b16bcf7306b6eb4b486d81a48d3b8b8f206589b5d1d5a6101
Status: Downloaded newer image for master1:12345/hana_shin/busybox:ver1

イメージを確認する。Dockerレジストリからイメージをpullできたことがわかる。
[root@master1 ~]# docker images |grep busybox
master1:12345/hana_shin/busybox                       ver1                               e02e811dd08f        8 weeks ago         1.093 MB


-------------------------------------------------------------
6. dockerコマンドのパラメータの説明
-------------------------------------------------------------
docker run -d -p 12345:5000 --name test-registry registry
            A      A            A                  A
            |      |            |                  +--- イメージの名前を指定する。
            |      |            +---------------------- コンテナの名前を指定する。任意の名前でOK
            |      +----------------------------------- ホスト側TCPポート番号(12345)をコンテナのポート番号(5000)に対応付けする。
            +------------------------------------------ コンテナをバックグラウンドで動かすための指定


docker tag busybox localhost:12345/test/busybox:ver1
             A       A         A     A    A      A
             |       |         |     |    |      +------ tag名
             |       |         |     |    +------------- イメージ名
             |       |         |     +------------------ リポジトリ名
             |       |         +------------------------ ホストのTCPポート番号(ホストとはDockerサーバが動作しているサーバのIPアドレスです)
             |       +---------------------------------- ホストのIPアドレス
             +------------------------------------------ 元のイメージの名前

3.2 ホストからコンテナへのルーティング(2の続き)

registryサーバを起動すると、DNATテーブルが作られます。DNATの変換ルールの意味は次のとおり。
ホストの任意(0.0.0.0)のインタフェースに到着したIPパケットで宛先TCPポート番号が12345のパケットは、
宛先IPアドレスを172.17.0.2,宛先ポート番号を5000に変換する。
[root@master1 ~]# iptables -L -t nat -n |grep -B3 12345
Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:12345 to:172.17.0.2:5000


コンテナにログインしてIPアドレスを調べる。コンテナのIPアドレスは"172.17.0.2"であることがわかる。
[root@master1 ~]# docker exec -it test-registry sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
20: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link
       valid_lft forever preferred_lft forever
/ #

コンテナのプロセスが使用しているポート番号を調べる。
/ # netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 :::5000                 :::*                    LISTEN      1/registry
/ #

さらにもう1つregistryサーバを起動したときのホストの様子を以下に示します。

[root@master1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
467b1628f13b        registry            "/entrypoint.sh /etc/"   30 minutes ago      Up 30 minutes       0.0.0.0:22222->5000/tcp   test2-registry
b00c90063f16        registry            "/entrypoint.sh /etc/"   3 hours ago         Up 33 minutes       0.0.0.0:12345->5000/tcp   test-registry

[root@master1 ~]# iptables -L -t nat -n |grep -e 12345 -e 22222
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:12345 to:172.17.0.2:5000
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22222 to:172.17.0.3:5000

docker0はブリッジです。containerは起動すると、このブリッジに接続されます。
ブリッジにはポートが割り当てられます。container1とvethXXX,container2とvethYYYがそれぞれつながっています。


 +---------- Host(CentOS7.2)-------------+
 |                                       |
 |  +- container1 -+   +- container2 -+  |
 |  |              |   |              |  |
 |  |   port=5000  |   |   port=5000  |  |
 |  |              |   |              |  |
 |  +---- eth0 ----+   +---- eth0 - --+  |   -*-
 |    A    | .2               | .3  A    |    |
 |    |    |                  |     |    | 172.16.0.0/16のサブネット
 |  +-|- vethXXX --------- vethYYY -|-+  |    |
 |  | |    docker0(172.17.0.1/16)   | |  |    |
 |  +-|-----------------------------|-+  |   -*-
 |    |              |              |    |
 |    +----+         |          +---+    |
 |         |         |          |        |
 |  +------|--------------------|-----+  |
 |  |      |       Routing      |     | ========> +----------------------------------------------------------------------------------------+
 |  +------|--------------------|-----+  |        |【ルーティングテーブル】宛先IPアドレスより、出力するデバイス(eth0,dcoker0)を決める            |
 |         |         |          |        |        | [root@master1 ~]# route -n                                                             |
 |  port=12345       |      port=22222   |        | Kernel IP routing table                                                                |
 |         |         |          |        |        | Destination     Gateway         Genmask         Flags Metric Ref    Use Iface          |
 +----- eth0 (192.168.0.10/24) -|--------+        | 0.0.0.0         192.168.0.1     0.0.0.0         UG    100    0        0 eth0           |
           |         |          |                 | 172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0        |
                     |                            | 192.168.0.0     0.0.0.0         255.255.255.0   U     100    0        0 eth0           |
                     |                            +----------------------------------------------------------------------------------------+



3.3 コンテナIDからプロセスIDを求める方法

コンテナを起動する。
[root@master1 ~]# docker run -it --name test-con centos:centos7 bash
[root@22914bed7a73 /]# ps
   PID TTY          TIME CMD
     1 ?        00:00:00 bash
    16 ?        00:00:00 ps

別ターミナルを起動して、コンテナIDを求める
[root@master1 ~]# CID=$(docker ps --no-trunc=true|grep "test-con"|awk '{print $1}')

コンテナIDを確認する。
[root@master1 ~]# echo $CID
22914bed7a73ee10382d23a1066dfb3ec94e44de0390af087ccfb4b2b751384b

PIDを求める。
[root@master1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

PIDを確認する。
[root@master1 ~]# echo $PID
2857

プロセスの状態を確認する。
[root@master1 ~]# ps -lp 2857
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0   2857   1053  0  80   0 -  2944 n_tty_ pts/2    00:00:00 bash

3.4 コンテナがホストのディレクトリをマウントする方法

-------------------------------------------------------------
1. マウントするディレクトリを明示的に指定する方法(-vオプション)
-------------------------------------------------------------

マウントするディレクトリに"svirt_sandbox_file_t"というSElinuxのタイプを設定する。
[root@master1 ~]# ls -ldZ registry/
drwxr-xr-x. root root unconfined_u:object_r:admin_home_t:s0 registry/
[root@master1 ~]# chcon -Rt svirt_sandbox_file_t registry
[root@master1 ~]# ls -ldZ registry/
drwxr-xr-x. root root unconfined_u:object_r:svirt_sandbox_file_t:s0 registry/

コンテナを起動する。
[root@master1 ~]# docker run -it -v $HOME/registry:/var/lib/registry --name test centos:centos7 bash


マウントしたディレクトリにファイルを作成する。
[root@08497e222b5e /]# touch /var/lib/registry/test.txt
[root@08497e222b5e /]# echo "This is container" > /var/lib/registry/test.txt
[root@08497e222b5e /]# cat /var/lib/registry/test.txt
This is container


別ターミナルで作成したファイルの中身を確認する。コンテナで作成したファイルの中身が確認できた。
[root@master1 ~]# pwd
/root
[root@master1 ~]# cat registry/test.txt
This is container


-------------------------------------------------------------
2. マウントするディレクトを明示的に指定しない方法。
-------------------------------------------------------------

この場合、コンテナはホストの/var/lib/docker/volumes配下のディレクトリをマウントします。


--------------------------------------------------------------------------------------
2.1 DockerfileでVOLUMEを指定する方法
--------------------------------------------------------------------------------------
Dockerfileを作成する。
[root@master1 ~]# vi Dockerfile
[root@master1 ~]# cat Dockerfile
FROM centos:centos7
VOLUME /root/dir01
VOLUME /root/dir02

イメージをビルドする。
[root@master1 ~]# docker build -t test-image:v1 .
Sending build context to Docker daemon  84.3 MB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : VOLUME /root/dir01
 ---> Using cache
 ---> 226d9d64338d
Step 3 : VOLUME /root/dir02
 ---> Using cache
 ---> 6584f874444e
Successfully built 6584f874444e
[root@master1 ~]#

コンテナを起動する。
[root@master1 ~]# docker run -itd --name test-con test-image:v1
45f6382fd50f21361a911080bf1a3e5d8b91781df0677f6d63ebca5fb334cb64

コンテナの状態を確認する。
[root@master1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
45f6382fd50f        test-image:v1       "/bin/bash"         26 seconds ago      Up 24 seconds                           test-con

jqコマンドがのインストール
[root@master1 ~]# yum -y install jq

ホスト側ディレクトリを確認する。/var/lib/docker/volumes配下(★印)にマッピングされていることがわかる。
[root@master1 ~]# docker inspect test-con | jq .|less

-中略-
    "Mounts": [
      {
        "Name": "d7b8625f00b37f7648fbb5b7d92e1204c7d5b4b2c314051208929080e2d3d82d",
      ★"Source": "/var/lib/docker/volumes/d7b8625f00b37f7648fbb5b7d92e1204c7d5b4b2c314051208929080e2d3d82d/_data",
        "Destination": "/root/dir01",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
      },
      {
        "Name": "761db694fb793079933981ce9094920c1814f964eba4635bf292e1a038a8f428",
      ★"Source": "/var/lib/docker/volumes/761db694fb793079933981ce9094920c1814f964eba4635bf292e1a038a8f428/_data",
        "Destination": "/root/dir02",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
      }
    ],
以下、略


コンテナのbashに接続する。
[root@master1 ~]# docker exec -it test-con bash

VOLUMEで指定したディレクトが作成されていることを確認する。
[root@45f6382fd50f /]# cd /root/
[root@45f6382fd50f ~]# ls
anaconda-ks.cfg  dir01  dir02


dir01配下にファイル(file01)を作成する
[root@45f6382fd50f ~]# cd dir01/
[root@45f6382fd50f dir01]# touch file01
[root@45f6382fd50f dir01]# echo "This is file01" > file01
[root@45f6382fd50f dir01]# cat file01
This is file01


作成したファイルの中身をホスト側で確認する。もう1つターミナルを起動する。
コンテナで書いたファイルの内容がホストで読めた。
[root@master1 ~]# cat /var/lib/docker/volumes/d7b8625f00b37f7648fbb5b7d92e1204c7d5b4b2c314051208929080e2d3d82d/_data/file01
This is file01


--------------------------------------------------------------------------------------
2.2. docker run実行時に指定する方法.  確認方法は2.1を参考にしてください。
--------------------------------------------------------------------------------------
[root@master1 ~]# docker run -it --rm -v /root/dir01 -v /root/dir02 centos:centos7 bash
[root@0e646e283a53 /]# cd root/
[root@0e646e283a53 ~]# ls
anaconda-ks.cfg  dir01  dir02
[root@0e646e283a53 ~]#


3.5 ホストのディレクトリをリードオンリー(roオプション)でマウントする。

コンテナでマウントするディレクトリを作成する。
[root@master1 ~]# mkdir /hostdir
[root@master1 ~]# chcon -Rt svirt_sandbox_file_t /hostdir
[root@master1 ~]# ls -ldZ /hostdir
drwxr-xr-x. root root unconfined_u:object_r:svirt_sandbox_file_t:s0 /hostdir

ホストのディレクトリをリードオンリー(roオプション)でマウントする。エラーが発生してファイルの作成ができない。
[root@master1 ~]# docker run -it -v /hostdir:/tmp:ro busybox sh
/ # echo "This is container" > /tmp/test.txt
sh: can't create /tmp/test.txt: Read-only file system
/ # exit

今度は、書き込み可でマウントする。コンテナでファイルを作成することができた。
[root@master1 ~]# docker run -it -v /hostdir:/tmp busybox sh
/ # echo "This is container" > /tmp/test.txt
/ # exit
[root@master1 ~]# cat /hostdir/test.txt
This is container
[root@master1 ~]#

3.6 データ保存専用コンテナの作成方法

data_conコンテナの/data_dirに対して、conコンテナからファイルの読み書きをする。

    conコンテナ                data_conコンテナ(データ保存専用)
                 -------->     /data_dir
                read/write


データ保存専用コンテナを起動する。-vオプションを使って、/data_dirを他コンテナから参照できるようにする。
[root@master1 ~]# docker run -it -v /data_dir --name data_con busybox sh
/ # ls /data_dir/
/ # echo "This is data-container" > /data_dir/data.txt
/ # exit

もう1つコンテナを起動する。データ保存専用コンテナに保存した
[root@master1 ~]# docker run -it --volumes-from data_con --name con busybox sh
/ # cat /data_dir/data.txt
This is data-container
/ # exit


3.7 同一ホストでnginxコンテナを複数起動する。

ホストのTCPポート番号11111をコンテナのポート番号80にマップする。
[root@master1 ~]# docker run -d -p 11111:80 --name web1 nginx
498c3d59429b7756d63a83cbd8285f68a0a6a4470227fa58cc62c3f1cf682164

ホストのTCPポート番号22222をコンテナのポート番号80にマップする。
[root@master1 ~]# docker run -d -p 22222:80 --name web2 nginx
cc5d925c88ca18542931dba346f0ae011cd414f7aad3d00fc95172e4d7fc6d69

コンテナを確認する。それぞれ、11111->80,22222->80 にマップされていることがわかる。
[root@master1 ~]# docker ps |grep -e web1 -e web2
cc5d925c88ca        nginx               "nginx -g 'daemon off"   15 seconds ago      Up 13 seconds       443/tcp, 0.0.0.0:22222->80/tcp   web2
498c3d59429b        nginx               "nginx -g 'daemon off"   26 seconds ago      Up 23 seconds       443/tcp, 0.0.0.0:11111->80/tcp   web1

[root@master1 ~]# curl http://localhost:11111
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
以下、略

[root@master1 ~]# curl http://localhost:22222
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
以下、略

[root@master1 ~]# docker rm -f web1 web2
web1
web2
[root@master1 ~]#


3.8 コンテナが動作するCPUを指定する方法(--cpuset-cpusオプション)


----------------------------------------------------
1. ddコマンドでCPU負荷をかける
----------------------------------------------------
コンテナがどのCPUで動いているかを確認するため、htopパッケージをインストールする。
[root@master1 ~]# yum -y install epel-release
[root@master1 ~]# yum -y install htop

ホストのCPUを確認する。CPUが4個あることがわかる。
[root@master1 ~]# cat /proc/cpuinfo |grep processor
processor       : 0
processor       : 1
processor       : 2
processor       : 3
[root@master1 ~]#


CPU=0でコンテナを動かす。--cpuset-cpusに0を指定する。
[root@master1 ~]# docker run -it -d --name con0 --cpuset-cpus=0 busybox dd if=/dev/zero of=/dev/null
06ef3f9b7cd70b3b2e0df2917aaef8702491e34f9019ee0361266e86081d0a42

コンテナがどのCPUで動いているかの確認方法の説明。
htopの画像を張り付けて説明したいけど、貼り付けつけ方がわからないので、言葉で説明する。

1. htopを起動する。
[root@master1 ~]# htop

2. F2キーを押下する。画面が切り替わる。
3. ↑↓キーを操作して、"Setup"列の"Columns"にカーソルを合わせ、Enterキーを押下する。
4. <-->キーを選択して、右端の"Available Columens"列にカーソルを移動する。
5. "Available Columens"列の"PROCESSOR"という項目にカーソルを移動してEnterキーを押下する。
6. F5キーを押下する。"PROCESSOR"項目を表示項目に追加する。
7. F10キーを押下して、設定を保存する。
8. 画面が切り替わる。プロセス一覧が表示される。"CPU"列が追加されている。
9. ddプロセスを検索するためF3キーを押下する。続けて、"dd"と入力する。
10. ddプロセスが画面の一番上に表示される。
11. ddコマンドが動作しているCPU番号を確認する。CPU=0で動いていることが確認できる。

CPU番号の数え方が、ホストとhtopでは異なるので(ホストは0,1,..htopは1,2..)、
ホストに合わせる場合は"Display options" -> "Count CPUs from 0 instead of 1"を選択する。
htopでもCPU番号が0,1,2...と表示されるようになる。


他にも、以下のようにCPU番号を変化させて、htopで確認する。指定したCPUでコンテナが動いていることが確認できる。
[root@master1 ~]# docker run -it -d --name con1 --cpuset-cpus=1 busybox dd if=/dev/zero of=/dev/null
[root@master1 ~]# docker run -it -d --name con2 --cpuset-cpus=2 busybox dd if=/dev/zero of=/dev/null
[root@master1 ~]# docker run -it -d --name con3 --cpuset-cpus=3 busybox dd if=/dev/zero of=/dev/null


----------------------------------------------------
2. opensslコマンドでCPU負荷をかける
----------------------------------------------------
[root@master1 ~]# vi Dockerfile
[root@master1 ~]# cat Dockerfile
FROM centos:centos7
ENV container docker
RUN yum -y install openssl && yum clean all
[root@master1 ~]#


イメージをビルドする。
[root@master1 ~]# docker build -t test --no-cache=true .
Sending build context to Docker daemon 84.29 MB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : ENV container docker
 ---> Running in f75f52ceffb5
 ---> 49803a7122bf
Removing intermediate container f75f52ceffb5
Step 3 : RUN yum -y install openssl && yum clean all
 ---> Running in 3cae1e4c3680
以下、略


[root@master1 ~]# docker run -it -d --name cpuload --cpuset-cpus=0-1 test /usr/bin/openssl speed -multi 2
7cc24954486249466f4c8f31586ae73a34be7eb0eee5c9155d88df0f4aa61115
[root@master1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
7cc249544862        test                "/usr/bin/openssl spe"   4 seconds ago       Up 2 seconds                            cpuload
[root@master1 ~]#


htopを起動する。
[root@master1 ~]# htop

CPU=0,1でopensslコマンドの使用率が100%になっていることがわかる。


今度は、CPU0とCPU3でopensslコマンドを実行する。
[root@master1 ~]# docker run -it -d --name cpuload --cpuset-cpus=0,3 test /usr/bin/openssl speed -multi 2
041d17acb164c629ac9d1d8052439961c8881b7d124e57268214abeffb3e066c
[root@master1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
041d17acb164        test                "/usr/bin/openssl spe"   6 seconds ago       Up 3 seconds                            cpuload
[root@master1 ~]#

htopを起動する。
[root@master1 ~]# htop

CPU0とCPU3でopensslコマンドの使用率が100%になっていることがわかる。

3.9 コンテナが動作するCPUの確認方法

コンテナを起動する。
[root@master1 ~]# docker run -it --rm --name test-con1 centos:centos7 bash
[root@0b9b40152ac4 /]#

コンテナIDを取得する。
[root@master1 ~]# CID=$(docker ps -a --no-trunc=true |grep test-con1 | awk '{print $1}')

コンテナIDを確認する。
[root@master1 ~]# echo $CID
0b9b40152ac4377080bb77ba8fca267d1c4cf11cb2d6314f3ad8ac064efe5b35

コンテナが動作するCPUを確認する。CPU=0,1,2,3で動く設定であることがわかる。
[root@master1 ~]# cat /sys/fs/cgroup/cpuset/system.slice/docker-${CID}.scope/cpuset.cpus
0-3


コンテナを起動する。コンテナはCPU=0で動く設定。
[root@master1 ~]# docker run -it --rm --cpuset-cpus=0 --name test-con1 centos:centos7 bash
[root@923a81f60736 /]#

コンテナIDを取得する。
[root@master1 ~]# CID=$(docker ps -a --no-trunc=true |grep "test-con1" | awk '{print $1}')

コンテナIDを確認する。
[root@master1 ~]# echo $CID
923a81f60736846eaf10627fe8408173180e08163f285252f1cb5b6a52730608

コンテナが動作するCPUを確認する。CPU=0で動く設定であることがわかる。
[root@master1 ~]# cat /sys/fs/cgroup/cpuset/system.slice/docker-${CID}.scope/cpuset.cpus
0

3.10 コンテナが使うCPU割り当て時間指定する(--cpu--sharesオプション)

コンテナを3つ起動する。CPU割り当て時間を1024:1024:1024の割合で割り当てる。
[root@master1 ~]# docker run -it -d --name con0 --cpuset-cpus=0 --cpu-shares=1024  busybox dd if=/dev/zero of=/dev/null
b0d0b5c19b2504066b5b78c908fc5e7bb2cba44efacb3c334dd093986f354956
[root@master1 ~]# docker run -it -d --name con1 --cpuset-cpus=0 --cpu-shares=1024  busybox dd if=/dev/zero of=/dev/null
d61db7e92a491934a80168580b2a6f3fa2941ce3984b822e8b65916a1e7f602a
[root@master1 ~]# docker run -it -d --name con3 --cpuset-cpus=0 --cpu-shares=1024  busybox dd if=/dev/zero of=/dev/null
64d2d6c2dde6bd2ea4b3b1e98fa4a205290d3fcb024f4d0254b85a5f343c7c3b
[root@master1 ~]#

htopを起動する。
[root@master1 ~]# htop


CPU=0でddプロセスが3つ動いていることが確認できる。
その時の各プロセスのCPU使用率が33%前後になっている。

-------------------------------------------------------------------------
今度は--cpu-shares=128を指定する。
[root@master1 ~]# docker run -it -d --name con0 --cpuset-cpus=0 --cpu-shares=128  busybox dd if=/dev/zero of=/dev/null
96e2a54cdd306b39e04cdbd16e5b9a013e8109197c6f9966aedba6dd6620286f
[root@master1 ~]# docker run -it -d --name con1 --cpuset-cpus=0 --cpu-shares=128  busybox dd if=/dev/zero of=/dev/null
ed1fbce1deb59563ca327a740bb7ef02bb665d6dc7c432539bdfc2c2feef8c48
[root@master1 ~]# docker run -it -d --name con2 --cpuset-cpus=0 --cpu-shares=128  busybox dd if=/dev/zero of=/dev/null
591136e723f0ff2371ae127721924423fc2337b7d856240d1578ab715d7b5752
[root@master1 ~]#

htopを起動する。
[root@master1 ~]# htop

CPU=0でddプロセスが3つ動いていることが確認できる。
--cpu-shares=128と指定した場合でも、各プロセスのCPU使用率が33%前後になっている。



-------------------------------------------------------------------------
今度は、--cpu-sharesを128:128:256に指定する。
[root@master1 ~]# docker run -it -d --name con1 --cpuset-cpus=0 --cpu-shares=128  busybox dd if=/dev/zero of=/dev/null
f1e0c7a0ebfb51502eab81f9d4138f290d8edfffce466c15dc02395e935a5a61
[root@master1 ~]# docker run -it -d --name con2 --cpuset-cpus=0 --cpu-shares=128  busybox dd if=/dev/zero of=/dev/null
f0515a66cb18af7f88affa944567b557fc5ebaf5b8a23e7909de1b44e485f33d
[root@master1 ~]# docker run -it -d --name con3 --cpuset-cpus=0 --cpu-shares=256  busybox dd if=/dev/zero of=/dev/null
bf35847b04244840d2fdc69107bc37366b612269a6cb090a481dc12c1662aa19

htopを起動する。
[root@master1 ~]# htop

CPU=0でddプロセスが3つ動いていることが確認できる。
CPU使用率を確認すると、con1:con2:con3が1:1:2の割合になった。

3.11 コンテナが出力するログをsyslogやjournaldに出力する(--log-driverオプション)


-----------------------------------------------------------
1. コンテナ単位で有効にする方法
-----------------------------------------------------------
[root@master1 ~]# docker pull centos:centos7
[root@master1 ~]# docker run --log-driver=syslog centos:centos7 echo 'bbbbbbbbbb'

[root@master1 ~]# grep bbbbbbbbbb /var/log/messages
-中略-
Nov 20 22:23:47 master1 docker-current/978df20ce856[1037]: bbbbbbbbbb


毎回起動時にパラメータを指定するのは面倒なので、設定ファイルにsyslogへのログ出力を指定する。
[root@master1 ~]# vi /etc/sysconfig/docker
-中略-
DOCKER_OPTS="--log-driver syslog"

[root@master1 ~]# systemctl restart docker
[root@master1 ~]# docker run centos:centos7 echo 'cccccccccc'
cccccccccc

[root@master1 ~]# grep cccccccccc /var/log/messages
Nov 20 22:27:47 master1 journal: cccccccccc


-----------------------------------------------------------
2. 全てのコンテナで有効にする
-----------------------------------------------------------
[root@master1 ~]# vi /etc/sysconfig/docker
DOCKER_OPTS="--log driver syslog"

[root@master1 ~]# systemctl restart docker

3.12 コンテナが使うメモリ量に制限をかける(-mオプション)

コンテナが使うメモリ量を256Mに制限する。
[root@master1 ~]# docker run -it -m 256m --name memload centos:centos7 bash
[root@f020e33fb040 /]#

下記コマンドを実行する。
[root@af2e80e36842 /]# /dev/null < $(yes)

htopを起動する。
[root@master1 ~]# htop

メモリが256M近くまで消費するのを繰り返したあと、bashがkillされる。
[root@f020e33fb040 /]# /dev/null < $(yes)
Killed

3.13 コンテナが使うfd(ファイルディスクリプタ)数に制限をかける(--ulimitオプションを使う)

オプションを指定せず、コンテナを起動する。
[root@master1 test2]# docker run -it --rm centos:centos7 bash

デフォルトのfd数は1048576であることがわかる。
[root@290563aa925e /]# ulimit -n
1048576

コンテナを起動する。fd数が512に制限されていることがわかる。
[root@master1 test2]# docker run -it --rm --ulimit="nofile=512" centos:centos7 bash
[root@master1 test2]# docker run -it --rm --ulimit="nofile=512" centos:centos7 bash
[root@2621ef057b15 /]# ulimit -n
512

コンテナを起動する。fd数が1024に制限されていることがわかる。
[root@master1 test2]# docker run -it --rm --ulimit="nofile=1024" centos:centos7 bash
[root@38c6f57b1af8 /]# ulimit -n
1024

3.14 コンテナのイメージを削除するスクリプト

これから作成するスクリプト(rmcon)が存在しないことを確認する。
[root@master1 ~]# which rmcon
/usr/bin/which: no rmcon in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)

[root@master1 ~]# touch /usr/local/bin/rmcon
[root@master1 ~]# chmod 744 /usr/local/bin/rmcon
[root@master1 ~]# vi /usr/local/bin/rmcon
[root@master1 ~]# cat /usr/local/bin/rmcon
#!/usr/bin/bash
docker rm $(docker ps -qa)


[root@master1 ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
54851f2549eb        nginx               "nginx -g 'daemon off"   14 seconds ago      Exited (0) 10 seconds ago                       test

自作スクリプトを実行する。イメージが削除できたことがわかる。
[root@master1 ~]# rmcon
54851f2549eb
[root@master1 ~]#

3.15 dockerブリッジを流れるパケットを見る。

コンテナ起動前のDNAT定義を確認する。ポート番号11111,22222宛は定義されていない。
[root@master1 ~]# iptables -L -t nat -n |grep -e 11111 -e 22222
[root@master1 ~]#


80番ポートで待つコンテナを2つ起動する。それぞれのホスト側ポート番号は11111,22222
[root@master1 ~]# docker run -d --name nginx1 -p 11111:80 nginx
[root@master1 ~]# docker run -d --name nginx2 -p 22222:80 nginx


コンテナを起動すると、DNATの定義は以下のようになる。
[root@master1 ~]# iptables -L -t nat -n |grep -e 11111 -e 22222
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:11111 to:172.17.0.2:80
DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22222 to:172.17.0.3:80



コンテナを起動したときのホスト内のネットワークは以下のようになる。

  +--- nginx1 ---+   +--- nginx2 ---+
  |    port=80   |   |    port=80   |
  |              |   |              |
  +---- eth0 ----+   +---- eth0 ----+
      172.17.0.2        172.17.0.3
          |  A               |   A
          |  |               |   |
  +-------+--|---------------+---|--+
  |          |  docker0(Bridge)  |  | <=== tcpdump -i docker0 tcp port 80 -nn
  +----------|-------+-----------|--+
             |       |           |
             |       |           |
 [after]     |       |           | [after]
   DstIP=172.17.0.2  |           |   DstIP=172.17.0.3
   DstPort=80        |           |   DstPort=80
             |       |           |
 +-------------------------- DNAT -----------------------------------------------+
 |  [root@master1 ~]# iptables -L -t nat -n |grep -e 11111 -e 22222              |
 |  DNAT   tcp  --  0.0.0.0/0      0.0.0.0/0     tcp dpt:11111 to:172.17.0.2:80  |
 |  DNAT   tcp  --  0.0.0.0/0      0.0.0.0/0     tcp dpt:22222 to:172.17.0.3:80  |
 +-------------------------------------------------------------------------------+
                     |
            eth0(192.168.0.10/24)
              A                A
              |                |
              |                |
  [before]    |                | [before]
     DstIP=192.168.0.10        |   DstIP=192.168.0.10
     DstPort=11111             |   DstPort=22222


tcpdumpを起動する。
[root@master1 ~]# tcpdump -i docker0 tcp port 80 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on docker0, link-type EN10MB (Ethernet), capture size 65535 bytes


別のターミナルでNginxにcurlコマンドでアクセスする。
[root@master1 ~]# curl http://192.168.0.10:11111
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

この時、tcpdumpで採取したパケットは以下のとおり。TCPコネクション確立時のみ抜粋
21:12:08.660096 IP 192.168.0.10.57391 > 172.17.0.2.80: Flags [S], seq 1382156843, win 43690, options [mss 65495,sackOK,TS val 5452241 ecr 0,nop,wscale 7], length 0
21:12:08.660252 IP 172.17.0.2.80 > 192.168.0.10.57391: Flags [S.], seq 3030911224, ack 1382156844, win 14480, options [mss 1460,sackOK,TS val 5452241 ecr 5452241,nop,wscale 7], length 0
21:12:08.660301 IP 192.168.0.10.57391 > 172.17.0.2.80: Flags [.], ack 1, win 342, options [nop,nop,TS val 5452241 ecr 5452241], length 0


次に宛先ポート番号を22222に変更してコンテナにアクセスする。
[root@master1 ~]# curl http://192.168.0.10:22222
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

宛先TCPポート番号が22222のときのtcpdumpで採取したパケット
21:14:13.673223 IP 192.168.0.10.42175 > 172.17.0.3.80: Flags [S], seq 2685052290, win 43690, options [mss 65495,sackOK,TS val 5577254 ecr 0,nop,wscale 7], length 0
21:14:13.673333 IP 172.17.0.3.80 > 192.168.0.10.42175: Flags [S.], seq 1261474781, ack 2685052291, win 14480, options [mss 1460,sackOK,TS val 5577254 ecr 5577254,nop,wscale 7], length 0
21:14:13.673375 IP 192.168.0.10.42175 > 172.17.0.3.80: Flags [.], ack 1, win 342, options [nop,nop,TS val 5577255 ecr 5577254], length 0


3.16 Dockerクライアント <=> Dockerサーバ間のUNIX domainソケットを流れるパケットを見る。

Dockerクライアントとサーバの間にproxyを作成する。
[root@master1 ~]# socat -v UNIX-LISTEN:/tmp/dockerapi.sock UNIX-CONNECT:/var/run/docker.sock&
[1] 9449


Dockerサーバにアクセスする.HTTPリクエストとレスポンスが観測できる。
[root@master1 ~]# docker -H unix:///tmp/dockerapi.sock ps -a
> 2016/11/21 21:37:09.017349  length=95 from=0 to=94           ======> HTTPリクエストの開始
GET /v1.22/containers/json?all=1 HTTP/1.1\r
Host: \r
User-Agent: Docker-Client/1.10.3 (linux)\r
\r
< 2016/11/21 21:37:09.019849  length=141 from=0 to=140          ========> HTTPレスポンスの開始
HTTP/1.1 200 OK\r
Content-Type: application/json\r
Server: Docker/1.10.3 (linux)\r
Date: Mon, 21 Nov 2016 12:37:09 GMT\r
Content-Length: 3\r
\r
[]
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@master1 ~]#




socatの使い方
[root@master1 ~]# socat tcp-listen:11111 stdout

別のターミナルで以下のように実行する。
[root@master1 ~]# socat tcp-connect:localhost:11111 stdin
test

もう一方のターミナル
[root@master1 ~]# socat tcp-listen:11111 stdout
test

3.17 コンテナのMACアドレスとIPアドレスを確認する方法(docker network inspect bridge)

コンテナを3つ起動する。
[root@master1 ~]# docker run -d --name nginx1 nginx
4b93774b8e7ac70ba0f70f5ead741e3a82a10a19cf4a940ca9cb6c4ca16b6329
[root@master1 ~]# docker run -d --name nginx2 nginx
2f12861523f1f019d89a4dec32233c09eccad44e0a792b12a9a5e19eb857014d
[root@master1 ~]# docker run -d --name nginx3 nginx
f8d753a23cbcd71810d8c04d411b3a71d9908211bbeb3244cc510e21e2170e2e
[root@master1 ~]#


docker network inspect bridgeを実行する。コンテナがどんなIP/MACアドレスをもっているのかわかる。
[root@master1 ~]# docker network inspect bridge
[
-中略-
        "Containers": {
            "2f12861523f1f019d89a4dec32233c09eccad44e0a792b12a9a5e19eb857014d": {
                "Name": "nginx2",
                "EndpointID": "53001e97e15fd900134f01884b208277796ead9795ab78c6d03631829429b6ed",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "4b93774b8e7ac70ba0f70f5ead741e3a82a10a19cf4a940ca9cb6c4ca16b6329": {
                "Name": "nginx1",
                "EndpointID": "4f3b361b89607f78f15f3cacbbcc76e261bc75c7093ad32f32bc2e6c15135ea9",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            },
            "f8d753a23cbcd71810d8c04d411b3a71d9908211bbeb3244cc510e21e2170e2e": {
                "Name": "nginx3",
                "EndpointID": "bd49d3847cf5372376bcf12a93414dc7eb432ad23352639c5515ea25acbc33b9",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            }
以下、略

3.18 コンテナが使用するディスクサイズ(dm.basesize)を変更する

コンテナを起動する。
[root@master3 ~]# docker run -it --name centos centos:centos7 bash

ルートパーティションのサイズを確認する。10G(★印)であることがわかる。
[root@144e5f96041b /]# df -h
Filesystem                                                                                         Size  Used Avail Use% Mounted on
/dev/mapper/docker-8:3-202336481-871f24af84360d9307d0015d201d28088fdbe73c6684110afb2c4fdffa13d81a ★10G  240M  9.8G   3% /
tmpfs                                                                                              490M     0  490M   0% /dev
tmpfs                                                                                              490M     0  490M   0% /sys/fs/cgroup
/dev/sda3                                                                                           40G  1.7G   38G   5% /etc/hosts
shm                                                                                                 64M     0   64M   0% /dev/shm
[root@144e5f96041b /]# exit
exit

docker infoコマンドでも確認してみる。10.74 GBであることが確認できる。
[root@master3 ~]# docker info |grep "Base Device Size:"
 Base Device Size: 10.74 GB


ディスクサイズを10G->20Gに変更する。
[root@master3 ~]# vi /etc/sysconfig/docker-storage
DOCKER_STORAGE_OPTIONS=--storage-opt dm.basesize=20G

Dockerを停止する。停止しないと、/var/lib/docker配下が削除できない。
[root@master3 ~]# systemctl stop docker

/var/lib/docker配下を削除する。今まで作成したイメージが全て消去されるので注意!!!
[root@master3 ~]# rm -f -r /var/lib/docker/

Dockerを再起動する。
[root@master3 ~]# systemctl start docker

コンテナを起動する。/var/lib/docker配下を削除したので、再度、イメージのダウンロードが始まる。
[root@master3 ~]# docker run -it --name centos centos:centos7 bash
Unable to find image 'centos:centos7' locally
Trying to pull repository docker.io/library/centos ...
centos7: Pulling from docker.io/library/centos
08d48e6f1cff: Pull complete
Digest: sha256:b2f9d1c0ff5f87a4743104d099a3d561002ac500db1b9bfa02a783a46e0d366c
Status: Downloaded newer image for docker.io/centos:centos7


ディスクサイズを確認する。20G(★印)になっていることが確認できる。
[root@13f57f8cd4fb /]# df -h
Filesystem                                                                                         Size  Used Avail Use% Mounted on
/dev/mapper/docker-8:3-135722635-214924edf11302e77f89a1d577930cd48168d4d4987cd175cb67f6d937d21aa9 ★20G  240M   20G   2% /
tmpfs                                                                                              490M     0  490M   0% /dev
tmpfs                                                                                              490M     0  490M   0% /sys/fs/cgroup
/dev/sda3                                                                                           40G  1.7G   38G   5% /etc/hosts
shm                                                                                                 64M     0   64M   0% /dev/shm
[root@13f57f8cd4fb /]# exit
exit

docker infoコマンドでも確認してみる。21.47 GBであることが確認できる。
[root@master3 ~]# docker info |grep "Base Device Size:"
 Base Device Size: 21.47 GB

-------------------------------------------------------------------------------------------
0.  truncateコマンドの使い方。知らなかったのでメモ
-------------------------------------------------------------------------------------------
1Kサイズのファイル作成
[root@master1 ~]# truncate --size 1K /root/file_1K
[root@master1 ~]# ls -la file_1K
-rw-r--r--. 1 root root 1024 11月 23 09:02 file_1K

1Mサイズのファイル作成
[root@master1 ~]# truncate --size 1M /root/file_1M
[root@master1 ~]# ls -la file_1M
-rw-r--r--. 1 root root 1048576 11月 23 09:02 file_1M

1Gサイズのファイル作成
[root@master1 ~]# truncate --size 1G /root/file_1G
[root@master1 ~]# ls -la file_1G
-rw-r--r--. 1 root root 1073741824 11月 23 09:02 file_1G


ちなみに、どのファイルも実際にディスク領域は消費していない。
[root@master1 ~]# du file_1K
0       file_1K
[root@master1 ~]# du file_1M
0       file_1M
[root@master1 ~]# du file_1G
0       file_1G



-------------------------------------------------------------------------------------------
1. ルートパーティションのサイズ(10G)より小さなサイズ(500M)のファイルは作成できることを確認する。
-------------------------------------------------------------------------------------------
[root@master3 ~]# vi Dockerfile
[root@master3 ~]# docker build -t small .
Sending build context to Docker daemon 24.06 kB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : RUN truncate --size 500M /root/file
 ---> Running in 72309990b267
 ---> d9e74f07cb1a
Removing intermediate container 72309990b267
Successfully built d9e74f07cb1a

コンテナを起動する。
[root@master3 ~]# docker run -it --rm samll bash

ルートパーティションのサイズを確認する。サイズは10G(★印)であることがわかる。
[root@4a6240b311cb /]# df -h
Filesystem                                                                                         Size  Used Avail Use% Mounted on
/dev/mapper/docker-8:3-135722635-c8ee47480aa38ff8849f715f2d93d4ece493b25a3adde1bb72b783841bfae129 ★10G  740M  9.3G   8% /
tmpfs                                                                                              490M     0  490M   0% /dev
tmpfs                                                                                              490M     0  490M   0% /sys/fs/cgroup
/dev/sda3                                                                                           40G  3.2G   37G   9% /etc/hosts
shm                                                                                                 64M     0   64M   0% /dev/shm
[root@4a6240b311cb /]# exit
exit

ファイルサイズを確認する。500Mのファイルを作成することができた。
[root@2d0e98bd08bd /]# ls -la /root/file
-rw-r--r--. 1 root root 524288000 Nov 22 13:14 /root/file



-------------------------------------------------------------------------------------------
2. ルートパーティションのサイズ(10G)より大きなファイル(11G)を作成して、エラーが発生することを確認する。
-------------------------------------------------------------------------------------------
今度は11Gのファイルを作成するDockerfileを作成する。
[root@master3 ~]# vi Dockerfile
[root@master3 ~]# cat Dockerfile
FROM centos:centos7
RUN truncate --size 11G /root/file

ルートパーティションのサイズ(10G)より大きなファイル(11G)を作成することはできない。
[root@master3 ~]# docker build --no-cache -t big .
Sending build context to Docker daemon 24.06 kB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : RUN truncate --size 11G /root/file
 ---> Running in 40ebcbd0670c
ApplyLayer exit status 1 stdout:  stderr: write /root/file: no space left on device
[root@master3 ~]#


-------------------------------------------------------------------------------------------
3. 実際にどこが消費されるか確認してみる。
-------------------------------------------------------------------------------------------
[root@e2f80a45bad0 /]# df -h
Filesystem                                                                                      Size  Used Avail Use% Mounted on
/dev/mapper/docker-8:3-713942-3c889cab414769b972f8b76f02a67365ffbbf868f10737e29bd959ff761ac7bc   10G  240M★9.8G   3% /
tmpfs                                                                                           490M     0  490M   0% /dev
tmpfs                                                                                           490M     0  490M   0% /sys/fs/cgroup
/dev/sda3                                                                                        40G  5.0G   35G  13% /etc/hosts
shm                                                                                              64M     0   64M   0% /dev/shm

1Gのファイルを作成する。
[root@e2f80a45bad0 /]# dd if=/dev/zero of=test.txt bs=1024k count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 90.7417 s, 11.8 MB/s

/dev/mapper配下が使われたことがわかる。
[root@e2f80a45bad0 /]# df -h
Filesystem                                                                                      Size  Used Avail Use% Mounted on
/dev/mapper/docker-8:3-713942-3c889cab414769b972f8b76f02a67365ffbbf868f10737e29bd959ff761ac7bc   10G  1.3G★8.8G  13% /
tmpfs                                                                                           490M     0  490M   0% /dev
tmpfs                                                                                           490M     0  490M   0% /sys/fs/cgroup
/dev/sda3                                                                                        40G  6.0G   34G  16% /etc/hosts
shm                                                                                              64M     0   64M   0% /dev/shm



3.19 コンテナのプロセスをstraceでデバッグする方法(nsenter)

nginxのコンテナには、straceコマンドが入っていない。
yumコマンドも入っていないので、そもそも、straceをダウンロードすることができない。
たとえば、コンテナのNginxをデバッグするとき、どのようにしたら良いか?
そのような場合、nsenterを使うことで解決できる。

Nginxコンテナでstrace,yumコマンドを実行する。コンテナにstraceは入っていないことがわかる。
[root@master1 ~]# docker run -it --rm nginx bash
root@a42cfaf8c6f8:/# strace
bash: strace: command not found
root@a42cfaf8c6f8:/# yum
bash: yum: command not found
root@a42cfaf8c6f8:/#


ホストにnsenterをインストールする。
[root@master1 ~]# docker run -v /usr/local/bin:/target --privileged jpetazzo/nsenter
Unable to find image 'jpetazzo/nsenter:latest' locally
Trying to pull repository docker.io/jpetazzo/nsenter ...
latest: Pulling from docker.io/jpetazzo/nsenter
5c90d4a2d1a8: Downloading [===============>                                   ] 15.73 MB/51.35 MB
-中略-

Digest: sha256:a30e7da907a9abb715027677c21468005beee06251b7737c86f84fa148d572b0
Status: Downloaded newer image for docker.io/jpetazzo/nsenter:latest
Installing nsenter to /target
Installing docker-enter to /target
Installing importenv to /target

ダウンロードしたnsenterのイメージを確認する。
[root@master1 ~]# docker images |grep nsenter
docker.io/jpetazzo/nsenter                            latest                             c16fe938c1a5        4 months ago        370.8 MB

nsenterコマンドは、以下のパスにインストールされる。
[root@master1 ~]# ls /usr/local/bin/nsenter
/usr/local/bin/nsenter


Nginxコンテナを起動する。ホスト側ポート番号11111,コンテナ側ポート番号80で起動する。
[root@master1 ~]# CID=$(docker run -d --name test -p 11111:80 nginx)
[root@master1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
900ae34b590a        nginx               "nginx -g 'daemon off"   13 seconds ago      Up 11 seconds       443/tcp, 0.0.0.0:11111->80/tcp   test
[root@master1 ~]# echo $CID
900ae34b590a567ad396f6a02015d545b82a75608f660d5275f9a96914acc667

[root@master1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)
[root@master1 ~]# echo $PID
15780

nsenterを起動して、Nginxコンテナに接続する。
[root@master1 ~]# nsenter --target $PID --uts --ipc --net /bin/bash

straceを実行するため、NginxのPIDを調べる。
[root@900ae34b590a ~]# ps aux|grep nginx
root      15780  0.4  0.2  31752  2868 ?        Ss   11:17   0:00 nginx: master process nginx -g daemon off;
104       15796  0.0  0.1  32144  1664 ?        S    11:17   0:00 nginx: worker process
root      15875  0.0  0.0 112656   972 pts/0    S+   11:18   0:00 grep --color=auto nginx

Nginxのプロセスに対して、straceを実行する。epollでイベント待ち。
[root@900ae34b590a ~]# strace -ttT -f -p 15796
Process 15796 attached
11:18:48.761204 epoll_wait(8, {{EPOLLIN, {u32=1517506576, u64=140502782660624}}}, 512, -1) = 1 <4.638268>


このとき、別ターミナルよりcurlコマンドでNginxにアクセスする。
[root@master1 ~]#
[root@master1 ~]# curl http://localhost:11111
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

Nginxのイベント待ちが解除される。
[root@900ae34b590a ~]# strace -ttT -f -p 15796
11:18:48.761204 epoll_wait(8, {{EPOLLIN, {u32=1517506576, u64=140502782660624}}}, 512, -1) = 1 <4.638268> ★イベント待ちでブロック

curlコマンドで80番ポートにアクセスすると、Nginxのブロックが解除され、以下のトレースが表示された。
11:18:53.399994 accept4(6, {sa_family=AF_INET, sin_port=htons(44234), sin_addr=inet_addr("172.17.0.1")}, [16], SOCK_NONBLOCK) = 3 <0.000048>
11:18:53.400279 epoll_ctl(8, EPOLL_CTL_ADD, 3, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=1517507056, u64=140502782661104}}) = 0 <0.000033>
11:18:53.400514 epoll_wait(8, {{EPOLLIN, {u32=1517507056, u64=140502782661104}}}, 512, 60000) = 1 <0.000033>
11:18:53.400742 recvfrom(3, "GET / HTTP/1.1\r\nUser-Agent: curl"..., 1024, 0, NULL, NULL) = 79 <0.000039>
11:18:53.401093 stat("/usr/share/nginx/html/index.html", {st_mode=S_IFREG|0644, st_size=612, ...}) = 0 <0.013186>
11:18:53.414573 open("/usr/share/nginx/html/index.html", O_RDONLY|O_NONBLOCK) = 11 <0.000241>
11:18:53.419455 fstat(11, {st_mode=S_IFREG|0644, st_size=612, ...}) = 0 <0.000029>
11:18:53.419783 writev(3, [{"HTTP/1.1 200 OK\r\nServer: nginx/1"..., 238}], 1) = 238 <0.000212>
11:18:53.420595 sendfile(3, 11, [0], 612) = 612 <0.000958>
11:18:53.421907 write(5, "172.17.0.1 - - [23/Nov/2016:02:1"..., 91) = 91 <0.002888>
11:18:53.424934 close(11)               = 0 <0.000082>
11:18:53.425137 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0 <0.000038>
11:18:53.425293 epoll_wait(8, {{EPOLLIN|EPOLLRDHUP, {u32=1517507056, u64=140502782661104}}}, 512, 65000) = 1 <0.009390>
11:18:53.434845 recvfrom(3, "", 1024, 0, NULL, NULL) = 0 <0.000039>
11:18:53.434999 close(3)                = 0 <0.000194>
11:18:53.435281 epoll_wait(8,   ★ここで、またイベント待ちでブロックする。

3.20 コンテナが出力するログを確認する。(docker logs)

-------------------------------------------------------------
1. ログ末尾(-fオプション)や時刻表示(-tオプション)のログを出力する.
-------------------------------------------------------------

コンテナを起動する。
[root@master1 ~]# docker run -itd -p 11111:80 --name test-con nginx
c21e8fd203992631946deb0e9eb91c6cc34eceb5cb57b56e9071a5e74867fe18
[root@master1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
c21e8fd20399        nginx               "nginx -g 'daemon off"   4 seconds ago       Up 1 seconds        443/tcp, 0.0.0.0:11111->80/tcp   test-con


別のターミナルから、Nginxコンテナにアクセスする。
[root@master1 ~]# curl http://localhost:11111

Nginxが出力するログを確認する。-fはログの末尾を表示する。-tは時刻を表示するオプション
[root@master1 ~]# docker logs -ft test-con
2016-11-23T07:43:51.860181000Z 172.17.0.1 - - [23/Nov/2016:07:43:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
2016-11-23T07:44:12.619368000Z 172.17.0.1 - - [23/Nov/2016:07:44:12 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
2016-11-23T07:44:14.394863000Z 172.17.0.1 - - [23/Nov/2016:07:44:14 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"

-------------------------------------------------------------
2. ある時刻以降のログだけを出力する。(--sinceオプション)
-------------------------------------------------------------
全てのログを表示する。
[root@master1 ~]# docker logs -t test-con
2016-11-23T07:43:51.860181000Z 172.17.0.1 - - [23/Nov/2016:07:43:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
2016-11-23T07:44:12.619368000Z 172.17.0.1 - - [23/Nov/2016:07:44:12 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
2016-11-23T07:44:14.394863000Z 172.17.0.1 - - [23/Nov/2016:07:44:14 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
2016-11-23T07:44:23.147067000Z 172.17.0.1 - - [23/Nov/2016:07:44:23 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
2016-11-23T07:44:29.820801000Z 172.17.0.1 - - [23/Nov/2016:07:44:29 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
2016-11-23T07:54:26.968246000Z 172.17.0.1 - - [23/Nov/2016:07:54:26 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
★
2016-11-23T07:54:28.472748000Z 172.17.0.1 - - [23/Nov/2016:07:54:28 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
2016-11-23T07:54:29.249195000Z 172.17.0.1 - - [23/Nov/2016:07:54:29 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
2016-11-23T07:57:23.897494000Z 172.17.0.1 - - [23/Nov/2016:07:57:23 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"

たとえば、★以降のログだけを表示するには、--sinceオプションを使う。
[root@master1 ~]# docker logs --since 2016-11-23T07:54:28.472748000Z test-con
172.17.0.1 - - [23/Nov/2016:07:54:28 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
172.17.0.1 - - [23/Nov/2016:07:54:29 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
172.17.0.1 - - [23/Nov/2016:07:57:23 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"

正確な時刻を指定しなくても、07:54:28.000000000Z のように指定することもできる。
[root@master1 ~]# docker logs --since 2016-11-23T07:54:28.000000000Z test-con
172.17.0.1 - - [23/Nov/2016:07:54:28 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
172.17.0.1 - - [23/Nov/2016:07:54:29 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
172.17.0.1 - - [23/Nov/2016:07:57:23 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
[root@master1 ~]#

他に以下のような省略した場合でも、期待通りのログを表示できた。".0Z"
[root@master1 ~]# docker logs --since 2016-11-23T07:54:28.0Z test-con
172.17.0.1 - - [23/Nov/2016:07:54:28 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
172.17.0.1 - - [23/Nov/2016:07:54:29 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
172.17.0.1 - - [23/Nov/2016:07:57:23 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"

".00Z"
[root@master1 ~]# docker logs --since 2016-11-23T07:54:28.00Z test-con
172.17.0.1 - - [23/Nov/2016:07:54:28 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
172.17.0.1 - - [23/Nov/2016:07:54:29 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
172.17.0.1 - - [23/Nov/2016:07:57:23 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"

3.21 コンテナの状態をtarファイルに保存したり、tarファイルからイメージを取り出す(export/import)

---------------------------------------------------------------------
1. コンテナイメージをファイルに書き出す(export)
---------------------------------------------------------------------
コンテナを起動する。
[root@master1 test]# docker run -it --name test-con centos:centos7 bash

コンテナ内でファイルを作成する。
[root@7066811e42e1 /]# touch test.txt
[root@7066811e42e1 /]# echo "This is container" > test.txt
[root@7066811e42e1 /]# cat test.txt
This is container

Ctrlキーを押下しながら、PキーとQキーを押下して、コンテナから抜ける。
[root@7066811e42e1 /]# 

コンテナの状態を確認する。
[root@master1 test]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
7066811e42e1        centos:centos7      "bash"              28 seconds ago      Up 25 seconds                           test-con

コンテナを停止する。停止してから、コンテナイメージをファイルに書き出す。
[root@master1 test]# docker stop test-con
test-con

コンテナのファイルシステムをファイルに書き出す。
[root@master1 test]# docker export test-con > test-img.tar

ファイルを確認する。
[root@master1 test]# file test-img.tar
test-img.tar: POSIX tar archive

コンテナで作成したファイルを取り出す。
[root@master1 test]# tar xvf test-img.tar test.txt
test.txt

ファイルの中身を確認する。
[root@master1 test]# cat test.txt
This is container


---------------------------------------------------------------------
2. ファイルからコンテナイメージを取りだす(import)
---------------------------------------------------------------------
[root@master1 test]# ls
test-img.tar

ファイルからコンテナイメージを取り出す。
[root@master1 test]# cat test-img.tar | docker import - test-img:ver2
sha256:37a6835802e35b05a3e095705774f4002a0e5a1799cb569d30e57dc310174ac8

取り出したイメージを確認する。
[root@master1 test]# docker images
REPOSITORY                                            TAG                                IMAGE ID            CREATED             SIZE
test-img                                              ver2                               37a6835802e3        28 seconds ago      196.5 MB
以下、略

登録したイメージからコンテナを起動する。
[root@master1 test]# docker run -it --rm test-img:ver2 bash

[root@5e12df260b97 /]# ls
anaconda-post.log  bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  test.txt  tmp  usr  var

作成したファイルの中身を確認する。
[root@5e12df260b97 /]# cat test.txt
This is container

3.22 イメージをtarファイルに保存したり、tarファイルからイメージを取り出す(save/load)

3.22.1 基本的な使い方

------------------------------------------------------
0. 全体像
------------------------------------------------------
master1,master2は仮想マシン(CentOS7.2)です。
 (1) イメージをtarに保存(save)
 (2) tarをscpで転送(master1->master2)
 (3) tarからイメージを取り出す(load)

    master1   ----------------------- master2

     <save>   ------- (scp) -------->  <load>

------------------------------------------------------
1. master1の操作
------------------------------------------------------
tarファイルに保存するイメージを確認する
[root@master1 test2]# docker images |grep busybox
docker.io/busybox                                     latest                             e02e811dd08f        7 weeks ago         1.093 MB

イメージをtarに保存する。
[root@master1 test2]# docker save busybox > busybox_ver1.tar
[root@master1 test2]# ls
busybox_ver1.tar

tarファイルを別ホスト(master2)に転送する。
[root@master1 test2]# scp busybox_ver1.tar root@master2:/root/test

------------------------------------------------------
2. master2の操作
------------------------------------------------------
master1から転送したファイルを確認する。
[root@master2 test]# ls
busybox_ver1.tar

tarファイルからイメージを復元する。
[root@master2 test]# docker load -i busybox_ver1.tar
[root@master2 test]# docker images |grep busybox
docker.io/busybox                                     latest                             e02e811dd08f        7 weeks ago         1.093 MB

コンテナにログインする
[root@master2 test]# docker run -it busybox sh
/ # exit

3.22.2 登録済イメージをtarファイルに変換

登録済イメージを確認する。
[root@master1 ~]# docker images |grep skydns
gcr.io/google_containers/skydns                       2015-03-11-001      d808d12f05f0        22 months ago       8.811 MB

イメージをtarファイルに保存する。
[root@master1 ~]# docker save gcr.io/google_containers/skydns:2015-03-11-001 > skydns.tar
[root@master1 ~]# ls skydns.tar
skydns.tar

登録済みイメージを削除する。
[root@master1 ~]# docker rmi d808d12f05f0
Untagged: gcr.io/google_containers/skydns:2015-03-11-001
Deleted: sha256:d808d12f05f04a0f99443d803c49ac557540f0453de1599d07c0b761ddf89625
Deleted: sha256:81a0d366188e44745f6c5ef56f7509002b96886c662697c9dbb8faf0878e8ffa
Deleted: sha256:327cc3abb2d292aca8af2e4342914d4239e22c45d49b4b2eea53435d471c47a7

イメージが削除できたかどうかを確認する。削除できた。
[root@master1 ~]# docker images |grep skydns
[root@master1 ~]#

イメージをロードする。
[root@master1 ~]# docker load -i skydns.tar

イメージが登録できたかどうかを確認する。
[root@master1 ~]# docker images |grep skydns
gcr.io/google_containers/skydns                       2015-03-11-001      d808d12f05f0        22 months ago       8.811 MB
[root@master1 ~]#


ちなみに、tarファイルの中身を見てみる。
[root@master1 ~]# tar tvf skydns.tar
drwxr-xr-x 0/0               0 2015-03-11 14:51 0db03cc7860ce2e801eb4f0ce4b84943cec176fcdf6db56fc37b7cf9490b7354/
-rw-r--r-- 0/0               3 2015-03-11 14:51 0db03cc7860ce2e801eb4f0ce4b84943cec176fcdf6db56fc37b7cf9490b7354/VERSION
-rw-r--r-- 0/0            1220 2015-03-11 14:51 0db03cc7860ce2e801eb4f0ce4b84943cec176fcdf6db56fc37b7cf9490b7354/json
-rw-r--r-- 0/0            1024 2015-03-11 14:51 0db03cc7860ce2e801eb4f0ce4b84943cec176fcdf6db56fc37b7cf9490b7354/layer.tar
drwxr-xr-x 0/0               0 2015-03-11 14:51 768d4f50f65f00831244703e57f64134771289e3de919a576441c9140e037ea2/
-rw-r--r-- 0/0               3 2015-03-11 14:51 768d4f50f65f00831244703e57f64134771289e3de919a576441c9140e037ea2/VERSION
-rw-r--r-- 0/0             388 2015-03-11 14:51 768d4f50f65f00831244703e57f64134771289e3de919a576441c9140e037ea2/json
-rw-r--r-- 0/0            1024 2015-03-11 14:51 768d4f50f65f00831244703e57f64134771289e3de919a576441c9140e037ea2/layer.tar
drwxr-xr-x 0/0               0 2015-03-11 14:51 8189e88be4567d5094319a378e339a729c56a4cfb1e4514ff1dfdb5338a9ba20/
-rw-r--r-- 0/0               3 2015-03-11 14:51 8189e88be4567d5094319a378e339a729c56a4cfb1e4514ff1dfdb5338a9ba20/VERSION
-rw-r--r-- 0/0             464 2015-03-11 14:51 8189e88be4567d5094319a378e339a729c56a4cfb1e4514ff1dfdb5338a9ba20/json
-rw-r--r-- 0/0         6382592 2015-03-11 14:51 8189e88be4567d5094319a378e339a729c56a4cfb1e4514ff1dfdb5338a9ba20/layer.tar
drwxr-xr-x 0/0               0 2015-03-11 14:51 96c5134b442cd6446dfae4b1ae1de0aad4b0f408ccd0cf6126566a096da7a209/
-rw-r--r-- 0/0               3 2015-03-11 14:51 96c5134b442cd6446dfae4b1ae1de0aad4b0f408ccd0cf6126566a096da7a209/VERSION
-rw-r--r-- 0/0             464 2015-03-11 14:51 96c5134b442cd6446dfae4b1ae1de0aad4b0f408ccd0cf6126566a096da7a209/json
-rw-r--r-- 0/0         2643968 2015-03-11 14:51 96c5134b442cd6446dfae4b1ae1de0aad4b0f408ccd0cf6126566a096da7a209/layer.tar
drwxr-xr-x 0/0               0 2015-03-11 14:51 b3bbc4636fc59ec067f4a877899f2e008bf3e2fe55451ef78c090dd9709b3818/
-rw-r--r-- 0/0               3 2015-03-11 14:51 b3bbc4636fc59ec067f4a877899f2e008bf3e2fe55451ef78c090dd9709b3818/VERSION
-rw-r--r-- 0/0             464 2015-03-11 14:51 b3bbc4636fc59ec067f4a877899f2e008bf3e2fe55451ef78c090dd9709b3818/json
-rw-r--r-- 0/0            1024 2015-03-11 14:51 b3bbc4636fc59ec067f4a877899f2e008bf3e2fe55451ef78c090dd9709b3818/layer.tar
drwxr-xr-x 0/0               0 2015-03-11 14:51 b888703acbfd97fc1bce3fb2badfcf7f98da8cb6529af2be1a56ab82422a1504/
-rw-r--r-- 0/0               3 2015-03-11 14:51 b888703acbfd97fc1bce3fb2badfcf7f98da8cb6529af2be1a56ab82422a1504/VERSION
-rw-r--r-- 0/0             464 2015-03-11 14:51 b888703acbfd97fc1bce3fb2badfcf7f98da8cb6529af2be1a56ab82422a1504/json
-rw-r--r-- 0/0            1024 2015-03-11 14:51 b888703acbfd97fc1bce3fb2badfcf7f98da8cb6529af2be1a56ab82422a1504/layer.tar
-rw-r--r-- 0/0            2473 2015-03-11 14:51 d808d12f05f04a0f99443d803c49ac557540f0453de1599d07c0b761ddf89625.json
drwxr-xr-x 0/0               0 2015-03-11 14:51 f65db1fc72e498be5329bab6c2f9f5aa6bb4d4747644a984e53fd9dbb17db8bc/
-rw-r--r-- 0/0               3 2015-03-11 14:51 f65db1fc72e498be5329bab6c2f9f5aa6bb4d4747644a984e53fd9dbb17db8bc/VERSION
-rw-r--r-- 0/0             464 2015-03-11 14:51 f65db1fc72e498be5329bab6c2f9f5aa6bb4d4747644a984e53fd9dbb17db8bc/json
-rw-r--r-- 0/0            1024 2015-03-11 14:51 f65db1fc72e498be5329bab6c2f9f5aa6bb4d4747644a984e53fd9dbb17db8bc/layer.tar
-rw-r--r-- 0/0             697 1970-01-01 09:00 manifest.json
-rw-r--r-- 0/0             122 1970-01-01 09:00 repositories
[root@master1 ~]#

3.23 Nginxイメージのつくり方

[root@master1 ~]# mkdir nginx
[root@master1 ~]# cd nginx/

Dockerfileを編集する。
[root@master1 nginx]# vi Dockerfile
[root@master1 nginx]# cat Dockerfile
FROM centos:centos7
RUN yum -y install epel-release
RUN yum -y install nginx
ADD index.html /usr/share/nginx/html/
CMD /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
[root@master1 nginx]#

index.htmlファイルを編集する。
[root@master1 nginx]# vi index.html
[root@master1 nginx]# cat index.html
Hello hana_shin

[root@master1 nginx]# ls
Dockerfile  index.html

イメージをビルドする。
[root@master1 nginx]# docker build -t nginx-img:v1 --no-cache=true .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : RUN yum -y install epel-release
 ---> Running in e48a494481c1
Loaded plugins: fastestmirror, ovl
-以下、略


イメージを確認する。
[root@master1 nginx]# docker images
REPOSITORY                                            TAG                                IMAGE ID            CREATED             SIZE
nginx-img                                             v1                                 3df7144df03d        18 seconds ago      400.8 MB

コンテナを起動する。
[root@master1 nginx]# docker run -d -p 11111:80 nginx-img:v1
a6f13663ca199463519f08ca81f33f1fa5133440ed1ddf58f1d6f1d7a064d760

コンテナにHTTPアクセスする。
[root@master1 nginx]# curl http://localhost:11111
Hello hana_shin

3.24 ビルドに不要なファイルの除外方法(.dockerignoreファイルを使う)

ビルドする時間は4秒
[root@master1 ~]# time docker build -t test-img --no-cache=true .
Sending build context to Docker daemon 83.64 MB
Step 1 : FROM busybox
 ---> e02e811dd08f
Successfully built e02e811dd08f

real    0m4.368s
user    0m0.363s
sys     0m0.882s


ビルドするディレクトリに1Gのファイルを作成する。
[root@master1 ~]# dd if=/dev/zero of=./file_1G bs=1024k count=1024
1024+0 レコード入力
1024+0 レコード出力
1073741824 バイト (1.1 GB) コピーされました、 3.67382 秒、 292 MB/秒

ファイルサイズを確認する。
[root@master1 ~]# ls -la file_1G
-rw-r--r--. 1 root root 1073741824 11月 23 20:33 file_1G

イメージをビルドする。ビルドに47秒かかる。
[root@master1 ~]# time docker build -t test-img --no-cache=true .
Sending build context to Docker daemon 1.157 GB
Step 1 : FROM busybox
 ---> e02e811dd08f
Successfully built e02e811dd08f

real    0m47.847s
user    0m2.671s
sys     0m8.364s
[root@master1 ~]#


ビルド対象外のファイルを作成する。
[root@master1 ~]# vi .dockerignore
[root@master1 ~]# cat .dockerignore
file_1G

イメージをビルドする。今度は3.7秒しかかからない。
[root@master1 ~]# time docker build -t test-img --no-cache=true .
Sending build context to Docker daemon 83.64 MB
Step 1 : FROM busybox
 ---> e02e811dd08f
Successfully built e02e811dd08f

real    0m3.764s
user    0m0.209s
sys     0m1.398s

3.25 systemdからコンテナを起動する。

サービス定義ファイルを作成する。
[root@master1 system]# pwd
/etc/systemd/system
[root@master1 system]# touch test.service
[root@master1 system]# vi test.service
[root@master1 system]# cat test.service
[Unit]
Description=Simple Nginx Test
After=docker.service
Requires=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker run --name nginx-con -p 11111:80 nginx
ExecStop=/usr/bin/docker rm -f nginx-con

[Install]
WantedBy=multi-user.target


[root@master1 system]# systemctl enable /etc/systemd/system/test.service
Created symlink from /etc/systemd/system/multi-user.target.wants/test.service to /etc/systemd/system/test.service.

コンテナを起動する。
[root@master1 system]# systemctl start test.service

コンテナの状態を確認する。
[root@master1 system]# systemctl status test.service
● test.service - Simple Nginx Test
   Loaded: loaded (/etc/systemd/system/test.service; enabled; vendor preset: disabled)
   Active: active (running) since 金 2016-11-25 22:47:25 JST; 7s ago
 Main PID: 20391 (docker-current)
   Memory: 9.8M
   CGroup: /system.slice/test.service
           mq20391 /usr/bin/docker-current run --name nginx-con -p 11111:80 nginx

11月 25 22:47:25 master1 systemd[1]: Started Simple Nginx Test.
11月 25 22:47:25 master1 systemd[1]: Starting Simple Nginx Test...


コンテナの状態を確認する。Nginxのコンテナが起動している。
[root@master1 system]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
ddd3608f807d        nginx               "nginx -g 'daemon off"   48 seconds ago      Up 44 seconds       443/tcp, 0.0.0.0:11111->80/tcp   nginx-con

コンテナにアクセスする。
[root@master1 ~]# curl http://localhost:11111
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

コンテナを停止する。
[root@master1 system]# systemctl stop test.service

コンテナの状態を確認する。
[root@master1 system]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

3.26 コンテナイメージから履歴を削除する方法(秘密情報を削除したい場合に使う)


--------------------------------------------------
1. テスト用イメージを作成する。
--------------------------------------------------
Dockerfileを作成する。
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
RUN echo "This is secret information" >> /tmp/secret_key
RUN cat /tmp/secret_key
RUN rm /tmp/secret_key

イメージをビルドする。
[root@master1 test2]# docker build -t test-img:ver1 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : RUN echo "This is secret information" >> /tmp/secret_key
 ---> Running in ed00cad28d24
 ---> 9c6db5e3cad3
Removing intermediate container ed00cad28d24
Step 3 : RUN cat /tmp/secret_key
 ---> Running in 7641391a877c
This is secret information
 ---> 99b9ea91137e
Removing intermediate container 7641391a877c
Step 4 : RUN rm /tmp/secret_key
 ---> Running in 041fc96f4ce2
 ---> 06d81d6769f1
Removing intermediate container 041fc96f4ce2
Successfully built 06d81d6769f1

イメージに対する操作履歴を確認する。
[root@master1 test2]# docker history test-img:ver1
IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
06d81d6769f1        About a minute ago   /bin/sh -c rm /tmp/secret_key                   0 B
99b9ea91137e        About a minute ago   /bin/sh -c cat /tmp/secret_key                  0 B
9c6db5e3cad3        About a minute ago   /bin/sh -c echo "This is secret information"    27 B
0584b3d2cf6d        3 weeks ago          /bin/sh -c #(nop)  CMD ["/bin/bash"]            0 B
<missing>           3 weeks ago          /bin/sh -c #(nop)  LABEL name=CentOS Base Ima   0 B
<missing>           3 weeks ago          /bin/sh -c #(nop) ADD file:54df3580ac9fb66389   196.5 MB
<missing>           12 weeks ago         /bin/sh -c #(nop)  MAINTAINER https://github.   0 B

履歴の上から2番目の操作を実行する。情報が読めてしまう!!!
[root@master1 test2]# docker run 99b9ea91137e cat /tmp/secret_key
This is secret information


--------------------------------------------------
2. イメージから履歴を削除する。
--------------------------------------------------
コンテナを起動する。
[root@master1 test2]# docker run -d test-img:ver1 /bin/true
8cb069ea1ef9bf058b7515fb6061a33a9512df956fef7b13413c926cd7403805

コンテナの状態を確認する。
[root@master1 test2]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                 CREATED             STATUS                     PORTS               NAMES
8cb069ea1ef9        test-img:ver1       "/bin/true"             10 seconds ago      Exited (0) 7 seconds ago                       focused_chandrasekhar

イメージから履歴を削除する。
[root@master1 test2]# docker export 8cb069ea1ef9 | docker import - test-img:ver1
sha256:a1691c449d092903e16522566a747a85dbbf69486a7b1122984cf147a33594fe
[root@master1 test2]#

コンテナイメージの履歴を確認する。履歴が削除されたことがわかる。
[root@master1 test2]# docker history test-img:ver1
IMAGE               CREATED             CREATED BY          SIZE                COMMENT
a1691c449d09        38 seconds ago                          196.5 MB            Imported from -

3.27 イメージ一覧に"none:none"というエントリが作成される理由

同じ名前のイメージをビルドすると、イメージ一覧の中に"none:none"というエントリが作成される。

----------------------------------------------
1. 1回目のビルド実行
----------------------------------------------
[root@master1 test2]# less Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
RUN echo "This is V1" >> /tmp/version
RUN cat /tmp/version
RUN rm /tmp/version

[root@master1 test2]# docker build -t test-img:ver1 .
以下、略

[root@master1 test2]# docker images
REPOSITORY                                            TAG                                IMAGE ID            CREATED             SIZE
test-img                                              ver1                               ada297f58022        9 seconds ago       196.5 MB


------------------------------------------------
2. Dockerfileの中身を書き換えて、2回目のビルド実行
------------------------------------------------
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
RUN echo "This is V2" >> /tmp/version
RUN cat /tmp/version
RUN rm /tmp/version

[root@master1 test2]# docker build -t test-img:ver1 .
以下、略

1回目に作成したイメージの"リポジトリ名:TAG"が"none:none"にかわっていることがわかる。
[root@master1 test2]# docker images
REPOSITORY                                            TAG                                IMAGE ID            CREATED              SIZE
test-img                                              ver1                               7a09677e71ac        8 seconds ago        196.5 MB
<none>                                                <none>                             ada297f58022        About a minute ago   196.5 MB
以下、略


------------------------------------------------
3. Dockerfileの中身を書き換えて、3回目のビルド実行
------------------------------------------------
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
RUN echo "This is V3" >> /tmp/version
RUN cat /tmp/version
RUN rm /tmp/version

[root@master1 test2]# docker build -t test-img:ver1 .
以下、略

1回目,2回目に作成したイメージの"リポジトリ名:TAG"が"none:none"にかわっていることがわかる。
[root@master1 test2]# docker images
REPOSITORY                                            TAG                                IMAGE ID            CREATED              SIZE
test-img                                              ver1                               77f33e665cac        7 seconds ago        196.5 MB
<none>                                                <none>                             7a09677e71ac        About a minute ago   196.5 MB
<none>                                                <none>                             ada297f58022        About a minute ago   196.5 MB
以下、略


3.28 コンテナのユーザIDを調べる方法

コンテナを起動する。
[root@master ~]# docker run -d --name test-con nginx
e509a143aec99f60494ffb7ece7ad4798ba7a251a84dda3b12682448fcfd940b

コンテナの名前(●印)を確認する。
[root@master ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
e509a143aec9        nginx               "nginx -g 'daemon off"   5 seconds ago       Up 2 seconds        80/tcp, 443/tcp   ●test-con

名前("test-con")をもとにコンテナIDを求める。
[root@master ~]# CID=$(docker ps --no-trunc=true|grep "test-con"|awk '{print $1}')

コンテナIDを表示する。
[root@master ~]# echo $CID
e509a143aec99f60494ffb7ece7ad4798ba7a251a84dda3b12682448fcfd940b

プロセスIDを求める。
[root@master ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

プロセスIDを表示する。
[root@master ~]# echo $PID
20648

コンテナのユーザID(UID)を調べる。ユーザID(UID)は0であることがわかる。つまりrootユーザと同じ
[root@master ~]# ps -p $PID -o cmd,pid,ppid,uid,euid
CMD                            PID   PPID   UID  EUID
nginx: master process nginx  20648  20632     0     0

3.29 コンテナのIPアドレスを調べる方法

コンテナを起動する。
[root@master1 ~]# docker run -it --rm --name test-con centos:centos7 bash

別ターミナルを開いて、コンテナの名前(●印)を確認する。
[root@master1 ~]# docker ps
CONTAINER ID      IMAGE              COMMAND        CREATED             STATUS          PORTS     NAMES
bf30021d03ac      centos:centos7     "bash"         9 seconds ago       Up 6 seconds            ●test-con

名前("test-con")をもとにIPアドレスを確認する。IPアドレスが172.17.0.2であることがわかる(★印)。
[root@master1 ~]# IP=$(docker inspect -f {{.NetworkSettings.IPAddress}} test-con)
[root@master1 ~]# echo $IP
172.17.0.2 ★


コンテナに入って、コンテナの中からもIPアドレスを確認してみる。
[root@bf30021d03ac /]# yum -y install iproute
[root@bf30021d03ac /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
40: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
  ★inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link
       valid_lft forever preferred_lft forever
[root@bf30021d03ac /]#


3.30 コンテナのリソース消費を調べる方法(htopを使うより、こっちのほうが簡単かも)

コンテナ(con0)を起動する。
[root@master1 ~]# docker run -it -d --name con0 --cpu-shares=1024  busybox dd if=/dev/zero of=/dev/null
b67ad54132fc2d05797f32830d15306484e17678af75b6505559ef8f80216f1c

コンテナ(con1)を起動する。
[root@master1 ~]# docker run -it -d --name con1 --cpu-shares=1024  busybox dd if=/dev/zero of=/dev/null
f3b736c38bee1b713d9da908f14bc846ad6c3522ccbe9b41410e0b6967145d20

コンテナの状態を確認する。
[root@master1 ~]# docker ps
CONTAINER ID     IMAGE         COMMAND                  CREATED             STATUS           PORTS           NAMES
f3b736c38bee     busybox       "dd if=/dev/zero of=/"   5 seconds ago       Up 2 seconds                     con1
b67ad54132fc     busybox       "dd if=/dev/zero of=/"   12 seconds ago      Up 10 seconds                    con0

コンテナの統計情報を確認する。CPU使用率、メモリ使用量等といった情報が取得できる。
[root@master1 ~]# docker stats $(docker inspect -f {{.Name}} $(docker ps -q))
CONTAINER           CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O
/con0               51.97%              1.057 MB / 1.027 GB   0.10%               1.296 kB / 648 B    1.108 MB / 0 B
/con1               48.78%              1.118 MB / 1.027 GB   0.11%               718 B / 648 B       1.108 MB / 0 B

3.31 タグなしのイメージをすべて削除する

タグなしイメージ一覧を確認する。
[root@master1 test2]# docker images |grep none
<none>                                                <none>                             987633f4efac        About a minute ago   196.5 MB
<none>                                                <none>                             817a3d2131b4        2 minutes ago        196.5 MB
<none>                                                <none>                             98a0ac2e3be6        7 minutes ago        196.5 MB

タグなしイメージを全て削除する
[root@master1 test2]# docker rmi $(docker images | grep '<none>' | awk '{print$3}')
Deleted: sha256:987633f4eface07f7d53b84cc7464182ccbcd8c2c63ae319ad324f255fce815b
-以下、略-

イメージを確認する。タグなしのイメージが全て削除できた。
[root@master1 test2]# docker images |grep none
[root@master1 test2]#

3.32 コンテナが終了するときの終了コードについて

Exit Codes With Special Meanings

----------------------------------------------------------------
1. コンテナを正常終了する
----------------------------------------------------------------
[root@master1 ~]# docker run --rm busybox /bin/sh -c 'uname -r'
3.10.0-229.el7.x86_64

終了コードを確認する。正常終了したことがわかる。
[root@master1 ~]# echo $?
0

----------------------------------------------------------------
2. コンテナを異常終了(終了コード=1)する
----------------------------------------------------------------
意図的にコンテナを異常終了(終了コード=1)する。
[root@master1 ~]# docker run busybox /bin/sh -c 'exit 1'

終了コードを確認する。
[root@master1 ~]# echo $?
1

コンテナの状態を確認する。STATUSが"Exited (1)"となっていることがわかる。
[root@master1 ~]# docker ps -a
CONTAINER ID      IMAGE        COMMAND                 CREATED           STATUS                     PORTS         NAMES
1528b8e7a77f      busybox      "/bin/sh -c 'exit 1'"   10 seconds ago  ★Exited (1) 8 seconds ago                 stupefied_visvesvaraya

後始末。コンテナを削除する。
[root@master1 ~]# docker rm 1528b8e7a77f
1528b8e7a77f

----------------------------------------------------------------
3. コンテナを異常終了(終了コード=5)する
----------------------------------------------------------------
意図的にコンテナを異常終了(終了コード=5)する。
[root@master1 ~]# docker run busybox /bin/sh -c 'exit 5'

終了コードを確認する。
[root@master1 ~]# echo $?
5

コンテナの状態を確認する。STATUSが"Exited (5)"となっていることがわかる。
[root@master1 ~]# docker ps -a
CONTAINER ID      IMAGE        COMMAND                 CREATED           STATUS                     PORTS         NAMES
720f0ea21f28      busybox      "/bin/sh -c 'exit 5'"   9 seconds ago   ★Exited (5) 7 seconds ago                 fervent_engelbart

後始末。コンテナを削除する。
[root@master1 ~]# docker rm 720f0ea21f28
720f0ea21f28

----------------------------------------------------------------------------
4. コンテナ内でコマンドが見つからない場合で終了する場合  (終了コード=127)
----------------------------------------------------------------------------
実在しないコマンドlllを実行する。
[root@master1 ~]# docker run busybox /bin/sh -c 'lll'
/bin/sh: lll: not found

終了コードを確認する。
[root@master1 ~]# echo $?
127

[root@master1 ~]# docker ps -a
CONTAINER ID      IMAGE       COMMAND             CREATED            STATUS                       PORTS        NAMES
bb22f6b73563      busybox     "/bin/sh -c lll"    12 seconds ago   ★Exited (127) 9 seconds ago                jovial_thompson

----------------------------------------------------------------
5. Docker自身のエラーの場合(終了コード=125)
----------------------------------------------------------------
[root@master1 ~]# docker run --rm --foo busybox
flag provided but not defined: --foo
See '/usr/bin/docker-current run --help'.

終了コードを確認する。
[root@master1 ~]# echo $?
125

3.33 コンテナ終了時の挙動について(--restart=on-failure,no)

--restart=on-failure:X (Xは再起動の回数を表す) コンテナが異常終了(終了コードが0以外)した場合の再起動の回数を指定するオプション。
--restart=noは、コンテナが異常終了しても再起動しないようにするオプション。

---------------------------------------------------------
1. 異常終了時の --restart=on-failure の動作を確認する。
---------------------------------------------------------
docker eventsを実行する。コンテナの開始、終了のイベントを得るため、grepで絞り込む。
[root@master1 ~]# docker events |grep -e start -e die

別ターミナルを開く。on-failure:3を付けてコンテナを起動する。
[root@master1 ~]# docker run --restart=on-failure:3 busybox /bin/sh -c 'exit 1'

コンテナの状態を確認する。
[root@master1 ~]# docker ps -a
CONTAINER ID     IMAGE       COMMAND                 CREATED           STATUS                              PORTS      NAMES
2e8167f2125b     busybox     "/bin/sh -c 'exit 1'"   6 seconds ago   ★Exited (1) Less than a second ago              thirsty_ardinghelli

docker eventsを確認する。コンテナが3回再起動をしたことがわかる。再起動は●印の部分
[root@master1 ~]# docker events |grep -e start -e die
2016-12-06T22:11:09.171061352+09:00 container  start 2e8167f2125bf21f05193ca43e63a665685e05a94f356b48623cde97b1539615 (image=busybox, name=thirsty_ardinghelli)
2016-12-06T22:11:09.991771696+09:00 container  die 2e8167f2125bf21f05193ca43e63a665685e05a94f356b48623cde97b1539615 (image=busybox, name=thirsty_ardinghelli)
2016-12-06T22:11:10.193297589+09:00 container●start 2e8167f2125bf21f05193ca43e63a665685e05a94f356b48623cde97b1539615 (image=busybox, name=thirsty_ardinghelli)
2016-12-06T22:11:10.738386606+09:00 container  die 2e8167f2125bf21f05193ca43e63a665685e05a94f356b48623cde97b1539615 (image=busybox, name=thirsty_ardinghelli)
2016-12-06T22:11:11.139880436+09:00 container●start 2e8167f2125bf21f05193ca43e63a665685e05a94f356b48623cde97b1539615 (image=busybox, name=thirsty_ardinghelli)
2016-12-06T22:11:11.788550292+09:00 container  die 2e8167f2125bf21f05193ca43e63a665685e05a94f356b48623cde97b1539615 (image=busybox, name=thirsty_ardinghelli)
2016-12-06T22:11:12.848497457+09:00 container●start 2e8167f2125bf21f05193ca43e63a665685e05a94f356b48623cde97b1539615 (image=busybox, name=thirsty_ardinghelli)
2016-12-06T22:11:13.528665703+09:00 container  die 2e8167f2125bf21f05193ca43e63a665685e05a94f356b48623cde97b1539615 (image=busybox, name=thirsty_ardinghelli)
以下、何も出力されない。


---------------------------------------------------------
2. 正常終了時の --restart=on-failure の動作を確認する。
---------------------------------------------------------
docker eventsを実行する。コンテナの開始、終了のイベントを得るため、grepで絞り込む。
[root@master1 ~]# docker events |grep -e start -e die

別ターミナルを開く。on-failure:3を付けてコンテナを起動する。
[root@master1 ~]# docker run --restart=on-failure:3 busybox /bin/sh -c 'exit 0'
[root@master1 ~]# echo $?
0

コンテナの状態を確認する。
[root@master1 ~]# docker ps -a
CONTAINER ID      IMAGE        COMMAND                 CREATED           STATUS                     PORTS       NAMES
e9bef69f4b79      busybox      "/bin/sh -c 'exit 0'"   9 seconds ago   ★Exited (0) 7 seconds ago               sick_davinci

docker eventsを確認する。コンテナが再起動していないことがわかる。
[root@master1 ~]# docker events |grep -e start -e die
2016-12-06T22:23:51.403847392+09:00 container start e9bef69f4b79595cfac312c39550e567229c44f5569de009f565b8b6dea38967 (image=busybox, name=sick_davinci)
2016-12-06T22:23:52.449435115+09:00 container die e9bef69f4b79595cfac312c39550e567229c44f5569de009f565b8b6dea38967 (image=busybox, name=sick_davinci)
以下、何も出力されない。


------------------------------------------------------
3. --restart=no(デフォルト)の動作を確認する。
------------------------------------------------------
docker eventsを実行する。コンテナの開始、終了のイベントを得るため、grepで絞り込む。
[root@master1 ~]# docker events |grep -e start -e die

別ターミナルを開く。コンテナを起動する。
[root@master1 ~]# docker run busybox /bin/sh -c 'exit 1'
[root@master1 ~]# echo $?
1

コンテナの状態を確認する。
[root@master1 ~]# docker ps -a
CONTAINER ID       IMAGE       COMMAND                 CREATED            STATUS                      PORTS         NAMES
af4d7b72ebf7       busybox     "/bin/sh -c 'exit 1'"   16 seconds ago   ★Exited (1) 14 seconds ago                 big_mirzakhani

docker eventsを確認する。コンテナが再起動していないことがわかる。
[root@master1 ~]# docker events |grep -e start -e die
2016-12-06T22:17:32.421207276+09:00 container start af4d7b72ebf78122596b9c90370f1511bf9e454a272e2940f80fed0cc5af9243 (image=busybox, name=big_mirzakhani)
2016-12-06T22:17:33.363000228+09:00 container die af4d7b72ebf78122596b9c90370f1511bf9e454a272e2940f80fed0cc5af9243 (image=busybox, name=big_mirzakhani)
以下、何も出力されない。

3.34 一般ユーザ権限でコンテナを起動する(ただし起動したコンテナは特権ユーザ権限で動作)

Docker-docs-ja参照

-----------------------------------------------------
1. 準備(特権ユーザ(root)で行う)
-----------------------------------------------------
groupを確認する。dockerグループは存在しない。
[root@master1 ~]# cat /etc/group|grep docker
dockerroot:x:993:

dockerグループを追加する。
[root@master1 ~]# groupadd docker

groupを確認する。dockerグループが追加されたことがわかる。
[root@master1 ~]# cat /etc/group|grep docker
dockerroot:x:993:
docker:x:1002:

ユーザを追加する。
[root@master1 ~]# adduser hana_shin
[root@master1 ~]# passwd hana_shin

dockerグループにユーザ(hana_shin)を追加する。
[root@master1 ~]# usermod -aG docker hana_shin
[root@master1 ~]# cat /etc/group|grep docker
dockerroot:x:993:
docker:x:1002:hana_shin

Dockerを再起動する。
[root@master1 ~]# systemctl restart docker
[root@master1 ~]#

-----------------------------------------------------
2. 一般ユーザ権限でDockerを起動する。
-----------------------------------------------------
別ターミナルより、一般ユーザでログインする。
[hana_shin@master1 ~]$
[hana_shin@master1 ~]$ id
uid=1001(hana_shin) gid=1001(hana_shin) groups=1001(hana_shin),1002(docker) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

コンテナを起動する。
[hana_shin@master1 ~]$ docker run -it --name test-con centos:centos7 bash

Ctrlを押下しながら、PキーとQキーを押下して、コンテナから抜ける。
[root@f1e13169655f /]# [hana_shin@master1 ~]$

ホストで、コンテナのユーザID等を確認する。
[hana_shin@master1 ~]$ CID=$(docker ps --no-trunc=true|grep "test-con"|awk '{print $1}')
[hana_shin@master1 ~]$ PID=$(docker inspect --format {{.State.Pid}} $CID)

一般ユーザ(hana_shin)権限でコンテナを起動できた。
[hana_shin@master1 ~]$ ps -p $PID -o comm,pid,ppid,uid,euid
COMMAND            PID   PPID   UID  EUID
bash              2079   1655     0     0

親プロセスを確認する。親プロセスはdocker-currentであることがわかる。
[hana_shin@master1 ~]$ ps -p 1655 -o comm,pid,ppid,uid,euid
COMMAND            PID   PPID   UID  EUID
docker-current    1655      1     0     0

後始末。コンテナを終了する。
[hana_shin@master1 ~]$ docker stop f1e13169655f
f1e13169655f
[hana_shin@master1 ~]$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
f1e13169655f        centos:centos7      "bash"              16 minutes ago      Exited (137) 3 seconds ago                       test-con

イメージを削除する。
[hana_shin@master1 ~]$ docker rm f1e13169655f
f1e13169655f
[hana_shin@master1 ~]$

-----------------------------------------------------
3. 後始末(グループからユーザを削除する)
-----------------------------------------------------
[root@master1 ~]# gpasswd -d hana_shin docker
ユーザ hana_shin をグループ docker から削除
[root@master1 ~]# cat /etc/group|grep docker
dockerroot:x:993:
docker:x:1002:

3.35 userns-remap(使い方がいまいちわからない。。)

--userns-remap パラメータを指定することで、 /etc/subuid と /etc/subguid ファイルがユーザとオプションのグループ用に使われます。

Docker for your users - Introducing user namespace/a>
Oracleのドキュメント


------------------------------------------------------------------------
1. 準備(CentOS7.2以上が必要)
------------------------------------------------------------------------
[root@master1 ~]# uname -r
3.10.0-327.36.3.el7.x86_64

docker定義ファイルを編集する。"--userns-remap=default"を追加する。
[root@master1 ~]# vi /etc/sysconfig/docker
OPTIONS='--userns-remap=default'

--userns-remap=defaultを指定すると、dockremapというユーザとグループがつくれるので
それぞれのIDを設定ファイルに定義しておく。
[root@master1 ~]# echo dockremap:500000:65536 > /etc/subuid
[root@master1 ~]# echo dockremap:500000:65536 > /etc/subgid

カーネルのオプションパラメータ(user_namespace.enable=1)を追加する。
[root@master1 ~]# vi /etc/sysconfig/grub
GRUB_CMDLINE_LINUX="rhgb quiet biosdevname=0 net.ifnames=0 user_namespace.enable=1"

設定を有効にする。
[root@master1 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-229.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-229.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-f9ce816285894f709c0fd8ecf27b8212
Found initrd image: /boot/initramfs-0-rescue-f9ce816285894f709c0fd8ecf27b8212.img
done

カーネルを再起動する。
[root@master1 ~]# shutdown -r now

------------------------------------------------------------------------
2. カーネル再起動後
------------------------------------------------------------------------
カーネルのパラメータを確認する。見やすくするため途中で折り返しています。
[root@master1 ~]# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.0-327.36.3.el7.x86_64 root=UUID=c2cb61fd-0e07-4e92-bd38-f76181d9be81 
    ro rhgb quiet biosdevname=0 net.ifnames=0 user_namespace.enable=1 systemd.debug LANG=ja_JP.UTF-8

Dockerの状態を確認する。見やすくするため途中で折り返しています。
[root@master1 ~]# ps aux|grep docker
root       1066  2.9  3.2 586576 32460 ?        Ssl  18:26   0:09 /usr/bin/docker-current daemon 
  --exec-opt native.cgroupdriver=systemd 
  --userns-remap=default 
  --storage-opt dm.basesize=50G 
  --insecure-registry master1:12345

コンテナを起動する。
[root@master1 ~]# docker run -it --name test-con busybox sh
/ # id
uid=0(root) gid=0(root) groups=10(wheel)

別ターミナルを起動する。コンテナのUIDを確認する。UID=500000であることがわかる。
[root@master1 ~]# CID=$(docker ps --no-trunc=true|grep "test-con"|awk '{print $1}')
[root@master1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)
[root@master1 ~]# ps -p $PID -o comm,pid,ppid,uid,euid
COMMAND            PID   PPID   UID  EUID
sh                1489   1067 500000 500000

あと始末。コンテナを削除する。
[root@master1 ~]# docker rm -f test-con
test-con

-----------------------------------------------------
3. UID,GIDを変更する。
-----------------------------------------------------
UIDを変更する。
[root@master1 ~]# vi /etc/subuid
[root@master1 ~]# cat /etc/subuid
dockremap:510000:65536

GIDを変更する。
[root@master1 ~]# vi /etc/subgid
[root@master1 ~]# cat /etc/subgid
dockremap:510000:65536

Dockerを再起動する。
[root@master1 ~]# systemctl restart docker
[root@master1 ~]#

コンテナを起動する
[root@master1 ~]# docker run -it --name test-con busybox sh
/ # id
uid=0(root) gid=0(root) groups=10(wheel)

Ctrlキーを押下しながら、PキーとQキーを押下する。
/ # [root@master1 ~]#

コンテナのUIDを確認する。コンテナがUID=510000で動作していることがわかる。
[root@master1 ~]# CID=$(docker ps --no-trunc=true|grep "test-con"|awk '{print $1}')
[root@master1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)
[root@master1 ~]# ps -p $PID -o comm,pid,ppid,uid,euid
COMMAND            PID   PPID   UID  EUID
sh                4707   4540 510000 510000

3.36 --userオプションの使い方

--userに指定するユーザ(またはUID)は、コンテナ内のユーザ(またはUID)を指定する。
以下の例では、centos7とnginxのコンテナでは、daemonユーザのUIDが違うことを示している。

----------------------------------------------------
1. centos7コンテナでは、daemonユーザのUIDは2。
----------------------------------------------------
コンテナを起動する。
[root@master1 ~]# docker run -it --user=daemon:daemon --name test-con centos:centos7 bash

UIDを確認する。UID=2であることがわかる。
bash-4.2$ id
uid=2(daemon) gid=2(daemon) groups=2(daemon)

passwdファイルでUIDを確認する。UID=2であることがわかる。
bash-4.2$ grep daemon /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin

Ctrlキーを押下しながらPキーとQキーを押して、コンテナから抜ける。
bash-4.2$ [root@master1 ~]#

コンテナIDを求める。
[root@master1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@master1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

コンテナのUIDを求める。UID=2であることがわかる。
[root@master1 ~]# ps -p $PID -o comm,pid,ppid,uid,euid
COMMAND            PID   PPID   UID  EUID
bash              6396   1028   ★2     2

----------------------------------------------------
2. nginxコンテナでは、daemonユーザのUIDは1。
----------------------------------------------------
コンテナを起動する。
[root@master1 ~]# docker run -it --user=daemon:daemon --name test-con nginx bash

UIDを確認する。UID=1であることがわかる。
daemon@6acee3f32043:/$ id
uid=1(daemon) gid=1(daemon) groups=1(daemon)

passwdファイルでUIDを確認する。UID=1であることがわかる。
daemon@929d7b11ba72:/$ grep daemon /etc/passwd
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

Ctrlキーを押下しながらPキーとQキーを押して、コンテナから抜ける。
/ $ [root@master1 ~]#

コンテナIDを求める。
[root@master1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@master1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

コンテナのUIDを求める。UID=1であることがわかる。
[root@master1 ~]# ps -p $PID -o comm,pid,ppid,uid,euid
COMMAND            PID   PPID   UID  EUID
sh                6957   1028   ★1     1

3.37 コンテナの情報を整形して出力する方法(--format)

http://docs.docker.jp/engine/reference/commandline/ps.html

[root@master1 ~]# docker ps --format "table {{.ID}}\t{{.Status}}\t{{.Image}}"
CONTAINER ID        STATUS              IMAGE
847c578f3c8f        Up About a minute   gcr.io/google_containers/skydns:2015-03-11-001
517e07f64736        Up 4 minutes        gcr.io/google_containers/kube2sky:1.11
cca839d03bac        Up 28 minutes       nginx
27727fcf9348        Up 28 minutes       registry.access.redhat.com/rhel7/pod-infrastructure:latest
bdefbe6a6e33        Up 28 minutes       nginx
4bbd8a95cc0f        Up 28 minutes       registry.access.redhat.com/rhel7/pod-infrastructure:latest

3.38 dokcerイメージからPodを起動する

Dockerfileを作成する。
[root@master1 dockerfile]# vi Dockerfile
[root@master1 dockerfile]# cat Dockerfile
FROM centos:centos7
RUN useradd user1
USER user1

イメージをビルドする。
[root@master1 dockerfile]# docker build -t hana/test-img:v1 --no-cache=true .
Sending build context to Docker daemon 3.072 kB
-以下、略-

イメージを確認する。
[root@master1 dockerfile]# docker images hana/test-img:v1
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hana/test-img       v1                  d8de1bc46638        43 seconds ago      196.5 MB

Pod定義ファイルを作成する。
[root@master1 dockerfile]# vi test.yaml
[root@master1 dockerfile]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  restartPolicy: Never
  containers:
  - name: test
    image: hana/test-img:v1
    command: ["sleep", "3600"]

Podを起動する。
[root@master1 dockerfile]# kubectl create -f test.yaml
pod "test" created

Podの状態を確認する。
[root@master1 dockerfile]# kubectl get pod
NAME      READY     STATUS    RESTARTS   AGE
test      1/1       Running   0          7s

Podでbashを実行する。
[root@master1 dockerfile]# kubectl exec -it test bash
[user1@test /]$ id
uid=1000(user1) gid=1000(user1) groups=1000(user1)
[user1@test /]$ cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[user1@test /]$

3.39 コンテナのGUIを利用する。

上手くいかない。。。


Dockerfileを作成する。
[root@master1 dockergui]# vi Dockerfile
[root@master1 dockergui]# cat Dockerfile
FROM centos:centos7.2.1511
RUN yum -y install firefox
RUN groupadd -g 2002 guiuser
RUN useradd -d /home/guiuser -s /bin/bash -m guiuser -u 2002 -g 2002
USER guiuser
ENV HOME /home/guiuser
CMD /usr/bin/firefox

ユーザを追加する。
[root@master1 dockergui]# adduser guiuser
[root@master1 dockergui]# cat /etc/passwd|grep guiuser
guiuser:x:2002:2002::/home/guiuser:/bin/bash
[root@master1 dockergui]# cat /etc/group|grep guiuser
guiuser:x:2002:

イメージをビルドする。
[root@master1 dockergui]# docker build -t gui .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:centos7.2.1511
 ---> feac5e0dfdb2
Step 2 : RUN yum -y install firefox
 ---> Running in 5e3c45a8b3e8
Loaded plugins: fastestmirror

-中略-

Complete!
 ---> 5edd4cd2c3c9
Removing intermediate container 5e3c45a8b3e8
Step 3 : RUN groupadd -g 2002 guiuser
 ---> Running in 27c81dd37230
 ---> 93a3a4a1b09d
Removing intermediate container 27c81dd37230
Step 4 : RUN useradd -d /home/guiuser -s /bin/bash -m guiuser -u 2002 -g 2002
 ---> Running in 127631b45428
 ---> afa1633e5c1c
Removing intermediate container 127631b45428
Step 5 : USER guiuser
 ---> Running in f6be57dabc5b
 ---> 3110bf85d8fb
Removing intermediate container f6be57dabc5b
Step 6 : ENV HOME /home/guiuser
 ---> Running in 27a5cdd1c695
 ---> d5700b8b5316
Removing intermediate container 27a5cdd1c695
Step 7 : CMD /usr/bin/firefox
 ---> Running in 0df2f2d03910
 ---> fcf6a8321176
Removing intermediate container 0df2f2d03910
Successfully built fcf6a8321176

[root@master1 dockergui]# docker images gui
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
gui                 latest              fcf6a8321176        58 seconds ago      421.9 MB

[root@master1 dockergui]# docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=$DISPLAY -h $HOSTNAME -v $HOME/.Xauthority:/home/$USER/.Xauthority gui
Error: cannot open display:

3.xx 仮想化環境で利用しているゲストOSのイメージをDocker環境への移植

1.virt-tar-outを使って、qcow2を圧縮ファイル(tgz)に変換
2.docker importを使って、圧縮ファイル(tgz)をイメージに変換

4 Dockerfile

4.1 CMD (コンテナ起動時に自動的に実行するコマンドを指定する)

Dockerfile リファレンスより抜粋

Dockerfile で CMD 命令を一度だけ指定できます。複数の CMD がある場合、最も後ろの CMD のみ有効です。

---------------------------------------------------
1. CMD ["-a"] -> CMD ["-r"]の順番
---------------------------------------------------
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
ENTRYPOINT ["/usr/bin/uname"]
CMD ["-a"]
CMD ["-r"]

イメージをビルドする。
[root@master1 test2]# docker build -t test-img:ver1 --no-cache=true .
-中略 -

コンテナを起動する。uname -rが実行されていることがわかる。
[root@master1 test2]# docker run --rm test-img:ver1
3.10.0-229.el7.x86_64


---------------------------------------------------
2. 順番を入れ替える( CMD ["-r"] -> CMD ["-a"])
---------------------------------------------------
Dockerfileを作成する。
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
ENTRYPOINT ["/usr/bin/uname"]
CMD ["-r"]
CMD ["-a"]

イメージをビルドする。
[root@master1 test2]# docker build -t test-img:ver1 --no-cache=true .
-中略 -

コンテナを起動する。uname -aが実行されていることがわかる。
[root@master1 test2]# docker run --rm test-img:ver1
Linux bafbe7f69bb2 3.10.0-229.el7.x86_64 #1 SMP Fri Mar 6 11:36:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

4.2 CMDとENTRYPOINTの使い方

CMDもENTRYPOINTもコンテナ起動時に自動的に実行するコマンドを指定する。
コンテナ起動時に実行するコマンドをENTRYPOINTに指定して、
あとから変更可能なコマンドの引数のデフォルト値をCMDに指定する、というように使う。

--------------------------------------------------------------
1. CMDで指定したコマンド引数は変更可能であることを確認する。
--------------------------------------------------------------
Dockerfileを作成する。
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
ENTRYPOINT ["/usr/bin/uname"]
CMD ["-a"]

イメージを作成する。
[root@master1 test2]# docker build -t test-img:ver1 .
-中略-

コンテナを起動する。コンテナの起動パラメータに何も指定しなかれば、uname -aが実行される。
[root@master1 test2]# docker run --rm test-img:ver1
Linux 9496baeb4980 3.10.0-229.el7.x86_64 #1 SMP Fri Mar 6 11:36:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

起動パラメータ(uname -rの"-r")を指定してコンテナを起動する。uname -rが実行される。
つまり、CMD ["-a"]が上書きされたことがわかる。
[root@master1 test2]# docker run --rm test-img:ver1 -r
3.10.0-229.el7.x86_64


--------------------------------------------------------------
2. ENTRYPOINTで指定したコマンド引数は変更不可であることを確認する。
--------------------------------------------------------------
Dockerfileを作成する。
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
ENTRYPOINT ["/usr/bin/uname","-a"]

イメージをビルドする。
[root@master1 test2]# docker build -t test-img:ver1 --no-cache=true .
-中略-

引数なしでコンテナを起動する。
[root@master1 test2]# docker run --rm test-img:ver1
Linux 4a7180accb88 3.10.0-229.el7.x86_64 #1 SMP Fri Mar 6 11:36:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

引数ありでコンテナを起動する。しかし、引数(-r)が無視されていることが確認できる。
ENTRYPOINTで指定したコマンド引数は変更できないことがわかる。
[root@master1 test2]# docker run --rm test-img:ver1 -r
Linux 4b71de2fda69 3.10.0-229.el7.x86_64 #1 SMP Fri Mar 6 11:36:42 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

4.3 ADDとCOPYの違い

ADDはアーカイブファイルを展開してしまうが、COPYは展開せず、そのままをイメージにコピーする。

---------------------------------------------------------
1. アーカイブファイルの準備
---------------------------------------------------------
ファイルを2つ作成する。
[root@master1 test2]#  head -c 1000 /dev/urandom > a.txt
[root@master1 test2]#  head -c 1000 /dev/urandom > b.txt

アーカイブファイルを作成する。
[root@master1 test2]# tar cvfz test.tar.gz a.txt b.txt
a.txt
b.txt

作成したファイルを確認する。
[root@master1 test2]# ls -lt
合計 12
-rw-r--r--. 1 root root 2207 11月 26 16:47 test.tar.gz
-rw-r--r--. 1 root root 1000 11月 26 16:47 b.txt
-rw-r--r--. 1 root root 1000 11月 26 16:47 a.txt

---------------------------------------------------------
2. ADDを使った場合 (アーカイブが展開されてしまう)
---------------------------------------------------------
Dockerfileを作成する。
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
RUN mkdir /opt/test
ADD test.tar.gz /opt/test/
RUN ls -lRt /opt/test

カレントディレクトリのファイルを確認する
[root@master1 test2]# ls
Dockerfile  a.txt  b.txt  test.tar.gz

イメージをビルドする。圧縮ファイルが展開されていることがわかる。
[root@master1 test2]# docker build -t test-img:ver1 .
Sending build context to Docker daemon 8.192 kB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : RUN mkdir /opt/test
 ---> Running in f6129d2aa4c3
 ---> af19cbd77e74
Removing intermediate container f6129d2aa4c3
Step 3 : ADD test.tar.gz /opt/test/
 ---> c21b8d439958
Removing intermediate container e6810a0aabec
Step 4 : RUN ls -lRt /opt/test
 ---> Running in 9b751e97e690
/opt/test:
total 8
-rw-r--r--. 1 root root 1000 Nov 26 07:47 b.txt  <=== アーカイブが展開された。
-rw-r--r--. 1 root root 1000 Nov 26 07:47 a.txt  <=== アーカイブが展開された。
 ---> 995292e70c54
Removing intermediate container 9b751e97e690
Successfully built 995292e70c54

コンテナに入って確認する。圧縮ファイルが展開されていることがわかる。
[root@master1 test2]# docker run -it --rm test-img:ver1 bash
[root@16fc609ba268 /]# cd /opt/test/
[root@16fc609ba268 test]# ls -lt
total 8
-rw-r--r--. 1 root root 1000 Nov 26 07:47 b.txt   <=== アーカイブが展開された。
-rw-r--r--. 1 root root 1000 Nov 26 07:47 a.txt   <=== アーカイブが展開された。


---------------------------------------------------------
3. COPYを使った場合 (アーカイは展開されない)
---------------------------------------------------------
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
RUN mkdir /opt/test
COPY test.tar.gz /opt/test/
RUN ls -lRt /opt/test

イメージをビルドする。アーカイブは展開されないことがわかる。
[root@master1 test2]# docker build -t test-img:ver1 .
Sending build context to Docker daemon 8.192 kB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : RUN mkdir /opt/test
 ---> Running in 9acb716ae732
 ---> a9f38033cf21
Removing intermediate container 9acb716ae732
Step 3 : COPY test.tar.gz /opt/test/
 ---> 47f2b98dee82
Removing intermediate container b7129e471f34
Step 4 : RUN ls -lRt /opt/test
 ---> Running in 175575dda529
/opt/test:
total 4
-rw-r--r--. 1 root root 2207 Nov 26 07:47 test.tar.gz  <=== アーカイブは展開されない。
 ---> 2b55986f826b
Removing intermediate container 175575dda529
Successfully built 2b55986f826b

コンテナに入って確認する。アーカイブファイルが展開されないことがわかる。
[root@master1 test2]# docker run -it --rm test-img:ver1 bash
[root@1dc516c1a917 /]# cd /opt/test/
[root@1dc516c1a917 test]# ls -lt
total 4
-rw-r--r--. 1 root root 2207 Nov 26 07:47 test.tar.gz  <=== アーカイブは展開されない


---------------------------------------------------------------------------------
4. ADDコマンドを使って、インターネット上のアーカイブファイルをイメージに追加する
   COPYコマンドではできない。
---------------------------------------------------------------------------------
Dockerfileを作成する。
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
RUN mkdir /opt/test
ADD http://tamacom.com/global/global-6.5.5.tar.gz /opt/test/
RUN ls -lRt /opt/test

イメージをビルドする。
[root@master1 test2]# docker build -t test-img:ver1 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : RUN mkdir /opt/test
 ---> Using cache
 ---> a9f38033cf21
Step 3 : ADD http://tamacom.com/global/global-6.5.5.tar.gz /opt/test/
Downloading [==================================================>] 2.935 MB/2.935 MB
 ---> 74f57a040737
Removing intermediate container ffba4d6a3c60
Step 4 : RUN ls -lRt /opt/test
 ---> Running in db028ae06a11
/opt/test:
total 2868
-rw-------. 1 root root 2934542 Sep 21 04:57 global-6.5.5.tar.gz  <===アーカイブが追加された。
 ---> d4c6f9b643ea
Removing intermediate container db028ae06a11
Successfully built d4c6f9b643ea

コンテナを起動する。
[root@master1 test2]# docker run -it --rm test-img:ver1 bash

イメージに追加したアーカイブを確認する。
[root@d05a61cfe82f /]# cd /opt/test/
[root@d05a61cfe82f test]# ls -lt
total 2868
-rw-------. 1 root root 2934542 Sep 21 04:57 global-6.5.5.tar.gz

4.4 LABEL(イメージにコメントやバージョン情報をつける)

Dockerfileを作成する。
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
LABEL title="Test image"
LABEL version="1.0"
LABEL descriptuon="This is test"

イメージをビルドする。
[root@master1 test2]# docker build -t test-img:ver1 --no-cache=true .
-中略-

イメージの中身を調べる。コメント等が確認できる。
[root@master1 test2]# docker inspect --format="{{ .Config.Labels }}" test-img:ver1
map[build-date:20161102 descriptuon:This is test license:GPLv2 name:CentOS Base Image title:Test image vendor:CentOS version:1.0]

4.5 WORKDIR(作業用ディレクトリを指定する。)

-----------------------------------------------
1. 絶対パスのあとに相対パスを使った場合
-----------------------------------------------
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
WORKDIR /first
WORKDIR second
WORKDIR third
CMD ["pwd"]

イメージをビルドする。
[root@master1 test2]# docker build -t test-img:ver1 --no-cache=true .
-以下、略-

コンテナを起動する。
[root@master1 test2]# docker run --rm test-img:ver1
/first/second/third

-----------------------------------------------
2. 絶対パスを続けて使った場合
-----------------------------------------------
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
WORKDIR /first
WORKDIR /second
WORKDIR /third
CMD ["pwd"]

イメージをビルドする。
[root@master1 test2]# docker build -t test-img:ver1 --no-cache=true .

コンテナを起動する。
[root@master1 test2]# docker run --rm test-img:ver1
/third

4.6 USER(USER以降のコマンドをUSER権限で実行する)

----------------------------------------------------
1. ホストでユーザ(hana_shin)を作成する。
----------------------------------------------------
[root@master1 test]# useradd -u 2000 hana_shin
[root@master1 test]# grep hana_shin /etc/passwd
hana_shin:x:2000:2000::/home/hana_shin:/bin/bash
[root@master1 test]# grep hana_shin /etc/group
hana_shin:x:2000:

----------------------------------------------------
2. コンテナでホストと同じユーザ(hana_shin)を作成する。
----------------------------------------------------
[root@master1 test]# vi Dockerfile
[root@master1 test]# cat Dockerfile
FROM centos:centos7
RUN useradd -u 2000 hana_shin
USER hana_shin
CMD tail -f /dev/null

イメージをビルドする。
[root@master1 test]# docker build -t test-img:ver1 --no-cache=true .
-以下、略-

コンテナを起動する。
[root@master1 test]# docker run -it --rm --name test-con test-img:ver1 bash

UIDを確認する。UID=2000のユーザが作成できたことがわかる。
[hana_shin@4fbb369c1d2d /]$ id
uid=2000(hana_shin) gid=2000(hana_shin) groups=2000(hana_shin)

[hana_shin@4fbb369c1d2d /]$ grep hana_shin /etc/passwd
hana_shin:x:2000:2000::/home/hana_shin:/bin/bash

----------------------------------------------------
3. 別ターミナルでコンテナの状態を確認する。
----------------------------------------------------
コンテナの名前(test-con)を確認する。
[root@master1 ~]# docker ps
CONTAINER ID      IMAGE            COMMAND      CREATED           STATUS              PORTS         NAMES
4fbb369c1d2d      test-img:ver1    "bash"       4 minutes ago     Up 4 minutes                      test-con

コンテナIDを求める。
[root@master1 ~]# CID=$(docker ps --no-trunc=true|grep "test-con"|awk '{print $1}')

コンテナのPIDを求める。
[root@master1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

コンテナのpid,uid等を確認する。
[root@master1 ~]# ps -p $PID -o pid,ppid,uid,euid
   PID   PPID   UID  EUID
  3191   1028  2000  2000

親プロセスを確認する。親プロセスはdocker-current であることがわかる。
[root@master1 ~]# ps -p 1028 -o comm,pid,ppid,uid,euid
COMMAND            PID   PPID   UID  EUID
docker-current    1028      1     0     0

プロセスを確認する。
[root@master1 ~]# ps aux|grep hana
hana_sh+   1480  0.0  0.0   4328   648 ?        Ss   19:35   0:00 /bin/sh -c tail -f /dev/null
hana_sh+   1488  0.0  0.0   4260   352 ?        S    19:35   0:00 tail -f /dev/null
hana_sh+   3191  0.0  0.1  11776  1904 pts/1    Ss+  19:59   0:00 bash
root       3916  0.0  0.0 112664   960 pts/2    S+   20:11   0:00 grep --color=auto hana

4.7 ARG(ビルド時の引数を指定する)

ビルド時に引数xを指定したらイメージX、引数yを指定したらイメージY、というように、
ビルド時の引数にしたがって異なるイメージを作ることができます。

4.7.1 その1 (ARG xxx=yyy と定義した場合)

--------------------------------------------------
1. ARGを使ったDockerfile (下記2,3で同じものを使う)
--------------------------------------------------
[root@node1 test]# vi Dockerfile
[root@node1 test]# cat Dockerfile
FROM centos:centos7
ARG user=nginx
RUN useradd $user
USER $user

----------------------------------------------------
2. ビルド時に引数を指定しない(--build-argを使わない)
----------------------------------------------------
イメージをビルドする。イメージ内に、デフォルトのnginxユーザを作成する。
[root@node1 test]# docker build -t test-img:ver1 --no-cache=true .
Sending build context to Docker daemon 2.048 kB
-以下、略-

ユーザを確認する。デフォルトのユーザ名(nginx)になっている。
[root@node1 test]# docker run -it --rm test-img:ver1 bash
[nginx@a1a98aa3000d /]$ id
uid=1000(nginx) gid=1000(nginx) groups=1000(nginx)

----------------------------------------------------
3. ビルド時に引数を指定する。(--build-arg user=httpd)
----------------------------------------------------
イメージをビルドする。イメージ内に、引数で指定したhttpdユーザを作成する。
[root@node1 test]# docker build -t test-img:ver1 --no-cache=true --build-arg user=httpd .
Sending build context to Docker daemon 2.048 kB
-以下、略-

ユーザを確認する。ビルド時に指定したユーザ名(httpd)になっている。
[root@node1 test]# docker run -it --rm test-img:ver1 bash
[httpd@fb7fdb408f5b /]$ id
uid=1000(httpd) gid=1000(httpd) groups=1000(httpd)

4.7.1 その2 (ARG xxx と定義した場合)

----------------------------------------------------
1. テスト用ファイルの準備 (下記2,3,4で同じものを使う)
----------------------------------------------------
[root@node1 test]# vi Dockerfile
[root@node1 test]# cat Dockerfile
FROM centos:centos7
ARG arg
COPY test_$arg /tmp

[root@node1 test]# touch test_10
[root@node1 test]# touch test_20
[root@node1 test]# echo 10 > test_10
[root@node1 test]# echo 20 > test_20
[root@node1 test]# ls
Dockerfile  test_10  test_20

------------------------------------------------------
2. 引数に10を指定(--build-arg arg=10)してビルドする
------------------------------------------------------
ビルドする。イメージ内に、/tmp/test_10というファイルを作成する。
[root@node1 test]# docker build -t test-img:ver1 --no-cache=true --build-arg arg=10 .
Sending build context to Docker daemon 4.096 kB
-以下、略-

コンテナを起動する。
[root@node1 test]# docker run -it --rm test-img:ver1 bash

テストファイルを読み出す。ビルド時に指定したファイルの中身がよめた。
[root@74312d24207d /]# cat /tmp/test_10
10
[root@74312d24207d /]# exit
exit

------------------------------------------------------
3. 引数に20を指定(--build-arg arg=20)してビルドする
------------------------------------------------------
ビルドする。イメージ内に、/tmp/test_20というファイルを作成する。
[root@node1 test]# docker build -t test-img:ver1 --no-cache=true --build-arg arg=20 .
Sending build context to Docker daemon 4.096 kB
-以下、略-

コンテナを起動する。
[root@node1 test]# docker run -it --rm test-img:ver1 bash

テストファイルを読み出す。ビルド時に指定したファイルの中身がよめた。
[root@636350430fc3 /]# cat /tmp/test_20
20
[root@636350430fc3 /]# exit
exit

-----------------------------------------------------^
4. 引数に何も指定しないでビルドする
------------------------------------------------------
ビルドする。引数を指定しないとエラー発生する。
[root@node1 test]# docker build -t test-img:ver1 --no-cache=true .
Sending build context to Docker daemon 4.096 kB
-中略-
Step 3 : COPY test_$arg /tmp
lstat test_: no such file or directory ★

4.8 ONBUILD

DockerfileのONBUILD

4.9 Dockerfileの中からシェルスクリプトを実行する。

Dockerfileを作成する。
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
ADD test.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/test.sh
ENTRYPOINT ["/usr/local/bin/test.sh"]

シェルスクリプトを作成する。
[root@master1 test2]# vi test.sh
[root@master1 test2]# cat test.sh
#!/usr/bin/bash
date
df -HT

ファイルを確認する。
[root@master1 test2]# ls
Dockerfile  test.sh

イメージをビルドする。
[root@master1 test2]# docker build -t test-img:ver1 --no-cache=true .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : ADD test.sh /usr/local/bin/
 ---> 47e0b863dc89
Removing intermediate container cb92e3c9f034
Step 3 : RUN chmod +x /usr/local/bin/test.sh
 ---> Running in 9bf731f15e9c
 ---> 7c9d1c388c8a
Removing intermediate container 9bf731f15e9c
Step 4 : ENTRYPOINT /usr/local/bin/test.sh
 ---> Running in b70e9cf496aa
 ---> 9d8185069d7f
Removing intermediate container b70e9cf496aa
Successfully built 9d8185069d7f

コンテナを起動する。
[root@master1 test2]# docker run --rm test-img:ver1
Sat Nov 26 12:06:16 UTC 2016
Filesystem                                                                                     Type   Size  Used Avail Use% Mounted on
/dev/mapper/docker-8:3-713942-b4002d9923c4ebdf11156b914942131e8f9b34ffe43b646f4ebe55914855d553 xfs     11G  252M   11G   3% /
tmpfs                                                                                          tmpfs  514M     0  514M   0% /dev
tmpfs                                                                                          tmpfs  514M     0  514M   0% /sys/fs/cgroup
/dev/sda3                                                                                      xfs     43G  5.4G   37G  13% /etc/hosts
shm                                                                                            tmpfs   68M     0   68M   0% /dev/shm
[root@master1 test2]#

4.10 コンテナを動作させ続ける(tail -f /dev/null)

Dockerfileを作成する。
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM centos:centos7
CMD tail -f /dev/null

イメージをビルドする。
[root@master1 test2]# docker build -t test-img:ver1 --no-cache=true .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM centos:centos7
 ---> 0584b3d2cf6d
Step 2 : CMD tail -f /dev/null
 ---> Running in 51c3bd766516
 ---> 9ddc19b87832
Removing intermediate container 51c3bd766516
Successfully built 9ddc19b87832

コンテナを起動する。
[root@master1 test2]# docker run -d --name test-con test-img:ver1
ab0b4bd16be96e4df1fa01bd47df5e663c67a9a56d97f72d9038280d4d7d9e5b

コンテナの状態を確認する。動作して続けていることがわかる。
[root@master1 test2]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
ab0b4bd16be9        test-img:ver1       "/bin/sh -c 'tail -f "   2 minutes ago       Up 2 minutes                            test-con


5 実用編

5.1 WordPress(ブログソフトウェア)とMySQL(データベース)の連携

-------------------------------------------------------------
1. 構成
-------------------------------------------------------------
WordPressとMySQLは、以下の構成になっています。


                +--------------- Host(CentOS7.2) ------------------+
                |                                                  |
              TCP port            container             container  |
   web  <---> 10003 <----------> 80(wordpress) <------> (wp-mysql) |
 browser        |                                                  |
                |                                                  |
                +--------------------------------------------------+


-------------------------------------------------------------
2. 設定
-------------------------------------------------------------
コンテナ(MySQL)を起動する。
[root@master1 ~]# docker run -d --name wp-mysql -e MYSQL_ROOT_PASSWORD=hana_shin mysql
ac631804cc003747cfb16549b8738e5ea0d89d9c4ccc747f277397e36258ae33

コンテナ(wordpress)を起動する。linkオプションは、<連携したいコンテナ名:エイリアス名>のようにつける。
[root@master1 ~]# docker run -d --name wordpress --link wp-mysql:mysql -p 10003:80 wordpress
6c02355bd6b3d357a1d6627ebae4bd353598f096be529406ef5e161aa63e2b3f

コンテナの状態を確認する。
[root@master1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
6c02355bd6b3        wordpress           "docker-entrypoint.sh"   6 seconds ago       Up 2 seconds        0.0.0.0:10003->80/tcp   wordpress
ac631804cc00        mysql               "docker-entrypoint.sh"   11 seconds ago      Up 9 seconds        3306/tcp                wp-mysql

wordpressが取得した環境変数を表示する。
[root@master1 ~]# docker exec -it wordpress env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=6c02355bd6b3
MYSQL_PORT=tcp://172.17.0.2:3306
MYSQL_PORT_3306_TCP=tcp://172.17.0.2:3306
MYSQL_PORT_3306_TCP_ADDR=172.17.0.2
MYSQL_PORT_3306_TCP_PORT=3306
MYSQL_PORT_3306_TCP_PROTO=tcp
-以下、略-

ブラウザで下記アドレスにアクセスする。
http://192.168.0.10:10003/

5.2 CentOSとMySQLの連携(用途あるのか???)

コンテナ(MySQL)起動
[root@master1 test2]# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=hana_shin mysql
7ddd8884ada441341361d45a74bdb252c1082e1cf3226141a26e6c1b992fe17c

コンテナ(CentOS)起動
[root@master1 test2]# docker run -it --name test-con --link mysql:db centos:centos7 bash

CentOSにmysqlパッケージをインストールする。
[root@8b616eca9919 /]# yum -y install mysql
Loaded plugins: fastestmirror, ovl
-以下、略-

接続するDBのIPアドレスを確認する。
[root@8b616eca9919 /]# env|grep DB_PORT_3306_TCP_ADDR
DB_PORT_3306_TCP_ADDR=172.17.0.2

CentOSからMySQLに接続する。
[root@8b616eca9919 /]# mysql -u root -p -h 172.17.0.2
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.16 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

5.3 Jenkins(開発支援ツール)を起動する。

(1) Jenkinsを起動する。

Dockerfileを作成する。
[root@master1 test2]# vi Dockerfile
[root@master1 test2]# cat Dockerfile
FROM jenkins
COPY jenkins_plugins.txt /tmp/jenkins_plugins.txt
RUN /usr/local/bin/plugins.sh /tmp/jenkins_plugins.txt
USER root
RUN rm /tmp/jenkins_plugins.txt
RUN groupadd -g 142 docker
RUN addgroup -a jenkins docker
USER jenkins

プラグイン用ファイルを作成する。
[root@master1 test2]# vi jenkins_plugins.txt
[root@master1 test2]# cat jenkins_plugins.txt
swarm:1.22

作成したファイルを確認する。
[root@master1 test2]# ls
Dockerfile  jenkins_plugins.txt

イメージをビルドする。
[root@master1 test2]# docker build -t jenkins_server .

コンテナを起動する。
[root@master1 test2]# docker run --name jenkins_server -p 11111:8080 -p 50000:50000 -v /var/run/docker.sock:/var/run/docker.sock -v /tmp:/var/jenkins_home -d jenkins_server
64e6856dbe6ed15f575b0b916eae82c116c1bfa6300876a2ce607993120327d6

コンテナの状態を確認する。
[root@master1 test2]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                               NAMES
64e6856dbe6e        jenkins_server      "/bin/tini -- /usr/lo"   5 seconds ago       Up 3 seconds        0.0.0.0:50000->50000/tcp, 0.0.0.0:11111->8080/tcp   jenkins_server

ブラウザで下記URLにアクセスする。
http://192.168.0.10:11111/

セットアップするためのパスワード入力を求められるので、jenkinsにログインする。
[root@master1 var]# docker exec -it jenkins_server bash

jenkinsのセットアップ用パスワードを読みだす。
jenkins@64e6856dbe6e:~$ cat /var/jenkins_home/secrets/initialAdminPassword
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

パスワードを入力すると、jenkinsのセットアップが開始される。

(2) jenkinsセットアップ完了後のコンテナの状態を保存(commit)する。

コンテナの状態を確認する。
[root@master1 test2]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                               NAMES
64e6856dbe6e        jenkins_server      "/bin/tini -- /usr/lo"   16 minutes ago      Up 16 minutes       0.0.0.0:50000->50000/tcp, 0.0.0.0:11111->8080/tcp   jenkins_server

コンテナを停止する。
[root@master1 test2]# docker stop jenkins_server
jenkins_server

コンテナイメージを保存(commit)する。保存するのは、セットアップ完了済イメージ。
[root@master1 test2]# docker commit jenkins_server jenkins_server:ver1
sha256:6d5dbe73cf0422e9ba14e2577454386b3ab0600f5b379c9ced52905144522de8

イメージを確認する。セットアップ完了後のイメージは jenkins_server:ver1
[root@master1 test2]# docker images |grep jenkins_server
jenkins_server                                        ver1                               6d5dbe73cf04        55 seconds ago      714.1 MB
jenkins_server                                        latest                             b8081e64f449        21 minutes ago      714.1 MB

jenkinsを起動する。セットアップ完了後のイメージから再起動できた。
[root@master1 test2]# docker run --name jenkins_server -p 11111:8080 -p 50000:50000 -v /var/run/docker.sock:/var/run/docker.sock -v /tmp:/var/jenkins_home -d jenkins_server:ver1

6 コンテナの権限(Capabilities)

Secure Your Containers with this One Weird Trick
Hardening Docker Containers: Disable SUID Programs
CIS Docker 1.11.0 Benchmark
コンテナでcronを動かした時に出るPAMエラーの対処法
Docker networking considered harmful

6.1 コンテナの権限を確認する方法

pscapコマンドをインストールする。pscapでプロセスの権限を確認します。
[root@master1 ~]# yum -y install libcap-ng-utils

コンテナを起動する。
[root@master1 ~]# docker run -it --name test-con centos:centos7 bash

コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
[root@14cbbaf4c108 /]# [root@master1 ~]#

コンテナIDを求める。
[root@master1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@master1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

コンテナの権限(capabilities)を確認する。1行が長いので折り返しています。
[root@master1 ~]# pscap |grep $PID
ppid  pid   name   command   capabilities
1028  13295 root   bash      chown, dac_override, fowner, fsetid, kill, 
                             setgid, setuid, setpcap, net_bind_service, 
                             net_raw, sys_chroot, mknod, audit_write, setfcap

6.2 全ての権限を与える。全ての権限を落とす

------------------------------------------
1. 全ての権限を与える(--cap-add=all)
------------------------------------------
コンテナを起動する。全ての権限を与える。
[root@node1 ~]# docker run -it --cap-add=all --name test-con centos:centos7 bash

コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
[root@0f1503dc4f09 /]# [root@node1 ~]#

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。全ての権限が与えられていることがわかる。
[root@node1 ~]# pscap |grep $PID
ppid  pid   name        command           capabilities
1009  1367  root        bash            ★full


------------------------------------------
2. 全ての権限を落とす(--cap-drop=all)
------------------------------------------
コンテナを起動する。全ての権限を落とす。
[root@node1 ~]# docker run -it --cap-drop=all --name test-con centos:centos7 bash

コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
[root@536f79628b07 /]# [root@node1 ~]#

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。権限が何も与えられていることがわかる
[root@node1 ~]# pscap |grep $PID
[root@node1 ~]#

------------------------------------------
3. 特定の権限だけ与える
------------------------------------------
コンテナを起動する。全ての権限を落としてから、必要な権限だけを与える。
[root@node1 ~]# docker run -it --cap-drop=all --cap-add=NET_ADMIN --name test-con centos:centos7 bash

コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
[root@2768d178ef7d /]# [root@node1 ~]#
[root@node1 ~]#

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。NET_ADMINだけ与えられていることがわかる。
[root@node1 ~]# pscap |grep $PID
ppid  pid   name        command           capabilities
1009  1739  root        bash              net_admin

6.3 NET_ADMINの使い方(その1:経路情報の追加/削除を制御する)

-----------------------------
1. NET_ADMINが有効の場合
-----------------------------
コンテナを起動する。NET_ADMINだけ有効にする。
[root@node1 ~]# docker run -it --cap-drop=all --cap-add=NET_ADMIN  --name test-con busybox sh

経路情報を確認する。
/ # ip route show
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0  src 172.17.0.2

経路情報を追加する。
/ # ip route add 8.8.8.8 via 172.17.0.1 dev eth0

経路情報を確認する。経路情報が追加されたことがわかる。
/ # ip route show
default via 172.17.0.1 dev eth0
8.8.8.8 via 172.17.0.1 dev eth0 ★
172.17.0.0/16 dev eth0  src 172.17.0.2

コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
/ # [root@node1 ~]#

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。NET_ADMINが有効であることがわかる。
[root@node1 ~]# pscap |grep $PID
ppid  pid   name        command           capabilities
1009  2062  root        sh              ★net_admin

-----------------------------
2. NET_ADMINが無効の場合
-----------------------------
コンテナを起動する。全ての権限を落とす。
[root@node1 ~]# docker run -it --cap-drop=all --name test-con busybox sh

経路情報を確認する。
/ # ip route show
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0  src 172.17.0.2

経路情報を追加する。追加できない。
/ # ip route add 8.8.8.8 via 172.17.0.1 dev eth0
ip: RTNETLINK answers: Operation not permitted

コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
/ # [root@node1 ~]#

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。権限が何も与えられていることがわかる
[root@node1 ~]# pscap |grep $PID
[root@node1 ~]#

6.4 NET_ADMINの使い方(その2:ネットワークデバイスの作成可否を制御する)

-----------------------------
1. NET_ADMINが有効の場合
-----------------------------
コンテナを起動する。NET_ADMINだけ有効にする。
[root@node1 ~]# docker run -it --cap-drop=all --cap-add=NET_ADMIN --name test-con busybox sh

dummyタイプのデバイスを作成する。
/ # ip link add foo type dummy

デバイス(foo)が作成できた。
/ # ip link show foo
2: foo: <BROADCAST,NOARP> mtu 1500 qdisc noop
    link/ether 1a:f8:ed:6b:f0:91 brd ff:ff:ff:ff:ff:ff

デバイスを削除する。
/ # ip link del foo

デバイスが削除できたことがわかる。
/ # ip link show foo
ip: can't find device 'foo'

コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
/ # [root@node1 ~]#

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。NET_ADMINが有効であることがわかる。
[root@node1 ~]# pscap |grep $PID
ppid  pid   name        command           capabilities
1009  3378  root        sh              ★net_admin

-----------------------------
2. NET_ADMINが無効の場合
-----------------------------
コンテナを起動する。全ての権限を無効にする。
[root@node1 ~]# docker run -it --cap-drop=all --name test-con busybox sh

デバイス(foo)を作成する。しかし権限がないため作成できない。
/ # ip link add foo type dummy
ip: RTNETLINK answers: Operation not permitted

コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
/ # [root@node1 ~]#

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。権限が何も与えられていることがわかる
[root@node1 ~]# pscap |grep $PID
[root@node1 ~]#

6.5 NET_BIND_SERVICEの使い方(特権ポートでのリッスンを制御する)

----------------------------------
1. NET_BIND_SERVICEが有効の場合
----------------------------------
コンテナを起動する。NET_BIND_SERVICEだけ有効にする。
[root@node1 ~]# docker run -it --cap-drop=all --cap-add=NET_BIND_SERVICE  --name test-con busybox sh

rotoユーザで実行する。
/ # id
uid=0(root) gid=0(root) groups=10(wheel)

一般ポート(80)でリッスンする。リッスンできた。Ctrl+Cで終了。
/ # nc -l -p 80
^C
一般ポート(1023)でリッスンする。リッスンできた。Ctrl+Cで終了。
/ # nc -l -p 1023
^C
特権ポート(1024以上)でリッスンする。リッスンできた。Ctrl+Cで終了。
/ # nc -l -p 1024
^C
/ #


別ターミナルを開く。リッスンしているポート番号が確認できる。
[root@node1 ~]# docker exec -it test-con sh
/ # netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 :::80★                 :::*                    LISTEN      20/nc

/ # netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 :::1023★               :::*                    LISTEN      22/nc

/ # netstat -antp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 :::1024★

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。NET_BIND_SERVICEが有効であることがわかる。
[root@node1 ~]# pscap |grep $PID
ppid  pid   name        command           capabilities
2308  2357  root        nc              ★net_bind_service

----------------------------------
2. NET_BIND_SERVICEが無効の場合
----------------------------------
コンテナを起動する。全ての権限を無効にする。
[root@node1 ~]# docker run -it --cap-drop=all --name test-con busybox sh

rotoユーザで実行する。
/ # id
uid=0(root) gid=0(root) groups=10(wheel)

特権ポート(1-1023)ではリッスンできない。
/ # nc -l -p 80
nc: bind: Permission denied

一般ポートではリッスンできる。
[root@node1 ~]# docker exec -it test-con sh
/ # nc -l -p 1024
^C

コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
/ # [root@node1 ~]#
[root@node1 ~]#

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。権限が何も与えられていることがわかる
[root@node1 ~]# pscap |grep $PID
[root@node1 ~]#

6.6 NET_RAWの使い方

ping,traceroute,arping,tcpdumpといったプログラムが使えなくなる。

-----------------------------
1. NET_RAWが有効の場合
-----------------------------
コンテナを起動する。NET_RAWだけ有効にする。
[root@node1 ~]# docker run -it --cap-drop=all --cap-add=NET_RAW busybox sh

経路情報を検索する。(ping,tracerouteの宛先を確認するため)
/ # ip route show
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0  src 172.17.0.2

pingを実行する。応答がある。
/ # ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: seq=0 ttl=64 time=0.194 ms
-以下、略-

tracerouteを実行する。応答がある。
/ # traceroute 172.17.0.1
traceroute to 172.17.0.1 (172.17.0.1), 30 hops max, 46 byte packets
 1  172.17.0.1 (172.17.0.1)  0.016 ms  0.070 ms  0.016 ms

arpingを実行する。ルータのMACアドレスを得ることができる。
/ # arping -I eth0 172.17.0.1
ARPING to 172.17.0.1 from 172.17.0.2 via eth0
Unicast reply from 172.17.0.1 [02:42:4c:40:95:b7] 0.031ms
-以下、略-


-----------------------------
2. NET_RAWが無効の場合
-----------------------------
コンテナを起動する。全ての権限を無効にする。
[root@node1 ~]# docker run -it --cap-drop=all busybox sh

経路情報を検索する。(ping,tracerouteの宛先を確認するため)
/ # ip route show
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0  src 172.17.0.2

pingを実行する。応答がない。
/ # ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1): 56 data bytes
ping: permission denied (are you root?)

tracerouteを実行する。応答がない。
/ # traceroute 172.17.0.1
traceroute: socket: Operation not permitted

arpingを実行する。応答がない。
/ # arping -I eth0 172.17.0.1
arping: socket: Operation not permitted


busyboxにはyum,tcpdumpが入っていないので、centos7で確認。
[root@node1 ~]# docker run -it --rm --cap-drop=NET_RAW centos:centos7 bash
[root@f54069514adf /]# yum -y install tcpdump
[root@f54069514adf /]# tcpdump -i eth0 port 80
tcpdump: eth0: You don't have permission to capture on that device
(socket: Operation not permitted)

6.7 MKNODの使い方

-----------------------------
1. MKNODが有効な場合
-----------------------------
コンテナを起動する。MKNODだけ有効にする。
[root@node1 ~]# docker run -it --cap-drop=all --cap-add=MKNOD --name test-con busybox sh

デバイスを作成する。
/ # mknod -m 660 /dev/hda b 56 0

デバイスを確認する。作成できた。
/ # ls -la /dev/hda
brw-rw----    1 root     root       56,   0 Dec 16 12:07 /dev/hda


コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
/ # [root@node1 ~]#

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。MKNODが有効であることがわかる。
[root@node1 ~]# pscap |grep $PID
ppid  pid   name        command           capabilities
1009  3118  root        sh              ★mknod

-----------------------------
2. MKNODが無効な場合
-----------------------------
コンテナを起動する。全ての権限を無効にする。
[root@node1 ~]# docker run -it --cap-drop=all --name test-con busybox sh

デバイスを作成する。しかし、作成できない。
/ # mknod -m 660 /dev/hda b 56 0
mknod: /dev/hda: Operation not permitted

コンテナからぬける(Ctrlキーを押下しながら、PキーとQキーを押下する)
/ # [root@node1 ~]#
[root@node1 ~]#

コンテナIDからコンテナのPIDを求める。
[root@node1 ~]# CID=$(docker ps --no-trunc=true|grep -w "test-con"|awk '{print $1}')
[root@node1 ~]# PID=$(docker inspect --format {{.State.Pid}} $CID)

権限を確認する。MKNODが無効であることがわかる。
[root@node1 ~]# pscap |grep $PID
[root@node1 ~]#

6.8 CHOWNの使い方

-----------------------------
1. CHOWNが有効の場合
-----------------------------
コンテナを起動する。CHOWNだけ有効にする。
[root@node1 ~]# docker run -it --cap-drop=all --cap-add=CHOWN busybox sh

ファイルを作成する。所有者、グループを確認する。
/ # touch /tmp/aa.txt
/ # ls -la /tmp/aa.txt
-rw-r--r--    1 root     root             0 Dec 18 12:01 /tmp/aa.txt

所有者、グループを変更する。
/ # id daemon
uid=1(daemon) gid=1(daemon) groups=1(daemon)
/ # chown daemon:daemon /tmp/aa.txt

所有者、グループを確認する。変更できた。
/ # ls -la /tmp/aa.txt
-rw-r--r--    1 daemon   daemon           0 Dec 18 12:01 /tmp/aa.txt


-----------------------------
2. CHOWNが無効の場合
-----------------------------
コンテナを起動する。全ての権限を無効にする。
[root@node1 ~]# docker run -it --cap-drop=all busybox sh

ファイルを作成する。所有者、グループを確認する。
/ # touch /tmp/aa.txt
/ # ls -la /tmp/aa.txt
-rw-r--r--    1 root     root             0 Dec 18 12:03 /tmp/aa.txt

所有者、グループを確認する。変更できない。
/ # chown daemon:daemon /tmp/aa.txt
chown: /tmp/aa.txt: Operation not permitted

6.9 SETUIDの使い方

Added no-new-privileges Security Flag to Docker

使い方がよくわからない。想定通りに動作しない!!!

テスト用プログラム(実行ユーザIDを確認する)を作成する。
[root@node1 test]# vi uid_test.c
[root@node1 test]# cat uid_test.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char *argv[])
{
        printf("Effective uid: %d\n", geteuid());
        return 0;
}

Dockerfileを作成する。
[root@node1 test]# vi Dockerfile
[root@node1 test]# cat Dockerfile
FROM centos:centos7
ADD uid_test /tmp/uid_test
RUN chmod u+s /tmp/uid_test
RUN useradd -u 2000 hana_shin
USER hana_shin
ENTRYPOINT /tmp/uid_test

[root@node1 test]# ls
Dockerfile  uid_test  uid_test.c

イメージをビルドする。
[root@node1 test]# docker build -t test-img:ver1 .
Sending build context to Docker daemon 12.29 kB
-以下、略-

7. セキュリティ

7.1 イメージの署名チェック機能(DOCKER_CONTENT_TRUST)を有効にする

イメージの署名チェック機能を有効にすると、イメージが改ざんされているかどうか確認できる。
本機能はDocker1.8で実装された。

--------------------------------------------------------
1. 署名チェック機能(DOCKER_CONTENT_TRUST)について確認する。
--------------------------------------------------------
イメージの署名チェック機能を有効にする。
[root@master1 ~]# export DOCKER_CONTENT_TRUST=1

イメージをダウンロードする。
[root@master1 ~]# docker pull busybox
Using default tag: latest
Pull (1 of 1): docker.io/busybox:latest@sha256:29f5d56d12684887bdfa50dcd29fc31eea4aaf4ad3bec43daf19026a7ce69912
Trying to pull repository docker.io/library/busybox ...
sha256:29f5d56d12684887bdfa50dcd29fc31eea4aaf4ad3bec43daf19026a7ce69912: Pulling from docker.io/library/busybox
56bec22e3559: Pull complete
Digest: sha256:29f5d56d12684887bdfa50dcd29fc31eea4aaf4ad3bec43daf19026a7ce69912
Status: Downloaded newer image for docker.io/busybox@sha256:29f5d56d12684887bdfa50dcd29fc31eea4aaf4ad3bec43daf19026a7ce69912
Tagging docker.io/busybox@sha256:29f5d56d12684887bdfa50dcd29fc31eea4aaf4ad3bec43daf19026a7ce69912 as docker.io/busybox:latest

イメージがダウンロードできた。
[root@master1 ~]# docker images |grep busybox
docker.io/busybox                                     latest                             e02e811dd08f        7 weeks ago         1.093 MB
docker.io/busybox                                     <none>                             e02e811dd08f        7 weeks ago         1.093 MB


別のイメージをダウンロードする。イメージに署名がないため、ダウンロードが失敗する。
[root@master1 ~]# docker pull sdurrheimer/prom-busybox
Using default tag: latest
Error: remote trust data does not exist for docker.io/sdurrheimer/prom-busybox: notary.docker.io does not have trust data for docker.io/sdurrheimer/prom-busybox

                                  <none>                             e02e811dd08f        7 weeks ago         1.093 MB

署名チェック機能を無効にする。
[root@master1 ~]# export DOCKER_CONTENT_TRUST=0

もう一度、イメージをダウンロードする。署名チェック機能が無効なので、イメージに署名がなくてもダウンロードできた。
[root@master1 ~]# docker pull sdurrheimer/prom-busybox
Using default tag: latest
Trying to pull repository docker.io/sdurrheimer/prom-busybox ...
latest: Pulling from docker.io/sdurrheimer/prom-busybox
56bec22e3559: Already exists
2e3e1c51b98e: Pull complete
Digest: sha256:d2db77d1721fc54fab36939e94a329572c274ec4870d846771264991a0cd94d1
Status: Downloaded newer image for docker.io/sdurrheimer/prom-busybox:latest

イメージを確認する。公式のBusyboxに加え、prom-busyboxというイメージもダウンロードできた。
[root@master1 ~]# docker images |grep busybox
docker.io/sdurrheimer/prom-busybox                    latest                             172d95747d74        7 weeks ago         2.492 MB
docker.io/busybox                                     latest                             e02e811dd08f        7 weeks ago         1.093 MB
docker.io/busybox                                     <none>                             e02e811dd08f        7 weeks ago         1.093 MB
[root@master1 ~]#


--------------------------------------------------------------------------
2. 特定のイメージだけチェック機能を無効にしたい場合(--disable-content-trust)
--------------------------------------------------------------------------
イメージの署名チェック機能を有効にする。
[root@master1 ~]# export DOCKER_CONTENT_TRUST=1

イメージをダウンロードする。署名がないのでダウンロードできない。
[root@master1 ~]# docker pull sdurrheimer/prom-busybox
Using default tag: latest
Error: remote trust data does not exist for docker.io/sdurrheimer/prom-busybox: notary.docker.io does not have trust data for docker.io/sdurrheimer/prom-busybox

署名がなくてもダウンロードできるオプション(--disable-content-trust)をつけて、ダウンロードする。
[root@master1 ~]# docker pull --disable-content-trust sdurrheimer/prom-busybox
Using default tag: latest
Trying to pull repository docker.io/sdurrheimer/prom-busybox ...
latest: Pulling from docker.io/sdurrheimer/prom-busybox
56bec22e3559: Pull complete
2e3e1c51b98e: Pull complete
Digest: sha256:d2db77d1721fc54fab36939e94a329572c274ec4870d846771264991a0cd94d1
Status: Downloaded newer image for docker.io/sdurrheimer/prom-busybox:latest

7.2 コンテナ間通信を禁止(--icc=false)にする方法

-------------------------------------------------
1. デフォルト(--icc=true)のときの挙動を調べる
-------------------------------------------------
コンテナを起動する。コンテナは5001番ポートで接続待ち状態にしておく。
[root@master1 ~]# docker run -d --name nc-test amouat/network-utils nc -l 5001
b8f13cffe0748431b05ed08491c3fa36b3173ba9b4e5a93abdcf35ae89e4cb7e

コンテナの状態を確認する。
[root@master1 ~]# docker ps
CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS              PORTS               NAMES
b8f13cffe074        amouat/network-utils   "nc -l 5001"        8 seconds ago       Up 4 seconds                            nc-test

接続待ちコンテナにメッセージ(hello)を送ることができる。
[root@master1 ~]# docker run -e IP=$(docker inspect -f {{.NetworkSettings.IPAddress}} nc-test) amouat/network-utils sh -c 'echo -n "hello" | nc -w 2 -v $IP 5001'
Connection to 172.17.0.2 5001 port [tcp/*] succeeded!


-------------------------------------------------
2. コンテナ間通信を無効(--icc=false)にする
-------------------------------------------------
[root@master1 ~]# vi /etc/sysconfig/docker
[root@master1 ~]# cat /etc/sysconfig/docker|grep OPTIONS
OPTIONS='--iptables=true --icc=false'

設定を反映する。
[root@master1 ~]# systemctl restart docker

設定を確認する。--icc=falseが設定されていることがわかる。
[root@master1 ~]# ps -C docker-current -o cmd
CMD
/usr/bin/docker-current daemon --exec-opt native.cgroupdriver=systemd --iptables=true ★--icc=false --storage-opt dm.basesize=50G --insecure-registry 192.
[root@master1 ~]#

コンテナを起動する。コンテナは5001番ポートで接続待ち状態にしておく。
[root@master1 ~]# docker run -d --name nc-test amouat/network-utils nc -l 5001
11d2572c0efa9b43c8818fa01922035965653ffcc669de4df2fed1dcea186a07

コンテナの状態を確認する。
[root@master1 ~]# docker ps
CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS              PORTS               NAMES
11d2572c0efa        amouat/network-utils   "nc -l 5001"        14 seconds ago      Up 11 seconds                           nc-test

接続待ちコンテナにメッセージ(hello)を送る。しかし、今度は送信できない。
[root@master1 ~]# docker run -e IP=$(docker inspect -f {{.NetworkSettings.IPAddress}} nc-test) amouat/network-utils sh -c 'echo -n "hello" | nc -w 2 -v $IP 5001'
nc: connect to 172.17.0.2 port 5001 (tcp) timed out: Operation now in progress

7.3 Docker Bench for Securityを使う

Docker Bench for Securityをつかって、
コンテナのセキュリティチェックを行う。現時点では使い方だけ。

-------------------------------------------------------------
1. Docker Bench for Securityのイメージをビルドする。
-------------------------------------------------------------
Docker Bench for Securityをダウンロードする。
[root@master1 ~]# git clone https://github.com/docker/docker-bench-security.git
Cloning into 'docker-bench-security'...
remote: Counting objects: 810, done.
remote: Total 810 (delta 0), reused 0 (delta 0), pack-reused 810
Receiving objects: 100% (810/810), 395.98 KiB | 153.00 KiB/s, done.
Resolving deltas: 100% (546/546), done.

ビルドするディレクトリに移動する。
[root@master1 ~]# cd docker-bench-security/
[root@master1 docker-bench-security]# ls
CONTRIBUTING.md  LICENSE.md   README.md          distros                   docker-compose.yml  output_lib.sh
Dockerfile       MAINTAINERS  benchmark_log.png  docker-bench-security.sh  helper_lib.sh       tests

イメージをビルドする。
[root@master1 docker-bench-security]# docker build -t docker-bench-security .
Sending build context to Docker daemon 154.1 kB
Step 1 : FROM alpine:3.2
 ---> 7bed0150ea37
-以下、略-

イメージを確認する。
[root@master1 docker-bench-security]# docker images docker-bench-security
REPOSITORY              TAG            IMAGE ID           CREATED             SIZE
docker-bench-security   latest         d59bf3a4d941       24 seconds ago      41.21 MB


-------------------------------------------------------------
2. 試験対象のコンテナを起動する。
-------------------------------------------------------------
試験対象(Nginx)のコンテナを起動する。
[root@master1 docker-bench-security]# docker run -d --name nginx nginx
5ffaf5d636bf575b066b1e9995157c0600e5b8b645dc8b023c1239d564e5840e

コンテナの状態を確認する。
[root@master1 docker-bench-security]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
5ffaf5d636bf        nginx               "nginx -g 'daemon off"   6 seconds ago       Up 4 seconds        80/tcp, 443/tcp     nginx
[root@master1 docker-bench-security]#


-------------------------------------------------------------
3. コンテナのセキュリティチェックを行う。
-------------------------------------------------------------
Docker Bench for Securityを実行する。続けて、セキュリティチェックの実行結果が表示される。
Nginxのチェック結果には★印をつけています。
[root@master1 docker-bench-security]# docker run -it --net host --pid host --cap-add audit_control \
      -v /var/lib:/var/lib \
      -v /var/run/docker.sock:/var/run/docker.sock \
      -v /usr/lib/systemd:/usr/lib/systemd \
      -v /etc:/etc --label docker_bench_security \
      docker-bench-security
# ------------------------------------------------------------------------------
# Docker Bench for Security v1.1.0
#
# Docker, Inc. (c) 2015-
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Inspired by the CIS Docker 1.11 Benchmark:
# https://benchmarks.cisecurity.org/downloads/show-single/index.cfm?file=docker16.110
# ------------------------------------------------------------------------------

Initializing Sun Dec  4 09:09:01 GMT 2016


[INFO] 1 - Host Configuration
[WARN] 1.1  - Create a separate partition for containers
[PASS] 1.2  - Use an updated Linux Kernel
[WARN] 1.4  - Remove all non-essential services from the host - Network
[WARN]      * Host listening on: 13 ports
[WARN] 1.5  - Keep Docker up to date
[WARN]       * Using 1.10.3, when 1.12.3 is current as of 2016-10-26
[INFO]       * Your operating system vendor may provide support and security maintenance for docker
[INFO] 1.6  - Only allow trusted users to control Docker daemon
[WARN] 1.7  - Failed to inspect: auditctl command not found.
[WARN] 1.8  - Failed to inspect: auditctl command not found.
[WARN] 1.9  - Failed to inspect: auditctl command not found.
[WARN] 1.10 - Failed to inspect: auditctl command not found.
[INFO] 1.11 - Audit Docker files and directories - docker.socket
[INFO]      * File not found
[INFO] 1.12 - Audit Docker files and directories - /etc/default/docker
[INFO]      * File not found
[INFO] 1.13 - Audit Docker files and directories - /etc/docker/daemon.json
[INFO]      * File not found
[INFO] 1.14 - Audit Docker files and directories - /usr/bin/docker-containerd
[INFO]      * File not found
[INFO] 1.15 - Audit Docker files and directories - /usr/bin/docker-runc
[INFO]      * File not found


[INFO] 2 - Docker Daemon Configuration
[WARN] 2.1  - Restrict network traffic between containers
[WARN] 2.2  - Set the logging level
[PASS] 2.3  - Allow Docker to make changes to iptables
[PASS] 2.4  - Do not use insecure registries
[PASS] 2.5  - Do not use the aufs storage driver
[INFO] 2.6  - Configure TLS authentication for Docker daemon
[INFO]      * Docker daemon not listening on TCP
[INFO] 2.7 - Set default ulimit as appropriate
[INFO]      * Default ulimit doesn't appear to be set
[WARN] 2.8  - Enable user namespace support
[PASS] 2.9  - Confirm default cgroup usage
[PASS] 2.10 - Do not change base device size until needed
[WARN] 2.11 - Use authorization plugin
[WARN] 2.12 - Configure centralized and remote logging
[WARN] 2.13 - Disable operations on legacy registry (v1)


[INFO] 3 - Docker Daemon Configuration Files
[PASS] 3.1  - Verify that docker.service file ownership is set to root:root
[PASS] 3.2  - Verify that docker.service file permissions are set to 644
[INFO] 3.3  - Verify that docker.socket file ownership is set to root:root
[INFO]      * File not found
[INFO] 3.4  - Verify that docker.socket file permissions are set to 644
[INFO]      * File not found
[PASS] 3.5  - Verify that /etc/docker directory ownership is set to root:root
[PASS] 3.6  - Verify that /etc/docker directory permissions are set to 755
[PASS] 3.7  - Verify that registry certificate file ownership is set to root:root
[PASS] 3.8  - Verify that registry certificate file permissions are set to 444
[INFO] 3.9  - Verify that TLS CA certificate file ownership is set to root:root
[INFO]      * No TLS CA certificate found
[INFO] 3.10 - Verify that TLS CA certificate file permissions are set to 444
[INFO]      * No TLS CA certificate found
[INFO] 3.11 - Verify that Docker server certificate file ownership is set to root:root
[INFO]      * No TLS Server certificate found
[INFO] 3.12 - Verify that Docker server certificate file permissions are set to 444
[INFO]      * No TLS Server certificate found
[INFO] 3.13 - Verify that Docker server key file ownership is set to root:root
[INFO]      * No TLS Key found
[INFO] 3.14 - Verify that Docker server key file permissions are set to 400
[INFO]      * No TLS Key found
[WARN] 3.15 - Verify that Docker socket file ownership is set to root:docker
[WARN]      * Wrong ownership for /var/run/docker.sock
[PASS] 3.16 - Verify that Docker socket file permissions are set to 660
[INFO] 3.17 - Verify that daemon.json file ownership is set to root:root
[INFO]      * File not found
[INFO] 3.18 - Verify that daemon.json file permissions are set to 644
[INFO]      * File not found
[INFO] 3.19 - Verify that /etc/default/docker file ownership is set to root:root
[INFO]      * File not found
[INFO] 3.20 - Verify that /etc/default/docker file permissions are set to 644
[INFO]      * File not found


[INFO] 4 - Container Images and Build Files
[WARN] 4.1  - Create a user for the container
[WARN]      * Running as root: nginx  ★
[WARN] 4.5  - Enable Content trust for Docker


[INFO] 5  - Container Runtime
[WARN] 5.1  - Verify AppArmor Profile, if applicable
[WARN]      * No AppArmorProfile Found: nginx  ★
[WARN] 5.2  - Verify SELinux security options, if applicable
[WARN]      * No SecurityOptions Found: nginx  ★
[PASS] 5.3  - Restrict Linux Kernel Capabilities within containers
[PASS] 5.4  - Do not use privileged containers
[PASS] 5.5  - Do not mount sensitive host system directories on containers
[PASS] 5.6  - Do not run ssh within containers
[PASS] 5.7  - Do not map privileged ports within containers
[PASS] 5.9 - Do not share the host's network namespace
[WARN] 5.10 - Limit memory usage for container
[WARN]      * Container running without memory restrictions: nginx ★
[WARN] 5.11 - Set container CPU priority appropriately
[WARN]      * Container running without CPU restrictions: nginx ★
[WARN] 5.12 - Mount container's root filesystem as read only
[WARN]      * Container running with root FS mounted R/W: nginx  ★
[PASS] 5.13 - Bind incoming container traffic to a specific host interface
[WARN] 5.14 - Set the 'on-failure' container restart policy to 5
[WARN]      * MaximumRetryCount is not set to 5: nginx     ★
[PASS] 5.15 - Do not share the host's process namespace
[PASS] 5.16 - Do not share the host's IPC namespace
[PASS] 5.17 - Do not directly expose host devices to containers
[INFO] 5.18 - Override default ulimit at runtime only if needed
[INFO]      * Container no default ulimit override: nginx   ★
[PASS] 5.19 - Do not set mount propagation mode to shared
[PASS] 5.20 - Do not share the host's UTS namespace
[PASS] 5.21 - Do not disable default seccomp profile
[PASS] 5.24 - Confirm cgroup usage
[WARN] 5.25 - Restrict container from acquiring additional privileges
[WARN]      * Privileges not restricted: nginx   ★


[INFO] 6  - Docker Security Operations
[INFO] 6.4 - Avoid image sprawl
[INFO]      * There are currently: 22 images
[WARN]      * Only 2 out of 22 are in use
[INFO] 6.5 - Avoid container sprawl
[INFO]      * There are currently a total of 2 containers, with 2 of them currently running
[root@master1 docker-bench-security]#

7.3.1 "[WARN] * Running as root: <コンテナの名前>"に対処する

コンテナがrootユーザで動作しているために出力される警告です。
コンテナを一般ユーザで動かすことで警告は解消されます。

[root@node1 test]# vi Dockerfile
[root@node1 test]# cat Dockerfile
FROM centos:centos7
RUN useradd -u 2000 hana_shin
USER hana_shin
[root@node1 test]# docker build -t test-img:ver1 --no-cache=true .
Sending build context to Docker daemon  5.12 kB
-以下、略-

[root@node1 test]# docker run -it --name test-con test-img:ver1 bash
[hana_shin@54ba61db5ac7 /]$ id
uid=2000(hana_shin) gid=2000(hana_shin) groups=2000(hana_shin)

8 dockerのデバッグオプション

8.1 デバッグオプションの指定方法

定義ファイル(/etc/sysconfig/docker)の--log-levelにデバッグレベルを指定する。
デバッグレベルとしては以下のものがある。fatalが最も重要度が高く、debugが最も重要度が低い。

 1. fatal(優先度高)
 2. error
 3. warning
 4. info(デフォルト)
 5. debug(優先度低)

デフォルトはinfoレベルになっている。info以上のログを出力する。
debugを指定すると、全てのレベルのログを出力することになる。

デバッグレベルにdebugを指定した場合を以下に示す。
[root@master ~]# vi /etc/sysconfig/docker
OPTIONS='--log-level=debug'

8.2 infoを指定した場合(「デフォルトのレベル)

infoを指定すると、info以上のレベルのものが表示されるようになる。

dockerを起動する。
[root@master ~]# systemctl start docker

別のターミナルをひらいて、syslogを確認する。warningとinfoレベルのログが出力されていることがわかる。
[root@master ~]# tail -f /var/log/messages|grep -E '(fatal|error|warning|info|debug)'
Mar 12 10:02:46 master dockerd-current: time="2017-03-12T10:02:46.494348443+09:00" level=info msg="libcontainerd: new containerd process, pid: 12877"
Mar 12 10:02:47 master dockerd-current: time="2017-03-12T10:02:47.734320975+09:00" level=warning msg="devmapper: Usage of loopback devices is strongly discouraged for production use. Please use `--storage-opt dm.thinpooldev` or use `man docker` to refer to dm.thinpooldev section."
Mar 12 10:02:47 master dockerd-current: time="2017-03-12T10:02:47.937309476+09:00" level=warning msg="devmapper: Base device already exists and has filesystem xfs on it. User specified filesystem  will be ignored."
Mar 12 10:02:48 master dockerd-current: time="2017-03-12T10:02:48.031061132+09:00" level=info msg="[graphdriver] using prior storage driver \"devicemapper\""
Mar 12 10:02:48 master dockerd-current: time="2017-03-12T10:02:48.054100692+09:00" level=info msg="Graph migration to content-addressability took 0.00 seconds"
Mar 12 10:02:48 master dockerd-current: time="2017-03-12T10:02:48.058632306+09:00" level=info msg="Loading containers: start."
Mar 12 10:02:49 master dockerd-current: time="2017-03-12T10:02:49.018324023+09:00" level=info msg="Loading containers: done."
Mar 12 10:02:49 master dockerd-current: time="2017-03-12T10:02:49.021027153+09:00" level=info msg="Daemon has completed initialization"
Mar 12 10:02:49 master dockerd-current: time="2017-03-12T10:02:49.021911520+09:00" level=info msg="Docker daemon" commit="047e51b/1.12.5" graphdriver=devicemapper version=1.12.5
Mar 12 10:02:49 master dockerd-current: time="2017-03-12T10:02:49.106995415+09:00" level=info msg="API listen on /var/run/docker.sock"

8.3 warningを指定した場合

warningを指定すると、warning以上のレベルのものが表示されるようになる。

[root@master ~]# vi /etc/sysconfig/docker
OPTIONS='--log-level=warning'

dockerを起動する。
[root@master ~]# systemctl start docker

別のターミナルをひらいて、syslogを確認する。warningレベルのログだけが出力されていることがわかる。
infoレベルのログは出力されなくなったことがわかる。
Mar 12 10:15:09 master dockerd-current: time="2017-03-12T10:15:09.791169342+09:00" level=warning msg="devmapper: Usage of loopback devices is strongly discouraged for production use. Please use `--storage-opt dm.thinpooldev` or use `man docker` to refer to dm.thinpooldev section."
Mar 12 10:15:09 master dockerd-current: time="2017-03-12T10:15:09.962940297+09:00" level=warning msg="devmapper: Base device already exists and has filesystem xfs on it. User specified filesystem  will be ignored."

9.各種イメージの起動

----------------
1. CentOS5.11
----------------
コンテナを起動する。
[root@master1 ~]# docker run -it --rm centos:centos5.11 bash
Unable to find image 'centos:centos5.11' locally
Trying to pull repository docker.io/library/centos ...
centos5.11: Pulling from docker.io/library/centos
2068b24f564b: Pull complete
Digest: sha256:c40041f5894293d0df8f5c6c2049b92a82c53f1718ecdd73cbf3c1826a08ba4a
Status: Downloaded newer image for docker.io/centos:centos5.11

版数を確認する。
[root@4d4c5a456ff3 /]# cat /etc/redhat-release
CentOS release 5.11 (Final)

[root@master1 ~]# docker images centos:centos5.11
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos    centos5.11          b424fba01172        4 months ago        284.1 MB

----------------
2. CentOS6.8
----------------
コンテナを起動する。
[root@master1 ~]# docker run -it --rm centos:centos6.8 bash
Unable to find image 'centos:centos6.8' locally
Trying to pull repository docker.io/library/centos ...
centos6.8: Pulling from docker.io/library/centos
67f15db7c18f: Pull complete
Digest: sha256:37ee2dcd9a3a430136b566efb4aa1111ed332bfdef8b0de51a25d26891689fd7
Status: Downloaded newer image for docker.io/centos:centos6.8

版数を確認する。
[root@805bd6c7ec2f /]# cat /etc/redhat-release
CentOS release 6.8 (Final)
[root@805bd6c7ec2f /]#

[root@master1 ~]# docker images centos:centos6.8
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos    centos6.8           0cd976dc0a98        4 months ago        194.5 MB

----------------
3. CentOS7.2
----------------
コンテナを起動する。
[root@master1 ~]# docker run -it centos:centos7.2.1511 bash

版数を確認する。
[root@7726e3a77531 /]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[root@7726e3a77531 /]#
[root@7726e3a77531 /]# exit
exit
[root@master1 ~]# docker images centos:centos7.2.1511
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos    centos7.2.1511      feac5e0dfdb2        4 months ago        194.6 MB
[root@master1 ~]#

----------------
4. CentOS7.3
----------------
コンテナを起動する。
[root@master1 ~]# docker run -it centos:centos7.3.1611 bash
Unable to find image 'centos:centos7.3.1611' locally
Trying to pull repository docker.io/library/centos ...
centos7.3.1611: Pulling from docker.io/library/centos
Digest: sha256:c577af3197aacedf79c5a204cd7f493c8e07ffbce7f88f7600bf19c688c38799
Status: Downloaded newer image for docker.io/centos:centos7.3.1611

版数を確認する。
[root@b66640a84593 /]# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
[root@b66640a84593 /]# exit
exit
[root@master1 ~]# docker images centos:centos7.3.1611
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos    centos7.3.1611      67591570dd29        5 weeks ago         191.8 MB
[root@master1 ~]#

10. 参考資料

Dockerプライベートリポジトリ(Docker Registry)構築レシピ
Docker ドキュメント日本語化プロジェクト
さくらのナレッジ
Docker Content Trust 入門
Docker Content Trust Gets Hardware Signing
Alien (ソフトウェア)
Dockerfile ベストプラクティス

Docker実践入門
Docker実践ガイド
プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化

Best practices for writing Dockerfiles
Create the smallest possible Docker container
[初心者向け] Dockerコンテナの内側
Docker/Aarukas入門ハンズオン資料~第1回さくらとコンテナの夕べ #さくらの夕べ 番外編