Всем доброго дня.
После прохождения курсов «Яндекс Практикум» захотелось немного проработать полученные навыки. К сожалению, на текущем месте работы глобальных и интересных задач нет, т.ч. приходится оттачивать навыки на том, что есть.
А есть гипервизор PROXMOX. И вот почему бы не попробовать для него сделать IaC (Infrastructure as Code).
Ниже покажу как я сделал.
Сразу оговорюсь: я новичок в этом деле, т.ч. не факт что конфиг-файлы истинно верные в плане написания и всегда можно сделать лучше. Т.ч. прошу сильно не ругать.
Погнали…
Содержание
Предварительная подготовка.
На машине, откуда будет запускаться Ansible и на самом Proxmox’е надо установить нужные компоненты Python — proxmoxer и requests (выполняется от обычного пользователя, хотя там root по умолчанию):
1 2 3 | pip3 install proxmoxer pip3 install requests |
Если у ваc там Интернет через прокси, то так:
1 2 3 | pip3 --proxy http://192.168.1.2:3128 install proxmoxer pip3 --proxy http://192.168.1.2:3128 install requests |
вместо 192.168.1.2 подставить адрес своего прокси-сервера.
Файлы конфигурации ANSIBLE.
Для самого первого теста создадим простой файл inventory с таким содержимым:
1 2 | [proxmox-h] proxmox ansible_host=192.168.1.100 ansible_ssh_private_key_file=/home/admin/test_ansible/proxmox_pve ansible_ssh_user=root ansible_ssh_common_args='-o StrictHostKeyChecking=no' ansible_python_interpreter=/usr/bin/python3 |
где:
proxmox-h: название группы;
proxmox: имя машины (будет использоваться в playbook’е);
ansible_host: ip-адрес сервера proxmox где будет выполняться Playbook. Если у вас настроен DNS, то этот параметр можно не указывать;
ansible_ssh_private_key_file: предварительно сгенерировал ключи ssh и импортировал в proxmox, а здесь уже указал расположение ключа;
ansible_ssh_user: пользователь, под которым происходит подключение к proxmox;
ansible_ssh_common_args=’-o StrictHostKeyChecking=no’: необязательный параметр, который как будто бы не показывает окно принятия ключей при подключении по ssh;
ansible_python_interpreter=/usr/bin/python3: выделил цветом. Без этого параметра у меня была вот такая ошибка:
FAILED! => {«changed»: false, «msg»: «proxmoxer required for this module»}
Теперь можно проверить подключение к серверу:
1 | ansible proxmox -i inventory -m ping |
после ansible указываем имя хоста, потом
-i: файл inventory
-m ping: модуль ping
на выходе получаем следующее
Теперь создадим простой playbook.yml с таким содержимым:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | --- - name: PROXMOX TEST 1 hosts: proxmox tasks: - name: CREATE VM community.general.proxmox_kvm: proxmox_default_behavior: no_defaults api_user: 'root@pam' api_password: '12345678' api_host: 'proxmox.test.local' name: test-vm-1 node: proxmox vmid: 400 cores: 4 vcpus: 2 numa_enabled: true numa: 'cpuunits=2048' memory: 8192 net: net0: 'virtio,bridge=vmbr0' virtio: virtio0: 'vm_drive:50,format=raw' ide: '{"ide2":"local:iso/ubuntu-22.04.1-live-server-amd64.iso,media=cdrom,size=1440306"}' |
По параметрам:
proxmox_default_behavior: no_defaults — без него была вот такая ошибка:
FAILED! => {«changed»: false, «msg»: «creation of qemu VM spynal with vmid 400 failed with exception=400 Bad Request: Parameter verification failed. — {‘archive’: \»missing property — ‘force’ requires this property\»}»}
если попробовать указать не использовать этот модуль, то будет такая ошибка:
fatal: [proxmox]: FAILED! => {«changed»: false, «msg»: «Unsupported parameters for (community.general.proxmox_kvm) module: archive Supported parameters include: acpi, agent, api_host, api_password, api_token_id, api_token_secret, api_user, args, autostart, balloon, bios, boot, bootdisk, cicustom, cipassword, citype, ciuser, clone, cores, cpu, cpulimit, cpuunits, delete, description, digest, force, format, freeze, full, hostpci, hotplug, hugepages, ide, ipconfig, keyboard, kvm, localtime, lock, machine, memory, migrate_downtime, migrate_speed, name, nameservers, net, newid, node, numa, numa_enabled, onboot, ostype, parallel, pool, protection, proxmox_default_behavior, reboot, revert, sata, scsi, scsihw, searchdomains, serial, shares, skiplock, smbios, snapname, sockets, sshkeys, startdate, startup, state, storage, tablet, target, tdf, template, timeout, update, validate_certs, vcpus, vga, virtio, vmid, watchdog»}
api_user: ‘root@pam’ — пользователь для авторизации, здесь по умолчанию указан. Если у вас другой, то указывать его. Вообще, это хорошая практика создавать отдельную учетку, но для примера я не стал морочиться;
api_password: ‘12345678’ — пароль пользователя;
api_host: ‘proxmox.test.local’ — доменное имя сервера, можно посмотреть у него в /etc/hosts;
name: test-vm-1 — имя вм;
node: srv1 — имя ноды, я так понимаю что если у вас кластер из Proxmox’ов;
vmid: 400 — ID вм. Можно не указывать, тогда он сам задаст этот ID;
cores: 4 — кол-во ядер процессора;
vcpus: 2 — кол-во вирт процессоров;
numa_enabled: true — включение NUMA1
numa: ‘cpuunits=2048‘
memory: 8192 — кол-во оперативной памяти (RAM);
net: — настройка сети;
net0: ‘virtio,bridge=vmbr0’ — типа адаптера (virtio), тип подключения — в данном случае «мост»;
virtio: — параметры жесткого диска;
virtio0: ‘vm_drive:50,format=raw’ — где будет хранится жесткий диск (у меня отдельный раздел), и тип — у меня raw из-за особенностей. Может быть qcow2;
ide: ‘{«ide2″:»local:iso/ubuntu-22.04.1-live-server-amd64.iso,media=cdrom,size=1440306»}’ — добавление CD-ROM’а и образа диска. Тут в качестве примера указан Ubuntu Server 22.04, образ которого находится на диске local. Если у вас как-то иначе, то надо указать где лежит образ, его точное название и размер.
Я просто в пустую ВМ добавил образ и списал параметры.
Обращаю внимание, что здесь самый простой конфиг. Т.е. ВМ создастся с такими параметрами и пустая — без ОС.
Если вам надо что-то другое, например EFI, то надо будет добавить. Так же всякие MAC-адреса и прочее.
Все параметры я перебрать не смогу, к сожалению.
После этого можно запустить:
1 | ansible-playbook -i inventory createvm_playbook.yml |
Вывод примерно будет таким:
И в самом гипервизоре можно увидеть созданную машину (через web-консоль):
либо через консоль
1 | qm showcmd 400 --pretty |
и вывод будет таким:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | /usr/bin/kvm \ -id 400 \ -name 'test-vm-1,debug-threads=on' \ -no-shutdown \ -chardev 'socket,id=qmp,path=/var/run/qemu-server/400.qmp,server=on,wait=off' \ -mon 'chardev=qmp,mode=control' \ -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect=5' \ -mon 'chardev=qmp-event,mode=control' \ -pidfile /var/run/qemu-server/400.pid \ -daemonize \ -smbios 'type=1,uuid=db31d489-2808-4e6d-b63f-adc2a5190b68' \ -smp '2,sockets=1,cores=4,maxcpus=4' \ -nodefaults \ -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ -vnc 'unix:/var/run/qemu-server/400.vnc,password=on' \ -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ -m 8192 \ -object 'memory-backend-ram,id=ram-node0,size=8192M' \ -numa 'node,nodeid=0,cpus=0-3,memdev=ram-node0' \ -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ -device 'vmgenid,guid=03888569-33b0-42df-a2f7-afc2ca3f002b' \ -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ -device 'VGA,id=vga,bus=pci.0,addr=0x2' \ -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ -iscsi 'initiator-name=iqn.1993-08.org.debian:01:47191567fee' \ -drive 'file=/var/lib/vz/template/iso/ubuntu-22.04.1-live-server-amd64.iso,if=none,id=drive-ide2,media=cdrom,aio=io_uring' \ -device 'ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=101' \ -drive 'file=/dev/zvol/vm_drive/vm-400-disk-0,if=none,id=drive-virtio0,format=raw,cache=none,aio=io_uring,detect-zeroes=on' \ -device 'virtio-blk-pci,drive=drive-virtio0,id=virtio0,bus=pci.0,addr=0xa,bootindex=100' \ -netdev 'type=tap,id=net0,ifname=tap400i0,script=/var/lib/qemu-server/pve-bridge,downscript=/var/lib/qemu-server/pve-bridgedown,vhost=on' \ -device 'virtio-net-pci,mac=4A:51:0F:7D:B7:ED,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=1024,bootindex=102' \ -machine 'type=pc+pve0' \ -serial unix:/var/run/qemu-server/400.serial,server,nowait |
ANSIBLE-VAULT.
Внесем улучшения. Т.к. у нас в Playbook’е логин и пароль передаются в открытом виде — это очень плохо. Надо поправить.
Для этого используем ansible-vault.
Создадим файл с именем vault.yml с таким содержанием:
1 2 3 | --- vault_api_user: root@pam vault_api_paswword: 12345678 |
Далее его зашифруем
1 | ansible-vault encrypt vault.yml |
будет запрошен ввод пароля (надо задать для шифровки) и его подтверждение
на выводе получим что-то такое:
Посмотреть его содержимое можно так:
1 | ansible-vault view vault.yml |
ввести ранее заданный пароль и на выводе получить что-то типа такого:
для редактирования:
1 | ansible-vault edit vault.yml |
тут так же надо будет ввести пароль.
Изменим наш Playbook:
- укажем файл, откуда брать переменные,
- вместо логина и пароля укажем переменные из зашифрованного файла
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | --- - name: PROXMOX TEST 1 hosts: proxmox vars_files: - vault.yml tasks: - name: CREATE VM community.general.proxmox_kvm: proxmox_default_behavior: no_defaults api_user: "{{ vault_api_user }}" api_password: "{{ vault_api_password }}" api_host: 'proxmox.test.local' name: test-vm-1 node: proxmox vmid: 400 cores: 4 vcpus: 2 numa_enabled: true numa: 'cpuunits=2048' memory: 8192 net: net0: 'virtio,bridge=vmbr0' virtio: virtio0: 'vm_drive:50,format=raw' ide: '{"ide2":"local:iso/ubuntu-22.04.1-live-server-amd64.iso,media=cdrom,size=1440306"}' |
После чего выполнить команду:
1 | ansible-playbook -i inventory createvm_playbook.yml --ask-vault-pass |
где:
—ask-vault-pass для запроса ввода пароля.
Помимо ручного ввода пароля, можно его добавить в файл, который будет доступен только вам и никому больше. Это позволит не вводить пароль.
Попробуем.
1 | echo "[ранее созданный пароль]" > my_ansible_password |
Местоположение и название файла по вашем усмотрению, здесь просто для примера. Файл будет в том же каталоге, где все тестовые скрипты.
Теперь попробуем запустить наш Playbook так:
1 | ansible-playbook -i inventory createvm_playbook.yml --vault-password-file my_ansible_password |
Ну и увидим, что всё работает.
Клонирование ВМ из шаблона.
Каждый раз создавать ВМ иногда затруднительно и долго. Проще создать, установить ОС, настроить и сделать шаблон, из которого потом развернуть новую ВМ дело пары минут.
Далее подразумевается, что шаблон уже есть на Proxmox’е.
Подготовим отдельный playbook — vm_clone_templ.yml. Отличается от первоначального тем, что здесь указываем шаблон из которого будем клонировать машину и остальные параметры:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | --- - name: PROXMOX TEST 1 hosts: proxmox vars_files: - vault.yml tasks: - name: CLONE VM FROM TEMPLATE community.general.proxmox_kvm: proxmox_default_behavior: no_defaults api_user: "{{ vault_api_user }}" api_password: "{{ vault_api_password }}" api_host: 'proxmox.test.local' node: proxmox vmid: 301 newid: 500 clone: linux-srv name: clone-vm1 full: true storage: local format: raw timeout: 500 |
где:
vmid: 301 — id шаблона;
newid: 500 — новый ID для склонированной машины. Если не указывать, то Proxmox сам назначит свободный ID;
clone: linux-srv — название вирт с шаблоном;
name: clone-vm1 — новое имя склонированной ВМ;
full: true — вид клонирования. Есть FULL и LINKED. Если не указывать, то по умолчанию — full;
timeout: 500 — время выполнения. Можно не указывать, я просто взял из шаблона;
format: raw — у меня формат такой, но можно использовать — qcow2.
Разное.
Добавить описание к ВМ.
Так же можно добавить описание для создаваемой ВМ (думаю, что и для клонированной из шаблона тоже).
Для этого достаточно в конфиг добавить:
description: ‘[описание какое хотите добавить.]’
Например,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | --- - name: PROXMOX TEST 1 hosts: proxmox vars_files: - vault.yml tasks: - name: CREATE VM community.general.proxmox_kvm: proxmox_default_behavior: no_defaults api_user: "{{ vault_api_user }}" api_password: "{{ vault_api_password }}" api_host: 'proxmox.test.local' name: test-vm-1 node: proxmox vmid: 400 cores: 4 vcpus: 2 numa_enabled: true numa: 'cpuunits=2048' memory: 8192 net: net0: 'virtio,bridge=vmbr0' virtio: virtio0: 'vm_drive:50,format=raw' ide: '{"ide2":"local:iso/ubuntu-22.04.1-live-server-amd64.iso,media=cdrom,size=1440306"}' description: 'MY TEST VM FROM ANSIBLE PLAYBOOK' |
Если надо что-то в пару строк, то так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | --- - name: PROXMOX TEST 1 hosts: proxmox vars_files: - vault.yml tasks: - name: CREATE VM community.general.proxmox_kvm: proxmox_default_behavior: no_defaults api_user: "{{ vault_api_user }}" api_password: "{{ vault_api_password }}" api_host: 'proxmox.test.local' name: test-vm-1 node: proxmox vmid: 400 cores: 4 vcpus: 2 numa_enabled: true numa: 'cpuunits=2048' memory: 8192 net: net0: 'virtio,bridge=vmbr0' virtio: virtio0: 'vm_drive:50,format=raw' ide: '{"ide2":"local:iso/ubuntu-22.04.1-live-server-amd64.iso,media=cdrom,size=1440306"}' description: | MY TEST VM FROM ANSIBLE PLAYBOOK \ LINE 2 \ LINE 3 |
1 2 3 4 | description: | MY TEST VM FROM ANSIBLE PLAYBOOK \ LINE 2 \ LINE 3 |
Выполним и посмотрим на описание:
Параметры модуля.
А вот все параметры, которые есть у модуля proxmox_kvm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | acpi agent api_host api_password api_token_id api_token_secret api_user args autostart balloon bios boot bootdisk cicustom cipassword citype ciuser clone cores cpu cpulimit cpuunits delete description digest force format freeze full hostpci hotplug hugepages ide ipconfig keyboard kvm localtime lock machine memory migrate_downtime migrate_speed name nameservers net newid node numa numa_enabled onboot ostype parallel pool protection proxmox_default_behavior reboot revert sata scsi scsihw searchdomains serial shares skiplock smbios snapname sockets sshkeys startdate startup state storage tablet target tdf template timeout update validate_certs vcpus vga virtio vmid watchdog |
Цвета.
Если вам надо отключить цветовое раскрашивание в консоли, то надо выполнить такую команду:
1 | export ANSIBLE_NOCOLOR=True |
Источники.
If you found an error, highlight it and press Shift + Enter or to inform us.
- NUMA (Non-Uniform Memory Access — неравномерный доступ к памяти или Non-Uniform Memory Architecture — Архитектура с неравномерной памятью) — схема реализации компьютерной памяти, используемая в мультипроцессорных системах, когда время доступа к памяти определяется её расположением по отношению к процессору.