Puppet/Запуск puppetry (пример с libvirt)
- цель
Помимо прочего на этой странице получилось своеобразное руководство к некоторым командам virt-* (для libvirt). Приветствуются исправления и дополнения к этому тексту (и пакетам и образам)! Нерешённые проблемы и задачи сейчас:
- описано как Выполнение манифеста на другой ноде. -- #Тестирование puppet
- Проверка и адаптация к ALT базовых средств, модулей puppet (пакетный менеджер в первую очередь, задействованный при работе некоторых других модулей). -- task #175947 test-only sisyphus ruby-facter.git=2.0.1-alt2 puppet.git=4.8.1-alt1
- Подготовка образа для тестирования puppet.
- Проверка и адаптация к ALT прочих модулей.
(Об оформлении. Изменяемые (по вкусу каждого пользователя) параметры в примерах я старался выделять жирным, чтобы можно было их легко отличить от определённых не нами штук с жёстко заданными именами.)
Создание сети
- цель
- В сети у нас будет свой DNS (для обращения к puppet по имени), и для удобства -- свой DHCP-сервер. При этом хотелось бы сохранить возможность выхода в "интернет" (сеть хост-системы).
Такая сеть таким образом (как нам нужно) будет использоваться, когда машина будет создаваться virt-install --network network=puppettheatre (а не --network bridge=BRIDGE; см. man virt-install).
(удобно) КОМАНДОЙ
???
(неудобно) ВРУЧНУЮ через GUI virt-manager
(Использовался virt-manager-1.4.0-alt1.)
virt-manager > Edit > Connection Details > Virtual Networks
+ (Add Network)
Тип такой сети, как нам нужна, будет называться "Isolated Physical Network".
Параметры в итоге получаются такие:
- Name
puppettheatre
- Device
- some
vibr
NN - Domain
theatre
(??? для чего используется? для чего важно?)- Network
- e.g.,
192.168.121.0/24
- Gateway
- будет автоматически выставлен в
192.168.121.1
; - Static routing
- наверное, не нужно;
- DHCP range
- Disabled
- Forwarding
- NAT
Создание машины с ALTовым puppet-мастером
(удобно) КОМАНДОЙ
???
(неудобно) ВРУЧНУЮ через GUI инсталлятора alterator через virt-viewer
(Использовался virt-viewer-5.0-alt1.)
Пример:
virt-install --virt-type kvm \ --name imz-puppet-master-ALT0 \ --memory 1024 --disk size=10 \ --cdrom /space/iso/nightly/tested/regular-lxde-latest-x86_64.iso \ --network network=puppettheatre \ --os-variant altlinux7
- --name imz-puppet-master-ALT0 -- какое-нибудь имя;
- regular-lxde-latest-x86_64.iso выбран как небольшой образ для инсталляции системы с systemd (сначала грузится LiveCD, что пока не важно, хотя есть планы тестировать puppet-мастер прямо с LiveCD);
- --network network=... прокомментирован выше в #Создание сети;
- --os-variant altlinux7 просто выбран как самый старший из известных ему ALTовых.
Запуск машины
См. #Запуск машин.
Конфигурация сети на машине
(Конфигурация сети на машине задаётся, конечно, вручную -- во время инсталляции или через alterator или привычным образом через конф.файлы.)
[user@puppet ~]$ tail /etc/sysconfig/network /etc/net/ifaces/eth0/* ==> /etc/sysconfig/network <== # Used by hotplug/pcmcia/ifplugd scripts to detect current network config # subsystem. CONFMETHOD=etcnet # Used by rc.sysinit to setup system hostname at boot. HOSTNAME=puppet.localdomain # This is used by ALTLinux ppp-common to decide if we want to install # nameserver lines into /etc/resolv.conf or not. RESOLV_MODS=yes ==> /etc/net/ifaces/eth0/ipv4address <== 192.168.121.2/24 ==> /etc/net/ifaces/eth0/ipv4route <== default via 192.168.121.1 ==> /etc/net/ifaces/eth0/options <== TYPE=eth CONFIG_WIRELESS=no BOOTPROTO=static CONFIG_IPV4=yes ==> /etc/net/ifaces/eth0/resolv.conf <== nameserver 10.4.0.1 [user@puppet ~]$
- Здесь имя машины сделано
puppet
специально. - IP-адрес назначен произвольно из доступного диапазона. (Один из адресов этой сети уже использован для шлюза -- хост-системы с гипервизором.)
- Т.к. в сети есть NAT для связи со внешним миром, мы можем использовать наш реальный DNS из внешнего мира. (Был прописан вручную, конечно.)
Напоследок включим sshd для входа по сети (правда, только с хочт-системы, потому что IP нашей виртуальной машины за NAT.)
Общие добавочные костыли и плюшки в конфигурации
Добавочные "костыли" в конфигурации этой создаваемой ВРУЧНУЮ машины делаем ради удобства/быстроты получения уже чуточку сконфигурированных подчинённых машин как клонов.
TODO: Планируется реализовать эту добавочную конфигурацию более прозрачными, чем костыли, способами: сетевыми сервисами; внести всё потребовавшееся и описанное на этой странице в запланированный нами профиль для mkimage (образ VM/LiveCD для тестирования puppet в сети-песочнице -- "puppettheatre.img/.iso").
- Пусть клоны видят свой puppet-мастер по имени на фиксированном IP-адресе (этой машины):
echo '192.168.121.2 puppet' >>/etc/hosts
- Можно поставить какие-то любимые пакеты сейчас, перед тем, как эта машина будет использована как исходник для клонирования; например:
apt-get update; apt-get install emacs25-X11-gtk3 slocate apt-printchanges systemctl enable crond updatedb
- Для удобства положим технический SSH-ключ:
[root@vb ~]# rsync -avP ~/.ssh/id_rsa.pub user@192.168.121.2:.ssh/hypervisor-id_rsa.pub [root@vb ~]# ssh user@192.168.121.2 'cat .ssh/hypervisor-id_rsa.pub >>.ssh/authorized_keys' [root@vb ~]# ssh user@192.168.121.2 -t su -c "'cat ~user/.ssh/hypervisor-id_rsa.pub >>/root/.ssh/authorized_keys'"
Используем машину как исходник для клонирования
Прежде, чем что-то делать с машиной, используем её как исходник для клонирования и создания других (подчинённых) нод с ALT, чтобы не повторять инсталляцию вручную.
Думаю, удобно будет её сохранить в первоначальном виде и не трогать эту копию. (А копию уже использовать как исходник для всяких ALTовых нод.)
ssh user@192.168.121.2 -t su -c /sbin/poweroff; ping 192.168.121.2 virt-clone --original imz-puppet-master-ALT0 --auto-clone
Заметьте, что сеть будет использоваться та же самая -- как нам и нужно (для общения создаваемых нод между собой).[1]
Для удобства будущей перенастройки новых клонов этого клона без выключения других машин (без коллизии с IP-адресом работающего puppet-мастера) я бы в клоне сразу поменял IP-адрес на некий выделенный временный, как это делается потом для всех рабочих подчинённых нод, например, 192.168.121.16
:
[root@vb ~]# virsh start imz-puppet-master-ALT0-clone [root@vb ~]# ssh root@192.168.121.2 [root@puppet ~]# emacs /etc/net/ifaces/eth0/ipv4address [root@puppet ~]# cat /etc/net/ifaces/eth0/ipv4address 192.168.121.16/24 [root@puppet ~]# poweroff
Создание подчинённой машины с ALTом
(удобно) КОМАНДОЙ
???
(неудобно) ВРУЧНУЮ: склонируем что-то; сконфигурируем
Для простоты склонируем созданную ВРУЧНУЮ машину; у нас уже заготовлена копия; её склонируем и сконфигурируем потом:
virt-clone --original imz-puppet-master-ALT0-clone --name imz-puppet-slave-ALT0 --auto-clone
Сконфигурируем сеть (пока исходник клона опущен), зайдя по ssh по старому IP-адресу:
[root@vb ~]# virsh start imz-puppet-slave-ALT0; ping 192.168.121.16 [root@vb ~]# ssh user@192.168.121.16 [user@puppet ~]$ su - # emacs /etc/net/ifaces/eth0/ipv4address /etc/sysconfig/network
Назначим новый IP-адрес и имя, убдимся, что по имени puppet
мы можем обратиться к puppet-мастеру:
[root@puppet ~]# tail /etc/net/ifaces/eth0/ipv4address /etc/sysconfig/network /etc/hosts ==> /etc/net/ifaces/eth0/ipv4address <== 192.168.121.3/24 ==> /etc/sysconfig/network <== # Used by hotplug/pcmcia/ifplugd scripts to detect current network config # subsystem. CONFMETHOD=etcnet # Used by rc.sysinit to setup system hostname at boot. HOSTNAME=slave0.localdomain # This is used by ALTLinux ppp-common to decide if we want to install # nameserver lines into /etc/resolv.conf or not. RESOLV_MODS=yes ==> /etc/hosts <== 127.0.0.1 localhost.localdomain localhost 192.168.121.2 puppet [root@puppet ~]#
Можно перезагружать: ssh user@192.168.121.16 -t su -c /sbin/reboot; ping 192.168.121.3
Запуск машин
virsh start imz-puppet-master-ALT0
Работа с машинами происходит подключением через virt-manager или по ssh с хост-системы-гипервизора.
Удаление машин
Если нужно, удаление той или иной машины делается[1] так, как записано в скрипте virt-delete из virt-utils.
Тестирование puppet
Предварительные штуки: пакеты, сервисы
[root@puppet ~]# apt-get install puppet-server [root@slave0 ~]# apt-get install puppet
[root@puppet ~]# service puppetmaster start [root@puppet ~]# systemctl enable puppetmaster
Демона агента на подчинённой ноде пока апускать не будем, потому что тестировать интереснее однократным вызовом с отладочной информацией (как будет ниже в примере: puppet agent --test --debug):
[root@slave0 ~]# #service puppet start
Создание и выполнение тестовых манифестов
Место, где лежат манифесты, которые будут выполнятся (в конфигурации по умолчанию). (В конфигурации по умолчанию агент обращается к мастеру на хосте по имени puppet
.)
[root@puppet puppet]# mkdir -p /etc/puppet/environments/production/manifests
Попробуем простейший пример манифеста, который создаст /tmp/puppet-testfile; в начале работы его нет:
[root@slave0 ~]# l /tmp/puppet-testfile ls: cannot access /tmp/puppet-testfile: No such file or directory
Сам манифест:
[root@puppet puppet]# cat >/etc/puppet/environments/production/manifests/test0.pp file { "/tmp/puppet-testfile": ensure => "present", owner => "root", group => "root", mode => "664", content => "This is a test file created using puppet. Puppet is really cool", }
Выполнить его на slave0 не получится с первого раза (см. решение про подпись ниже), но на том же хосте (puppet), где мастер, получается с первого раза. Перезапускать puppetmaster не нужно, чтобы читался новый манифест. Имя .pp-файла не важно. Одноразовое тестирование выполнения с отладочной информацией делается командой:
puppet agent --test --debug l /tmp/pup*
(service puppet start собственно и запускает такого агента, но не в одноразовом режиме; мы пока так демона-агента не запускаем, потому что неинтересно для тестирования выполнения манифестов.)
Чтобы выполнить на другом хосте, а именно slave0, нужно подписать ключ этого подчинённого хоста (чтобы ходить к puppet-мастеру с этим сертификатом). Это делается просто, если знать; можно просто подписать на puppet-мастере. Перед началом работы на puppet-мастере видим только свой сертификат (подписанный -- отмечено +):
[root@puppet ~]# puppet cert list --all + "puppet.localdomain" (SHA256) 05:70:76:4B:78:42:57:D8:10:14:29:42:FD:E1:84:5D:39:AB:77:60:EF:2F:87:3C:80:B5:59:BB:75:62:D9:16 (alt names: "DNS:puppet", "DNS:puppet.localdomain")
а после первого вызова агента на подчинённом хосте (обычным образом, т.е. так, как указано выше: puppet agent --test --debug) в этом списке появится его ключ:
[root@puppet ~]# puppet cert list --all "slave0.localdomain" (SHA256) 4C:D1:8F:00:76:FD:A1:50:D5:BD:3F:4F:C7:69:E0:1E:17:1E:EC:9F:B0:F6:D2:32:2E:C3:4C:F0:99:71:88:C7 + "puppet.localdomain" (SHA256) 05:70:76:4B:78:42:57:D8:10:14:29:42:FD:E1:84:5D:39:AB:77:60:EF:2F:87:3C:80:B5:59:BB:75:62:D9:16 (alt names: "DNS:puppet", "DNS:puppet.localdomain")
(имя явно берётся не из DNS мастером, потому что имени slave0.localdomain мастеру неизвестно; оно было вписано подчинённой нодой при создании запроса на подпись сертификата). Подписываем:
[root@puppet ~]# puppet cert sign slave0.localdomain Signing Certificate Request for: "slave0.localdomain" (SHA256) 4C:D1:8F:00:76:FD:A1:50:D5:BD:3F:4F:C7:69:E0:1E:17:1E:EC:9F:B0:F6:D2:32:2E:C3:4C:F0:99:71:88:C7 Notice: Signed certificate request for slave0.localdomain Notice: Removing file Puppet::SSL::CertificateRequest slave0.localdomain at '/etc/puppet/ssl/ca/requests/slave0.localdomain.pem' [root@puppet ~]# puppet cert list --all + "puppet.localdomain" (SHA256) 05:70:76:4B:78:42:57:D8:10:14:29:42:FD:E1:84:5D:39:AB:77:60:EF:2F:87:3C:80:B5:59:BB:75:62:D9:16 (alt names: "DNS:puppet", "DNS:puppet.localdomain") + "slave0.localdomain" (SHA256) 1A:2A:15:08:F4:AD:0B:3A:CA:46:EF:2A:B5:0D:60:4E:DC:BA:BA:E2:63:EC:D1:A3:84:4A:06:B3:9A:A4:22:ED
После этого повторный запуск puppet agent --test --debug на подчинённой ноде выполняет наш тестовый манифест![2]
Примечания
- ↑ Посмотрите, что получилось с клоном:
[root@vb ~]# diff -du <(virsh dumpxml imz-puppet-master-ALT0) <(virsh dumpxml imz-puppet-master-ALT0-clone) --- /dev/fd/63 2017-01-24 14:04:17.089573354 +0300 +++ /dev/fd/62 2017-01-24 14:04:17.089573354 +0300 @@ -1,6 +1,6 @@ <domain type='kvm'> - <name>imz-puppet-master-ALT0</name> - <uuid>887ffdb5-3222-4717-8b13-820c1ba543ad</uuid> + <name>imz-puppet-master-ALT0-clone</name> + <uuid>463057db-4470-4b6a-b44b-6f19d8040793</uuid> <memory unit='KiB'>1048576</memory> <currentMemory unit='KiB'>1048576</currentMemory> <vcpu placement='static'>1</vcpu> @@ -32,7 +32,7 @@ <emulator>/usr/bin/qemu-kvm</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2'/> - <source file='/var/lib/libvirt/images/imz-puppet-master-ALT0.qcow2'/> + <source file='/var/lib/libvirt/images/imz-puppet-master-ALT0-clone.qcow2'/> <target dev='vda' bus='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </disk> @@ -65,7 +65,7 @@ <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </controller> <interface type='network'> - <mac address='52:54:00:60:5e:ca'/> + <mac address='52:54:00:e3:ae:bd'/> <source network='puppettheatre'/> <model type='virtio'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> [root@vb ~]#
- ↑
повторный запуск puppet agent --test --debug на подчинённой ноде выполняет наш тестовый манифест:
... Debug: Caching connection for https://puppet:8140 Info: Caching catalog for slave0.localdomain Debug: Creating default schedules Info: Applying configuration version '1485527400' Notice: /Stage[main]/Main/File[/tmp/puppet-testfile]/ensure: defined content as '{md5}2f09fcc0123eb12d2b07a2a87135a278' Debug: /Stage[main]/Main/File[/tmp/puppet-testfile]: The container Class[Main] will propagate my refresh event Debug: Class[Main]: The container Stage[main] will propagate my refresh event Debug: Finishing transaction 16750420 Debug: Storing state Info: Creating state file /var/lib/puppet/state/state.yaml Debug: Stored state in 0.06 seconds Notice: Applied catalog in 0.11 seconds Debug: Dynamically-bound server lookup failed, falling back to report_server setting Debug: Dynamically-bound port lookup failed; falling back to report_port setting Debug: Using cached connection for https://puppet:8140 Debug: Caching connection for https://puppet:8140 Debug: Closing connection for https://puppet:8140 [root@slave0 ~]# l /tmp/p* -rw-rw-r-- 1 root root 83 янв 27 17:30 /tmp/puppet-testfile