DockerCon 2017 で発表された Moby プロジェクト を利用して
LinuxKit が動作するところまでを確認します。
Moby
もともと使われている意味の Moby
Docker 社のロゴにもなっている、このクジラの愛称1。
(https://blog.docker.com/2015/06/winners-dockercon-2015-contests/ より拝借)
最近チラ見せしていた Moby OS
Alpine Linux ベースの軽量 OS。Docker for Mac の記事でよく
Message of The Day のアスキーアートとともに紹介されていますが
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\_______/
Docker for AWS などでは Docker Inc. が用意したであろう
Moby な AMI で EC2 クラスタが起動するなど、
Docker 製品群では近頃大活躍している OS です。
Moby
今回発表されたコンテナ環境を組み立てるためのフレームワーク。
標準化されたランタイム、オーケストレーション、ネットワーキング
セキュリティ、ビルド / イメージ配布方法などを利用して、
様々なプラットフォーム / アーキテクチャ上で実行可能なものを
組み立てることができます。
Linux や Mac、Windows なら実行形式ファイルを、
クラウドや仮想化事業者に向けては VM イメージが生成されます。
上述の Moby OS なども、いずれは Moby 経由で生成されるかもですね。
CTO の Solomon Hykes 氏が PR で Moby への移行を語っています。
LinuxKit
Publickey さんの記事 がわかりやすかったのですが
DockerCon のデモでもあったように、この LinuxKit を
Moby を使えば簡単にビルドすることができます。やってみましょう。
LinuxKit を動かすまで
以下、MacBook Pro (Early 2015) macOS Sierra で動作確認しています。
1. moby コマンドのインストール
方法 1
Go 環境があれば楽勝
go get -u github.com/docker/moby/src/cmd/moby
方法 2
- GNU make
- GNU or BSD tar (not busybox tar)
- Docker
のインストールされた環境で
git clone https://github.com/linuxkit/linuxkit.git
cd linuxkit
make
でビルドすれば、bin 以下に moby バイナリが生成されます。
PATH の通ったところに置いて実行権限をつけましょう。
2. LinuxKit イメージのビルド
moby 自体も内部的に Docker の仕組みを使うので
Docker がインストールされた環境で以下のコマンドを実行します。
moby build linuxkit.yml
するとログにあるように、linuxkit-xxx というファイルが生成されましたね!
Create outputs:
linuxkit-bzImage linuxkit-initrd.img linuxkit-cmdline
linuxkit.iso
linuxkit-efi.iso
3. LinuxKit を起動します
とても簡単です。
moby run linuxkit
以下のような表示になるまで待ちましょう
Welcome to LinuxKit
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\_______/
/ # [ 2.449400] IPVS: Creating netns size=2104 id=1
[ 2.449828] IPVS: ftp: loaded support on port[0] = 21
[ 2.699956] IPVS: Creating netns size=2104 id=2
[ 2.700419] IPVS: ftp: loaded support on port[0] = 21
[ 3.408548] clocksource: Switched to clocksource tsc
LinuxKit をさわってみる
動いているものの確認
デモにもありましたが、プロセスはこんな感じ。
/ # pstree
init-+-containerd-+-containerd-shim---nginx---nginx
| `-containerd-shim---tini---rngd
|-containers---2*[ctr]
|-sh---pstree
`-sh
containerd が見えますが、runc からコンテナの状態も確認できます。
/ # runc list
ID PID STATUS BUNDLE CREATED OWNER
nginx 543 running /run/containerd/linux/nginx 2017-04-18T22:12:11.1635803Z root
rngd 599 running /run/containerd/linux/rngd 2017-04-18T22:12:11.3155512Z root
コンテナへアクセス
まず host ネットワーク上で nginx コンテナが動いているので
HTTP リクエストをローカルホストに送信してみます。
/ # wget -qO - 127.0.0.1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
設定値を runc 経由で確認してみます。
/ # runc exec nginx cat /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
LinuxKit 上で Docker を動かす
LinuxKit は読み込み専用で起動する設定になっているため
ファイルに書き込むような操作は何もできません。
そこで、Nginx の代わりに Docker が起動する設定の LinuxKit を起動してみます。
ビルドと起動
リポジトリにある このサンプル を使ってビルド・起動します。
(Docker イメージがちゃんと保存されるようになっている)
$ moby build docker.yml
$ moby run docker
起動した Docker サービスコンテナに接続2
VM の中に起動している Docker サービスに runc exec で
sh プロセスを起動して、-t でターミナルをアタッチします。
/ # runc exec -t docker sh
Docker 内の挙動を確認
dind ならぬ docker in runc 状態ですが、
docker コマンドが打てるこの安心感。
/ # docker system info
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 1
Server Version: 17.04.0-ce
Storage Driver: overlay2
Backing Filesystem: tmpfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary:
containerd version: 422e31ce907fd9c3833a38d7b8fdd023e5a76e73
runc version: 9c2d8d184e5da67c95d601382adf14862e4f2228
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 4.9.22-moby
Operating System: Alpine Linux v3.5 (containerized)
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 992.5MiB
Name: moby-025000000008
ID: NIKL:AY2Z:MQQL:OJYX:6OZD:BKYA:T3ZT:TKJF:T5XD:C46N:N5BF:V7ZZ
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Docker コンテナの起動
df -h
するとわかりますが、ここまでの流れで起動した VM は
ディスク容量がとても少ないのであまり遊べません。
というわけで node.js あたりを。
docker run --rm -it node:7.9-alpine sh
普通に使えますね。
/ # node -v
v7.9.0
/ # node
> 1+1;
2
この時点で、こんなことになってます。
Mac -> LinuxKit + docker -> Node.js コンテナ -> Node.js REPL
なので、Mac まで戻るには
Ctrl + D -> Ctrl + D -> Ctrl + D -> halt
です。