DockerとLinux OSのリソース共有状況の調査
DockerコンテナとベースとなるLinux OSとは、カーネルや様々なリソースを共有している。リソースを個別に保持するサーバ型仮想化と比較するとリソース消費量が少なく、1台のサーバ上でより多くの仮想マシンを起動させることが可能である。
コンテナ型仮想化のメリットはわかりやすいが、同時にこの特徴は、共有されているリソースをあるコンテナが大量に消費するような状況が発生した場合、ベースOSにも影響を及ぼす可能性があるという懸念を生じさせる。この懸念を払拭し問題点を明らかにするために、DockerコンテナからベースOSのリソースを消費させる試験を行い、その影響について検証した。
本連載で性能評価などを行ってきた過程で、Dockerの動作は(若干ではあるが)Linuxディストリビューションごとに異なることもわかっている。そこで今回は、LinuxディストリビューションによるDockerのリソース使用状況の差異についても合わせて調査を実施した。
調査対象としたLinuxディストリビューション
調査対象として選択したLinuxディストリビューションを表1に示す。Dockerに関しては、バージョンによる差異の発生を抑止するため、全て同一のバージョン(1.5.0, build a8a31ef)とした。
ディストリビューション | カーネル | 選択した理由 |
---|---|---|
CentOS 6.6 x86_64 | kernel-centos6 2.6.32-504.el6.x86_64 | カーネル 2.6系の挙動を検証する |
CentOS 7.0 x86_64 | kernel-centos7 3.10.0-123.el7.x86_64 | カーネル 3.0系の挙動を検証する |
Ubuntu Server 14.04 x86_64 | 3.13.0-46-generic | Debian系とRed Hat系の挙動の差異を検証する |
実行モジュールのカーネル差異による不具合の発生を抑止するため、検証を実行するDockerコンテナもベースOSと同じディストリビューションとバージョンで作成されたものを使用している。つまり、CentOS 6.6 x86_64での検証では、CentOS 6.6上で作成されたコンテナを使っているということだ。
調査対象項目および検証方法
調査対象に選定した項目と検証方法を表2に示す。その調査対象を選定した理由と、想定する状況や発生事象についても記載しておく。
調査対象項目 | 検証方法 | 想定する状況・発生事象 |
---|---|---|
コンテナ上のファイル格納方法 | Dockerコンテナを生成し、コンテナ内のファイルがベースOSのディスク上のどこに格納されているかを確認する | Linuxディストリビューションごとに、使用するファイルシステムとファイルの格納場所に差異が存在するのではないか? |
ディスク容量 | コンテナ内で大容量のファイルを作成する | ベースOSの空きディスク容量が枯渇することで、ファイル作成や書き込みが不能にならないか? |
ベースOSと共用する領域が存在する場合に、大容量ファイルを作成する | ||
inode数 | コンテナ内で大量にファイルを生成する | ベースOSのinodeが枯渇することで、ファイル生成が不能にならないか? |
メモリ使用量 | コンテナ内でメモリを大量に使用するアプリを実行する | ベースOSの空きメモリ容量が枯渇することで、システムに異常が発生しないか? |
プロセス数 | コンテナ内で子プロセスを大量に生成する | ベースOSのプロセス数の制限に抵触し、プロセスが生成できない状態にならないか? |
では、表2の各調査項目について検証を見ていこう。
コンテナ上のファイル格納方法
Dockerコンテナ内のファイルは原則、仮想ストレージに格納される。その仮想ストレージの形式は、ストレージドライバによって選択が可能である。各ディストリビューションの、標準で利用可能および標準インストール時に選択されたストレージドライバは、表3のようになる。
ディストリビューション | ストレージドライバ | 備考 |
---|---|---|
CentOS 6.6 x86_64 | device-mapper(標準) vfs | dockerのオプション定義ファイル(/etc/sysconfig/docker)で変更が可能 |
CentOS 7.0 x86_64 | device-mapper(標準) vfs | |
Ubuntu Server 14.04 x86_64 | aufs(標準) device-mapper vfs | インストール方法によってdevice-mapeprが選択される場合もある dockerのオプション定義ファイル(/etc/default/docker)で変更が可能 |
同じバージョンのDockerをインストールしても、ベースOSのディストリビューションによって異なるストレージドライバが選択される。さらにUbuntuでは、Dockerのインストール方法によって選択されるストレージドライバが変わる。この事象については、弊社の松井による記事に詳しく記載されている。
CentOS/Ubuntuのバージョンとインストール手順によるDockerバージョンとストレージドライバの差異 - Qiita
http://qiita.com/nmatsui/items/7dc75fa6af0adde0eeec
CentOS 6.6とCentOS 7.0は、標準インストールではストレージドライバにdevice-mapperを採用している。コンテナのベースイメージやコンテナ内の仮想ディスクイメージは、Sparseファイル内に格納されている。Sparseファイル内のデータの格納にはDevice-mapper Thin Provisioningを採用しており、重複排除などにより効率化された配置が行われている。詳細はレッドハットのクラウドエバンジェリストである中井氏による資料に記載されているので、ご一読をお勧めする。
CentOS 6.6
実際に構築してみると、CentOS 6.6とCentOS 7.0 ではマウントのされ方が異なっていた。CentOS 6.6ではコンテナ内のディスクはまず、ベースOSのフォルダ内にマウントされる。そのフォルダをデバイスにマッピングし、読み込み専用のベースイメージに重ねる形でマウントしている(図1)。この方法により、同一のベースイメージから複数のコンテナを生成し、その差分を個々に保存できる状況を実現している。Dockerコンテナ内のファイルは、ベースOS上のファイルシステムの一部となっているため、ベースOSからもアクセスが可能で、ファイル自体の操作も行える。
CentOS 7.0
一方CentOS 7.0ではCentOS 6.6とは異なり、ベースOS上のファイルシステムにはマウントせず、Sparseファイル上のコンテナ用の仮想ディスク領域を直接、pool領域上にマウントしている(図2)。そのため、コンテナ内のファイルシステムに対するベースOS上からの直接操作はできなくなっている。
前述の中井氏の資料に、Dockerコンテナ上のファイルシステムをベースOSからマウントする方法が記載されている。実際に試したところ、読み込みは行えたが、書き込みを行おうとするとエラーになった。さらにマウント後にコンテナ側でファイルの書き込み操作を行った場合、読み込み自体もエラーとなり、再マウントを行うまで解消されなかった。本操作自体が非推奨とされていることも納得である。
Ubuntu 14.04
Ubuntu 14.04のaufsは、device-mapperとはかなり構造が異なる。Dockerコンテナに提供するファイルシステムは仮想ディスクイメージではなく、旧来のlxcと同様にベースOSのファイルシステムの一部をchrootの機能で切り出して提供している。そのため、CentOS 6.6と同様にコンテナ内のファイルはベースOSからも操作が可能である。
Ubuntu 14.04でのマウント方式
(1)コンテナの内にファイルシステムのルート / の格納フォルダ
# cat/proc/self/mountinfo 44 23 0:40 / /var/lib/docker/aufs/mnt/[コンテナID] rw,relatime - auds none rw,si=303ed1ddc4bb38b3
(2)コンテナの内にで更新されたファイルを格納するフォルダ
# ls -1/var/lib/docker/aufs/diff/[コンテナID] /var/lib/docker/aufs/diff/[コンテナID]
(3)Doclerコンテナのマウントイメージ
/(rootfs) └ mount/var/lib/docker/aufs/mnt/[コンテナID] / └ mount/var/lib/docker/aufs/diff/[コンテナID] /
※コンテナの / に対してベースOSのフォルダを重ねるようにマウント(union mount)している。
またUbuntu 14.04では、/etc/default/dockerのDOCKER_OPTSに「--storage-driver=devicemapper」を加えて再起動することで、ストレージドライバをdevice-mapperに切り替えられる。このように明示的にdevice-mapperを指定した際の挙動は、CentOS 7.0と同様であった。
ただし、実行中にDocker環境のストレージドライバを切り替えると、Dockerの設定ファイルに不整合が生じ、過去に利用していたコンテナが利用できなくなる。ストレージドライバを切り替える際の不整合を避けるには、必要なイメージやコンテナをdocker exportなどのコマンドで退避した後、Dockerの起動前に/var/lib/docker以下を全て削除する必要がある。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- CentOS 7の仮想化、Docker、リソース管理(後編)
- Dockerの導入前に知っておくべきこと
- コンテナ関連技術の現状を確認しておく
- Dockerコンテナのパフォーマンス劣化とチューニング
- Dockerの誤解と神話。識者が語るDockerの使いどころとは? Docker座談会(前編)
- ベアメタル環境とDockerコンテナ環境の性能比較
- CoreOS&Docker環境においてOracle Database 11g Release 2をインストールするためのポイント
- Dockerコンテナ環境のバックアップツール「Convoy」を使う
- Dockerの導入前の設計、CentOS 7.xとDockerのインストール
- Docker向けの軽量Linux OS 主要3種を比較する