Elaboration in, Garbage out

Twitt*r ではメモできない何かそれ的なモノ・コトを

ansible の libvirt モジュールがあったので使おうとしてみた。

動機

Production 環境でもダイジョーブな、 Linux での仮想環境をさくっと作りたい、でもなんちゃら Stack を入れるのはちょっと重すぎ!ていうわけで、手軽に KVM で動かせればなーという動機です。探したら別の手段ありそうですが。そこ Docker でいいじゃんとは言わない。

で、色々調べていた所、ansible のモジュール virt を発見:virt - Manages virtual machines supported by libvirt — Ansible Documentation

怪しい匂いがする、というところで、KVM を勉強するついでに触ろうとしました。

動作環境

DigitalOcean は日本に進出しないみたいですかねー。DigitalOcean は vagrant 用のプラグインを公開しているので、それを使うと楽です。

KVM の操作

必要なものの準備

最低限のパッケージと OS イメージは準備しておく。

- name: Ensure kvm packages are installed
  yum:
    name: "{{ item }}"
    state: present
  with_items:
    - libvirt
    - qemu-kvm
    - bridge-utils
    - libvirt-python
- name: Ensure Centos 7 ISO file is downloaded
  get_url:
    url: http://ftp.jaist.ac.jp/pub/Linux/CentOS/7/isos/x86_64/CentOS-7-x86_64-Minimal-1511.iso
    dest: /download/path/to/CentOS-7-x86_64-Minimal-1511.iso
    sha256sum: f90e4d28fa377669b2db16cbcb451fcb9a89d2460e3645993e30e137ac37d284

get_url で何回もダウンロードさせないよう、dest はファイル名まで指定するという基本テク?ですね。

virt モジュールを使う

libvirt でいうところの define コマンドを使う

では virt モジュールで指定しましょう。

stackoverflow.com

にあるように、XML は実は文字列を指定するものです。ファイル名であれば {{lookup('template', 'your_define.xml.j2')}} のようにしようね、とのことです。ちなみに lookup('template', path) も、roles/some_role/template ではなくroles/some_role/file を探しに行くようです。こんなエラーがでました。

fatal: [machine1] => Failed to template {{ lookup('template', 'centos7_def.j2') }}: unable to read /path/to/roles/some_role/files/centos7_def.j2

壮大なるフェイントじゃないか。だからといって、template ファイルを flle ディレクトリに置くのは気持ち悪い。というわけでこんな感じ

- name: Define VM using the XML file
  virt:
    command: define
    name: centos_via_ansible
    xml: "{{ lookup('template', '../templates/centos7_def.xml.j2') }}"

なんだかなー感あるのは気にしない。これを実行すると、

[vagrant@digital_ocean_host ~]$ sudo virsh list --all
 Id    名前                         状態
----------------------------------------------------
 -     centos7_temp                   シャットオフ

とでます。ちなみに、XMLname を指定しないと怒られます。

<domain type='kvm'>
  <name>centos7_temp</name>
  (後略:最後に貼り付け)

と指定してます。VM の定義はできましたが、なんかやな予感……

define した VM を走らせる。

さて、定義した VM を走らせてみましょう。タスクは次のようにします

- name: Define VM using the XML file
  virt:
    command: define
    name: centos_via_ansible
    xml: "{{ lookup('template', '../templates/centos7_def.xml.j2') }}"

- name: Ensure VM is started
  virt:
    name: centos_via_ansible
    state: running
    uri: qemu:///system

実行結果

TASK: [some_role | Define VM using the XML file] ********************************* 
failed: [digital_ocean_host] => {"failed": true}
msg: operation failed: domain 'centos7_temp' already exists with uuid 6106bbb7-a310-43e8-b94e-576d00e98b3e

FATAL: all hosts have already failed -- aborting

PLAY RECAP ******************************************************************** 
           to retry, use: --limit @/Users/******/site.retry

digital_ocean_host          : ok=1    changed=0    unreachable=0    failed=1   

冪等性がないようです。ちなみに、公式 virt モジュールのドキュメントにも

in addition to state management, various non-idempotent commands are available. See examples

と、冪等性なんてないよ!といってます。

では Ensure VM s Started だけで実行してみます。

TASK: [some_role | Ensure VM is started] ***************************************** 
failed: [digital_ocean_host] => {"failed": true}
msg: virtual machine centos_via_ansible not found

FATAL: all hosts have already failed -- aborting

やな予感的中。ちなみに、先ほど2つのタスクを同時に実行しても同じ結果です。そのため結局 XML の方に合わせました。

- name: Define VM using the XML file
  virt:
    command: define
    name: centos_via_ansible
    xml: "{{ lookup('template', '../templates/centos7_def.xml.j2') }}"
- name: Ensure VM is started
  virt:
    name: centos_temp
    state: running
    uri: qemu:///system

この後しばらく libviet の VM 定義ファイル(XML)と格闘する

結局格闘し続けてます。

おわりに

virt-install というツールが優秀すぎて、ansible の virt モジュールを使う気がなくなりました。まずは KVM をがっつり勉強しなさいっていうことですね、はい。

そのため、libvirt での VM 定義ファイルをふつーに勉強すれば、おそらく virt-install ではなく ansible の virt モジュールと template エンジンでうまいこと様々なことが出来そうですね。

また、virt-install でも virt モジュールでも、どちらでも KickStart が必要ですね。kickstart と、ansible または virt-install のどちらか一つを組み合わせると無人で VM デプロイが可能ですね。この辺が見えてきてよかったかなーと。もうちょっと virt モジュールは頑張っても良かったのでは