SlideShare a Scribd company logo
Linux女子部 Dockerを支える技術
ver1.8 中井悦司
Twitter @enakai00
オープンクラウド・キャンパス
Linux女子部
Dockerを支える技術
Open Cloud Campus
2
Linux女子部 Dockerを支える技術
自己紹介
 中井悦司(なかいえつじ)
– Twitter @enakai00
 日々の仕事
– Senior Solution Architect and
Cloud Evangelist at Red Hat K.K.
企業システムでオープンソースの活用を希望される
お客様を全力でご支援させていただきます。
 昔とった杵柄
– 素粒子論の研究(超弦理論とか)
– 予備校講師(物理担当)
– インフラエンジニア(Unix/Linux専門)
好評発売中!
Open Cloud Campus
3
Linux女子部 Dockerを支える技術
Contents
 Linuxコンテナ
 Device Mapper Thin-Provisioning
 Network Namespace
 systemdとcgroups
 参考資料
(*) 本資料の説明は、Fedora20の「docker-io-1.0.0-1.fc20.x86_64」を前提としています。
Linux女子部 Dockerを支える技術
Linuxコンテナ
Open Cloud Campus
5
Linux女子部 Dockerを支える技術
一般的なサーバ仮想化の分類
物理マシン
物理マシン
ホスト OS
ハイパーバイザ
(カーネルモジュール)
仮想
マシン
ゲスト
OS
VMware vSphere, Xen など
Linux KVM
ハードウェアによる仮想化
(物理マシンにハイパーバイザを内蔵)
ソフトウェアによる仮想化
(物理マシン上にハイパーバイザを導入)
ソフトウェアによる仮想化
(ホスト OS にハイパーバイザ機能を追加)
物理マシン
OS
非仮想化環境
基本的には「物理マシン」と同等の「仮想マシン」を複数
作り出す技術です。
仮想
マシン
ゲスト
OS
仮想
マシン
ゲスト
OS
仮想
マシン
ゲスト
OS
仮想
マシン
ゲスト
OS
仮想
マシン
ゲスト
OS
仮想
マシン
ゲスト
OS
仮想
マシン
ゲスト
OS
ハイパーバイザ(ソフトウェア)
仮想
マシン
ゲスト
OS
仮想
マシン
ゲスト
OS
仮想
マシン
ゲスト
OS
物理マシン
ハイパーバイザ(ファームウェア)
Open Cloud Campus
6
Linux女子部 Dockerを支える技術
 「Linuxコンテナ」は、Linux標準のコンテナ型仮想化技術です。Linuxカーネルの機能によ
り、ユーザプロセスの実行環境(ユーザ空間)を独立した「コンテナ」に閉じ込めます。
 コンテナごとに独立したリソースを割り当てることで、アプリケーションの実行環境を分離
します。「カーネル共有型」の軽量な仮想化機能と言えます。
– コンテナごとに異なるファイルシステムを割り当て
– コンテナごとに異なるネットワーク設定(仮想NIC)を割り当て
– コンテナごとにCPU、メモリーの割り当て量を制限
 クラウド上のLinux仮想マシンの上で、コンテナを利用することも可能です。
カーネル空間
ユーザプロセス
・・・
物理マシン
物理マシン
OS
コンテナ型仮想化
非仮想化環境
ユーザプロセス
ユーザプロセス
ユーザ空間
カーネル空間
ユーザプロセス
ユーザプロセス
ユーザ空間
ユーザプロセス
ユーザプロセス
ユーザ空間
・・・
コンテナ
コンテナ型の仮想化とは?
Open Cloud Campus
7
Linux女子部 Dockerを支える技術
 コンテナによって分離されるリソースにはいくつかの種類がありますが、内部的には、それ
ぞれ異なる技術によって実現されています。
– ファイルシステムの分離  → Mount namespace (kernel 2.4.19)
– ホストネームの分離 → UTS namespace (kernel 2.6.19)
– IPCの分離 → IPC namespece (kernel 2.6.19)
– ユーザ(UID/GID)の分離 → User namespace (kernel 2.6.23〜kernel 3.8)
– プロセステーブルの分離  → PID namespace (kernel 2.6.24) 
– ネットワーク設定の分離  → Network Namepsace (kernel 2.6.24)
– リソース配分の制御 → Control groups
※参考資料「Namespaces in operation, part 1: namespaces overview」
• http://lwn.net/Articles/531114/
 Linuxコンテナはこれらの機能を組み合わせて実現されるものであり、「コンテナ」という単
一の技術があるわけではありません。これら機能を統合してコンテナを作り上げる管理ツー
ル/ライブラリには、いくつかの種類があります。(ツール/ライブラリによって利用する
ネームスペースの種類が異なる場合もあります。)
– lxctools : コンテナを作成・管理するコマンドを集めたもの。
– libvirt : KVM/Xenなどの仮想化環境の操作を共通化するAPIライブラリ。コンテナも管理可能。
– Docker : 本資料のメインテーマとなるツール。ディスクイメージの管理機能が特徴的。
Linuxコンテナの実体
Open Cloud Campus
8
Linux女子部 Dockerを支える技術
 各コンテナのプロセスは、同じLinuxカーネルで実行されますが、プロセステーブルはコンテ
ナごとに独立しているので、他のコンテナのプロセスは見えません。
– コンテナの外部にあたるホストLinux上では全てのプロセスが見えます。ホストLinux上のプロセス
テーブルでは、コンテナに属するプロセスには、内部的にコンテナ名ラベルが付与されます。
コンテナによるリソース分割 〜 プロセステーブルの分離
# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:49 ? 00:00:00 /bin/sh /usr/local/bin/init.sh
root 35 1 0 09:49 ? 00:00:00 /usr/sbin/sshd
root 47 1 0 09:49 ? 00:00:00 /usr/sbin/httpd
apache 49 47 0 09:49 ? 00:00:00 /usr/sbin/httpd
apache 50 47 0 09:49 ? 00:00:00 /usr/sbin/httpd
...
apache 56 47 0 09:49 ? 00:00:00 /usr/sbin/httpd
root 57 1 0 09:49 ? 00:00:00 /bin/bash
# ps -ef
UID PID PPID C STIME TTY TIME CMD
...
root 802 1 0 18:10 ? 00:01:20 /usr/bin/docker -d --selinux-enabled -H fd://
...
root 3687 802 0 18:49 pts/2 00:00:00 /bin/sh /usr/local/bin/init.sh
root 3736 3687 0 18:49 ? 00:00:00 /usr/sbin/sshd
root 3748 3687 0 18:49 ? 00:00:00 /usr/sbin/httpd
48 3750 3748 0 18:49 ? 00:00:00 /usr/sbin/httpd
...
48 3757 3748 0 18:49 ? 00:00:00 /usr/sbin/httpd
root 3758 3687 0 18:49 pts/2 00:00:00 /bin/bash
コンテナ内から見えるプロセス
ホストLinuxから見えるプロセス
Open Cloud Campus
9
Linux女子部 Dockerを支える技術
コンテナによるリソース分割 〜 プロセステーブルの分離
dockerデーモン
fork&exec
sshd
PID namespace
 全ページの例では、dockerデーモンが最初のプロセスである「init.sh」を起動するタイミン
グで、新たな「PID namespace」に入れます。その後、init.shからフォークしていくプロセ
スは、すべて同じPID namespaceで起動していきます。
– コンテナ内部では、PIDは、ホストLinuxとは独立した値が「1」から振られていきます。
– Docker0.9ではUID namespaceは使用しておらず、UID/GIDの値はコンテナ内外で同じです。
/etc/passwdなどのファイルが異なるため、表示される名前は異なっています。
• 参考:"Docker 1.0 and user namespaces"
https://groups.google.com/forum/#!topic/docker-dev/MoIDYDF3suY
PID=1
bash
/bin/sh /usr/local/bin/init.sh
httpd
httpd
・・・
#!/bin/sh
service sshd start
service httpd start
while [[ true ]]; do
/bin/bash
done
init.sh
Open Cloud Campus
10
Linux女子部 Dockerを支える技術
コンテナによるリソース分割 〜 ファイルシステム
 一般には、コンテナ内に独立したディレクトリツリーを用意して、ホストLinuxのディレクト
リをコンテナ内のツリーにbind mountすることで、コンテナからアクセス可能にします。
 lxctoolsやlibvirtでは、コンテナごとのルートファイルシステムを事前にホストLinux上に用
意して利用します。
– 特定のアプリケーションの実行に必要な最小限のファイルのみを配置しても構いません。
– 特定のLinuxディストリビューションのルートファイルシステムと同じものをごっそり用意して、まと
めて見せることも可能です。
– /devや/procはコンテナ起動時に個別に(必要に応じて)構成します。
Mount namespace
/
|--etc
|--bin
|--sbin
...
/export/container01/rootfs/
|--etc
|--bin
|--sbin
...
bind mount
Open Cloud Campus
11
Linux女子部 Dockerを支える技術
コンテナによるリソース分割 〜 ファイルシステム
 Dockerでは、独自のディスクイメージ管理機能を利用して、指定のイメージをホストLinux
上にマウントしたものをコンテナのルートファイルシステムとして見せます。
# df -a
Filesystem 1K-blocks Used Available Use% Mounted on
rootfs 10190136 169036 9480428 2% /
/dev/mapper/docker-252:3-130516-d798a41bcba1dbe621bf2dd87de0f9c6dd9f9c8aadb79f84e0170
5ee82f364c6
10190136 169036 9480428 2% /
proc 0 0 0 - /proc
sysfs 0 0 0 - /sys
tmpfs 1025136 0 1025136 0% /dev
shm 65536 0 65536 0% /dev/shm
devpts 0 0 0 - /dev/pts
/dev/vda3 14226800 3013432 10467640 23% /.dockerinit
/dev/vda3 14226800 3013432 10467640 23% /etc/resolv.conf
/dev/vda3 14226800 3013432 10467640 23% /etc/hostname
/dev/vda3 14226800 3013432 10467640 23% /etc/hosts
devpts 0 0 0 - /dev/console
...
# df
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
...
/dev/dm-2 10190136 169036 9480428 2%
/var/lib/docker/devicemapper/mnt/d798a41bcba1dbe621bf2dd87de0f9c6dd9f9c8aadb79f84e017
05ee82f364c6
コンテナ内から見える
ファイルシステム
ホストLinuxで用意した
ディスクイメージ
ホストLinux上でマウント
されたディスクイメージ
一部のファイルは個別に
bind mountされている
Open Cloud Campus
12
Linux女子部 Dockerを支える技術
Network namespace
コンテナによるリソース分割 〜 ネットワーク
 コンテナと外部の通信は、vethを通じて行います。
– vethはLinuxカーネルが標準で提供する機能で、クロスケーブルで直結したかのような仮想NICのペア
を作成します。
 vethのペアの片方をコンテナ用のNetwork namespaceに入れて、コンテナからのみ見えるよ
うにします。もう一方は、ホストLinuxの仮想ブリッジに接続します。
– コンテナ内のvethは名前を「eth0」などに変更しておきます。IPアドレスの割り当てやルーティング
テーブル、iptablesなどもコンテナ内のNetwork namespaceで独立して設定が可能です。
– 仮想ブリッジから先の接続は、ホストLinux側で自由に構成します。(物理NICに直結、もしく
は、iptablesでNATして外部に接続する。)
ホストLinux
vethXX
eth0
docker0
eth0
IPマスカレード
外部ネットワーク
 Dockerの場合、デフォルトではブリッジ「docker0」に接
続して、IPマスカレードで外部に出る設定が行われます。
– 特定のポートについて、ホストLinuxからDNATよるポート転
送の設定も可能です。
172.17.42.1
Open Cloud Campus
13
Linux女子部 Dockerを支える技術
コンテナによるリソース分割 〜 CPUとメモリ
 CPUとメモリについては、コンテナ内部から物理ホスト全体のリソースが認識されます。た
だし、cgroupsを利用して、コンテナ内のプロセスについて、CPUの割り当て時間や利用可能
なメモリの上限を設定することが可能です。
– 原理的には、cgroupsの機能の範囲で、I/Oの帯域制御なども含めて、自由にリソースの割り当て制限
が可能です。
 Dockerでは、systemdと連携することで、コンテナ内のプロセスに対してcgroupsのグループ
を割り当てます。
– コンテナを起動する際に、Unitを動的に生成して、最初のプロセスをUnitから起動します。 
systemdは、それぞれのUnitごとに自動的にcgroupsのグループを割り当てて管理するので、結果的
にコンテナ内のプロセスがまとめて特定のグループに入ります。
# systemd-cgls
...
└─system.slice
├─docker-cc08291a81556ba55f049e50fd2c04287b04c6cf657a8a9971ef42468a2befa7.scope
│ ├─7444 nginx: master process ngin
│ ├─7458 nginx: worker proces
│ ├─7459 nginx: worker proces
│ ├─7460 nginx: worker proces
│ └─7461 nginx: worker proces
...
「docker-<コンテナID>.scope」が
cgroupsのグループ名
Linux女子部 Dockerを支える技術
Device Mapper Thin-Provisioning
Open Cloud Campus
15
Linux女子部 Dockerを支える技術
 Device Mapperはブロックデバイス(/dev/sdXなど)の上にソフトウェアのWrapperを被せ
て、さまざまな機能拡張を行ったブロックデバイスを作成する仕組みです。次のような機能
拡張を行うモジュールがあります。
– ソフトウェアRAID(dm-raid)
– マルチパスアクセス(dm-multipath)
– 暗号化(dm-crypt)
– アクセス遅延挿入(dm-delay)
– etc...
Device Mapperとは?
/dev/sda /dev/sdb
/dev/dm1
ミラーリング
dm-raid
/dev/sda
/dev/dm1
dm-crypt
暗号化/復号化
/dev/sda
/dev/dm1
dm-delay
遅延挿入
Open Cloud Campus
16
Linux女子部 Dockerを支える技術
 Device Mapperのモジュールで、一般的なストレージ製品が持つ(NetApp的な?)「シンプ
ロビジョニング」と「スナップショット」の機能を提供します。
 1つの物理デバイスを「ブロックプール」として確保します。併せて、もう1つの物理デバ
イスをメタデータ保存用に使用します。
– 論理デバイスに対して動的にプールからブロックを追加していくので、プールの残り容量よりも大き
なサイズの論理デバイスが定義できます。
– 論理デバイスからプール内のブロックへのポインタを「メタデータ」として保存します。
– 複数の論理デバイスから同一ブロックへのポインタを持たせることで、CoW(Copy on Write)方式
のスナップショットを作成します。スナップショットは任意の世代数が作成可能です。
Device Mapper Thin-Provisioningとは?
データ用デバイス
(ブロックプール)
メタデータ用
デバイス
論理デバイスの各ブロックが
ブロックプールのどのブロックに
対応するかをメタデータとして保存
論理デバイス#001 論理デバイス#002 論理デバイス#003
Open Cloud Campus
17
Linux女子部 Dockerを支える技術
 最近のLinuxでは、LVMのインターフェースからThin-Provisioning機能を利用できるように
なっています。
– はじめに通常の手順でVGを用意します。
– 「プール」を定義すると、ブロックプール用のLVとメタデータ用のLVが作成されます。
LVMによるDevice Mapper Thin-Provisioningの利用
# fallocate -l $((1024*1024*1024)) pooldev.img
# losetup -f pooldev.img
# losetup -a
/dev/loop0: [64768]:39781720 (/root/pooldev.img)
# pvcreate /dev/loop0
# vgcreate vg_data /dev/loop0
# lvcreate -L 900M -T vg_data/thinpool
Logical volume "lvol1" created
Logical volume "thinpool" created
# lvs
LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert
...
lvol0 vg_data -wi------- 4.00m
thinpool vg_data twi-a-tz-- 900.00m 0.00
LV: thinpool LV: lvol1
VG: vg_data
ブロックプール
メタデータ用
デバイス
論理デバイス
vol00
論理デバイス
vol01
・・・
Open Cloud Campus
18
Linux女子部 Dockerを支える技術
– 「-V」オプションで論理サイズを指定して、論理デバイスを作成します。プールのサイズよりも大き
な論理サイズも指定可能です。
– 次のコマンドでスナップショットを作成します。
– スナップショットに対応するLVMは安全のために無効化されています。次のコマンドで明示的に有効
化してから使用します。
LVMによるDevice Mapper Thin-Provisioningの利用
# lvcreate -V 100G -T vg_data/thinpool -n vol00
Logical volume "vol00" created
# lvs
LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert
...
lvol0 vg_data -wi------- 4.00m
thinpool vg_data twi-a-tz-- 900.00m 0.00
vol00 vg_data Vwi-a-tz-- 100.00g thinpool 0.00
# lvcreate -s --name vol01 vg_data/vol00
Logical volume "vol01" created
# lvs
LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert
...
lvol0 vg_data -wi------- 4.00m
thinpool vg_data twi-a-tz-- 900.00m 0.00
vol00 vg_data Vwi-a-tz-- 100.00g thinpool 0.00
vol01 vg_data Vwi---tz-k 100.00g thinpool vol00
# lvchange -K -ay /dev/vg_data/vol01
Open Cloud Campus
19
Linux女子部 Dockerを支える技術
 Dockerでは、ディスクイメージの管理方式(ドライバ)が選択できて、Fedora20/RHEL7で
は、「Device Mapperドライバ」を使用します。これは、Device Mapper Thin-Provisioning
による論理デバイスとして、各ディスクイメージを保存します。
– ディスクイメージを指定してコンテナを起動すると、指定イメージのスナップショットを作成して、
それをコンテナに割り当てます。
– 「docker commit」でコンテナのイメージを保存する際は、コンテナに割り当て中の(先にスナップ
ショットで作成した)イメージのスナップショットを作成します。(「docker stop」でコンテナを
停止してから、「docker commit」で保存。)
DockerにおけるThin Povisioningの利用
保存イメージ
スナップ
ショット
コンテナ起動時に
スナップショットを作成
×
run
commit
rm
プロセス
スナップ
ショット
stop
start
保存イメージ
コンテナを停止するとプロセスが停止
(ディスクイメージは残っている)
コンテナを削除すると
ディスクイメージを破棄
ディスクイメージを複製して
保存イメージとして登録
参考:Dockerにおけるコンテナのライフサイクル
http://d.hatena.ne.jp/enakai00/20140628/1403933390
Open Cloud Campus
20
Linux女子部 Dockerを支える技術
 Dockerでは、LVMを経由せず、ネイティブにDevice Mapperを操作してThin Provisioningを
利用しています。
– dockerサービスを起動すると下記の「data」と「metadata」をループバックマウントして、Thin
Provisioning用のプールを用意します。
DockerにおけるThin Povisioningの利用方式
# ls -lh /var/lib/docker/devicemapper/devicemapper/
合計 1.2G
-rw-------. 1 root root 100G 5月 11 21:37 data
-rw-------. 1 root root 2.0G 5月 11 22:05 metadata
# losetup
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0 0 0 1 0 /var/lib/docker/devicemapper/devicemapper/data
/dev/loop1 0 0 1 0 /var/lib/docker/devicemapper/devicemapper/metadata
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
...
loop0 7:0 0 100G 0 loop
└─docker-252:3-130516-pool 253:0 0 100G 0 dm
loop1 7:1 0 2G 0 loop
└─docker-252:3-130516-pool 253:0 0 100G 0 dm
データ用デバイス
メタデータ用デバイス
Open Cloud Campus
21
Linux女子部 Dockerを支える技術
 論理デバイスの管理情報は、下記のJSONファイルに記録されています。
– /var/lib/docker/devicemapper/metadata/<Image ID>
– 特に、デバイスID「0」の論理デバイスは、最初にDockerサービスを起動した際に10GBで作成され、
ext4にフォーマットされます。 外部レジストリからイメージをダウンロードすると、この論理デバ
イスのスナップショットを作成して、空のext4ファイルシステムを用意して、その中にダウンロード
したファイルを展開します。(そのため、すべての論理デバイスのサイズは10GBになります。)
DockerにおけるThin Povisioningの利用方式
# docker images enakai/httpd
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
enakai/httpd ver1.0 d3d92adfcafb 36 hours ago 206.6 MB
# cat /var/lib/docker/devicemapper/metadata/d3d92adfcafb* | python -mjson.tool
{
"device_id": 72,
"initialized": false,
"size": 10737418240,
"transaction_id": 99
}
# cat /var/lib/docker/devicemapper/metadata/base | python -mjson.tool
{
"device_id": 0,
"initialized": true,
"size": 10737418240,
"transaction_id": 1
}
Open Cloud Campus
22
Linux女子部 Dockerを支える技術
 dmsetupコマンドでネイティブにDevice Mapperを操作すると、Dockerが管理するディスク
イメージを直接にマウントして内容を確認することができます。手順の例は次の通りです。
– 前ページの方法で、対象のディスクイメージのIDから、対応する「device_id」と「size」の値を確認
します。また、次のコマンドで、プールの名称(この例では「docker-252:3-130516-pool」)を確
認します。
– 簡単のため、確認した情報を変数にセットしておきます。
Dockerのディスクイメージを直接操作する方法
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
...
loop0 7:0 0 100G 0 loop
└─docker-252:3-130516-pool 253:0 0 100G 0 dm
loop1 7:1 0 2G 0 loop
└─docker-252:3-130516-pool 253:0 0 100G 0 dm
# device_id=72
# size=10737418240
# pool=docker-252:3-130516-pool
Open Cloud Campus
23
Linux女子部 Dockerを支える技術
– 次のコマンドで論理デバイスを有効化して、マウントします。下記の「rootfs」以下がコンテナから
みえるルートファイルシステムになります。
– 最後に次のコマンドでアンマウントして、論理デバイスを無効化しておきます。
※ この手順でイメージ内のファイルを修正することは、Docker的には想定外の使い方ですので、 
 予想外の問題が起きる可能性はあるかも知れません。
– 参考:https://www.kernel.org/doc/Documentation/device-mapper/thin-provisioning.txt
Dockerのディスクイメージを直接操作する方法
# dmsetup create myvol --table "0 $(($size / 512)) thin /dev/mapper/$pool $device_id"
# lsblk
...
loop0 7:0 0 100G 0 loop
└─docker-252:3-130516-pool 253:0 0 100G 0 dm
└─myvol 253:1 0 10G 0 dm
loop1 7:1 0 2G 0 loop
└─docker-252:3-130516-pool 253:0 0 100G 0 dm
└─myvol 253:1 0 10G 0 dm
# mount /dev/mapper/myvol /mnt
# ls /mnt
id lost+found rootfs
# cat /mnt/rootfs/var/www/html/index.html
Hello, World!
# umount /mnt
# dmsetup remove myvol
Linux女子部 Dockerを支える技術
Network Namespace
Open Cloud Campus
25
Linux女子部 Dockerを支える技術
Network namespace
Dockerの基本的なネットワーク構成
 コンテナの仮想NIC「eth0」は、仮想ブリッジ
「docker0」に接続されます。コンテナと外部の通信は、
ホストLinuxのiptablesで制御されます。
– コンテナから外部への接続はIPマスカレードで行います。
– コンテナ内の特定ポートへの接続をホストLinuxからポート
転送する設定が可能です。iptablesのNAT機能でポート転送
が行われます。
 iptablesの設定を確認してみます。
ホストLinux
vethXX
eth0
docker0
eth0
IPマスカレード
172.17.42.1
– 「8000 → 80」と「2222 → 22」のポート転送を指定してコンテナを起動します。
– ブリッジ「docker0」に「veth」の片割れが接続されています。
# docker run -itd -p 8000:80 -p 2222:22 enakai/httpd:ver1.0
a7838c84cd008161086839379e4a0be2d0e109e02c779229cde49f53b79ae1d5
# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.56847afe9799 no veth66c0
# ifconfig docker0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.42.1 netmask 255.255.0.0 broadcast 0.0.0.0
...
Open Cloud Campus
26
Linux女子部 Dockerを支える技術
Dockerの基本的なネットワーク構成
– iptablesのnatテーブルは、次のようになっています。
① 外部からホストLinux宛に来たパケットはDOCKERチェーンにまわしてポート転送処理する。
② ホストLinux上で「"localhost"以外の」ホスト自身のIPアドレスを指定したパケットもDOCKER 
 チェーンでポート転送する。
③ コンテナからブリッジ経由で外部に出るパケットは、IPマスカレードする。
④⑤ DNATでコンテナにポート転送する設定です。
– ②の意味がちょっと不明ですが、実際には、ホストLinux用で「localhost」宛のパケットも正しく
ポート転送されます。その理由は・・・
# iptables-save
# Generated by iptables-save v1.4.19.1 on Fri Jun 13 22:36:14 2014
*nat
...
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -d 172.17.0.0/16 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 172.17.0.23:22
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8000 -j DNAT --to-destination 172.17.0.23:80
COMMIT
①
②
③
④
⑤
Open Cloud Campus
27
Linux女子部 Dockerを支える技術
Dockerの基本的なネットワーク構成
– Dockerデーモン自身もポート転送用のProxy機能を提供しており、iptablesで転送されなかったパ
ケットは、こちらを経由して転送されます。
– このProxy機能は、iptablesが利用できない環境のために用意されています。今回の環境
で、localhost宛のパケットだけiptablesを使わない理由はまだ不明です。
# lsof -i -P
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
docker 20003 root 11u IPv6 177010 0t0 TCP *:2222 (LISTEN)
docker 20003 root 12u IPv6 178468 0t0 TCP *:8000 (LISTEN)
...
Open Cloud Campus
28
Linux女子部 Dockerを支える技術
Network namespaceの操作方法
 Network namespaceは、次のようなステップで作成・利用します。
– 新しいネームスペースを定義
– ネームスペース内部でネットワークを構成
• 仮想NICとIPアドレスの割り当て、ルーティングテーブルの作成、iptablesの定義など
– ネームスペース内部でプロセスを起動
 一般には、「ip netns」コマンドで上記の作業を行いますが、DockerはNativeにやっている
ので、Dockerが用意したネームスペースを後から操作するには少し工夫が必要です。
– まず、コンテナ内で動いているプロセスのPIDを1つ見つけます。
– このプロセスの/procの下に、ネームスペースを操作するためのFDへのリンクがあります。
# systemd-cgls
...
└─system.slice
├─docker-61151db106a7fd6d5cf937a03eac0e9b33c7799d3d48b6cddc83070839afeea9.scop
│ ├─502 /bin/sh /usr/local/bin/init.sh
│ ├─545 /usr/sbin/sshd
│ ├─557 /usr/sbin/httpd
...
# ls -l /proc/502/ns/net
lrwxrwxrwx 1 root root 0 6月 13 22:52 /proc/502/ns/net -> net:[4026532255]
Open Cloud Campus
29
Linux女子部 Dockerを支える技術
Network namespaceの操作方法
– /var/run/netns/以下からFDにシンボリックリンクを張ると、ipコマンド管理下のネームスペースと
して認識されます。
– この後は、次のコマンドにより、ネームスペース「hoge-ns」内部でコマンド(プロセス)を実行で
きるようになります。
– たとえば、bashを起動するとネームスペース内部のネットワーク構成が確認できます。(あくまで
「Network namespace」だけを切り替えているので、ネットワーク以外の環境はホストLinuxと同じ
状態です。)
# mkdir /var/run/netns
# ln -s /proc/502/ns/net /var/run/netns/hoge-ns
# ip netns
hoge-ns
# ip netns exec hoge-ns <command>
# ip netns exec hoge-ns bash
# ifconfig eth0
eth0: flags=67<UP,BROADCAST,RUNNING> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
...
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.17.42.1 0.0.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
# exit
# ip netns exec hoge-ns <command>
Open Cloud Campus
30
Linux女子部 Dockerを支える技術
「オレオレ仮想NIC」の追加方法
 「ip netns exec」を駆使すると、起動中のコンテナにあとから仮想NICを追加することも可能
です。図のようにブリッジ「br0」を経由して、外部ネットワークに直結した仮想NICを追加
してみます。
– まずは、ブリッジ「br0」を用意して、物理NICのIPアドレス(この例では192.168.200.20/24)を
ブリッジに付け替えます。
# brctl addbr br0; ip link set br0 up
# ip addr del 192.168.200.20/24 dev eth0; ip addr add 192.168.200.20/24 broadcast
192.168.200.255 dev br0; brctl addif br0 eth0; route add default gw 192.168.200.1
# echo 'NM_CONTROLLED="no"' >> /etc/sysconfig/network-scripts/ifcfg-eth0
# systemctl enable network.service
ホストLinux
vethXX
eth0
コンテナ
docker0
IPマスカレード
外部ネットワーク
vethYY
eth1
br0
192.168.200.99
192.168.200.20
192.168.200.20
eth0
※IPアドレスを付け替える最後の3行は、何をやっているのか
 理解できる方だけ実施してください。
Open Cloud Campus
31
Linux女子部 Dockerを支える技術
「オレオレ仮想NIC」の追加方法
– vethペア「veth-host/veth-geust」を作成して、「veth-host」をブリッジ「br0」に接続します。
# ip link add name veth-host type veth peer name veth-guest
# ip link set veth-guest down
# brctl addif br0 veth-host
# brctl show br0
bridge name bridge id STP enabled interfaces
br0 8000.525400677470 no eth0
veth-host
ホストLinux
vethXX
eth0
コンテナ
docker0
IPマスカレード
外部ネットワーク
veth-host
veth-guest
br0
eth0
• この時点では、「veth-host」「veth-guest」共にホスト
Linuxから見えています。
Open Cloud Campus
32
Linux女子部 Dockerを支える技術
「オレオレ仮想NIC」の追加方法
– 次のコマンドで「veth-guest」をコンテナのネームスペースに入れます。この時点で、ホストLinux
からは、「veth-guest」は見えなくなります。
– この後は、コンテナのネームスペース内で、コンテナから見えるネットワーク環境を設定します。コ
ンテナ内でのデバイス名を「eth1」に変更した後に、IPアドレスを設定します。さらにルーティング
テーブルを変更して、「eth1」側をデフォルトゲートウェイにします。
# ip link set veth-guest netns hoge-ns
# ifconfig veth-guest
veth-guest: error fetching interface information: Device not found
# ip netns exec hoge-ns ip link set veth-guest name eth1
# ip netns exec hoge-ns ip addr add 192.168.200.99/24 dev eth1
# ip netns exec hoge-ns ip link set eth1 up
# ip netns exec hoge-ns ip route delete default
# ip netns exec hoge-ns ip route add default via 192.168.200.1
Open Cloud Campus
33
Linux女子部 Dockerを支える技術
「オレオレ仮想NIC」の追加方法
– コンテナにログインして、ネットワーク設定を確認します。
– これで、外部ネットワークからポート転送なしで、直接にアクセスできます。
– 「ip netns」コマンドでの設定が終わったら、先のシンボリックリンクは削除して構いません。
 ちなみに、これらの作業を自動でおこなうシェルスクリプトを作っている人がいます。
– jpetazzo/pipework
– https://github.com/jpetazzo/pipework
# ssh enakai@localhost -p 2222
$ ifconfig eth1
eth1 Link encap:Ethernet HWaddr BE:53:16:06:BF:3A
inet addr:192.168.200.99 Bcast:0.0.0.0 Mask:255.255.255.0
...
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.200.1 0.0.0.0 UG 0 0 0 eth1
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
192.168.200.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
$ curl http://192.168.200.99:80
Hello, World!
# rm /var/run/netns/hoge-ns
Linux女子部 Dockerを支える技術
systemdとcgroups
Open Cloud Campus
35
Linux女子部 Dockerを支える技術
systemdとcgroupsの基本
 基本情報は、下記の資料を読んでおいてください。
– 「Linux女子部 systemd徹底入門!」
• http://www.slideshare.net/enakai/linux-27872553
– 「Control Groups (cgroups) (めもめも)」
• http://d.hatena.ne.jp/enakai00/20110605/1307240161
 ここでは、特にUnitとcgroupsの関係が大切になります。
– systemdは、さまざまなサービスを「Unit」として定義します。
– 「Unit」としてサービスを起動すると、該当サービス用にcgroupsのグループを作成して、そのサー
ビスから起動するプロセスをまとめてこのグループに入れます。
– Unitの設定ファイルで「CPUShares」と「MemoryLimit」を指定すると、該当のcgroupsの設定がな
されます。(それぞれ、CPU割り当て時間の相対的な重み指定と、物理メモリの使用量の上限を指
定。)
Open Cloud Campus
36
Linux女子部 Dockerを支える技術
systemdとcgroupsの基本
 systemdが管理するcgroupsの状態は、次のコマンドで確認します。
# systemd-cgls
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 23
├─user.slice
│ └─user-0.slice
│ ├─session-1.scope
│ │ ├─439 sshd: root@pts/0
│ │ ├─444 -bash
│ │ ├─464 systemd-cgls
│ │ └─465 systemd-cgls
│ └─user@0.service
│ ├─441 /usr/lib/systemd/systemd --user
│ └─442 (sd-pam)
└─system.slice
├─polkit.service
│ └─352 /usr/lib/polkit-1/polkitd --no-debug
├─auditd.service
│ └─301 /sbin/auditd -n
├─systemd-udevd.service
│ └─248 /usr/lib/systemd/systemd-udevd
...
Open Cloud Campus
37
Linux女子部 Dockerを支える技術
Dockerとsystemdの関係
 Dockerがコンテナを作る際は、該当コンテナに対応するUnitを動的に作成して、コンテナ内
の最初のプロセスをUnitから起動します。
– これにより、該当Unitのグループが作成されて、コンテナ内のプロセスは、すべて該当グループに入
ります。Unit名は「docker-<コンテナID>.scope」です。
# docker run -td -p 8000:80 -p 2222:22 enakai/httpd:ver1.0
# systemd-cgls -a
...
└─system.slice
├─var-lib-docker-devicemapper-mnt-a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a4
7f7c4bc8b37e3b488b.mount
├─docker-a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope
│ ├─496 /bin/sh /usr/local/bin/init.sh
│ ├─538 /usr/sbin/sshd
│ ├─550 /usr/sbin/httpd
│ ├─552 /bin/bash
│ ├─553 /usr/sbin/httpd
│ ├─554 /usr/sbin/httpd
│ ├─555 /usr/sbin/httpd
│ ├─556 /usr/sbin/httpd
│ ├─557 /usr/sbin/httpd
│ ├─558 /usr/sbin/httpd
│ ├─559 /usr/sbin/httpd
│ └─560 /usr/sbin/httpd
...
Open Cloud Campus
38
Linux女子部 Dockerを支える技術
Dockerとsystemdの関係
– Unitのstatusを確認することもできます。
# unitname=docker-a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope
# systemctl status $unitname
docker-a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope - docker
container a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b
Loaded: loaded (/run/systemd/system/docker-
a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope; static)
Drop-In: /run/systemd/system/docker-
a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope.d
└─90-BlockIOAccounting.conf, 90-CPUAccounting.conf, 90-Description.conf, 90-
MemoryAccounting.conf, 90-Slice.conf
Active: active (running) since 金 2014-06-13 23:05:27 JST; 1min 41s ago
CGroup: /system.slice/docker-
a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope
├─496 /bin/sh /usr/local/bin/init.sh
├─538 /usr/sbin/sshd
├─550 /usr/sbin/httpd
├─552 /bin/bash
├─553 /usr/sbin/httpd
├─554 /usr/sbin/httpd
├─555 /usr/sbin/httpd
...
└─560 /usr/sbin/httpd
6月 13 23:05:27 fedora20 systemd[1]: Started docker container
a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a...488b.
Hint: Some lines were ellipsized, use -l to show in full.
Open Cloud Campus
39
Linux女子部 Dockerを支える技術
Dockerとsystemdの関係
– Unitの設定パラメータとして、cgroupsの設定値が用意されています。これらは、「docker run」コ
マンドの 「-c」オプションと「-m」オプションの設定値に対応しています。
– コンテナ起動後にsystemdのインターフェースを通して、設定値を変更することも可能です。
 今後、systemdとcgroupsのより緊密な統合が計画されており、systemdを通して、その他の
リソース制御(CPU pinning、CPU quota、I/O bandwidthなど)も可能になると予想されま
す。
# systemctl show $unitname | grep -E "(CPUShares=|MemoryLimit=)"
CPUShares=1024
MemoryLimit=18446744073709551615
# systemctl set-property $unitname CPUShares=512 --runtime
# systemctl show $unitname | grep -E "(CPUShares=|MemoryLimit=)"
CPUShares=512
MemoryLimit=18446744073709551615
Linux女子部 Dockerを支える技術
参考資料
Open Cloud Campus
41
Linux女子部 Dockerを支える技術
参考資料
 Dockerクイックツアー
– http://www.slideshare.net/enakai/docker-34526343
 「めもめも」
– RHEL7におけるDockerのディスクイメージ管理方式
• http://d.hatena.ne.jp/enakai00/20140420/1397981156
– Dockerのネットワーク管理とnetnsの関係
• http://d.hatena.ne.jp/enakai00/20140424/1398321672
– RHEL7のDockerとsystemdとcgroups
• http://d.hatena.ne.jp/enakai00/20140427/1398576165
 クラウド時代のオープンソース実践活用
– 第41回 Linuxコンテナ(LXC)の基礎をまとめ直す
• http://www.school.ctc-g.co.jp/columns/nakai/nakai41.html
– 第42回 Dockerのイメージ管理を考える
• http://www.school.ctc-g.co.jp/columns/nakai/nakai42.html
– 第43回 「Dockerイメージ」のポータビリティとLinuxカーネルのABI
• http://www.school.ctc-g.co.jp/columns/nakai/nakai43.html
Open Cloud Campus
42
Linux女子部 Dockerを支える技術
QA
Linux女子部 Dockerを支える技術
中井悦司
Twitter @enakai00
オープンクラウド・キャンパス
RHEL7 & Fedoraで最新技術を
学びましょう!

More Related Content

Dockerを支える技術

  • 1. Linux女子部 Dockerを支える技術 ver1.8 中井悦司 Twitter @enakai00 オープンクラウド・キャンパス Linux女子部 Dockerを支える技術
  • 2. Open Cloud Campus 2 Linux女子部 Dockerを支える技術 自己紹介  中井悦司(なかいえつじ) – Twitter @enakai00  日々の仕事 – Senior Solution Architect and Cloud Evangelist at Red Hat K.K. 企業システムでオープンソースの活用を希望される お客様を全力でご支援させていただきます。  昔とった杵柄 – 素粒子論の研究(超弦理論とか) – 予備校講師(物理担当) – インフラエンジニア(Unix/Linux専門) 好評発売中!
  • 3. Open Cloud Campus 3 Linux女子部 Dockerを支える技術 Contents  Linuxコンテナ  Device Mapper Thin-Provisioning  Network Namespace  systemdとcgroups  参考資料 (*) 本資料の説明は、Fedora20の「docker-io-1.0.0-1.fc20.x86_64」を前提としています。
  • 5. Open Cloud Campus 5 Linux女子部 Dockerを支える技術 一般的なサーバ仮想化の分類 物理マシン 物理マシン ホスト OS ハイパーバイザ (カーネルモジュール) 仮想 マシン ゲスト OS VMware vSphere, Xen など Linux KVM ハードウェアによる仮想化 (物理マシンにハイパーバイザを内蔵) ソフトウェアによる仮想化 (物理マシン上にハイパーバイザを導入) ソフトウェアによる仮想化 (ホスト OS にハイパーバイザ機能を追加) 物理マシン OS 非仮想化環境 基本的には「物理マシン」と同等の「仮想マシン」を複数 作り出す技術です。 仮想 マシン ゲスト OS 仮想 マシン ゲスト OS 仮想 マシン ゲスト OS 仮想 マシン ゲスト OS 仮想 マシン ゲスト OS 仮想 マシン ゲスト OS 仮想 マシン ゲスト OS ハイパーバイザ(ソフトウェア) 仮想 マシン ゲスト OS 仮想 マシン ゲスト OS 仮想 マシン ゲスト OS 物理マシン ハイパーバイザ(ファームウェア)
  • 6. Open Cloud Campus 6 Linux女子部 Dockerを支える技術  「Linuxコンテナ」は、Linux標準のコンテナ型仮想化技術です。Linuxカーネルの機能によ り、ユーザプロセスの実行環境(ユーザ空間)を独立した「コンテナ」に閉じ込めます。  コンテナごとに独立したリソースを割り当てることで、アプリケーションの実行環境を分離 します。「カーネル共有型」の軽量な仮想化機能と言えます。 – コンテナごとに異なるファイルシステムを割り当て – コンテナごとに異なるネットワーク設定(仮想NIC)を割り当て – コンテナごとにCPU、メモリーの割り当て量を制限  クラウド上のLinux仮想マシンの上で、コンテナを利用することも可能です。 カーネル空間 ユーザプロセス ・・・ 物理マシン 物理マシン OS コンテナ型仮想化 非仮想化環境 ユーザプロセス ユーザプロセス ユーザ空間 カーネル空間 ユーザプロセス ユーザプロセス ユーザ空間 ユーザプロセス ユーザプロセス ユーザ空間 ・・・ コンテナ コンテナ型の仮想化とは?
  • 7. Open Cloud Campus 7 Linux女子部 Dockerを支える技術  コンテナによって分離されるリソースにはいくつかの種類がありますが、内部的には、それ ぞれ異なる技術によって実現されています。 – ファイルシステムの分離  → Mount namespace (kernel 2.4.19) – ホストネームの分離 → UTS namespace (kernel 2.6.19) – IPCの分離 → IPC namespece (kernel 2.6.19) – ユーザ(UID/GID)の分離 → User namespace (kernel 2.6.23〜kernel 3.8) – プロセステーブルの分離  → PID namespace (kernel 2.6.24)  – ネットワーク設定の分離  → Network Namepsace (kernel 2.6.24) – リソース配分の制御 → Control groups ※参考資料「Namespaces in operation, part 1: namespaces overview」 • http://lwn.net/Articles/531114/  Linuxコンテナはこれらの機能を組み合わせて実現されるものであり、「コンテナ」という単 一の技術があるわけではありません。これら機能を統合してコンテナを作り上げる管理ツー ル/ライブラリには、いくつかの種類があります。(ツール/ライブラリによって利用する ネームスペースの種類が異なる場合もあります。) – lxctools : コンテナを作成・管理するコマンドを集めたもの。 – libvirt : KVM/Xenなどの仮想化環境の操作を共通化するAPIライブラリ。コンテナも管理可能。 – Docker : 本資料のメインテーマとなるツール。ディスクイメージの管理機能が特徴的。 Linuxコンテナの実体
  • 8. Open Cloud Campus 8 Linux女子部 Dockerを支える技術  各コンテナのプロセスは、同じLinuxカーネルで実行されますが、プロセステーブルはコンテ ナごとに独立しているので、他のコンテナのプロセスは見えません。 – コンテナの外部にあたるホストLinux上では全てのプロセスが見えます。ホストLinux上のプロセス テーブルでは、コンテナに属するプロセスには、内部的にコンテナ名ラベルが付与されます。 コンテナによるリソース分割 〜 プロセステーブルの分離 # ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 09:49 ? 00:00:00 /bin/sh /usr/local/bin/init.sh root 35 1 0 09:49 ? 00:00:00 /usr/sbin/sshd root 47 1 0 09:49 ? 00:00:00 /usr/sbin/httpd apache 49 47 0 09:49 ? 00:00:00 /usr/sbin/httpd apache 50 47 0 09:49 ? 00:00:00 /usr/sbin/httpd ... apache 56 47 0 09:49 ? 00:00:00 /usr/sbin/httpd root 57 1 0 09:49 ? 00:00:00 /bin/bash # ps -ef UID PID PPID C STIME TTY TIME CMD ... root 802 1 0 18:10 ? 00:01:20 /usr/bin/docker -d --selinux-enabled -H fd:// ... root 3687 802 0 18:49 pts/2 00:00:00 /bin/sh /usr/local/bin/init.sh root 3736 3687 0 18:49 ? 00:00:00 /usr/sbin/sshd root 3748 3687 0 18:49 ? 00:00:00 /usr/sbin/httpd 48 3750 3748 0 18:49 ? 00:00:00 /usr/sbin/httpd ... 48 3757 3748 0 18:49 ? 00:00:00 /usr/sbin/httpd root 3758 3687 0 18:49 pts/2 00:00:00 /bin/bash コンテナ内から見えるプロセス ホストLinuxから見えるプロセス
  • 9. Open Cloud Campus 9 Linux女子部 Dockerを支える技術 コンテナによるリソース分割 〜 プロセステーブルの分離 dockerデーモン fork&exec sshd PID namespace  全ページの例では、dockerデーモンが最初のプロセスである「init.sh」を起動するタイミン グで、新たな「PID namespace」に入れます。その後、init.shからフォークしていくプロセ スは、すべて同じPID namespaceで起動していきます。 – コンテナ内部では、PIDは、ホストLinuxとは独立した値が「1」から振られていきます。 – Docker0.9ではUID namespaceは使用しておらず、UID/GIDの値はコンテナ内外で同じです。 /etc/passwdなどのファイルが異なるため、表示される名前は異なっています。 • 参考:"Docker 1.0 and user namespaces" https://groups.google.com/forum/#!topic/docker-dev/MoIDYDF3suY PID=1 bash /bin/sh /usr/local/bin/init.sh httpd httpd ・・・ #!/bin/sh service sshd start service httpd start while [[ true ]]; do /bin/bash done init.sh
  • 10. Open Cloud Campus 10 Linux女子部 Dockerを支える技術 コンテナによるリソース分割 〜 ファイルシステム  一般には、コンテナ内に独立したディレクトリツリーを用意して、ホストLinuxのディレクト リをコンテナ内のツリーにbind mountすることで、コンテナからアクセス可能にします。  lxctoolsやlibvirtでは、コンテナごとのルートファイルシステムを事前にホストLinux上に用 意して利用します。 – 特定のアプリケーションの実行に必要な最小限のファイルのみを配置しても構いません。 – 特定のLinuxディストリビューションのルートファイルシステムと同じものをごっそり用意して、まと めて見せることも可能です。 – /devや/procはコンテナ起動時に個別に(必要に応じて)構成します。 Mount namespace / |--etc |--bin |--sbin ... /export/container01/rootfs/ |--etc |--bin |--sbin ... bind mount
  • 11. Open Cloud Campus 11 Linux女子部 Dockerを支える技術 コンテナによるリソース分割 〜 ファイルシステム  Dockerでは、独自のディスクイメージ管理機能を利用して、指定のイメージをホストLinux 上にマウントしたものをコンテナのルートファイルシステムとして見せます。 # df -a Filesystem 1K-blocks Used Available Use% Mounted on rootfs 10190136 169036 9480428 2% / /dev/mapper/docker-252:3-130516-d798a41bcba1dbe621bf2dd87de0f9c6dd9f9c8aadb79f84e0170 5ee82f364c6 10190136 169036 9480428 2% / proc 0 0 0 - /proc sysfs 0 0 0 - /sys tmpfs 1025136 0 1025136 0% /dev shm 65536 0 65536 0% /dev/shm devpts 0 0 0 - /dev/pts /dev/vda3 14226800 3013432 10467640 23% /.dockerinit /dev/vda3 14226800 3013432 10467640 23% /etc/resolv.conf /dev/vda3 14226800 3013432 10467640 23% /etc/hostname /dev/vda3 14226800 3013432 10467640 23% /etc/hosts devpts 0 0 0 - /dev/console ... # df ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置 ... /dev/dm-2 10190136 169036 9480428 2% /var/lib/docker/devicemapper/mnt/d798a41bcba1dbe621bf2dd87de0f9c6dd9f9c8aadb79f84e017 05ee82f364c6 コンテナ内から見える ファイルシステム ホストLinuxで用意した ディスクイメージ ホストLinux上でマウント されたディスクイメージ 一部のファイルは個別に bind mountされている
  • 12. Open Cloud Campus 12 Linux女子部 Dockerを支える技術 Network namespace コンテナによるリソース分割 〜 ネットワーク  コンテナと外部の通信は、vethを通じて行います。 – vethはLinuxカーネルが標準で提供する機能で、クロスケーブルで直結したかのような仮想NICのペア を作成します。  vethのペアの片方をコンテナ用のNetwork namespaceに入れて、コンテナからのみ見えるよ うにします。もう一方は、ホストLinuxの仮想ブリッジに接続します。 – コンテナ内のvethは名前を「eth0」などに変更しておきます。IPアドレスの割り当てやルーティング テーブル、iptablesなどもコンテナ内のNetwork namespaceで独立して設定が可能です。 – 仮想ブリッジから先の接続は、ホストLinux側で自由に構成します。(物理NICに直結、もしく は、iptablesでNATして外部に接続する。) ホストLinux vethXX eth0 docker0 eth0 IPマスカレード 外部ネットワーク  Dockerの場合、デフォルトではブリッジ「docker0」に接 続して、IPマスカレードで外部に出る設定が行われます。 – 特定のポートについて、ホストLinuxからDNATよるポート転 送の設定も可能です。 172.17.42.1
  • 13. Open Cloud Campus 13 Linux女子部 Dockerを支える技術 コンテナによるリソース分割 〜 CPUとメモリ  CPUとメモリについては、コンテナ内部から物理ホスト全体のリソースが認識されます。た だし、cgroupsを利用して、コンテナ内のプロセスについて、CPUの割り当て時間や利用可能 なメモリの上限を設定することが可能です。 – 原理的には、cgroupsの機能の範囲で、I/Oの帯域制御なども含めて、自由にリソースの割り当て制限 が可能です。  Dockerでは、systemdと連携することで、コンテナ内のプロセスに対してcgroupsのグループ を割り当てます。 – コンテナを起動する際に、Unitを動的に生成して、最初のプロセスをUnitから起動します。  systemdは、それぞれのUnitごとに自動的にcgroupsのグループを割り当てて管理するので、結果的 にコンテナ内のプロセスがまとめて特定のグループに入ります。 # systemd-cgls ... └─system.slice ├─docker-cc08291a81556ba55f049e50fd2c04287b04c6cf657a8a9971ef42468a2befa7.scope │ ├─7444 nginx: master process ngin │ ├─7458 nginx: worker proces │ ├─7459 nginx: worker proces │ ├─7460 nginx: worker proces │ └─7461 nginx: worker proces ... 「docker-<コンテナID>.scope」が cgroupsのグループ名
  • 15. Open Cloud Campus 15 Linux女子部 Dockerを支える技術  Device Mapperはブロックデバイス(/dev/sdXなど)の上にソフトウェアのWrapperを被せ て、さまざまな機能拡張を行ったブロックデバイスを作成する仕組みです。次のような機能 拡張を行うモジュールがあります。 – ソフトウェアRAID(dm-raid) – マルチパスアクセス(dm-multipath) – 暗号化(dm-crypt) – アクセス遅延挿入(dm-delay) – etc... Device Mapperとは? /dev/sda /dev/sdb /dev/dm1 ミラーリング dm-raid /dev/sda /dev/dm1 dm-crypt 暗号化/復号化 /dev/sda /dev/dm1 dm-delay 遅延挿入
  • 16. Open Cloud Campus 16 Linux女子部 Dockerを支える技術  Device Mapperのモジュールで、一般的なストレージ製品が持つ(NetApp的な?)「シンプ ロビジョニング」と「スナップショット」の機能を提供します。  1つの物理デバイスを「ブロックプール」として確保します。併せて、もう1つの物理デバ イスをメタデータ保存用に使用します。 – 論理デバイスに対して動的にプールからブロックを追加していくので、プールの残り容量よりも大き なサイズの論理デバイスが定義できます。 – 論理デバイスからプール内のブロックへのポインタを「メタデータ」として保存します。 – 複数の論理デバイスから同一ブロックへのポインタを持たせることで、CoW(Copy on Write)方式 のスナップショットを作成します。スナップショットは任意の世代数が作成可能です。 Device Mapper Thin-Provisioningとは? データ用デバイス (ブロックプール) メタデータ用 デバイス 論理デバイスの各ブロックが ブロックプールのどのブロックに 対応するかをメタデータとして保存 論理デバイス#001 論理デバイス#002 論理デバイス#003
  • 17. Open Cloud Campus 17 Linux女子部 Dockerを支える技術  最近のLinuxでは、LVMのインターフェースからThin-Provisioning機能を利用できるように なっています。 – はじめに通常の手順でVGを用意します。 – 「プール」を定義すると、ブロックプール用のLVとメタデータ用のLVが作成されます。 LVMによるDevice Mapper Thin-Provisioningの利用 # fallocate -l $((1024*1024*1024)) pooldev.img # losetup -f pooldev.img # losetup -a /dev/loop0: [64768]:39781720 (/root/pooldev.img) # pvcreate /dev/loop0 # vgcreate vg_data /dev/loop0 # lvcreate -L 900M -T vg_data/thinpool Logical volume "lvol1" created Logical volume "thinpool" created # lvs LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert ... lvol0 vg_data -wi------- 4.00m thinpool vg_data twi-a-tz-- 900.00m 0.00 LV: thinpool LV: lvol1 VG: vg_data ブロックプール メタデータ用 デバイス 論理デバイス vol00 論理デバイス vol01 ・・・
  • 18. Open Cloud Campus 18 Linux女子部 Dockerを支える技術 – 「-V」オプションで論理サイズを指定して、論理デバイスを作成します。プールのサイズよりも大き な論理サイズも指定可能です。 – 次のコマンドでスナップショットを作成します。 – スナップショットに対応するLVMは安全のために無効化されています。次のコマンドで明示的に有効 化してから使用します。 LVMによるDevice Mapper Thin-Provisioningの利用 # lvcreate -V 100G -T vg_data/thinpool -n vol00 Logical volume "vol00" created # lvs LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert ... lvol0 vg_data -wi------- 4.00m thinpool vg_data twi-a-tz-- 900.00m 0.00 vol00 vg_data Vwi-a-tz-- 100.00g thinpool 0.00 # lvcreate -s --name vol01 vg_data/vol00 Logical volume "vol01" created # lvs LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert ... lvol0 vg_data -wi------- 4.00m thinpool vg_data twi-a-tz-- 900.00m 0.00 vol00 vg_data Vwi-a-tz-- 100.00g thinpool 0.00 vol01 vg_data Vwi---tz-k 100.00g thinpool vol00 # lvchange -K -ay /dev/vg_data/vol01
  • 19. Open Cloud Campus 19 Linux女子部 Dockerを支える技術  Dockerでは、ディスクイメージの管理方式(ドライバ)が選択できて、Fedora20/RHEL7で は、「Device Mapperドライバ」を使用します。これは、Device Mapper Thin-Provisioning による論理デバイスとして、各ディスクイメージを保存します。 – ディスクイメージを指定してコンテナを起動すると、指定イメージのスナップショットを作成して、 それをコンテナに割り当てます。 – 「docker commit」でコンテナのイメージを保存する際は、コンテナに割り当て中の(先にスナップ ショットで作成した)イメージのスナップショットを作成します。(「docker stop」でコンテナを 停止してから、「docker commit」で保存。) DockerにおけるThin Povisioningの利用 保存イメージ スナップ ショット コンテナ起動時に スナップショットを作成 × run commit rm プロセス スナップ ショット stop start 保存イメージ コンテナを停止するとプロセスが停止 (ディスクイメージは残っている) コンテナを削除すると ディスクイメージを破棄 ディスクイメージを複製して 保存イメージとして登録 参考:Dockerにおけるコンテナのライフサイクル http://d.hatena.ne.jp/enakai00/20140628/1403933390
  • 20. Open Cloud Campus 20 Linux女子部 Dockerを支える技術  Dockerでは、LVMを経由せず、ネイティブにDevice Mapperを操作してThin Provisioningを 利用しています。 – dockerサービスを起動すると下記の「data」と「metadata」をループバックマウントして、Thin Provisioning用のプールを用意します。 DockerにおけるThin Povisioningの利用方式 # ls -lh /var/lib/docker/devicemapper/devicemapper/ 合計 1.2G -rw-------. 1 root root 100G 5月 11 21:37 data -rw-------. 1 root root 2.0G 5月 11 22:05 metadata # losetup NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE /dev/loop0 0 0 1 0 /var/lib/docker/devicemapper/devicemapper/data /dev/loop1 0 0 1 0 /var/lib/docker/devicemapper/devicemapper/metadata # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT ... loop0 7:0 0 100G 0 loop └─docker-252:3-130516-pool 253:0 0 100G 0 dm loop1 7:1 0 2G 0 loop └─docker-252:3-130516-pool 253:0 0 100G 0 dm データ用デバイス メタデータ用デバイス
  • 21. Open Cloud Campus 21 Linux女子部 Dockerを支える技術  論理デバイスの管理情報は、下記のJSONファイルに記録されています。 – /var/lib/docker/devicemapper/metadata/<Image ID> – 特に、デバイスID「0」の論理デバイスは、最初にDockerサービスを起動した際に10GBで作成され、 ext4にフォーマットされます。 外部レジストリからイメージをダウンロードすると、この論理デバ イスのスナップショットを作成して、空のext4ファイルシステムを用意して、その中にダウンロード したファイルを展開します。(そのため、すべての論理デバイスのサイズは10GBになります。) DockerにおけるThin Povisioningの利用方式 # docker images enakai/httpd REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE enakai/httpd ver1.0 d3d92adfcafb 36 hours ago 206.6 MB # cat /var/lib/docker/devicemapper/metadata/d3d92adfcafb* | python -mjson.tool { "device_id": 72, "initialized": false, "size": 10737418240, "transaction_id": 99 } # cat /var/lib/docker/devicemapper/metadata/base | python -mjson.tool { "device_id": 0, "initialized": true, "size": 10737418240, "transaction_id": 1 }
  • 22. Open Cloud Campus 22 Linux女子部 Dockerを支える技術  dmsetupコマンドでネイティブにDevice Mapperを操作すると、Dockerが管理するディスク イメージを直接にマウントして内容を確認することができます。手順の例は次の通りです。 – 前ページの方法で、対象のディスクイメージのIDから、対応する「device_id」と「size」の値を確認 します。また、次のコマンドで、プールの名称(この例では「docker-252:3-130516-pool」)を確 認します。 – 簡単のため、確認した情報を変数にセットしておきます。 Dockerのディスクイメージを直接操作する方法 # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT ... loop0 7:0 0 100G 0 loop └─docker-252:3-130516-pool 253:0 0 100G 0 dm loop1 7:1 0 2G 0 loop └─docker-252:3-130516-pool 253:0 0 100G 0 dm # device_id=72 # size=10737418240 # pool=docker-252:3-130516-pool
  • 23. Open Cloud Campus 23 Linux女子部 Dockerを支える技術 – 次のコマンドで論理デバイスを有効化して、マウントします。下記の「rootfs」以下がコンテナから みえるルートファイルシステムになります。 – 最後に次のコマンドでアンマウントして、論理デバイスを無効化しておきます。 ※ この手順でイメージ内のファイルを修正することは、Docker的には想定外の使い方ですので、   予想外の問題が起きる可能性はあるかも知れません。 – 参考:https://www.kernel.org/doc/Documentation/device-mapper/thin-provisioning.txt Dockerのディスクイメージを直接操作する方法 # dmsetup create myvol --table "0 $(($size / 512)) thin /dev/mapper/$pool $device_id" # lsblk ... loop0 7:0 0 100G 0 loop └─docker-252:3-130516-pool 253:0 0 100G 0 dm └─myvol 253:1 0 10G 0 dm loop1 7:1 0 2G 0 loop └─docker-252:3-130516-pool 253:0 0 100G 0 dm └─myvol 253:1 0 10G 0 dm # mount /dev/mapper/myvol /mnt # ls /mnt id lost+found rootfs # cat /mnt/rootfs/var/www/html/index.html Hello, World! # umount /mnt # dmsetup remove myvol
  • 25. Open Cloud Campus 25 Linux女子部 Dockerを支える技術 Network namespace Dockerの基本的なネットワーク構成  コンテナの仮想NIC「eth0」は、仮想ブリッジ 「docker0」に接続されます。コンテナと外部の通信は、 ホストLinuxのiptablesで制御されます。 – コンテナから外部への接続はIPマスカレードで行います。 – コンテナ内の特定ポートへの接続をホストLinuxからポート 転送する設定が可能です。iptablesのNAT機能でポート転送 が行われます。  iptablesの設定を確認してみます。 ホストLinux vethXX eth0 docker0 eth0 IPマスカレード 172.17.42.1 – 「8000 → 80」と「2222 → 22」のポート転送を指定してコンテナを起動します。 – ブリッジ「docker0」に「veth」の片割れが接続されています。 # docker run -itd -p 8000:80 -p 2222:22 enakai/httpd:ver1.0 a7838c84cd008161086839379e4a0be2d0e109e02c779229cde49f53b79ae1d5 # brctl show bridge name bridge id STP enabled interfaces docker0 8000.56847afe9799 no veth66c0 # ifconfig docker0 docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.42.1 netmask 255.255.0.0 broadcast 0.0.0.0 ...
  • 26. Open Cloud Campus 26 Linux女子部 Dockerを支える技術 Dockerの基本的なネットワーク構成 – iptablesのnatテーブルは、次のようになっています。 ① 外部からホストLinux宛に来たパケットはDOCKERチェーンにまわしてポート転送処理する。 ② ホストLinux上で「"localhost"以外の」ホスト自身のIPアドレスを指定したパケットもDOCKER   チェーンでポート転送する。 ③ コンテナからブリッジ経由で外部に出るパケットは、IPマスカレードする。 ④⑤ DNATでコンテナにポート転送する設定です。 – ②の意味がちょっと不明ですが、実際には、ホストLinux用で「localhost」宛のパケットも正しく ポート転送されます。その理由は・・・ # iptables-save # Generated by iptables-save v1.4.19.1 on Fri Jun 13 22:36:14 2014 *nat ... -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER -A POSTROUTING -s 172.17.0.0/16 ! -d 172.17.0.0/16 -j MASQUERADE -A DOCKER ! -i docker0 -p tcp -m tcp --dport 2222 -j DNAT --to-destination 172.17.0.23:22 -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8000 -j DNAT --to-destination 172.17.0.23:80 COMMIT ① ② ③ ④ ⑤
  • 27. Open Cloud Campus 27 Linux女子部 Dockerを支える技術 Dockerの基本的なネットワーク構成 – Dockerデーモン自身もポート転送用のProxy機能を提供しており、iptablesで転送されなかったパ ケットは、こちらを経由して転送されます。 – このProxy機能は、iptablesが利用できない環境のために用意されています。今回の環境 で、localhost宛のパケットだけiptablesを使わない理由はまだ不明です。 # lsof -i -P COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ... docker 20003 root 11u IPv6 177010 0t0 TCP *:2222 (LISTEN) docker 20003 root 12u IPv6 178468 0t0 TCP *:8000 (LISTEN) ...
  • 28. Open Cloud Campus 28 Linux女子部 Dockerを支える技術 Network namespaceの操作方法  Network namespaceは、次のようなステップで作成・利用します。 – 新しいネームスペースを定義 – ネームスペース内部でネットワークを構成 • 仮想NICとIPアドレスの割り当て、ルーティングテーブルの作成、iptablesの定義など – ネームスペース内部でプロセスを起動  一般には、「ip netns」コマンドで上記の作業を行いますが、DockerはNativeにやっている ので、Dockerが用意したネームスペースを後から操作するには少し工夫が必要です。 – まず、コンテナ内で動いているプロセスのPIDを1つ見つけます。 – このプロセスの/procの下に、ネームスペースを操作するためのFDへのリンクがあります。 # systemd-cgls ... └─system.slice ├─docker-61151db106a7fd6d5cf937a03eac0e9b33c7799d3d48b6cddc83070839afeea9.scop │ ├─502 /bin/sh /usr/local/bin/init.sh │ ├─545 /usr/sbin/sshd │ ├─557 /usr/sbin/httpd ... # ls -l /proc/502/ns/net lrwxrwxrwx 1 root root 0 6月 13 22:52 /proc/502/ns/net -> net:[4026532255]
  • 29. Open Cloud Campus 29 Linux女子部 Dockerを支える技術 Network namespaceの操作方法 – /var/run/netns/以下からFDにシンボリックリンクを張ると、ipコマンド管理下のネームスペースと して認識されます。 – この後は、次のコマンドにより、ネームスペース「hoge-ns」内部でコマンド(プロセス)を実行で きるようになります。 – たとえば、bashを起動するとネームスペース内部のネットワーク構成が確認できます。(あくまで 「Network namespace」だけを切り替えているので、ネットワーク以外の環境はホストLinuxと同じ 状態です。) # mkdir /var/run/netns # ln -s /proc/502/ns/net /var/run/netns/hoge-ns # ip netns hoge-ns # ip netns exec hoge-ns <command> # ip netns exec hoge-ns bash # ifconfig eth0 eth0: flags=67<UP,BROADCAST,RUNNING> mtu 1500 inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0 ... # route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 172.17.42.1 0.0.0.0 UG 0 0 0 eth0 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0 # exit # ip netns exec hoge-ns <command>
  • 30. Open Cloud Campus 30 Linux女子部 Dockerを支える技術 「オレオレ仮想NIC」の追加方法  「ip netns exec」を駆使すると、起動中のコンテナにあとから仮想NICを追加することも可能 です。図のようにブリッジ「br0」を経由して、外部ネットワークに直結した仮想NICを追加 してみます。 – まずは、ブリッジ「br0」を用意して、物理NICのIPアドレス(この例では192.168.200.20/24)を ブリッジに付け替えます。 # brctl addbr br0; ip link set br0 up # ip addr del 192.168.200.20/24 dev eth0; ip addr add 192.168.200.20/24 broadcast 192.168.200.255 dev br0; brctl addif br0 eth0; route add default gw 192.168.200.1 # echo 'NM_CONTROLLED="no"' >> /etc/sysconfig/network-scripts/ifcfg-eth0 # systemctl enable network.service ホストLinux vethXX eth0 コンテナ docker0 IPマスカレード 外部ネットワーク vethYY eth1 br0 192.168.200.99 192.168.200.20 192.168.200.20 eth0 ※IPアドレスを付け替える最後の3行は、何をやっているのか  理解できる方だけ実施してください。
  • 31. Open Cloud Campus 31 Linux女子部 Dockerを支える技術 「オレオレ仮想NIC」の追加方法 – vethペア「veth-host/veth-geust」を作成して、「veth-host」をブリッジ「br0」に接続します。 # ip link add name veth-host type veth peer name veth-guest # ip link set veth-guest down # brctl addif br0 veth-host # brctl show br0 bridge name bridge id STP enabled interfaces br0 8000.525400677470 no eth0 veth-host ホストLinux vethXX eth0 コンテナ docker0 IPマスカレード 外部ネットワーク veth-host veth-guest br0 eth0 • この時点では、「veth-host」「veth-guest」共にホスト Linuxから見えています。
  • 32. Open Cloud Campus 32 Linux女子部 Dockerを支える技術 「オレオレ仮想NIC」の追加方法 – 次のコマンドで「veth-guest」をコンテナのネームスペースに入れます。この時点で、ホストLinux からは、「veth-guest」は見えなくなります。 – この後は、コンテナのネームスペース内で、コンテナから見えるネットワーク環境を設定します。コ ンテナ内でのデバイス名を「eth1」に変更した後に、IPアドレスを設定します。さらにルーティング テーブルを変更して、「eth1」側をデフォルトゲートウェイにします。 # ip link set veth-guest netns hoge-ns # ifconfig veth-guest veth-guest: error fetching interface information: Device not found # ip netns exec hoge-ns ip link set veth-guest name eth1 # ip netns exec hoge-ns ip addr add 192.168.200.99/24 dev eth1 # ip netns exec hoge-ns ip link set eth1 up # ip netns exec hoge-ns ip route delete default # ip netns exec hoge-ns ip route add default via 192.168.200.1
  • 33. Open Cloud Campus 33 Linux女子部 Dockerを支える技術 「オレオレ仮想NIC」の追加方法 – コンテナにログインして、ネットワーク設定を確認します。 – これで、外部ネットワークからポート転送なしで、直接にアクセスできます。 – 「ip netns」コマンドでの設定が終わったら、先のシンボリックリンクは削除して構いません。  ちなみに、これらの作業を自動でおこなうシェルスクリプトを作っている人がいます。 – jpetazzo/pipework – https://github.com/jpetazzo/pipework # ssh enakai@localhost -p 2222 $ ifconfig eth1 eth1 Link encap:Ethernet HWaddr BE:53:16:06:BF:3A inet addr:192.168.200.99 Bcast:0.0.0.0 Mask:255.255.255.0 ... $ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.200.1 0.0.0.0 UG 0 0 0 eth1 172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0 192.168.200.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 $ curl http://192.168.200.99:80 Hello, World! # rm /var/run/netns/hoge-ns
  • 35. Open Cloud Campus 35 Linux女子部 Dockerを支える技術 systemdとcgroupsの基本  基本情報は、下記の資料を読んでおいてください。 – 「Linux女子部 systemd徹底入門!」 • http://www.slideshare.net/enakai/linux-27872553 – 「Control Groups (cgroups) (めもめも)」 • http://d.hatena.ne.jp/enakai00/20110605/1307240161  ここでは、特にUnitとcgroupsの関係が大切になります。 – systemdは、さまざまなサービスを「Unit」として定義します。 – 「Unit」としてサービスを起動すると、該当サービス用にcgroupsのグループを作成して、そのサー ビスから起動するプロセスをまとめてこのグループに入れます。 – Unitの設定ファイルで「CPUShares」と「MemoryLimit」を指定すると、該当のcgroupsの設定がな されます。(それぞれ、CPU割り当て時間の相対的な重み指定と、物理メモリの使用量の上限を指 定。)
  • 36. Open Cloud Campus 36 Linux女子部 Dockerを支える技術 systemdとcgroupsの基本  systemdが管理するcgroupsの状態は、次のコマンドで確認します。 # systemd-cgls ├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 23 ├─user.slice │ └─user-0.slice │ ├─session-1.scope │ │ ├─439 sshd: root@pts/0 │ │ ├─444 -bash │ │ ├─464 systemd-cgls │ │ └─465 systemd-cgls │ └─[email protected] │ ├─441 /usr/lib/systemd/systemd --user │ └─442 (sd-pam) └─system.slice ├─polkit.service │ └─352 /usr/lib/polkit-1/polkitd --no-debug ├─auditd.service │ └─301 /sbin/auditd -n ├─systemd-udevd.service │ └─248 /usr/lib/systemd/systemd-udevd ...
  • 37. Open Cloud Campus 37 Linux女子部 Dockerを支える技術 Dockerとsystemdの関係  Dockerがコンテナを作る際は、該当コンテナに対応するUnitを動的に作成して、コンテナ内 の最初のプロセスをUnitから起動します。 – これにより、該当Unitのグループが作成されて、コンテナ内のプロセスは、すべて該当グループに入 ります。Unit名は「docker-<コンテナID>.scope」です。 # docker run -td -p 8000:80 -p 2222:22 enakai/httpd:ver1.0 # systemd-cgls -a ... └─system.slice ├─var-lib-docker-devicemapper-mnt-a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a4 7f7c4bc8b37e3b488b.mount ├─docker-a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope │ ├─496 /bin/sh /usr/local/bin/init.sh │ ├─538 /usr/sbin/sshd │ ├─550 /usr/sbin/httpd │ ├─552 /bin/bash │ ├─553 /usr/sbin/httpd │ ├─554 /usr/sbin/httpd │ ├─555 /usr/sbin/httpd │ ├─556 /usr/sbin/httpd │ ├─557 /usr/sbin/httpd │ ├─558 /usr/sbin/httpd │ ├─559 /usr/sbin/httpd │ └─560 /usr/sbin/httpd ...
  • 38. Open Cloud Campus 38 Linux女子部 Dockerを支える技術 Dockerとsystemdの関係 – Unitのstatusを確認することもできます。 # unitname=docker-a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope # systemctl status $unitname docker-a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope - docker container a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b Loaded: loaded (/run/systemd/system/docker- a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope; static) Drop-In: /run/systemd/system/docker- a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope.d └─90-BlockIOAccounting.conf, 90-CPUAccounting.conf, 90-Description.conf, 90- MemoryAccounting.conf, 90-Slice.conf Active: active (running) since 金 2014-06-13 23:05:27 JST; 1min 41s ago CGroup: /system.slice/docker- a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a47f7c4bc8b37e3b488b.scope ├─496 /bin/sh /usr/local/bin/init.sh ├─538 /usr/sbin/sshd ├─550 /usr/sbin/httpd ├─552 /bin/bash ├─553 /usr/sbin/httpd ├─554 /usr/sbin/httpd ├─555 /usr/sbin/httpd ... └─560 /usr/sbin/httpd 6月 13 23:05:27 fedora20 systemd[1]: Started docker container a985fc6dbe8dfc6335474ae68291ad3c51cddcbc28c1a...488b. Hint: Some lines were ellipsized, use -l to show in full.
  • 39. Open Cloud Campus 39 Linux女子部 Dockerを支える技術 Dockerとsystemdの関係 – Unitの設定パラメータとして、cgroupsの設定値が用意されています。これらは、「docker run」コ マンドの 「-c」オプションと「-m」オプションの設定値に対応しています。 – コンテナ起動後にsystemdのインターフェースを通して、設定値を変更することも可能です。  今後、systemdとcgroupsのより緊密な統合が計画されており、systemdを通して、その他の リソース制御(CPU pinning、CPU quota、I/O bandwidthなど)も可能になると予想されま す。 # systemctl show $unitname | grep -E "(CPUShares=|MemoryLimit=)" CPUShares=1024 MemoryLimit=18446744073709551615 # systemctl set-property $unitname CPUShares=512 --runtime # systemctl show $unitname | grep -E "(CPUShares=|MemoryLimit=)" CPUShares=512 MemoryLimit=18446744073709551615
  • 41. Open Cloud Campus 41 Linux女子部 Dockerを支える技術 参考資料  Dockerクイックツアー – http://www.slideshare.net/enakai/docker-34526343  「めもめも」 – RHEL7におけるDockerのディスクイメージ管理方式 • http://d.hatena.ne.jp/enakai00/20140420/1397981156 – Dockerのネットワーク管理とnetnsの関係 • http://d.hatena.ne.jp/enakai00/20140424/1398321672 – RHEL7のDockerとsystemdとcgroups • http://d.hatena.ne.jp/enakai00/20140427/1398576165  クラウド時代のオープンソース実践活用 – 第41回 Linuxコンテナ(LXC)の基礎をまとめ直す • http://www.school.ctc-g.co.jp/columns/nakai/nakai41.html – 第42回 Dockerのイメージ管理を考える • http://www.school.ctc-g.co.jp/columns/nakai/nakai42.html – 第43回 「Dockerイメージ」のポータビリティとLinuxカーネルのABI • http://www.school.ctc-g.co.jp/columns/nakai/nakai43.html
  • 42. Open Cloud Campus 42 Linux女子部 Dockerを支える技術 QA