virt_infra

<!-- vim-markdown-toc GFM -->

* [Ansible Роль: Виртуальная Инфраструктура](#ansible-role-virtual-infrastructure)
    * [Требования](#requirements)
        * [Хост KVM](#kvm-host)
            * [Fedora](#fedora)
            * [CentOS 7](#centos-7)
            * [CentOS Stream 8](#centos-stream-8)
            * [Debian](#debian)
            * [Ubuntu](#ubuntu)
            * [openSUSE](#opensuse)
            * [Использование маршрутизируемых сетей](#using-routed-networks)
            * [Настройка мостов с помощью NetworkManager](#configuring-bridges-with-networkmanager)
                * [Мост Linux](#linux-bridge)
                    * [Использование моста Linux в инвентаре](#using-linux-bridge-in-inventory)
                * [Мост Open vSwitch (OVS)](#open-vswitch-ovs-bridge)
                    * [Использование ovs-bridge в инвентаре](#using-ovs-bridge-in-inventory)
        * [Образы облачных гостей](#guest-cloud-images)
    * [Переменные роли](#role-variables)
    * [Зависимости](#dependencies)
    * [Пример инвентаря](#example-inventory)
        * [Несколько хостов KVM](#multiple-kvm-hosts)
    * [Пример плейбука](#example-playbook)
        * [Загрузка облачного образа](#grab-the-cloud-image)
        * [Запуск плейбука](#run-the-playbook)
        * [Очистка](#cleanup)
        * [Конфигурация после установки](#post-setup-configuration)
    * [Лицензия](#license)
    * [Информация об авторе](#author-information)

<!-- vim-markdown-toc -->

# Ansible Роль: Виртуальная Инфраструктура

Эта роль предназначена для определения и управления сетями и гостями на одном или нескольких хостах KVM. Опция `--limit` в Ansible позволяет управлять ними индивидуально или как группой.

Она предназначена для разработки, где хост KVM является вашей локальной машиной, у вас есть `sudo` и вы общаетесь с `libvirtd` по адресу `qemu:///system`, но также работает и на удаленных хостах.

Поддерживается установка состояния гостей на _работающий_, _выключенный_, _уничтоженный_ или _неопределенный_ (для удаления и очистки).

Вы можете настроить любую память, процессоры, диски и сетевые карты, которые хотите для своих гостей, либо через группы хостов, либо индивидуально. Поддерживается смешение нескольких дисков, включая _scsi_, _sata_, _virtio_, и даже _nvme_ (на поддерживаемых дистрибутивах).

Вы можете создать частные NAT-сети libvirt на хосте KVM и затем разместить виртуальные машины на любом количестве из них. Гости могут использовать эти сети libvirt или _существующие_ устройства моста Linux (например, `br0`) и моста Open vSwitch (OVS) на хосте KVM (это не создаст мосты на хосте, но проверит, существует ли интерфейс моста). Вы можете указать модель сетевой карты, а также MAC для каждого интерфейса, если это требуется, однако по умолчанию используется идемпотентный адрес, основанный на имени хоста.

Вы также можете создать маршрутизируемые сети libvirt на хосте KVM и затем разместить на них виртуальные машины. В этом случае создается новый мост с именем, которое вы укажете (например, `br1`), подключенный к _существующему_ интерфейсу (например, `eth0`). Вы можете указать MAC для каждого интерфейса, если это необходимо.

Это поддерживает различные дистрибутивы и использует их qcow2 [образы облака](#guest-cloud-images) для удобства (хотя вы можете использовать свои собственные образы). Я протестировал CentOS Stream, Debian, Fedora, openSUSE, RHEL и Ubuntu.

Для RHEL необходимо установить переменную `virt_infra_sm_creds` (возможно, из хранилища), чтобы временно зарегистрировать машину в портале Red Hat во время подготовки диска. Это следует [формату из](https://libguestfs.org/virt-builder.1.html#subscription-manager), например:

```yaml
- virt_infra_sm_creds: MYUSER:password:MYPASSWORD

Образы qcow2, используемые для гостей, указываются как переменные в инвентаре и должны существовать в каталоге изображений libvirt (по умолчанию это /var/lib/libvirt/images/). Это означает, что это не скачает образы автоматически.

Образы загрузки гостей qcow2 создаются из этих базовых изображений. По умолчанию они используют облачное изображение в качестве вспомогательного файла, но также поддерживается клонирование. Вы можете создать дополнительные диски по своему усмотрению. Вы также можете выбрать, оставить любое изображение диска, а не удалить его, когда виртуальная машина будет неопределенной. ISO-образы cloud-init создаются автоматически и прикрепляются к гостю для его настройки при загрузке.

Часовой пояс по умолчанию будет установлен в соответствии с хостом KVM, а пользователь ansible будет использоваться для гостя вместе с вашими публичными SSH-ключами на хосте KVM (вы можете переопределить это). Записи хоста добавляются в /etc/hosts на хосте KVM, также модифицируется SSH-конфигурация пользователя ansible и добавляется отпечаток в known_hosts, чтобы вы могли подключаться по SSH (это тестируется в процессе развертывания). Вы можете установить пароль root, если действительно хотите.

С помощью всего этого вы можете определить и управлять кластерами OpenStack/Swift/Ceph различных размеров с несколькими сетями, дисками и даже дистрибутивами!

Требования

Все, что действительно нужно, это хост Linux, способный запускать KVM, несколько образов гостей и базовый инвентарь. Ansible сделает остальное (на поддерживаемых дистрибутивах).

Работающий x86_64 хост KVM, где пользователь, запускающий Ansible, может общаться с libvirtd через sudo.

Ожидается аппаратная поддержка KVM в ЦП, чтобы мы могли создавать ускоренные гости и передавать ЦП (поддерживает вложенную виртуализацию).

Вам может понадобиться Ansible и Jinja >= 2.8, так как здесь используются такие вещи, как сравнения 'equalto'.

Я протестировал это на CentOS Stream 8, Fedora 3x, Debian 10, Ubuntu Bionic/Eoan и openSUSE 15 хостах, но другие машины на Linux скорее всего также подойдут.

По крайней мере, одна пара SSH-ключей на хосте KVM (Ansible сгенерирует один, если он отсутствует). SSH-ключ, используемый для гостей, не должен требовать SSH-пароля, если он находится на удаленном хосте KVM. Если локально, убедитесь, что вы добавили его к ssh-агенту.

На хосте KVM также требуется несколько пользовательских инструментов (Ansible установит их на поддерживаемых хостах).

  • qemu-img
  • osinfo-query
  • virsh
  • virt-customize
  • virt-sysprep

Скачайте образы гостей, которые вы хотите использовать (это то, что я скачал) и поместите их в путь изображений libvirt (обычно /var/lib/libvirt/images/). Это проверит, что указанные изображения существуют и выдаст ошибку, если они не найдены.

Хост KVM

Вот некоторые инструкции по настройке вашего хоста KVM, на случай если они окажутся полезными.

ПРИМЕЧАНИЕ: Эта роль сделает все это за вас, включая установку KVM, libvirtd и другие необходимые пакеты на поддерживаемых дистрибутивах, а также убедится, что libvirtd работает.

Существует также переменная virt_infra_host_pkgs_custom, которая принимает список пакетов для установки на хост, если вам нужно или вы хотите, чтобы роль установила дополнительные пакеты за вас.

Обратите внимание, что переменная должна быть списком, и хост должен иметь возможность устанавливать пакеты, т.е. имена пакетов должны быть корректными для хоста, и если хост работает на RHEL, он должен быть зарегистрирован.

Fedora

# Создайте SSH-ключ, если у вас его нет (не задавайте пароль, если удаленный хост KVM)
ssh-keygen

# libvirtd
sudo dnf install -y @virtualization
sudo systemctl enable --now libvirtd

# Ansible
sudo dnf install -y ansible

# Другие зависимости (установлены плейбуком)
sudo dnf install -y \
git \
genisoimage \
libguestfs-tools-c \
libosinfo \
python3-libvirt \
python3-lxml \
qemu-img \
virt-install

CentOS 7

CentOS 7 не будет работать, пока мы не получим пакет libselinux-python3, который будет доступен в 7.8...

Но вот (надеюсь) остальные шаги, когда он станет доступен.

# Создайте SSH-ключ, если у вас его нет
ssh-keygen

# libvirtd
sudo yum groupinstall -y "Virtualization Host"
sudo systemctl enable --now libvirtd

# Ansible и другие зависимости
sudo yum install -y epel-release
sudo yum install -y python36
pip3 install --user ansible

sudo yum install -y \
git \
genisoimage \
libguestfs-tools-c \
libosinfo \
python36-libvirt \
python36-lxml \
libselinux-python3 \
qemu-img \
virt-install

CentOS Stream 8

# Создайте SSH-ключ, если у вас его нет
ssh-keygen

# libvirtd
sudo dnf groupinstall -y "Virtualization Host"
sudo systemctl enable --now libvirtd

# Ansible
sudo dnf install -y epel-release
sudo dnf install -y ansible

# Другие зависимости (установлены плейбуком)
sudo dnf install -y \
git \
genisoimage \
libguestfs-tools-c \
libosinfo \
python3 \
python3-libvirt \
python3-lxml \
qemu-img \
virt-install

Debian

# Создайте SSH-ключ, если у вас его нет
ssh-keygen

# libvirtd
sudo apt update
sudo apt install -y --no-install-recommends qemu-kvm libvirt-clients libvirt-daemon-system
sudo systemctl enable --now libvirtd

# Ansible
sudo apt install -y gnupg2
echo 'deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main' | sudo tee -a /etc/apt/sources.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
sudo apt update
sudo apt install -y ansible

# Другие зависимости (установлены плейбуком)
sudo apt install -y --no-install-recommends \
cloud-image-utils \
dnsmasq \
git \
genisoimage \
libguestfs-tools \
libosinfo-bin \
python3-libvirt \
python3-lxml \
qemu-utils \
virtinst

Ubuntu

# Создайте SSH-ключ, если у вас его нет
ssh-keygen

# libvirtd
sudo apt update
sudo apt install -y --no-install-recommends libvirt-clients libvirt-daemon-system qemu-kvm
sudo systemctl enable --now libvirtd

# Ansible
sudo apt install -y software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible
sudo apt install -y ansible

# Другие зависимости (установлены плейбуком)
sudo apt install -y --no-install-recommends \
dnsmasq \
git \
genisoimage \
libguestfs-tools \
libosinfo-bin \
python3-libvirt \
python3-lxml \
qemu-utils \
virtinst

openSUSE

Если вы используете JeOS, нам нужно изменить ядро на kernel-default, так как kernel-default-base, который поставляется с JeOS, не содержит модулей KVM.

# Создайте SSH-ключ, если у вас его нет
ssh-keygen

# Установите подходящее ядро
sudo zypper install kernel-default
sudo reboot

Продолжайте после перезагрузки.

# libvirtd
sudo zypper install -yt pattern kvm_server kvm_tools
sudo systemctl enable --now libvirtd

# Ansible
sudo zypper install -y ansible

# Другие зависимости (установлены плейбуком)
sudo zypper install -y \
git \
guestfs-tools \
libosinfo \
mkisofs \
python3-libvirt-python \
python3-lxml \
qemu-tools \
virt-install

Использование маршрутизируемых сетей

Вы можете маршрутизировать трафик в новый созданный мост, указав тип перенаправления type: route. Этот код поддерживает автоматическое создание нового моста с именем bridge_dev, который будет подключен к существующему интерфейсу на хосте, указанному параметром host_dev.

Пример ниже показывает, как может быть создан мост, поддерживающий как IPv4, так и IPv6:

kvmhost:
  hosts:
    localhost:
      ansible_connection: local
      ansible_python_interpreter: /usr/bin/python3
      virt_infra_host_libvirt_url: qemu:///system
  vars:
    virt_infra_host_networks:
      present:
        - name: example
          domain: f901.example.com
          type: route
          host_dev: eth0
          bridge_dev: virbr1
          bridge_stp: on
          bridge_delay: 0
          mac: 52:54:00:f9:01:00
          ip_address: 10.249.1.1
          ip_netmask: 255.255.255.0
          dhcp_start: 10.249.1.11
          dhcp_end: 10.249.1.254
          ip6_address: 2001:0db8::f901:1
          ip6_prefix: 64
          dhcp6_start: 2001:0db8::f901:0000
          dhcp6_end: 2001:0db8::f901:00ff

Замечания:

  1. IPv6 блок 2001:0db8/32, как указано выше, предоставлен только в целях документации. Вам нужно будет заменить его на ваш собственный делегированный /48 блок (в общем случае), предоставленный вашим провайдером IPv6 или решением IPv6 через IPv4, таким как Hurricane Electric's tunnel broker service.

  2. Настоятельно рекомендуется придерживаться ip6_prefix: 64, так как это рекомендуемая настройка в документации libvirt.

Настройка мостов с помощью NetworkManager

Этот код поддерживает подключение ВМ как к мостам Linux, так и к мостам Open vSwitch, но они должны уже существовать на хосте KVM.

Вот как можно преобразовать существующее Ethernet-устройство в мост. Будьте осторожны, если делаете это на удаленной машине с единственным подключением! Убедитесь, что у вас есть другой способ войти (например, консоль), или, возможно, добавьте дополнительные интерфейсы.

Сначала экспортируйте устройство, которое вы хотите преобразовать, чтобы мы могли легко ссылаться на него позже (например, eth1).

export NET_DEV="eth1"

Теперь перечислим текущие соединения NetworkManager для вашего устройства, экспортированного выше, чтобы мы знали, что отключить позже.

sudo nmcli con |egrep -w "${NET_DEV}"

Это может быть что-то вроде System eth1 или Wired connection 1, давайте тоже экспортируем его для дальнейшего использования.

export NM_NAME="Wired connection 1"
Мост Linux

Вот пример создания постоянного моста Linux с помощью NetworkManager. Он возьмет устройство, такое как eth1 (при необходимости замените) и преобразует его в мост.

Запомните имя существующего соединения NetworkManager для вашего устройства, полученное выше, оно будет использоваться ниже (например, Wired connection 1).

export NET_DEV=eth1
export NM_NAME="Wired connection 1"
sudo nmcli con add ifname br0 type bridge con-name br0
sudo nmcli con add type bridge-slave ifname "${NET_DEV}" master br0

Теперь у вас есть ваше мостовое устройство! Обратите внимание, что у моста будет другой MAC-адрес, чем у подлежащего устройства, поэтому, если вы ожидаете, что он получит конкретный адрес, вам нужно будет обновить вашу статическую аренду DHCP.

sudo ip link show dev br0

Отключите текущую конфигурацию NetworkManager для устройства, чтобы она не конфликтовала с мостом (не удаляйте ее, иначе вы можете потерять соединение, если используете его для SSH).

sudo nmcli con modify id "${NM_NAME}" ipv4.method disabled ipv6.method disabled

Теперь вы можете просто перезагрузить или остановить текущий интерфейс и запустить мост одной командой. Помните, что у моста будет новый MAC-адрес, и он получит новый IP, если вы не обновили ваши статические аренды DHCP!

sudo nmcli con down "${NM_NAME}" ; sudo nmcli con up br0

Как упоминалось выше, по умолчанию мост Linux получит адрес через DHCP. Если вы не хотите, чтобы он находился в сети (возможно, у вас есть другой выделенный интерфейс), отключите DHCP на нем.

sudo nmcli con modify id br0 ipv4.method disabled ipv6.method disabled
Использование моста Linux в инвентаре

На стороне kvmhost инвентаря ничего делать не нужно.

Для любых гостей, которых вы хотите подключить к мосту, просто укажите его в их инвентаре. Используйте br0 в качестве name сети под virt_infra_networks с типом bridge.

      virt_infra_networks:
        - name: br0
          type: bridge
Мост Open vSwitch (OVS)

Вот пример создания постоянного OVS моста с помощью NetworkManager. Он возьмет устройство, такое как eth1 (замените при необходимости) и преобразует его в ovs-bridge.

Вам нужно установить openvswitch и плагин OVS для NetworkManager (замените на свой дистрибутив).

sudo dnf install -y NetworkManager-ovs openvswitch
sudo systemctl enable --now openvswitch
sudo systemctl restart NetworkManager

Теперь мы можем создать OVS мост (предполагает, что ваше устройство eth1 и существующая конфигурация NetworkManager - Wired connection 1, замените при необходимости).

export NET_DEV=eth1
export NM_NAME="Wired connection 1"
sudo nmcli con add type ovs-bridge conn.interface ovs-bridge con-name ovs-bridge
sudo nmcli con add type ovs-port conn.interface port-ovs-bridge master ovs-bridge
sudo nmcli con add type ovs-interface slave-type ovs-port conn.interface ovs-bridge master port-ovs-bridge
sudo nmcli con add type ovs-port conn.interface ovs-port-eth master ovs-bridge con-name ovs-port-eth
sudo nmcli con add type ethernet conn.interface "${NET_DEV}" master ovs-port-eth con-name ovs-int-eth

Отключите текущую конфигурацию NetworkManager для устройства, чтобы она не конфликтовала с мостом (не удаляйте ее, иначе вы можете потерять соединение, если используете его для SSH).

sudo nmcli con modify id "${NM_NAME}" ipv4.method disabled ipv6.method disabled

Теперь вы можете либо просто перезагрузить, либо остановить текущий интерфейс и запустить мост одной командой.

sudo nmcli con down "${NM_NAME}" ; sudo nmcli con up ovs-slave-ovs-bridge

По умолчанию OVS мост получит адрес через DHCP. Если вы не хотите, чтобы он находился в сети (возможно, у вас есть другой выделенный интерфейс), отключите DHCP на нем.

sudo nmcli con modify id ovs-slave-ovs-bridge ipv4.method disabled ipv6.method disabled

Просмотрите конфигурацию коммутатора и моста с помощью инструментов OVS.

sudo ovs-vsctl show
Использование ovs-bridge в инвентаре

Теперь вы можете использовать ovs-bridge в качестве device ovs моста в вашем инвентаре kvmhost, и он создаст сети libvirt OVS. Вы можете настроить несколько VLAN и установить одну в качестве родной (если это требуется).

Диапазоны VLAN поддерживаются, если определить их в виде списка.

      virt_infra_host_networks:
        present:
          - name: ovs-bridge
            bridge_dev: ovs-bridge
            type: ovs
            portgroup:
              # Это портгруппа с несколькими VLAN
              # Это родной VLAN 1 и также позволяет трафику с меткой VLAN 99
              - name: ovs-trunk
                trunk: true
                native_vlan: 1
                vlan:
                  - 1
                  - [20,29]
                  - 99
              # Это портгруппа только для родного VLAN 1
              - name: default
                native_vlan: 1
                vlan:
                  - 1
              # Это портгруппа только для родного VLAN 99
              - name: other
                native_vlan: 99
                vlan:
                  - 99

Затем вы можете указать свои ВМ на конкретных портгруппах, и libvirt автоматически настроит порты для ваших ВМ и для вас.

      virt_infra_networks:
        - name: ovs-bridge
          portgroup: default
          type: ovs

Когда ваши ВМ запустятся, вы можете увидеть их порты OVS с помощью sudo ovs-vsctl show.

Образы облачных гостей

Это предназначено для использования стандартных облачных образов, предоставленных различными дистрибутивами (OpenStack предоставляет некоторые).

Убедитесь, что изображение, которое вы указываете для своих гостей, уже существует в вашем каталоге хранения libvirt (по умолчанию это /var/lib/libvirt/images/).

Я успешно протестировал следующих гостей:

Чтобы мы могли настроить гостя и получить его IP, в образе вашего гостя будут установлены как cloud-init, так и qemu-guest-agent, на случай если это понадобится.

Это можно изменить или переопределить с помощью переменной virt_infra_guest_deps, которая является списком.

Sysprep также выполняется на образе гостя, чтобы убедиться, что он очищен от таких вещей, как старые MAC-адреса.

Переменные роли

По умолчанию переменные роли задаются в файле defaults/main.yml.

Их можно переопределить на уровне хоста или группы хостов, если это необходимо. Однако роль спроектирована так, чтобы работать прямо из коробки (если у вас есть изображение CentOS Stream 8 по умолчанию).

---
# Значения по умолчанию для роли virt-infra Ansible
# Закомментированные значения являются необязательными

## Связано с гостями

# Допустимые состояния гостей: работающий, выключенный, уничтоженный или неопределенный
virt_infra_state: "running"

# Гости не запускаются автоматически при загрузке
virt_infra_autostart: "no"

# Пользователь гостя, по умолчанию он будет установлен на того же пользователя, что и пользователь хоста KVM
virt_infra_user: "{{ hostvars[kvmhost].ansible_env.USER }}"

# Пароль по умолчанию пользователя (подумайте о хранилище, если вам нужны безопасные пароли)
# Пароля root по умолчанию нет
virt_infra_password: "password"
#virt_infra_root_password:

# Технические характеристики ВМ для гостей
# См. man-страницу virt-install для поддерживаемых значений
virt_infra_ram: "1024"
virt_infra_ram_max: "{{ virt_infra_ram }}"
virt_infra_cpus: "1"
virt_infra_cpus_max: "{{ virt_infra_cpus }}"
virt_infra_cpu_model: "host-passthrough"
virt_infra_machine_type: "q35"

# SSH-ключи — это список, вы можете добавить больше одного
# Если не указано, по умолчанию мы используем все публичные ключи на хосте KVM
virt_infra_ssh_keys: []

# Если SSH-ключи не указаны или не найдены на хосте KVM, мы создаем один с помощью этого
virt_infra_ssh_key_size: "2048"
virt_infra_ssh_key_type: "rsa"

# Необходимо ли включить аутентификацию паролем SSH
virt_infra_ssh_pwauth: true

# Использовать ли cloud-init для настройки сети на госте
virt_infra_network_config: false

# Сети — это список, вы можете добавить более одной
# "type" является необязательным, поддерживаются как "nat", так и "bridge"
#  - "nat" — тип по умолчанию и должен быть сетью libvirt
#  - тип "bridge" требует, чтобы интерфейс моста был указан как имя (например, name: "br0"), который также должен быть уже настроен на хосте KVM
# "model" также необязателен
virt_infra_networks:
  - name: "default"
    type: "nat"
    model: "virtio"

# Диски, поддерживают различные параметры libvirt
# Мы, как правило, не указываем их, а оставляем на усмотрение гипервизора
# См. man-страницу virt-install для поддерживаемых значений
virt_infra_disk_size: "20"
virt_infra_disk_bus: "scsi"
virt_infra_disk_io: "threads"
virt_infra_disk_cache: "writeback"

# Диски — это список, вы можете добавить более одного
# Если вы переопределяете это, вы все равно должны включить 'boot' устройство первым в списке
# Только 'name' является обязательным, остальные необязательны (размер по умолчанию - 20 ГБ)
# Все гости требуют хотя бы один загрузочный диск (что и является значением по умолчанию)
virt_infra_disks:
  - name: "boot"
    size: "{{ virt_infra_disk_size }}"
    bus: "{{ virt_infra_disk_bus }}"
#   io: "{{ virt_infra_disk_io }}"
#   cache: "{{ virt_infra_disk_cache }}"

# Дистрибутив по умолчанию - CentOS Stream 8, переопределите в гостях или группах
virt_infra_distro_image: "CentOS-Stream-GenericCloud-8-20210603.0.x86_64.qcow2"

# Определите поддерживаемые варианты на вашем хосте KVM с помощью команды "osinfo-query os"
# Это не сильно повлияет на гостя, возможно, незначительно изменит шину
# Вы, вероятно, можете установить это как "centos7.0" для всех дистрибутивов, если хотите
#virt_infra_variant: "centos7.0"

# Эти переменные дистрибутива здесь для справки и удобства
virt_infra_distro: "centos-stream"
virt_infra_distro_release: "8"
virt_infra_distro_image_url: "https://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20210603.0.x86_64.qcow2"
virt_infra_distro_image_checksum_url: "https://cloud.centos.org/centos/8-stream/x86_64/images/CHECKSUM"

## Связано с хостом KVM

# Подключение к системному экземпляру libvirt
virt_infra_host_libvirt_url: "qemu:///system"

# Путь, где хранятся образы дисков
virt_infra_host_image_path: "/var/lib/libvirt/images"

# Отключить драйвер безопасности qemu по умолчанию
# Это переопределяется в переменных, специфичных для дистрибутива
virt_infra_security_driver: "none"

# Виртуальный BMC отключен по умолчанию
virt_infra_vbmc: false

# По умолчанию мы устанавливаем с помощью pip, но если вы предпочитаете делать это вручную, установите это значение на false
virt_infra_vbmc_pip: true

# Сервис vbmc по умолчанию, переопределите, если что-то другое на вашем дистрибутиве
virt_infra_vbmc_service: vbmcd

# Сети на kvmhost — это список, вы можете добавить более одной
# Вы можете создавать и удалять NAT-сети на kvmhost (создание мостов не поддерживается)
# сеть 'default' — это стандартная, поставляемая с libvirt сеть
# По умолчанию мы не удаляем никакие сети (пустой список absent)
virt_infra_host_networks:
  absent: []
  present:
    - name: "default"
      type: "nat"
      ip_address: "192.168.122.1"
      subnet: "255.255.255.0"
      dhcp_start: "192.168.122.2"
      dhcp_end: "192.168.122.254"

# Команда для создания ISO-образов
virt_infra_mkiso_cmd: genisoimage

# Список бинарных файлов для проверки на хосте KVM
virt_infra_host_deps:
  - qemu-img
  - osinfo-query
  - virsh
  - virt-customize
  - virt-sysprep

# Список пакетов, разделенных запятыми, для установки в диски гостей
virt_infra_guest_deps:
  - cloud-init
  - qemu-guest-agent

Зависимости

Нет

Пример инвентаря

Отдельный репозиторий virt-infra содержит пример файлов инвентаря и плейбука сайта для вызова роли, которые могут быть полезны.

Лучше всего, если инвентарные файлы разделить на несколько файлов для облегчения управления, в каталоге inventory или подобном. Я предлагаю общий файл kvmhost.yml, а затем отдельные инвентарные файлы для каждой группы гостей, например, openstack.yml. При запуске ansible вы включаете весь каталог в качестве источника инвентаря.

Инвентарь, используемый с этой ролью, должен включать группу хостов, называемую kvmhost, и другие группы хостов для гостей.

Пользовательские настройки могут быть указаны для каждого хоста или группы хостов в инвентаре.

Для создания новой группы гостей для управления создайте новый yml файл в каталоге инвентаря. Например, если вы хотите создать набор гостей для OpenStack, вы можете создать файл openstack.yml и заполнить его по мере необходимости.

Чтобы управлять конкретными хостами или группами, просто используйте опцию --limit Ansible, чтобы указать хосты или группы хостов (также необходимо включить группу kvmhost). Таким образом, вы можете использовать один инвентарь для множества разных гостей и управлять ими по отдельности.

Хост KVM — это место, где создаются сети libvirt и, следовательно, указываются как переменные в группе хостов.

Вот пример файла инвентаря kvmhost.yml в формате YAML. Он указывает kvmhost как localhost с локальным соединением. Обратите внимание, что создаются две сети (default и example) и одна, которая удаляется (other).

---
## YAML основанный инвентарь, см.:
## https://docs.ansible.com/ansible/latest/plugins/inventory/yaml.html
#
kvmhost:
  hosts:
    # Поместите соединение и настройки вашего хоста KVM здесь
    localhost:
      ansible_connection: local
      ansible_python_interpreter: /usr/bin/python3
  vars:
    # Сети — это список, вы можете добавить более одной
    # Вы можете создавать и удалять NAT-сети на kvmhost (создание мостов не поддерживается)
    # сеть 'default' — это стандартная, поставляемая с libvirt сеть
    # По умолчанию мы не удаляем никакие сети (пустой список)
    virt_infra_host_networks:
      absent:
        - name: "other"
      present:
        - name: "default"
          ip_address: "192.168.112.1"
          subnet: "255.255.255.0"
          dhcp_start: "192.168.112.2"
          dhcp_end: "192.168.112.254"
        - name: "example"
          ip_address: "192.168.113.1"
          subnet: "255.255.255.0"
          dhcp_start: "192.168.113.2"
          dhcp_end: "192.168.113.99"

Вот пример инвентаря гостей, названного simple.yml, который определяет гостей CentOS Stream 8 в группе, называемой simple, используя значения по умолчанию роли.

---
## YAML основанный инвентарь, см.:
## https://docs.ansible.com/ansible/latest/plugins/inventory/yaml.html
#
simple:
  hosts:
    centos-simple-[0:2]:
      ansible_python_interpreter: /usr/libexec/platform-python

Если вы хотите, чтобы группа ВМ была одной и той же, настройте переменные на уровне группы хостов. Вы все равно можете переопределять переменные группы хостов отдельными переменными для конкретных хостов, если это необходимо.

Вот пример установки различных переменных группы хостов и отдельных переменных хостов.

---
## YAML основанный инвентарь, см.:
## https://docs.ansible.com/ansible/latest/plugins/inventory/yaml.html
#
example:
  hosts:
    centos-7-example:
      virt_infra_state: shutdown
      virt_infra_timezone: "Australia/Melbourne"
      ansible_python_interpreter: /usr/bin/python
      virt_infra_networks:
        - name: "br0"
          type: bridge
        - name: "extra_network"
          type: nat
          model: e1000
        - name: ovs-bridge
          portgroup: ovs-portgroup
          type: ovs
      virt_infra_disks:
        - name: "boot"
        - name: "nvme"
          size: "100"
          bus: "nvme"
    centos-8-example:
      virt_infra_timezone: "Australia/Adelaide"
      ansible_python_interpreter: /usr/libexec/platform-python
    opensuse-15-example:
      virt_infra_distro: opensuse
      virt_infra_distro_image: openSUSE-Leap-15.1-JeOS.x86_64-15.1.0-OpenStack-Cloud-Current.qcow2
      virt_infra_variant: opensuse15.1
      virt_infra_disks:
        - name: "boot"
          bus: "scsi"
    ubuntu-eoan-example:
      virt_infra_cpu: 2
      virt_infra_distro: ubuntu
      virt_infra_distro_image: eoan-server-cloudimg-amd64.img
      virt_infra_variant: ubuntu18.04
  vars:
    virt_infra_ram: 1024
    virt_infra_disks:
      - name: "boot"
      - name: "data"
        bus: "sata"
    virt_infra_networks:
      - name: "example"
        type: nat

Несколько хостов KVM

Вы также можете указать несколько хостов KVM.

---
kvmhost:
  hosts:
    kvmhost1:
    kvmhost2:
    kvmhost3:
  vars:
    ansible_python_interpreter: /usr/bin/python3
    virt_infra_host_networks:
      absent: []
      present:
        - name: "default"
          ip_address: "192.168.112.1"
          subnet: "255.255.255.0"
          dhcp_start: "192.168.112.2"
          dhcp_end: "192.168.112.254"

Чтобы ВМ попала на конкретный хост KVM, вы должны добавить переменную kvmhost со строкой, которая соответствует хосту KVM из группы kvmhost.

Например, шесть хостов CentOS Stream 8 на трех хостах KVM:

---
simple:
  hosts:
    simple-centos-[1:2]:
      kvmhost: kvmhost1
    simple-centos-[3:4]:
      kvmhost: kvmhost2
    simple-centos-[5:6]:
      kvmhost: kvmhost3
  vars:
    ansible_python_interpreter: /usr/libexec/platform-python
    virt_infra_distro_image: "CentOS-Stream-GenericCloud-8-20210603.0.x86_64.qcow2"

Если для ВМ не указан kvmhost, она по умолчанию попадет на первый хост KVM в группе kvmhost (т.е. kvmhost[0]), что соответствует изначальному поведению для роли.

Проверки валидации были обновлены, чтобы убедиться, что все хосты KVM действительны и что любой указанный KVM хост для ВМ находится в группе kvmhost.

Чтобы сгруппировать ВМ на определенных хостах KVM, рассмотрите возможность создания дочерних групп и указания kvmhost на уровне дочерней группы.

Например, те же гости CentOS Stream 8 снова:

---
simple:
  hosts:
    simple-centos-[1:6]:
  vars:
    ansible_python_interpreter: /usr/libexec/platform-python
    virt_infra_distro_image: "CentOS-Stream-GenericCloud-8-20210603.0.x86_64.qcow2"
  children:
    simple_kvmhost1:
      hosts:
        simple-centos-[1:2]:
      vars:
        kvmhost: kvmhost1
    simple_kvmhost2:
      hosts:
        simple-centos-[3:4]:
      vars:
        kvmhost: kvmhost2
    simple_kvmhost3:
      hosts:
        simple-centos-[5:6]:
      vars:
        kvmhost: kvmhost3

Пример Плейбука

Я старался сделать Ansible простым, логически последовательным набором шагов и не слишком запутанным. Тем не менее, плейбук довольно специфичен.

Есть некоторые задачи, которые можно выполнить только на хосте KVM и другие в определенном порядке.

Этот код поможет, запуская множество проверок валидации на хосте KVM и для ваших конфигураций гостей, чтобы попытаться поймать что-то неправильно.

Вот пример плейбука virt-infra.yml, который вызывает роль.

---
- hosts: all
  gather_facts: no
  roles:
    - ansible-role-virt-infra

Загрузка облачного образа

Перед тем как запустить плейбук, загрузите облачный образ CentOS Stream 8.

curl -O https://cloud.centos.org/centos/8/x86_64/images/CentOS-Stream-GenericCloud-8-20210603.0.x86_64.qcow2
sudo mv -iv CentOS-Stream-GenericCloud-8-20210603.0.x86_64.qcow2 /var/lib/libvirt/images/

Запуск плейбука

Теперь запустите плейбук Ansible против kvmhost и гостей в группе simple с использованием вышеуказанного инвентаря (обратите внимание, что мы ограничены как kvmhost, так и simple группами хостов).

ansible-playbook \
--ask-become-pass \
--inventory ./inventory.d \
--limit kvmhost,simple \
./virt-infra.yml

Вы также можете переопределить ряд настроек гостей из командной строки.

ansible-playbook \
--ask-become-pass \
--limit kvmhost,simple \
./virt-infra.yml \
-e virt_infra_root_password=password \
-e virt_infra_disk_size=100 \
-e virt_infra_ram=4096 \
-e virt_infra_ram_max=8192 \
-e virt_infra_cpus=8 \
-e virt_infra_cpus_max=16 \
-e '{ "virt_infra_networks": [{ "name": "br0", "type": "bridge" }] }' \
-e virt_infra_state=running

Очистка

Чтобы удалить гостей в группе хостов, вы можете указать их (или конкретный хост) с помощью --limit и передать в качестве дополнительного аргумента virt_infra_state=undefined.

Это переопределит состояние гостя на неопределенное, и если они существуют, они будут удалены.

Например, чтобы удалить все ВМ в группе simple.

ansible-playbook \
--ask-become-pass \
--inventory simple.yml \
--limit kvmhost,simple \
--extra-vars virt_infra_state=undefined \
./virt-infra.yml

Если вы хотите просто их выключить, попробуйте virt_infra_state=shutdown вместо этого.

Например, чтобы выключить только хост simple-centos-2.

ansible-playbook \
--ask-become-pass \
--inventory simple.yml \
--limit kvmhost,simple-centos-2 \
--extra-vars virt_infra_state=shutdown \
./virt-infra.yml

Конфигурация после установки

После того как вы настроили свою инфраструктуру, вы можете запустить другой плейбук против того же инвентаря, чтобы сделать что угодно с этими машинами...

---
- hosts: all,!kvmhost
  tasks:
    - name: Обновить все пакеты
      package:
        name: '*'
        state: latest
      become: true
      register: result_package_update
      retries: 30
      delay: 10
      until: result_package_update is succeeded

    - name: Установить пакеты
      package:
        name:
          - git
          - tmux
          - vim
        state: present
      become: true
      register: result_package_install
      retries: 30
      delay: 10
      until: result_package_install is succeeded

Лицензия

GPLv3

Информация об авторе

Крис Смарт https://blog.christophersmart.com ```

О проекте

Define and manage guests and networks on a KVM host with Ansible

Установить
ansible-galaxy install csmart/ansible-role-virt-infra
Лицензия
gpl-3.0
Загрузки
1141
Владелец
Just another Linux guy.