前回は、
今回はそのcgroup名前空間の応用例を紹介することを兼ねて、
今回はroot権限で動作するコンテナを使ってネストを試してみます。試している環境はUbuntu 16.
親コンテナの作成と起動
まずはホスト上にコンテナを作成します。
ubuntu@host:~$ sudo lxc-create -n parent -t download -- -d ubuntu -r xenial -a amd64
ここではネストさせるコンテナのparent
という名前のコンテナを作成しました。ここまでは通常のコンテナを作成する場合と同じです。
コンテナのネストを行うためには、nesting.
が付属していますので、lxc-create
で作成したコンテナの設定ファイルにincludeの設定を行うだけです。
ubuntu@host:~$ sudo sed -i '$ a lxc.include = /usr/share/lxc/config/nesting.conf' /var/lib/lxc/parent/config
これでコンテナの中でコンテナを起動する準備ができました。このコンテナを起動し、
ubuntu@host:~$ sudo lxc-start -n parent (コンテナの起動) ubuntu@host:~$ sudo lxc-ls -f (コンテナの起動確認) NAME STATE AUTOSTART GROUPS IPV4 IPV6 parent RUNNING 0 - 10.0.3.169 - ubuntu@host:~$ sudo lxc-attach -n parent(コンテナ環境に入る) root@parent:~# apt-get update && apt-get install lxc (LXCのインストール) :(略)
子コンテナの作成と起動
ここまででparent
コンテナ内でコンテナを作成する準備が整いました。
root@parent:~# lxc-create -n child -t download -- -d ubuntu -r xenial -a amd64 root@parent:~# sed -i '$ a lxc.include = /usr/share/lxc/config/nesting.conf' /var/lib/lxc/child/config
コンテナ名はchild
としました。
root@parent:~# lxc-start -n child (子コンテナの起動) root@parent:~# lxc-ls -f (子コンテナ起動の確認) NAME STATE AUTOSTART GROUPS IPV4 IPV6 child RUNNING 0 - 10.0.4.181 -
特に問題なく起動しています。
ネストしたコンテナの確認
ところで、lxc-ls
コマンドには--nesting
というオプションがあり、
一旦、lxc-ls
コマンドを実行してみましょう。
ubuntu@host:~$ sudo lxc-ls -f --nesting NAME STATE AUTOSTART GROUPS IPV4 IPV6 parent RUNNING 0 - 10.0.3.169, 10.0.4.1 - \child RUNNING 0 - 10.0.4.181 -
以上のように、parent
が実行されており、child
が実行されている様子が確認できます。また、parent
内でLXCをインストールしたため、10.
)
孫コンテナの作成と起動
以上で、
さきほど作成したchild
内でさらにコンテナを作成し、
root@parent:~# lxc-attch -n child (子コンテナに入る) root@child:~# apt-get update -y && apt-get install lxc (LXCのインストール) root@child:~# lxc-create -n grandchild -t download -- -d ubuntu -r xenial -a amd64 (コンテナの作成) root@child:~# lxc-start -n grandchild (孫コンテナの起動) root@child:~# lxc-ls -f (孫コンテナ起動の確認) NAME STATE AUTOSTART GROUPS IPV4 IPV6 grandchild RUNNING 0 - 10.0.3.157 -
最初の親コンテナから見ると孫になりますのでgrandchild
と名づけました。
先の実行例と同様に、lxc-ls
でネストされている状態を確認してみましょう。
ubuntu@host:~$ sudo lxc-ls -f --nesting NAME STATE AUTOSTART GROUPS IPV4 IPV6 parent RUNNING 0 - 10.0.3.169, 10.0.4.1 - \child RUNNING 0 - 10.0.3.1, 10.0.4.181 - \grandchild RUNNING 0 - 10.0.3.157 -
cgroupの確認
孫コンテナまで3段のネストをさせたところで、
孫コンテナのcgroup
まずは、grandchild
で、
root@grandchild:~# ls -F /sys/fs/cgroup/ blkio/ cpu,cpuacct/ freezer/ net_cls@ perf_event/ cpu@ cpuset/ hugetlb/ net_cls,net_prio/ pids/ cpuacct@ devices/ memory/ net_prio@ systemd/
/sys/
以下は、freezer
ディレクトリを見てみましょう。
root@grandchild:~# ls -F /sys/fs/cgroup/freezer/ cgroup.clone_children freezer.parent_freezing freezer.state tasks cgroup.procs freezer.self_freezing notify_on_release
以上のようにcgroupとfreezerサブシステム用のファイルが存在します。freezerサブシステムをオプションに指定して、
その他のサブシステムやsystemd用のcgroupについても、
子コンテナのcgroup
孫コンテナのcgroupを確認したところで、child
で、
root@child:~# tree -d /sys/fs/cgroup/freezer/ /sys/fs/cgroup/freezer/ └── lxc └── grandchild
今度はサブディレクトリが存在します。LXCコンテナは通常、lxc
というcgroupを作成し、child
内でgrandchild
という名前のコンテナを起動しましたので、lxc/
が見えています。
つまり、/sys/
として見えていたcgroupは、/sys/
に相当します。
cgroup名前空間の機能で、grandchild
)
親コンテナのcgroup
親コンテナであるparent
内でも同様に確認してみましょう。
root@parent:~# tree -d /sys/fs/cgroup/freezer/ /sys/fs/cgroup/freezer/ └── lxc └── child └── lxc └── grandchild
コンテナごとにlxc/
というcgroupが作成されており、
ホストのcgroup
同様にホストから確認しましょう。
ubuntu@host:~$ tree -d /sys/fs/cgroup/freezer/ /sys/fs/cgroup/freezer/ ├── lxc │ └── parent │ └── lxc │ └── child │ └── lxc │ └── grandchild :(略)
先の例と同様にcgroupがネストしていますね。
LXCコンテナ内でのDocker
ここまでで、
ここまでで作成したコンテナはすべてLXCコンテナでしたが、
まずはDockerデーモンを動かすためのLXCコンテナを作成します。LXCコンテナを表すlxcct
という名前にしてみました。
ubuntu@host:~$ sudo lxc-create -t download -n lxcct -- -d ubuntu -r xenial -a amd64
Ubuntu 16.
ubuntu@host:~$ sudo tail -n2 /var/lib/lxc/lxcct/config lxc.aa_profile = unconfined lxc.cap.drop =
AppArmorを無効にする設定と、
ubuntu@host:~$ sudo modprobe -v overlay insmod /lib/modules/4.4.0-79-generic/kernel/fs/overlayfs/overlay.ko
これで準備は完了です。コンテナを起動し、
ubuntu@host:~$ sudo lxc-start -n lxcct (LXCコンテナの起動) ubuntu@host:~$ sudo lxc-attach -n lxcct (LXCコンテナ環境に入る) root@lxcct:~# apt-get update root@lxcct:~# apt-get -y install docker.io (Dockerをパッケージインストール)
インストールはUbuntuのパッケージを使ってインストールします。動作を確認してみましょう。
root@lxcct:~# docker info :(略) Server Version: 1.12.6 Storage Driver: overlay Backing Filesystem: extfs Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: null host bridge overlay Swarm: inactive Runtimes: runc Default Runtime: runc Security Options: apparmor seccomp :(略)
動作していることが確認できました。ストレージとしてoverlayfsが使われていることがわかります。
それではDockerコンテナを起動してみましょう。
root@lxcct:~# docker run -t -i ubuntu /bin/bash Unable to find image 'ubuntu:latest' locally latest: Pulling from library/ubuntu :(略) Status: Downloaded newer image for ubuntu:latest root@54fa51853d2c:/# ls -la .dockerenv -rwxr-xr-x 1 root root 0 Jul 10 11:33 .dockerenv
Ubuntuイメージを使ってDockerコンテナが起動しました。/.dockerenv
ファイルがあるので確かにDockerコンテナ内にいるようですね。
Dockerコンテナ内からcgroupを確認してみます。
root@54fa51853d2c:/# ls -F /sys/fs/cgroup/freezer/ cgroup.clone_children cgroup.procs freezer.parent_freezing freezer.self_freezing freezer.state notify_on_release tasks
freezerサブシステムがマウントされており、
ubuntu@host:~$ tree -d /sys/fs/cgroup/freezer/ /sys/fs/cgroup/freezer/ ├── lxc │ └── lxcct │ └── docker │ └── 54fa51853d2c1e5dc0a6ca0488c5522b6bf8a77ac24c471ee2044daa845e255d :(略)
lxc/
がLXCが作成したcgroup、docker/
がDockerが作成したcgroupです。
LXCコンテナ上からみると、
root@lxcct:~# tree -d /sys/fs/cgroup/freezer/ /sys/fs/cgroup/freezer/ └── docker └── 54fa51853d2c1e5dc0a6ca0488c5522b6bf8a77ac24c471ee2044daa845e255d
Dockerコンテナを起動した場合も、
まとめ
今回は、
Linuxカーネルの機能的に見ると、
ただ、
LXCは、
LXCと同じく、
さて、
第11回 コンテナ型仮想化の情報交換会@大阪
6/
当日は、
当日のセッションそれぞれの動画の公開や発表資料へのリンクがありますので、