Vagrant Shell Provisioner + Ansible + LXCのサンプル紹介

Presenter Hiroaki Nakamura

誰?

なぜ今回LXCを使ったか?

  • RAM 4GBのノートPCでVagrantで複数VMを同時起動するのはつらかったから

    • 案件で2つのRailsアプリが連携するシステムを開発している

  • 仕事の案件で客先よりLXCを使うという指定があったから

なぜShell Provisioner?

  • WindowsからAnsibleは実行できないが、Vagrant上のLinuxにAnsibleをインストールすればOK
  • Macで使う場合もMac側にAnsibleインストール不要という利点がある

    • VirtualBoxとVagrantだけインストールしておけばすぐ使える

  • Ansibleインストール後Vagrant上のLinuxでAnsibleを実行

    • 実行中の経過を表示するには PYTHONUNBUFFERED 環境変数を true にしておく

export PYTHONUNBUFFERED=true
cd /vagrant/provisioning
ansible-playbook lxc_host.yml

今回の構成

container structure

作ったAnsibleプレーブック

Ansible Connection Plugin for lxc containers

  • https://github.com/Mic92/ansible-lxc
  • これを使えばコンテナにsshd不要
  • 依存コンポーネントとして https://github.com/lxc/python2-lxc が必要

    • lxc公式にバンドルされているliblxcバインディングはPython3
    • Ansibleは現状Python3非対応のためpython2-lxcが必要

  • Ansibleでコンテナに接続するにはコンテナ名を指定 (IPアドレス不要)

    • lxc-ls --active を使ったスクリプトでDynamic Inventoryを実現

コンテナのIPアドレス取得

  • LXCホスト上のnginxからコンテナのnginxにプロキシするためにコンテナのIPアドレスを知りたい
  • Ubuntuのlxcなら lxc-ls --fancy でコンテナのIPアドレスが取得可能
  • しかしCentOSの lxc-ls--fancy が使えない
  • lxc-attach でコンテナ上で ip コマンドを実行してIPアドレスを取得
lxc-attach -n {{ container_name }} -- ip a show eth0 | awk '$1=="inet" {sub(/\/[0-9]+/, ""); print $2}'

まとめ

  • vagrant upすればlxcセットアップからコンテナ作成まで行うAnsibleプレーブックを書いた
  • Vagrant Shell ProvisionerでAnsibleをインストールすればWindows上でもOK
  • Ansible Connection Plugin for lxc containersを使えばコンテナにsshd不要

なお、その後客先指定がlxcからdockerに変わったので実運用はしていません、あしからず。

dockerでも似たような構成(2つのunicornコンテナ + 1つのMySQLコンテナ)を作成中です。 https://github.com/hnakamur/vagrant-docker-rails-development-example