Ansible e le arti precontenitoriali

Prima che la containerizzazione rendesse così semplice la preparazione di immagini per la virtualizzazione, era un’arte preparare immagini ISO personalizzate per l’avvio da CD. In seguito queste immagini sono state utilizzate per avviare le macchine virtuali. In altre parole, le immagini ISO erano i precursori delle immagini dei container.

È così che ho avuto un paio di sfortunati incontri con il client Docker di Windows. Anche quando non era in esecuzione alcun container, il gestore della memoria di Windows gli passava tutta la memoria possibile rallentando qualsiasi cosa io stessi facendo. Ho quindi bandito il client Docker di Windows dal mio computer.

Non fraintendetemi. Non odio Docker, ma solo il suo client Windows.

Questo passo mi ha costretto a tornare indietro nel tempo. Ho iniziato a eseguire macchine virtuali direttamente su Hyper-V, l’hypervisor di Windows. Formare cluster Kubernetes su Windows divenne allora un felice hobby per me come si può vedere dai miei post passati pubblicati qui su DZone.

Shoemaker, Why Do You Go Barefoot?

Dopo aver seguito per molte ore gli stessi clic del mouse per creare macchine virtuali su Hyper-V Manager, mi sono reso conto che sono come un calzolaio che va a piedi nudi: costruisco una pipeline DevOps per una tariffa oraria, ma perdo tempo con i clic del mouse?

Sfida accettata. Ho letto su duckduckgo che è possibile creare macchine virtuali utilizzando PowerShell. Non ci è voluta una settimana per avere uno script che crea una nuova macchina virtuale come si può vedere qui. Uno script gemello può avviare una macchina virtuale spenta.

Una vecchia arte riscoperta

Questo era fantastico, ma mi sono reso conto che continuavo a fare clic con il mouse quando installavo Ubuntu. Automatizzare questa operazione sembrava una cosa più difficile da fare. Bisogna decomprimere un’immagine ISO, manipolarla in un modo o nell’altro e poi impacchettarla di nuovo avendo cura di lasciare intatte le istruzioni per l’avvio del computer.

Per fortuna, ho trovato un’eccellente guida su come fare proprio questo. Il processo consiste in tre fasi:

  1. Strappare l’immagine di avvio ISO di Ubuntu.
  2. Manipolare il contenuto:
      Spostare il master boot record (MBR) fuori.
      Specificare ciò che gli utenti fanno normalmente sulla GUI e personalizzare ciò che viene installato ed eseguito durante l’installazione. Questo viene fatto utilizzando un sottoinsieme del linguaggio Cloud-init di Ubuntu. Vedere qui per le istruzioni che ho creato.

    1. Istruire al bootloader (Grub, in questo caso) dove trovare le istruzioni di avvio personalizzate e non aspettare l’input dell’utente. Ecco la configurazione di Grub che ho scelto.
  3. Impacchettate il tutto usando un’applicazione chiamata Xorriso.

Per i maghi di questo antico mestiere, Xorriso funge da bacchetta magica. Ha pagine di documentazione in qualcosa che assomiglia a un libro di incantesimi. Dovrò sporcarmi le mani per capirlo appieno, ma la mia comprensione attuale (e molto probabilmente errata) è che crea partizioni di avvio, carica l’MBR copiato e fa qualcosa con le istruzioni simili a Cloud-init per creare un’immagine ISO modificata.

Ansible for the Finishing Touches

Anche se è stato con grande soddisfazione che sono riuscito ad avviare Ubuntu22 da PowerShell senza ulteriori input da parte mia, cosa succederà la prossima volta che Ubuntu presenterà una nuova versione? Il vero DevOps richiede di documentare il processo non in ASCII, ma in uno script pronto per essere eseguito quando necessario. Ansible dimostra la sua versatilità: sono riuscito a fare proprio questo in un pomeriggio. Il segreto è indicare ad Ansible che si tratta di un’azione locale. In altre parole, non si usa SSH per puntare a una macchina per ricevere istruzioni, ma il controllore di Ansible è anche lo studente:

YAML

 

- hosts: localhost
  connection: local

La rappresentazione completa è riportata di seguito e fornisce un’altra visione di quanto spiegato sopra:

YAML

 

# stamp_images.yml

- hosts: localhost
  connection: local
  become: true
  vars_prompt:
    - name: "base_iso_location"
      prompt: "Enter the path to the base image"
      private: no
      default: /tmp/ubuntu-22.04.4-live-server-amd64.iso

  tasks:
    - name: Install 7Zip
      ansible.builtin.apt:
        name: p7zip-full
        state: present

    - name: Install Xorriso
      ansible.builtin.apt:
        name: xorriso
        state: present

    - name: Unpack ISO
      ansible.builtin.command: 
        cmd: "7z -y x {{ base_iso_location }} -o/tmp/source-files"

    - name: Copy boot partitions
      ansible.builtin.copy:
        src: /tmp/source-files/[BOOT]/
        dest: /tmp/BOOT
  
    - name: Delete working boot partitions
      ansible.builtin.file:
        path:  /tmp/source-files/[BOOT]
        state: absent
  
    - name: Copy files for Ubuntu Bare
      ansible.builtin.copy:
        src: bare/source-files/bare_ubuntu
        dest: /tmp/source-files/

    - name: Copy boot config for Ubuntu bare
      ansible.builtin.copy:
        src: bare/source-files/boot/grub/grub.cfg
        dest: /tmp/source-files/boot/grub/grub.cfg

    - name: Stamp bare image
      ansible.builtin.command: 
        cmd: xorriso -as mkisofs -r   -V 'Ubuntu 22.04 LTS AUTO (EFIBIOS)'   -o ../ubuntu-22.04-wormhole-autoinstall-bare_V5_1.iso   --grub2-mbr ../BOOT/1-Boot-NoEmul.img -partition_offset 16   --mbr-force-bootable   -append_partition 2 28732ac11ff8d211ba4b00a0c93ec93b ../BOOT/2-Boot-NoEmul.img   -appended_part_as_gpt   -iso_mbr_part_type a2a0d0ebe5b9334487c068b6b72699c7   -c '/boot.catalog'   -b '/boot/grub/i386-pc/eltorito.img'     -no-emul-boot -boot-load-size 4 -boot-info-table --grub2-boot-info   -eltorito-alt-boot   -e '--interval:appended_partition_2:::'   -no-emul-boot .
        chdir: /tmp/source-files

    - name: Copy files for Ubuntu Atomika
      ansible.builtin.copy:
        src: atomika/source-files/atomika_ubuntu
        dest: /tmp/source-files/

    - name: Copy boot config for Ubuntu Atomika
      ansible.builtin.copy:
        src: atomika/source-files/boot/grub/grub.cfg
        dest: /tmp/source-files/boot/grub/grub.cfg

    - name: Stamp Atomika image
      ansible.builtin.command:
        cmd: xorriso -as mkisofs -r   -V 'Ubuntu 22.04 LTS AUTO (EFIBIOS)'   -o ../ubuntu-22.04-wormhole-autoinstall-atomika_V5_1.iso   --grub2-mbr ../BOOT/1-Boot-NoEmul.img -partition_offset 16   --mbr-force-bootable -append_partition 2 28732ac11ff8d211ba4b00a0c93ec93b ../BOOT/2-Boot-NoEmul.img   -appended_part_as_gpt   -iso_mbr_part_type a2a0d0ebe5b9334487c068b6b72699c7   -c '/boot.catalog'   -b '/boot/grub/i386-pc/eltorito.img'     -no-emul-boot -boot-load-size 4 -boot-info-table --grub2-boot-info   -eltorito-alt-boot   -e '--interval:appended_partition_2:::'   -no-emul-boot .
        chdir: /tmp/source-files        

Nota la magia del comando Xorriso usato qui per preparare due immagini: una con supporto e una senza supporto per Kubernetes.

L’unica avvertenza è di avere una macchina installata con Ansible da cui eseguire questa rappresentazione. L’output di questa rappresentazione può essere scaricato da qui e preinstallare una versione molto recente di Ansible.

Conclusione

Questo post è andato indietro nel tempo, ma è importante rivedere il punto di partenza per capire perché le cose sono così come sono. Windows e i container, inoltre, non vanno molto d’accordo e ogni indagine sui modi per migliorare le giornate degli sviluppatori dovrebbe essere benvenuta.

Ho fatto riferimento a una parte del codice, ma il progetto completo può essere consultato su GitHub.

Source:
https://dzone.com/articles/ansible-and-the-pre-container-arts