ども、かっぱです。前回の続き。
あくまでお試し
Python 版の Inventory スクリプト
ということで Ansible の Dynamic Inventory スクリプトの Docker コンテナ版を作ってみた。尚、Docker コンテナ版については Python 版が存在するが、consul 版と同様に手元の環境では動かなかったので止むなく自作した。
きっとちゃんと動かくはずなんだろうけど...すいません。
俺の Inventory スクリプト Ruby 版
拙作のスクリプトは以下の通り。docker-api を叩ける docker-api を利用した。
#!/usr/bin/env ruby require 'docker' require 'json' docker_host = "192.168.59.103" # boot2docker を使っている場合、他の環境は適宜差し替える target_host_name = "ansible_" target_user_name = "ansible" target_user_pass = "ansible" containers = Docker::Container.all(:running => true) targets = containers.select do |con| con.info['Names'][0].include? target_host_name end target = {} targets.map do |t| t.info['Ports'].each do |p| target.merge!({ t.info['Names'][0].gsub("/","") => { "ansible_ssh_host" => docker_host, "ansible_ssh_port" => p['PublicPort'], "ansible_ssh_user" => target_user_name, "ansible_ssh_pass" => target_user_pass }}) end end puts JSON.generate(target)
だいぶん力技感が否めないが...コンテナ名を指定して対象を絞り込む作戦。(コンテナ名を docker run
時に指定出来るのが超アリガタヤ、アリガタヤ...)
スクリプトを実行する前に以下のように環境変数をセットしておく。
export DOCKER_HOST=tcp://192.168.59.103:2376 export DOCKER_CERT_PATH=~/.boot2docker/certs/boot2docker-vm export DOCKER_TLS_VERIFY=1
スクリプトを素で以下のように実行する。
./docker_inventory.rb
スクリプトを直接実行すると以下のように出力される。
{ "ansible_01": { "ansible_ssh_host": "192.168.59.103", "ansible_ssh_pass": "ansible", "ansible_ssh_port": 49195, "ansible_ssh_user": "ansible" }, "ansible_02": { "ansible_ssh_host": "192.168.59.103", "ansible_ssh_pass": "ansible", "ansible_ssh_port": 49196, "ansible_ssh_user": "ansible" } }
前回の consul から情報を取得した時よりも Dynamic では無い、通常の Inventory ファイルに近い内容のように思える。
ということで、一連の動作を試せる環境を以下にアップした。
ということで、上記のお試し環境を利用して進める。
お試し
とりあえず docker build して run
git clone
してきたら inventories ディレクトリに移動して docker build
を実行。
cd sample-prj-20150305/inventories docker build -t your_container . docker run --name=ansible_01 -p 22 -t -i -d your_container docker run --name=ansible_02 -p 22 -t -i -d your_container
コンテナ作っておいて...コンテナを起動しておく。念の為にコンテナの起動を確認。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 74575bf2be7e inokappa/centos-ssh-ansible:latest "/bin/sh -c '/usr/sb 2 seconds ago Up 1 seconds 0.0.0.0:49196->22/tcp ansible_02 d6363688bd92 inokappa/centos-ssh-ansible:latest "/bin/sh -c '/usr/sb 8 seconds ago Up 8 seconds 0.0.0.0:49195->22/tcp ansible_01
ping
ansible -i ./docker_inventory.rb all -m ping
これだと...以下のような警告。どうやら Inventory ファイルに直接パスワードを記述してアクセスするのはよろしく無さそう。
ansible_01 | FAILED => to use the 'ssh' connection type with passwords, you must install the sshpass program ansible_02 | FAILED => to use the 'ssh' connection type with passwords, you must install the sshpass program
本来であれば公開鍵認証を選択するのであるが、今回はお試しということもあり以下のように実行。
ansible -i ./docker_inventory.rb all -m ping -c paramiko
この -c
オプションを利用すれば...
-c CONNECTION, --connection=CONNECTION connection type to use (default=smart)
上記の通り対象ホストへの接続モード(利用する SSH ライブラリ)を指定してすることが出来る。ドキュメントでは paramiko
がデフォルトのように記載されているが、現状は smart
がデフォルトのようだ。
気を取り直して -c paramiko
を追加して ping
を実行すると以下のように出力された。
ansible_01 | success >> { "changed": false, "ping": "pong" } ansible_02 | success >> { "changed": false, "ping": "pong" }
一応、コンテナ毎にも...ansible_01 を指定して。
% ansible -i inventories/docker_inventory.rb ansible_01 -m ping -c paramiko ansible_01 | success >> { "changed": false, "ping": "pong" }
ansible_02 を指定して。
% ansible -i inventories/docker_inventory.rb ansible_02 -m ping -c paramiko ansible_02 | success >> { "changed": false, "ping": "pong" }
なんかパッケージを...
せっかくなので Playbook も走らせてみたいので role 環境で以下のような Playbook を作った。
roles/my_test/tasks/main.yml は以下の通り。
- name: install the latest version of apps yum: name={{ item }} state=latest with_items: - "{{ packages }}"
roles/my_test/vars/main.yml は以下の通り。
--- packages: - telnet - vim
おもむろに実行...。
% ansible-playbook -i inventories/docker_inventory.rb my_test.yml -c paramiko --check PLAY [all] ******************************************************************** GATHERING FACTS *************************************************************** ok: [ansible_01] ok: [ansible_02] TASK: [my_test | install the latest version of apps] ************************** changed: [ansible_02] => (item=telnet,vim) changed: [ansible_01] => (item=telnet,vim) PLAY RECAP ******************************************************************** ansible_01 : ok=2 changed=1 unreachable=0 failed=0 ansible_02 : ok=2 changed=1 unreachable=0 failed=0
うまくいきそうや。
ということで、最後は画像で。
最後に
イマサラ言うか...って言われそうだけど Dynamic Inventory こそ Ansible の醍醐味だと思う。