Vai al contenuto

Creazione automatica di template con Packer e distribuzione con Ansible in un ambiente VMware vSphere

Conoscenza: ⭐ ⭐ :star
Complessità: ⭐ ⭐ ⭐ ⭐

Tempo di lettura: 30 minuti

Prerequisiti, presupposti e note generali

  • Un ambiente vSphere disponibile e un utente con accesso consentito.
  • Un server web interno per archiviare i file.
  • Accesso web ai repository Rocky Linux.
  • Una ISO di Rocky Linux.
  • Un ambiente Ansible disponibile.
  • Si presuppone che abbiate una certa conoscenza di ogni prodotto citato. In caso contrario, prima di iniziare, è necessario consultare la documentazione.
  • Vagrant non è in uso qui. È stato sottolineato che con Vagrant sarebbe stata fornita una chiave SSH non autofirmata. Se volete approfondire l'argomento, potete farlo, ma non è oggetto di questo documento.

Introduzione

Questo documento copre la creazione di modelli di macchine virtuali vSphere con Packer e come distribuire l'artefatto come nuove macchine virtuali con Ansible.

Possibili aggiustamenti

Naturalmente, potete adattare questo how-to per altri hypervisor.

Sebbene qui si utilizzi l'immagine ISO minima, si può scegliere di utilizzare l'immagine del DVD (molto più grande e forse troppo grande) o l'immagine di avvio (molto più piccola e forse troppo piccola). La scelta spetta a voi. Influisce in particolare sulla larghezza di banda di cui avrete bisogno per l'installazione, e quindi sul tempo di fornitura. Discuteremo in seguito l'impatto di questa scelta predefinita e come porvi rimedio.

Si può anche scegliere di non convertire la macchina virtuale in un modello, in questo caso si userà Packer per distribuire ogni nuova macchina virtuale, il che è ancora abbastanza fattibile (un'installazione che parte da 0 richiede meno di 10 minuti senza interazione umana).

Packer

Introduzione a Packer

Packer è uno strumento di imaging per macchine virtuali open source, rilasciato sotto licenza MPL 2.0 e creato da Hashicorp. Vi aiuterà ad automatizzare il processo di creazione di immagini di macchine virtuali con sistemi operativi preconfigurati e software installato da un'unica fonte di configurazione in ambienti virtualizzati sia cloud che on-prem.

Con Packer è possibile creare immagini da utilizzare sulle seguenti piattaforme:

Per ulteriori informazioni, potete consultare queste risorse:

Installazione di Packer

Esistono due modi per installare Packer nel sistema Rocky Linux.

Installazione di Packer dal repo di Hashicorp

HashiCorp mantiene e firma pacchetti per diverse distribuzioni Linux. Per installare Packer nel nostro sistema Rocky Linux, seguite i passi successivi:

Scaricare e installare dal sito web di Packer

  1. Installare dnf-config-manager:
$ sudo dnf install -y dnf-plugins-core
  1. Aggiungere il repository Hashicorp ai repository disponibili nel nostro sistema Rocky Linux:
$ sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/fedora/hashicorp.repo
  1. Installare Packer:
$ sudo dnf -y install packer

Scaricare e installare dal sito web di Packer

Si può iniziare scaricando i binari per la propria piattaforma con i download di Packer.

  1. Nella pagina di download, copiate il link di download nella sezione Linux Binary Download che corrisponde all'architettura del vostro sistema.

  2. Da una shell o da un terminale, scaricatelo utilizzando lo strumento wget:

$ wget https://releases.hashicorp.com/packer/1.8.3/packer_1.8.3_linux_amd64.zip
Verrà scaricato un file .zip.

  1. Per decomprimere l'archivio scaricato, eseguire il seguente comando nella shell:
$ unzip packer_1.8.3_linux_amd64.zip

Attenzione

Se si ottiene un errore e non si ha l'applicazione unzip installata sul sistema, è possibile installarla eseguendo questo comando sudo dnf install unzip

  1. Spostate l'applicazione Packer nella cartella bin:
$ sudo mv packer /usr/local/bin/

Verifica della corretta installazione di Packer

Se tutti i passaggi delle procedure precedenti sono stati completati correttamente, possiamo procedere alla verifica dell'installazione di Packer sul nostro sistema.

Per verificare che Packer sia stato installato correttamente, eseguite il comando packer e otterrete il risultato mostrato di seguito:

$ packer 
Usage: packer [--version] [--help] <command> [<args>]

Available commands are:
    build           build image(s) from template
    console         creates a console for testing variable interpolation
    fix             fixes templates from old versions of packer
    fmt             Rewrites HCL2 config files to canonical format
    hcl2_upgrade    transform a JSON template into an HCL2 configuration
    init            Install missing plugins or upgrade plugins
    inspect         see components of a template
    plugins         Interact with Packer plugins and catalog
    validate        check that a template is valid
    version         Prints the Packer version

Creazione di modelli con Packer

Per eseguire le seguenti operazioni si presuppone che l'utente abbia un sistema operativo Linux.

Poiché ci collegheremo a un server VMware vCenter per inviare i nostri comandi tramite Packer, dobbiamo memorizzare le nostre credenziali al di fuori dei file di configurazione che creeremo successivamente.

Creiamo un file nascosto con le nostre credenziali nella nostra home directory. Si tratta di un file json:

$ vim .vsphere-secrets.json {
    "vcenter_username": "rockstar",
    "vcenter_password": "mysecurepassword"
  }

Queste credenziali hanno bisogno di qualche assegnazione di accesso al vostro ambiente vSphere.

Creiamo un file json (in futuro, il formato di questo file cambierà in HCL):

{
  "variables": {
    "version": "0.0.X",
    "HTTP_IP": "fileserver.rockylinux.lan",
    "HTTP_PATH": "/packer/rockylinux/8/ks.cfg"
  },
  "sensitive-variables": ["vcenter_password"],
  "provisioners": [
    {
      "type": "shell",
      "expect_disconnect": true,
      "execute_command": "bash '{{.Path}}'",
      "script": "{{template_dir}}/scripts/requirements.sh"
    }
  ],
  "builders": [
    {
      "type": "vsphere-iso",
      "CPUs": 2,
      "CPU_hot_plug": true,
      "RAM": 2048,
      "RAM_hot_plug": true,
      "disk_controller_type": "pvscsi",
      "guest_os_type": "centos8_64Guest",
      "iso_paths": [
        "[datasyno-contentlibrary-mylib] contentlib-a86ad29a-a43b-4717-97e6-593b8358801b/3a381c78-b9df-45a6-82e1-3c07c8187dbe/Rocky-8.4-x86_64-minimal_72cc0cc6-9d0f-4c68-9bcd-06385a506a5d.iso"
      ],
      "network_adapters": [
        {
          "network_card": "vmxnet3",
          "network": "net_infra"
        }
      ],
      "storage": [
        {
          "disk_size": 40000,
          "disk_thin_provisioned": true
        }
      ],
      "boot_command": [
      "<up><tab> text ip=192.168.1.11::192.168.1.254:255.255.255.0:template:ens192:none nameserver=192.168.1.254 inst.ks=http://{{ user `HTTP_IP` }}/{{ user `HTTP_PATH` }}<enter><wait><enter>"
      ],
      "ssh_password": "mysecurepassword",
      "ssh_username": "root",
      "shutdown_command": "/sbin/halt -h -p",
      "insecure_connection": "true",
      "username": "{{ user `vcenter_username` }}",
      "password": "{{ user `vcenter_password` }}",
      "vcenter_server": "vsphere.rockylinux.lan",
      "datacenter": "DC_NAME",
      "datastore": "DS_NAME",
      "vm_name": "template-rockylinux8-{{ user `version` }}",
      "folder": "Templates/RockyLinux",
      "cluster": "CLUSTER_NAME",
      "host": "esx1.rockylinux.lan",
      "notes": "Template RockyLinux version {{ user `version` }}",
      "convert_to_template": true,
      "create_snapshot": false
    }
  ]
}
In seguito, descriveremo ogni sezione di questo file.

Sezione Variabili

In una prima fase, dichiariamo le variabili, soprattutto per motivi di leggibilità:

"variables": {
  "version": "0.0.X",
  "HTTP_IP": "fileserver.rockylinux.lan",
  "HTTP_PATH": "/packer/rockylinux/8/ks.cfg"
},

Useremo la variabile version più tardi nel nome del modello che creeremo. È possibile incrementare facilmente questo valore in base alle proprie esigenze.

È inoltre necessario che la macchina virtuale in fase di avvio acceda a un file ks.cfg (Kickstart).

Un file Kickstart contiene le risposte alle domande poste durante il processo di installazione. Questo file passa tutto il suo contenuto ad Anaconda (il processo di installazione), il che permette di automatizzare completamente la creazione del modello.

All'autore piace memorizzare il suo file ks.cfg in un server web interno accessibile dal suo modello, ma esistono altre possibilità che potresti invece scegliere di usare.

For example, the ks.cfg file is accessible from the VM at this url in our lab: http://fileserver.rockylinux.lan/packer/rockylinux/8/ks.cfg. Avrete bisogno di impostare qualcosa di simile per usare questo metodo.

Dato che vogliamo mantenere la nostra password privata, è dichiarata come una variabile sensibile. Esempio:

  "sensitive-variables": ["vcenter_password"],

Sezione Provisioners

La prossima parte è interessante, e sarà coperta più tardi fornendovi lo script per requirements.sh:

"provisioners": [
  {
    "type": "shell",
    "expect_disconnect": true,
    "execute_command": "bash '{{.Path}}'",
    "script": "{{template_dir}}/scripts/requirements.sh"
  }
],

Al termine dell'installazione, la VM si riavvierà. Non appena Packer rileva un indirizzo IP (grazie ai VMware Tools), copierà il requirements.sh e lo eseguirà. È una bella funzione per pulire la VM dopo il processo di installazione (rimuovere le chiavi SSH, pulire la cronologia, ecc.) e installare qualche pacchetto extra.

La sezione dei builders

Potete dichiarare uno o più builders per puntare a qualcosa di diverso dal vostro ambiente vSphere (forse un template Vagrant).

Ma qui stiamo usando il builder vsphere-iso:

"builders": [
  {
    "type": "vsphere-iso",

Questo builder ci permette di configurare l'hardware di cui abbiamo bisogno:

  "CPUs": 2,
  "CPU_hot_plug": true,
  "RAM": 2048,
  "RAM_hot_plug": true,
  "disk_controller_type": "pvscsi",
  "guest_os_type": "centos8_64Guest",
  "network_adapters": [
    {
      "network_card": "vmxnet3",
      "network": "net_infra"
    }
  ],
  "storage": [
    {
      "disk_size": 40000,
      "disk_thin_provisioned": true
    }
  ],

Alla fine del processo, la VM deve essere fermata. Note "Nota"

Non dimenticherete mai più di includere CPU_hot_plug perché ora è automatico!

Successivamente, ci occupiamo della configurazione di vSphere. Se si desidera effettuare altre regolazioni, consultare la documentazione.

Per iniziare l'installazione, avete bisogno di un'immagine ISO di Rocky Linux. Ecco un esempio di come utilizzare un'immagine situata in una libreria di contenuti vSphere. Naturalmente è possibile memorizzare la ISO altrove, ma nel caso di una libreria di contenuti vSphere, è necessario ottenere il percorso completo del file ISO sul server che ospita la libreria di contenuti (in questo caso è un Synology, quindi direttamente sul DSM explorer).

  "iso_paths": [
    "[datasyno-contentlibrary-mylib] contentlib-a86ad29a-a43b-4717-97e6-593b8358801b/3a381c78-b9df-45a6-82e1-3c07c8187dbe/Rocky-8.4-x86_64-minimal_72cc0cc6-9d0f-4c68-9bcd-06385a506a5d.iso"
  ],

Poi devi fornire il comando completo da inserire durante il processo di installazione: configurazione dell'IP e trasmissione del percorso del file di risposta Kickstart.

Note

Questo esempio prende il caso più complesso: usare un IP statico. Se avete un server DHCP disponibile, il processo sarà molto più facile.

Questa è la parte più divertente della procedura: Sono sicuro che andrete ad ammirare la console VMware durante la generazione, solo per vedere l'inserimento automatico dei comandi durante l'avvio.

"boot_command": [
"<up><tab> text ip=192.168.1.11::192.168.1.254:255.255.255.0:template:ens192:none nameserver=192.168.1.254 inst.ks=http://{{ user `HTTP_IP` }}/{{ user `HTTP_PATH` }}<enter><wait><enter>"
],

Alla fine del processo, la VM deve essere fermata. Si può usare l'utente root o un altro utente con diritti sudo, ma in ogni caso questo utente deve corrispondere all'utente definito nel file ks.cfg.

"ssh_password": "mysecurepassword",
"ssh_username": "root",

Successivamente, ci occupiamo della configurazione di vSphere. Le uniche cose degne di nota qui sono l'uso delle variabili definite all'inizio del documento nella nostra home directory, così come l'opzione insecure_connection, perché il nostro vSphere usa un certificato autofirmato (vedi nota in Presupposti all'inizio di questo documento):

"shutdown_command": "/sbin/halt -h -p",

Successivamente, ci occupiamo della configurazione di vSphere. Le uniche cose degne di nota qui sono l'uso delle variabili definite all'inizio del documento nella nostra home directory, così come l'opzione insecure_connection, perché il nostro vSphere usa un certificato autofirmato (vedi nota in Presupposti all'inizio di questo documento):

"insecure_connection": "true",
"username": "{{ user `vcenter_username` }}",
"password": "{{ user `vcenter_password` }}",
"vcenter_server": "vsphere.rockylinux.lan",
"datacenter": "DC_NAME",
"datastore": "DS_NAME",
"vm_name": "template-rockylinux8-{{ user `version` }}",
"folder": "Templates/RockyLinux",
"cluster": "CLUSTER_NAME",
"host": "esx1.rockylinux.lan",
"notes": "Template RockyLinux version {{ user `version` }}"

E infine, chiederemo a vSphere di convertire la nostra VM arrestata in un template.

A questo punto, si potrebbe anche scegliere di utilizzare la VM così com'è (senza convertirla in un modello). In questo caso, si può decidere di fare un'istantanea:

"convert_to_template": true,
"create_snapshot": false,

Il file ks.cfg

Come già detto, è necessario fornire un file di risposta di Kicstart che verrà utilizzato da Anaconda.

Ecco un esempio di questo file:

# Use CDROM installation media
repo --name="AppStream" --baseurl="http://download.rockylinux.org/pub/rocky/8.4/AppStream/x86_64/os/"
cdrom
# Use text install
text
# Don't run the Setup Agent on first boot
firstboot --disabled
eula --agreed
ignoredisk --only-use=sda
# Keyboard layouts
keyboard --vckeymap=us --xlayouts='us'
# System language
lang en_US.UTF-8

# Network information
network --bootproto=static --device=ens192 --gateway=192.168.1.254 --ip=192.168.1.11 --nameserver=192.168.1.254,4.4.4.4 --netmask=255.255.255.0 --onboot=on --ipv6=auto --activate

# Root password
rootpw mysecurepassword

# System services
selinux --permissive
firewall --enabled
services --enabled="NetworkManager,sshd,chronyd"
# System timezone
timezone Europe/Paris --isUtc
# System booloader configuration
bootloader --location=mbr --boot-drive=sda
# Partition clearing information
clearpart --all --initlabel --drives=sda
# Disk partitionning information
part /boot --fstype="xfs" --ondisk=sda --size=512
part pv.01 --fstype="lvmpv" --ondisk=sda --grow
volgroup vg_root --pesize=4096 pv.01
logvol /home --fstype="xfs" --size=5120 --name=lv_home --vgname=vg_root
logvol /var --fstype="xfs" --size=10240 --name=lv_var --vgname=vg_root
logvol / --fstype="xfs" --size=10240 --name=lv_root --vgname=vg_root
logvol swap --fstype="swap" --size=4092 --name=lv_swap --vgname=vg_root

skipx

reboot

%packages --ignoremissing --excludedocs
openssh-clients
curl
dnf-utils
drpm
net-tools
open-vm-tools
perl
perl-File-Temp
sudo
vim
wget
python3

# unnecessary firmware
-aic94xx-firmware
-atmel-firmware
-b43-openfwwf
-bfa-firmware
-ipw2100-firmware
-ipw2200-firmware
-ivtv-firmware
-iwl*-firmware
-libertas-usb8388-firmware
-ql*-firmware
-rt61pci-firmware
-rt73usb-firmware
-xorg-x11-drv-ati-firmware
-zd1211-firmware
-cockpit
-quota
-alsa-*
-fprintd-pam
-intltool
-microcode_ctl
%end

%addon com_redhat_kdump --disable
%end

%post

# Manage Ansible access
groupadd -g 1001 ansible
useradd -m -g 1001 -u 1001 ansible
mkdir /home/ansible/.ssh
echo -e "<---- PAST YOUR PUBKEY HERE ---->" >  /home/ansible/.ssh/authorized_keys
chown -R ansible:ansible /home/ansible/.ssh
chmod 700 /home/ansible/.ssh
chmod 600 /home/ansible/.ssh/authorized_keys
echo "ansible ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers.d/ansible
chmod 440 /etc/sudoers.d/ansible

systemctl enable vmtoolsd
systemctl start vmtoolsd

%end

Poiché si è scelto di usare l'iso minimale, invece del Boot o del DVD, non tutti i pacchetti di installazione richiesti saranno disponibili.

Poiché Packer si basa su VMware Tools per rilevare la fine dell'installazione, e il pacchetto open-vm-tools è disponibile solo nei repo di AppStream, dobbiamo specificare al processo di installazione che vogliamo usare come sorgente sia il cdrom che questo repo remoto:

Nota

Se non hai accesso ai repository esterni, puoi usare un mirror del repository, un proxy squid o il dvd.

# Use CDROM installation media
repo --name="AppStream" --baseurl="http://download.rockylinux.org/pub/rocky/8.4/AppStream/x86_64/os/"
cdrom

Passiamo alla configurazione della rete, poiché ancora una volta, in questo esempio non stiamo usando un server DHCP:

# Network information
network --bootproto=static --device=ens192 --gateway=192.168.1.254 --ip=192.168.1.11 --nameserver=192.168.1.254,4.4.4.4 --netmask=255.255.255.0 --onboot=on --ipv6=auto --activate

Ricorda che abbiamo specificato l'utente con cui connettersi via SSH a Packer alla fine dell'installazione. Dal momento che controlliamo l'ambiente in cui il nostro hardware funzionerà, possiamo rimuovere qualsiasi firmware che sarà inutile per noi:

# Root password
rootpw mysecurepassword

La parte successiva aggiunge alcuni utenti. Warning "Attenzione"

Puoi usare una password insicura qui, a patto che ti assicuri che questa password sarà cambiata immediatamente dopo la distribuzione della tua VM, per esempio con Ansible.

Ecco lo schema di partizionamento selezionato. Si possono fare cose molto più complesse. Potete definire uno schema di partizione che si adatti alle vostre esigenze, adattandolo allo spazio su disco definito in Packer, e che rispetti le regole di sicurezza definite per il vostro ambiente (partizione dedicata a /tmp, ecc.):

# System booloader configuration
bootloader --location=mbr --boot-drive=sda
# Partition clearing information
clearpart --all --initlabel --drives=sda
# Disk partitionning information
part /boot --fstype="xfs" --ondisk=sda --size=512
part pv.01 --fstype="lvmpv" --ondisk=sda --grow
volgroup vg_root --pesize=4096 pv.01
logvol /home --fstype="xfs" --size=5120 --name=lv_home --vgname=vg_root
logvol /var --fstype="xfs" --size=10240 --name=lv_var --vgname=vg_root
logvol / --fstype="xfs" --size=10240 --name=lv_root --vgname=vg_root
logvol swap --fstype="swap" --size=4092 --name=lv_swap --vgname=vg_root

The next section concerns the packages that will be installed. Puoi usare l'utente root o un altro utente con diritti sudo, ma in ogni caso, questo utente deve corrispondere all'utente definito nel tuo file ks.cfg.

Nota

All'autore piace limitare le azioni da fare nel processo di installazione e rimandare l'installazione di ciò che è necessario nello script post installazione di Packer. Quindi, in questo caso, installiamo solo i pacchetti minimi richiesti.

Il pacchetto openssh-clients sembra essere richiesto da Packer per copiare i suoi script nella VM.

Non solo si possono aggiungere pacchetti, ma anche rimuoverli. perl e perl-File-Temp saranno anche richiesti da VMware Tools durante la parte di distribuzione. Questo è un peccato perché richiede un sacco di altri pacchetti dipendenti. python3 (3.6) sarà anche richiesto in futuro perché Ansible funzioni (se non vuoi usare Ansible o python, rimuovili!).

%packages --ignoremissing --excludedocs
openssh-clients
open-vm-tools
python3
perl
perl-File-Temp
curl
dnf-utils
drpm
net-tools
sudo
vim
wget

La parte successiva aggiunge alcuni utenti. Dal momento che controlliamo l'ambiente in cui funzionerà il nostro hardware, possiamo rimuovere qualsiasi firmware che sia inutile per noi:

# unnecessary firmware
-aic94xx-firmware
-atmel-firmware
...

Poiché vSphere ora usa cloud-init tramite i VMware Tools per configurare la rete di una macchina ospite centos8, deve essere installato. Tuttavia, se non fate nulla, la configurazione sarà applicata al primo riavvio e tutto andrà bene. Questo permette a tutte le nostre nuove VM di essere accessibili dal nostro server Ansible per eseguire le azioni post-installazione:

# Manage Ansible access
groupadd -g 1001 ansible
useradd -m -g 1001 -u 1001 ansible
mkdir /home/ansible/.ssh
echo -e "<---- PAST YOUR PUBKEY HERE ---->" >  /home/ansible/.ssh/authorized_keys
chown -R ansible:ansible /home/ansible/.ssh
chmod 700 /home/ansible/.ssh
chmod 600 /home/ansible/.ssh/authorized_keys
echo "ansible ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers.d/ansible
chmod 440 /etc/sudoers.d/ansible

Ora dobbiamo abilitare e avviare vmtoolsd (il processo che gestisce open-vm-tools). vSphere rileverà l'indirizzo IP dopo il riavvio della VM.

systemctl enable vmtoolsd
systemctl start vmtoolsd

Il processo di installazione è finito e la VM si riavvierà.

I provisioners

Ricordate, abbiamo dichiarato in Packer un provisioner, che nel nostro caso corrisponde a uno script .sh, da memorizzare in una sottodirectory accanto al nostro file json.

Ci sono diversi tipi di provisioner, avremmo anche potuto usare Ansible. Siete liberi di esplorare queste possibilità.

Questo file può essere completamente modificato, ma fornisce un esempio di ciò che si può fare con uno script, in questo caso requirements.sh:

#!/bin/sh -eux

echo "Updating the system..."
dnf -y update

echo "Installing cloud-init..."
dnf -y install cloud-init

# see https://bugs.launchpad.net/cloud-init/+bug/1712680
# and https://kb.vmware.com/s/article/71264
# Virtual Machine customized with cloud-init is set to DHCP after reboot
echo "manual_cache_clean: True " > /etc/cloud/cloud.cfg.d/99-manual.cfg

echo "Disable NetworkManager-wait-online.service"
systemctl disable NetworkManager-wait-online.service

# cleanup current SSH keys so templated VMs get fresh key
rm -f /etc/ssh/ssh_host_*

# Avoid ~200 meg firmware package we don't need
# this cannot be done in the KS file so we do it here
echo "Removing extra firmware packages"
dnf -y remove linux-firmware
dnf -y autoremove

echo "Remove previous kernels that preserved for rollbacks"
dnf -y remove -y $(dnf repoquery --installonly --latest-limit=-1 -q)
dnf -y clean all  --enablerepo=\*;

echo "truncate any logs that have built up during the install"
find /var/log -type f -exec truncate --size=0 {} \;

echo "remove the install log"
rm -f /root/anaconda-ks.cfg /root/original-ks.cfg

echo "remove the contents of /tmp and /var/tmp"
rm -rf /tmp/* /var/tmp/*

echo "Force a new random seed to be generated"
rm -f /var/lib/systemd/random-seed

echo "Wipe netplan machine-id (DUID) so machines get unique ID generated on boot"
truncate -s 0 /etc/machine-id

echo "Clear the history so our install commands aren't there"
rm -f /root/.wget-hsts
export HISTSIZE=0

Alcune spiegazioni sono necessarie:

echo "Installing cloud-init..."
dnf -y install cloud-init

# see https://bugs.launchpad.net/cloud-init/+bug/1712680
# and https://kb.vmware.com/s/article/71264
# Virtual Machine customized with cloud-init is set to DHCP after reboot
echo "manual_cache_clean: True" > /etc/cloud/cloud.cfg.d/99-manual.cfg

Poiché vSphere ora usa cloud-init tramite i VMware Tools per configurare la rete di una macchina ospite centos8, deve essere installato. Tuttavia, se non fate nulla, la configurazione sarà applicata al primo riavvio e tutto andrà bene. Ma al prossimo riavvio, cloud-init non riceverà alcuna nuova informazione da vSphere. In questi casi, senza informazioni su cosa fare, cloud-init riconfigurerà l'interfaccia di rete della VM per usare DHCP, e si perderà la configurazione statica.

Si può andare rapidamente su vSphere e ammirare il lavoro.

Per questo, creiamo un file /etc/cloud/cloud.cfg.d/99-manual.cfg con la direttiva manual_cache_clean: True.

Nota

Questo implica che se avete bisogno di riapplicare una configurazione di rete tramite le personalizzazioni del guest vSphere (il che, nell'uso normale, dovrebbe essere abbastanza raro), dovrete cancellare voi stessi la cache di cloud-init.

Il resto dello script è commentato e non richiede ulteriori dettagli

Per questo, useremo un semplice playbook Ansible, che utilizza il modulo vmware_guest.

Creazione di Template

Questo playbook che vi forniamo, deve essere adattato alle vostre esigenze e al vostro modo di fare le cose.

È sufficiente inserire questo comando alla riga di comando:

./packer build -var-file=~/.vsphere-secrets.json rockylinux8/template.json

È possibile passare rapidamente a vSphere e ammirare il lavoro svolto.

Alla fine della creazione, troverete il vostro modello pronto all'uso in vSphere.

Come abbiamo visto, ci sono ora soluzioni DevOps completamente automatizzate per creare e distribuire le VM.

Parte della distribuzione

Per questo, useremo un semplice playbook Ansible, che utilizza il modulo vmware_guest.

Per un progetto dettagliato che copre anche l'implementazione di Rocky Linux e altri sistemi operativi utilizzando le ultime novità di vSphere, Packer e il Packer Plugin per vSphere, visitate questo progetto.

Questo playbook che vi forniamo, deve essere adattato alle vostre esigenze e al vostro modo di fare le cose.

---
- name: Deploy VM from template
  hosts: localhost
  gather_facts: no
  vars_files:
    - ./vars/credentials.yml

  tasks:

  - name: Clone the template
    vmware_guest:
      hostname: "{{ vmware_vcenter_hostname }}"
      username: "{{ vmware_username }}"
      password: "{{ vmware_password }}"
      validate_certs: False
      name: "{{ vm_name }}"
      template: "{{ template_name }}"
      datacenter: "{{ datacenter_name }}"
      folder: "{{ storage_folder }}"
      state: "{{ state }}"
      cluster: "{{ cluster_name | default(omit,true) }}"
      esxi_hostname: "{{ esxi_hostname | default(omit,true) }}"
      wait_for_ip_address: no
      annotation: "{{ comments | default('Deployed by Ansible') }}"
      datastore: "{{ datastore_name | default(omit,true) }}"
      networks:
      - name: "{{ network_name }}"
        ip: "{{ network_ip }}"
        netmask: "{{ network_mask }}"
        gateway: "{{ network_gateway }}"
        device_type: "vmxnet3"
        type: static
      hardware:
        memory_mb: "{{ memory_mb|int * 1024 }}"
        num_cpu: "{{ num_cpu }}"
        hotadd_cpu: True
        hotadd_memory: True
      customization:
        domain: "{{ domain }}"
        dns_servers: "{{ dns_servers.split(',') }}"
      guest_id: "{{ guest_id }}"
    register: deploy_vm

Potete memorizzare i dati sensibili nel file ./vars/credentials.yml, che ovviamente avrete precedentemente criptato con ansible-vault (specialmente se usate git per il vostro lavoro). Poiché tutto utilizza una variabile, si può facilmente adattarlo alle proprie esigenze.

Se non usi qualcosa come Rundeck o Awx, puoi lanciare la distribuzione con una linea di comando simile a questa:

ansible-playbook -i ./inventory/hosts  -e '{"comments":"my comments","cluster_name":"CS_NAME","esxi_hostname":"ESX_NAME","state":"started","storage_folder":"PROD","datacenter_name":"DC_NAME}","datastore_name":"DS_NAME","template_name":"template-rockylinux8-0.0.1","vm_name":"test_vm","network_name":"net_prod","network_ip":"192.168.1.20","network_gateway":"192.168.1.254","network_mask":"255.255.255.0","memory_mb":"4","num_cpu":"2","domain":"rockylinux.lan","dns_servers":"192.168.1.254","guest_id":"centos8_64Guest"}' ./vmware/create_vm.yml --vault-password-file /etc/ansible/vault_pass.py

È a questo punto che potete lanciare la configurazione finale della vostra macchina virtuale utilizzando Ansible. Non dimenticate di cambiare la password di root, proteggere SSH, registrare la nuova VM nel vostro strumento di monitoraggio e nell'inventario IT, ecc.

In sintesi

Come abbiamo visto, ci sono ora soluzioni DevOps completamente automatizzate per creare e distribuire le VM.

Allo stesso tempo, questo rappresenta un innegabile risparmio di tempo, soprattutto in ambienti cloud o data center. Facilita anche una conformità standard in tutti i computer dell'azienda (server e stazioni di lavoro), e una facile manutenzione / evoluzione dei modelli.

Altri riferimenti

Per un progetto dettagliato che copre anche l'implementazione di Rocky Linux e altri sistemi operativi utilizzando le ultime novità di vSphere, Packer e il Packer Plugin per vSphere, visitate questo progetto.


Ultimo aggiornamento: 10 novembre 2022

Author: Antoine Le Morvan

Contributors: Steven Spencer, Ryan Johnson, Pedro Garcia, Franco Colussi