コンテナ型仮想化といえばDockerが現在最もポピュラーなツールとして君臨しています。
昨年末はCoreOSによりRocketのリリースもアナウンスされ、「え、Dockerってマズイの?」みたいな人と「かまへん、かまへん」の人と居たはずです。
Dockerには色々思うところもあり、私の好みとしては開発途中とはいえRocketかな〜と思っています。
そこで、Rocketの中枢となっているsystemd-nspawnに目を付けてみたところ、これが意外に実用的なので現VPS上の仕様を変更してみました。
OSはArchLinuxを選択しました。
※画像は別のコンテナです
systemd-nspawn とは?
まぁね。ArchWikiに書いてあるしね・・・別にいらん世話かとは思いますけど、DockerやRocketみたいなコンテナ型の仮想化機構です。
systemdに付属しているのでArchユーザーならすぐ試せます。
シンプルなツールですので、docker pull
のような機能はありません。
man7.orgを見るとdocker pull
みたいな機能やコンテナのクローン機能などもあるようなのですが、現在Arch上では使用できてません。
systemdのバージョンは同じみたいなのですが・・・なんでだろ?
これって実装予定が載ってるだけなのかな?
http://man7.org//linux/man-pages/man1/machinectl.1.html#SEE_ALSO
しかし、Dockerからエクスポートしたイメージを動かすこともできます。
企業利用ではDockerコンテナをエクスポートしてsystemd-nspawnで実行してるってとこもあるみたいです。
Arch ユーザーなら systemd-nspawn で仮想化がオススメ
systemd-nspawn自体は他のディストリビューションでも使用できます。
Archなら次のコマンドで実マシン等にインストールした時と同じように簡単にコンテナ作成を始める事が可能です。
mkdir ~/MyContainer pacstrap -i -c -d ~/MyContainer base
めっちゃコマンド短いねん。
この時カーネルのインストールは不要なのでSkipします。
ネットワークの仮想化(ほとんどの場合不要)を行わないならdhcpcd
もいらないです。
公式Wikiではbaseだけでなくbase-develグループのインストールも推奨されております。
pacstrap
コマンドが使用できない場合は、ホスト側に公式リポジトリからarch-install-scripts
をインストールすると良いでしょう。
いざ、 コンテナ 内へ侵入!
試しにこのコンテナに入ってみましょう。
以下のコマンドでマシンにログインできます。
systemd-nspawn -bD ~/MyContainer
最初のログインはrootユーザでパスワードは空。
pacman・yaourtで好きにコンテナを構築していくといいでしょう。
ある程度構築が完了した段階で、コンテナの自動起動を行っておくとさらに捗ります。
ちなみに以下の様にbindオプションを付与してあげればホスト・コンテナ間でディレクトリの共有が可能になります。
systemd-nspawn -bD ~/MyContainer --bind=/usr/share/nginx/html/MyContainer:/usr/share/nginx/html
これはホストの/usr/share/nginx/html/MyContainer
をコンテナの/usr/share/nginx/html
へとバインドしています。
もちろんディレクトリは先に作っておいてください。
コンテナを破棄したいときはこのディレクトリを消せばよいです。
後述する自動起動の設定をした後に削除したいときはユニットファイルとシンボリックリンクの削除もお忘れなく。
コンテナ の自動起動 (ホストのinitに登録)
以下の操作でコンテナを自動起動させることができます。
この時作成したシンボリックリンクの名前=マシン名となりますので、この例だとMyContainer
がマシン名ということになります。
サービス名はsystemd-nspawn@MyContainer.service
です。
ちと長いですね。
最後の.service
は省略可能です。
ln -s ~/MyContainer /var/lib/machines/MyContainer systemctl enable systemd-nspawn@MyContainer.service
起動しているコンテナを操作したい場合はmachinectlコマンドを使用します。
machinectl login MyContainer(マシン名)
machinectlのコンソールから抜けたい場合はCtrl
押しっぱなしで]
を3回入力。
コンテナ の操作一覧
シンボリックリンクが貼られたコンテナは以下のように通常のサービスと同じ扱い方が可能になります。
systemctl enable systemd-nspawn@MyContainer.service systemctl disable systemd-nspawn@MyContainer.service systemctl start systemd-nspawn@MyContainer.service systemctl stop systemd-nspawn@MyContainer.service systemctl restart systemd-nspawn@MyContainer.service
bindオプションの追加
あぁ〜どんどん話が逸れてってるけど一応これも書いとくか。
自動起動もさせたい、ディレクトリ共有もさせたいって場合は以下の場所にユニットファイルを置きます。
/etc/systemd/system/systemd-nspawn@MyContainer.service.d/custom.conf # /etc/systemd/system/systemd-nspawn@マシン名.service.d/自由な名前.conf
※Systemd version 218よりユニットファイルのオーバーライドがコマンドで行えるようになり楽になりました。
上記の操作はsystemctl edit systemd-nspawn@MyContainer
で代用可能です。
このコマンドで作成した場合は最後のファイル名が自動的にoverride.conf
となるようです。
中身はこんな感じのたった3行。
ここはきちんとルールに沿って記述してください。
[Service] ExecStart= ExecStart=/usr/bin/systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --directory=/var/lib/container/%i --bind=/usr/share/nginx/html/MyContainer:/usr/share/nginx/html
2行目のExecStart=
ってのは必ず要ります。
後ろーーーの方にbindオプションを追記してあげればいいです。
終わったら以下を実行。
sudo systemctl daemon-reload sudo systemctl restart systemd-nspawn@MyContainer.service
Docker の愚痴
Dockerはコンテナ内でのsystemdに問題があり、systemctlでサービスの起動ができません。
というより本来そんな操作で動かすものじゃない・・・。
なんとか動かす手順もあるんですが、まぁ〜〜〜これが面倒くSay YO ☆
そもそもDockerは1コンテナ=1プロセスにすべきみたいな思想を掲げているんですが、この辺が私に合わない。
進歩の激しいOSS界で1コンテナ=1プロセスなんて無謀というか意味あんのっていうか。
規模の大きいサービスを1つだけ動かすみたいな場合はそれの方がいいでしょうけど、個人、もしくは少人数でそんな細切れコンテナ管理したくはないかな。
Dockerが合わない、わからないって人は大抵この話題ですよね。
どうせチューニングは必要になるんだし、それならコンテナに一時的に入ってイジったほうが手っ取り早くない?
んで色々イジってたら面倒臭くなるんだって。
まぁメールとかDBとかスタンダードなものは分けたい気持ちはわからんでもないですよ。
どちらにしろ1コンテナ=1アプリケーションってぐらいのゆるい感覚の方が楽に運用できるんじゃないでしょうか。
systemd-nspawn はsystemctlコマンドが使用できる
いやもうフッツーに使用できます。
稼働中のコンテナに普通にログインして普通のマシンと同じように使えます。
んで色々イジれます。
systemd-nspawnはこういったコンテナをイジる時のストレスから開放してくれる。
特に説明必要ないでしょうけどこれはデカイ。
Systemd使ってないディストリ使えよって言う人もいるけど、
Archに一度慣れてしまうと他のディストリビューションはちょっと使う気にならない。
ローリングリリースの安定性も抜群だし、Wikiの充実っぷり半端ない!
丁寧な運用ができるならばこんなに使い易いOSなくないですか?
というかAURは卑怯。他のディストリが頑張ってもサクッと旨いとこ取っていくし。
末永く運営していってもらいたいですね。
systemd-nspawn コンテナ のデプロイ
リモートの本番環境などにデプロイする場合は一旦tarballにしてしまうといいでしょう。
tar zcvf MyContainer.tar.gz MyContainer
んでscpやsftp、rsyncなど好きなツールで普通にアップロードします。
そして解凍します。
そして上記の自動起動設定を本番環境でも行います。
ワオ!原始的!・・・ってやってられるかメンドクセェ!
この辺がDockerと比べるとなぁ・・・その内Rocketがいい感じに整えてくれることを願います。
もしくはman7.orgに書いてある通りの動作ができるならもっとマシな方法があるんでしょうけども。
なお、転送先でもこんな感じに特権レベルで解凍を行えばパーミッションを保持してくれます。
sudo tar zxvf MyContainer.tar.gz
ローカルとリモートでUID・GIDを統一しておくとちょっとだけ楽ですね。
あれ何か最初書こうと思った事と違う!
いや最初はsystemd-nspawnでVPS構成しなおしたって話を書こうとしたんですよ。
なぜだ・・・なぜ使い方になってしまったんだ・・・
まぁいいや、ちょっと長くなったので一旦区切ります。
コンテナを利用して面白い試みもしていますので早めに紹介したいと思います。
2015/02/08追記
↓記事追加しました