RHEL8からdockerコマンドの代わりにpodmanコマンドの利用が推奨されるようになったので、podmanコマンドの使い方を以下のページに作成しました。
コンテナ起動時、コンテナ間通信の処理概要(Podman編)
コンテナイメージのレジストリ検索方法(Podman編)
podmanコマンドの使い方(Almalinux9)
podmanコマンドの使い方
コンテナーのネットワークについて
コンテナイメージのレジストリ検索方法(Podman編)
Podmanでコンテナ/ホスト間でファイルをコピーする方法
コンテナイメージの作り方(Containerfile 編)
Podman secretコマンドの使い方
仮想ファイルシステムのマスク/アンマスク方法
httpdコンテナの起動方法
コンテナを自動更新する方法
#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
別ターミナルを起動して、コンテナ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
##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)
[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 dockerイメージから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 で 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.各種イメージの起動
コンテナを起動する。
[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
コンテナを起動する。
[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
コンテナを起動する。
[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 ~]#
コンテナを起動する。
[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
#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回さくらとコンテナの夕べ #さくらの夕べ 番外編