ビビリフクロウの足跡

いつもお世話になっているインターネットへの恩返し

oVirt用のクラウドイメージテンプレートの作り方

またまたoVirtネタです。oVirtではcloud-initを使ってテンプレートからVMをプロビジョニングし、ネットワークなどの初期設定を行うことができます。これを実現するにはプロビジョニング元のテンプレートにcloud-initをインストールする必要があるのですが、単純にインストールするだけですとうまく初期設定ができずにはまったので、メモとして残しておきます。今回作ったのはCentOS7.4、Ubuntu16.04、Debian9のイメージです。

CentOS7.4イメージの作り方

  • Minimal installでOSをインストール
  • cloud-initをインストール。ですが、OS標準のYumリポジトリからインストールするのではなく、それよりも新しいバージョンのパッケージをcurlで引っ張ってきてインストールする。

参考URL: https://bugzilla.redhat.com/show_bug.cgi?id=1492726

# curl -O https://people.redhat.com/rmccabe/cloud-init/cloud-init-0.7.9-20.el7.x86_64.rpm
# yum -y install cloud-init-0.7.9-20.el7.x86_64.rpm
  • 必要に応じて、ovirt-guest-agentをインストール

手順URL: https://www.ovirt.org/documentation/how-to/guest-agent/install-the-guest-agent-in-centos/

Ubuntu16.04、Debian9のインストール

  • Minimal installでOSをインストール
  • cloud-initをインストール。その後、/etc/network/interfacesを以下のように書き換える。
$ sudo apt-get install cloud-init
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# Source interfaces
# Please check /etc/network/interfaces.d before changing this file
# as interfaces may have been defined in /etc/network/interfaces.d
# See LP: #1262951
source /etc/network/interfaces.d/*
  • 必要に応じて、ovirt-guest-agentをインストール。ただしインストール後、正常にサービスを起動するには以下の手順が必要。

手順URL(Ubuntu): https://www.ovirt.org/documentation/how-to/guest-agent/install-the-guest-agent-in-ubuntu/

手順URL(Debian): https://www.ovirt.org/documentation/how-to/guest-agent/install-the-guest-agent-in-debian/

$ sudo vi /etc/ovirt-guest-agent.conf
...
[virtio]
# device = /dev/virtio-ports/com.redhat.rhevm.vdsm
device = /dev/virtio-ports/ovirt-guest-agent.0     # この行を追加
...
$ sudo vi /etc/udev/rules.d/55-ovirt-guest-agent.rules # 新規作成
SYMLINK=="virtio-ports/ovirt-guest-agent.0", OWNER="ovirtagent", GROUP="ovirtagent"

oVirt環境のVMを管理するplaybookをさらす

久しぶりの投稿ですが、生きてますw 投稿しよう!と思いきれる真新しい発見なく過ごしていたので、放置気味でした…(汗

けど、細々としたことでもこまめにナレッジとして残しておいたほうが後々得すると思うので、少し更新頻度を上げたいと思います。 ということで今日はこんなAnsibleのplaybookを書いてみました、という話でも。

自宅ではoVirtという仮想化基盤でサーバ運用や技術検証を行っています。無償でライブマイグレーションの機能が使えたり、GlusterFSとのインテグレーションによってハイパーコンバージドインフラを構築できたりなど、個人利用には至れり尽くせりの機能を持っています。低予算かつ本格的な仮想化基盤を探している方は是非チェックしてみてください。

ところでこのoVirt、VMwareのようにAPIを叩くことも出来るようになっていて、API経由で仮想リソースを管理できるようになっています。つまり疑似プライベートクラウドのように使うことも可能なのです。そろそろお家環境もInfrastructure as Codeを適用しようと考えていたので、このAPIをバリバリ活用して自動化しようと思い立ちました。

それでインフラ構成をコード化するなら、最近ホットであり、仕事でも使っているAnsibleを使ってやろうということでplaybookを書いてみました。oVirtモジュールもVer 2.3で大量に導入されましたしね。数少ないoVirtユーザの参考になれば幸いです。

初めからconnection: localとせず、delegate_to: localhostを利用しているところがミソで、こうすることでVMを並列に作成・削除することができるようになります。また、host_varsのファイルもlocalhost.yamlに全VMのパラメータを格納することなく、<inventory_hostname>.yamlに各VMのパラメータを格納することができるようになり、保守性が高くなります!

◆manage-vm.yaml

---
- name: manage vm
  hosts: all
  gather_facts: no
  vars_files:
  - manage-vm_vars.yaml
  tasks:
  - name: login to ovirt
    ovirt_auth:
      url: https://<oVirt EngineのFQDN>/ovirt-engine/api
      username: admin@internal
      insecure: yes
      password: "{{ ovirt_admin_pass }}"
    connection: local
    delegate_to: localhost

  - block:
    - name: create disks
      ovirt_disk:
        auth: "{{ ovirt_auth }}"
        name: "{{ item.name }}"
        size: "{{ item.size }}"
        format: "{{ item.format }}"
        interface: "{{ item.interface }}"
        storage_domain: "{{ item.storage_domain }}"
        state: present
      with_items: "{{ ovirt_vm.persistent_disks | default([]) }}"

    - name: create vm
      ovirt_vms:
        auth: "{{ ovirt_auth }}"
        name: "{{ ovirt_vm.name }}"
        cluster: "{{ ovirt_cluster }}"
        template: "{{ ovirt_vm.template }}"
        memory: "{{ ovirt_vm.memory }}"
        cpu_cores: "{{ ovirt_vm.cpu_cores }}"
        nics: "{{ ovirt_vm.nics }}"
        cloud_init:
          host_name: "{{ ovirt_vm.hostname }}"
          dns_servers: "{{ ovirt_vm.dns_servers }}"
          user_name: "{{ ansible_user }}"
          root_password: "{{ ansible_ssh_pass | default('') }}"
          authorized_ssh_keys: "{{ ovirt_vm.authorized_keys | default('') }}"
          custom_script: "{{ ovirt_vm.custom_script | default('') }}"
        cloud_init_nics: "{{ ovirt_vm.nics }}"
        state: running

    - name: attach disks
      ovirt_disk:
        auth: "{{ ovirt_auth }}"
        name: "{{ item.name }}"
        vm_name: "{{ ovirt_vm.name }}"
        interface: "{{ item.interface }}"
        state: attached
      with_items: "{{ ovirt_vm.persistent_disks | default([]) }}"

    - name: wait for vm to be up
      wait_for:
        host: "{{ ansible_host }}"
        port: "{{ ansible_port }}"
        state: started
    when: ovirt_vm.state == "running"
    connection: local
    delegate_to: localhost

  - block:
    - name: detach disks
      ovirt_disk:
        auth: "{{ ovirt_auth }}"
        name: "{{ item.name }}"
        vm_name: "{{ ovirt_vm.name }}"
        state: detached
      when: item.protect_from_deletion | default(true)
      with_items: "{{ ovirt_vm.persistent_disks | default([]) }}"

    - name: remove vm
      ovirt_vms:
        auth: "{{ ovirt_auth }}"
        name: "{{ ovirt_vm.name }}"
        cluster: "{{ ovirt_cluster }}"
        state: absent
    when: ovirt_vm.state == "absent"
    connection: local
    delegate_to: localhost

◆manage-vm_vars.yaml

---
ovirt_admin_pass: <adminユーザのパスワード>
ovirt_cluster: <対象クラスタ名>

◆host_vars/<inventory_hostname>.yaml (サンプル)

---
ansible_host: <対象サーバのIP>
ansible_user: root
ansible_ssh_pass: <rootユーザのパスワード>
ansible_port: 22
ovirt_vm:
  name: <対象サーバの名前>
  template: <利用するテンプレート名(要cloud-init導入)>
  memory: 4GiB
  cpu_cores: 2
  hostname: <対象サーバのFQDN>
  dns_servers: <参照するDNSサーバ(カンマ区切り)>
  nics:
  - nic_boot_protocol: static
    nic_ip_address: "{{ ansible_host }}"
    nic_netmask: <サブネットマスク>
    nic_gateway: <デフォルトゲートウェイ>
    nic_name: eth0
    nic_on_boot: yes
    name: nic1
    interface: virtio
    profile_name : ovirtmgmt
  persistent_disks:
  - name: <追加するディスクの名前>
    size: 30GiB
    format: cow
    interface: virtio
    storage_domain: <ディスクの所属するストレージドメイン>
    protect_from_deletion: <削除時にこのディスクを保護するか(Boolean)>
  state: running

ナレッジWiki公開してます

本ブログの目的は勉強&備忘メモをとるためです。体系的なナレッジの集約にはブログは適さないと思っています。その目的にブログは雑音が入りすぎてしまう。

というわけで、体系的なナレッジを蓄積する場としてWikiも書いて公開してます。まだ始めて間もないのでこちらも中身は少ないですが、こちらもよろしくお願いします。

ビビリフクロウの巣

日々精進!

ブログ新規開設しました!

はじめまして。ビビリフクロウと申します。とあるSIerでインフラSEをやっています。

本ブログは私が日々、特にIT関連で勉強になったことや忘れがちなことをメモしておく場として開設されました。

以前の自分はインターネットから多くの情報、サービス、ソフトウェアを享受してきましたが、逆に自分からそれらを提供することはありませんでした。自分にはインターネット上に公開するような、人の役に立つ情報を持ち合わせていないと考えていたからです。

しかし、自分が勉強になったことや忘れがちなことは他人においてもそうで有り得ると思い直し、それらをただメモしたものでも十分、他人の役に立つ情報になり得ると考えました。そんなメモをインターネット上に公開することで少しでもインターネットに貢献すること、それが本ブログの開設理由です。

エンジニアとして至らない内容を記事にする場合もあるかと思いますが、その場合はコメントにてご指摘、ご鞭撻いただければ幸いです。

どうぞよろしくお願いいたします!