Dockerは便利だけど、もうちょっと素のコンテナが使いたい。ということでLXDを使ってみるけど、その場合の構成管理ツール?ってなんなんでしょう。よくわからなくてとりあえずAnsibleを使ってみたときのメモ。
LXDをインストール
sudo add-apt-repository ppa:ubuntu-lxc/lxd-git-master && sudo apt-get update
sudo apt-get install lxd
(最新版がほしいのでPPAを使ってますが、Ubuntu 15.10だともう通常のAPTレポジトリに入ってます。バージョンは0.20でした)
Ansibleをインストール
Installation — Ansible Documentation
sudo apt-add-repository ppa:ansible/ansible && sudo apt-get update
sudo apt-get install ansible
LXDのイメージをつくる
# イメージをインポート lxd-images import ubuntu --alias ubuntu # u1というコンテナを立ち上げる lxc launch ubuntu u1
lxc list
で起動しているコンテナが見えるはずです。
$ lxc list +------+---------+-----------+------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | EPHEMERAL | SNAPSHOTS | +------+---------+-----------+------+-----------+-----------+ | u1 | RUNNING | 10.0.3.61 | | NO | 0 | +------+---------+-----------+------+-----------+-----------+
SSHの設定
lxc_containerというモジュールがあるのでSSH不要なのでは?と思うんですが、うまくいかなかったのでふつうにSSHでやります(やり方ご存知の方は教えてください...)。
秘密鍵を生成
ssh-keygen -f ~/.ssh/lxc
ファイルをコピー
lxc file pull/push
というコマンドでファイルをコピーできます。コンテナのファイルパスはコンテナ名/path/to/target
という形式で指定するみたいです。
# 念のためバックアップ lxc file pull u1/root/.ssh/authorized_keys authorized_keys.bk lxc file push .ssh/lxc.pub u1/root/.ssh/authorized_keys # ログインできるか確認 ssh root@10.0.3.61 -i .ssh/lxc
Ansibleの設定
Ansibleは~/.ansible.cfg
にデフォルトの設定を書けます。ここにユーザ名と秘密鍵を書いておきます。
cat > ~/.ansible.cfg <<EOF [defaults] remote_user = root private_key_file = ~/.ssh/lxc EOF
で、これで準備完了かと思いきや、実行されません。
$ ansible -m ping u1
No hosts matched
Ansibleは、実行対象のホストをあらかじめinventry fileにリストアップしておく必要があります。
Ansibleのinventry fileにホスト名を書き出す
Dynamic Inventory — Ansible Documentationという手もありますが、JSONで結果を返すのがシェルワンライナーではちょっと無理そうだったので今回はパスして、静的なファイルに書き出しておきます。
lxc list
の結果はパースしづらいですが、AWK芸で頑張ります。(--format
というオプションがそのうち導入されるらしいです)
lxc list | awk '$NF > 1 && $2 != "NAME" {print $2}' | dd of=/etc/ansible/hosts
で、これでいよいよ準備完了かと思いきや、エラーが出ます。
# ansible -m ping u1 u1 | FAILED => SSH Error: ssh: Could not resolve hostname u1: Name or service not known It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue.
そう、sshするので名前解決できないといけません。
dnsmasqをresolv.confに
Ubuntuのパッケージの場合は、lxd(というかlxc?)をインストールするとdnsmasqが立って、コンテナの名前解決をしてくれるようになっています。ただ、resolv.confには入らないので手動で入れます。
echo 'nameserver 10.0.3.1' | sudo tee -a /etc/resolvconf/resolv.conf.d/head sudo resolvconf -u
これで名前解決ができるようになります。ほんとは.lxd
とかいうドメインを設定したほうがいいのかも。
$ dig u1 ; <<>> DiG 9.9.5-11ubuntu1-Ubuntu <<>> u1 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49270 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1280 ;; QUESTION SECTION: ;u1. IN A ;; ANSWER SECTION: u1. 0 IN A 10.0.3.61 ;; Query time: 1 msec ;; SERVER: 10.0.3.1#53(10.0.3.1) ;; WHEN: Fri Nov 06 09:58:19 EST 2015 ;; MSG SIZE rcvd: 47
ping
成功。
$ ansible -m ping u1 u1 | success >> { "changed": false, "ping": "pong" }