Immagini container multi-architettura per i dispositivi IoT

Questo documento è la prima parte di una serie che illustra la creazione di una pipeline di integrazione continua (CI) automatizzata per la creazione di immagini container multi-architettura su Google Cloud. I concetti spiegati in questo documento si applicano a qualsiasi ambiente cloud.

La serie è composta da questo documento e da un tutorial di accompagnamento. Questo documento spiega la struttura di una pipeline per la creazione di immagini container e ne illustra i passaggi di alto livello. Il tutorial ti guida nella creazione di una pipeline di esempio.

Questa serie è rivolta ai professionisti IT che vogliono semplificare e ottimizzare le pipeline complesse per la creazione di immagini container o estendere queste pipeline per creare immagini multiarchitettura. Si presume che tu abbia familiarità con le tecnologie e i container cloud.

Quando implementi una pipeline CI, snellisci le procedure di creazione degli artefatti. Non è necessario mantenere strumenti e hardware dedicati per creare immagini container per una determinata architettura. Ad esempio, se la tua pipeline attuale viene eseguita su un'architettura x86_64 e produce immagini container solo per quell'architettura, potresti dover gestire strumenti e hardware aggiuntivi se vuoi creare immagini container per altre architetture, come per la famiglia ARM.

Il dominio Internet of Things (IoT) spesso richiede build multi-architettura. Se hai un vasto parco di dispositivi con diversi stack hardware e software del sistema operativo, il processo di creazione, test e gestione delle applicazioni software per un dispositivo specifico diventa una sfida enorme. L'utilizzo di un processo di compilazione multi-architettura consente di semplificare la gestione delle applicazioni IoT.

La sfida della creazione di immagini container multi-architettura

Nella maggior parte delle implementazioni, le immagini container dipendono dall'architettura. Ad esempio, se crei un'immagine container per l'architettura x86_64, non può essere eseguita su un'architettura della famiglia ARM.

Puoi ovviare a questo limite in diversi modi:

  1. Crea le immagini container sulle architetture di destinazione per cui hai bisogno dell'immagine container.
  2. Mantieni strumenti dedicati e un parco risorse hardware. Il tuo parco risorse deve avere almeno un dispositivo per ogni architettura per cui devi creare un'immagine container.
  3. Crea immagini container multi-architettura.

La strategia più adatta a te dipende da vari fattori, tra cui:

  • Complessità pipeline
  • Requisiti di Automation
  • Risorse disponibili per progettare, implementare e gestire l'ambiente per la creazione di immagini container

Ad esempio, se il tuo ambiente di runtime ha accesso limitato a un alimentatore, potresti dover creare le immagini container in un ambiente separato dal tuo ambiente di runtime.

Il seguente diagramma illustra i punti decisionali nella scelta di una strategia praticabile.

Diagramma di flusso per decidere la strategia migliore per la creazione di immagini container multi-architettura.

Crea le immagini container sulle architetture di destinazione

Una strategia è la creazione di ogni immagine container di cui hai bisogno direttamente nell'ambiente di runtime che supporta il container stesso, come mostra il seguente diagramma.

Percorso di creazione dal repository del codice sorgente all'ambiente di runtime.

Per ogni build, segui questi passaggi:

  1. Scarica il codice sorgente dell'immagine container da un repository di codice sorgente su ogni dispositivo nell'ambiente di runtime.
  2. Crea l'immagine container nell'ambiente di runtime.
  3. Archivia l'immagine container nel repository di immagini container che è locale per ogni dispositivo nell'ambiente di runtime.

Il vantaggio di questa strategia è che non hai bisogno di eseguire il provisioning e la manutenzione dell'hardware, oltre a ciò che ti serve per i tuoi ambienti di runtime. Questa strategia presenta anche degli svantaggi. Innanzitutto, devi ripetere il processo di compilazione su ogni istanza hardware nel tuo ambiente di runtime, sprecando risorse. Ad esempio, se esegui il deployment dei carichi di lavoro containerizzati in un ambiente di runtime in cui i dispositivi non hanno accesso a un alimentatore continuo, sprechi tempo ed energia eseguendo le attività di build su tali dispositivi ogni volta che devi eseguire il deployment di una nuova versione di un carico di lavoro. Inoltre, devi mantenere gli strumenti per accedere al codice sorgente di ogni immagine container per creare immagini container nel tuo ambiente di runtime.

Manutenzione di parchi risorse e hardware dedicati

La seconda strategia consiste nel gestire un parco risorse dedicato esclusivamente alle attività che creano immagini dei container. Il seguente diagramma illustra l'architettura di questa strategia.

Percorso di build dal repository del codice sorgente a un ambiente di build dedicato.

Per ogni build, segui questi passaggi:

  1. Scarica il codice sorgente dell'immagine container su un dispositivo nel parco risorse con l'architettura hardware richiesta e le risorse per creare l'immagine container.
  2. Crea l'immagine container.
  3. Archiviare l'immagine container in un repository di immagini container centralizzato.
  4. Scarica l'immagine container su ogni dispositivo nell'ambiente di runtime quando devi eseguire il deployment di una nuova istanza di quell'immagine.

Per questa strategia, esegui il provisioning di almeno un'istanza di ogni architettura hardware per cui devi creare le immagini container. In un ambiente di produzione non banale, potresti avere più di un'istanza per aumentare la tolleranza di errore del tuo ambiente e ridurre i tempi di build se hai più job di build simultanei.

Questa strategia presenta un paio di vantaggi. In primo luogo, puoi eseguire ogni job di build solo una volta e archiviare l'immagine container risultante in un repository di immagini container centralizzato, come Container Registry. Inoltre, puoi eseguire suite di test sui dispositivi nel parco risorse che assomigliano molto alle architetture hardware presenti nei tuoi ambienti di runtime. Lo svantaggio principale di questa strategia è che devi eseguire il provisioning e la manutenzione di un'infrastruttura e di strumenti specifici per eseguire le attività che creano immagini dei container. In genere, ogni attività di creazione non consuma molte risorse o tempo per definizione, quindi questa infrastruttura rimane inattiva per la maggior parte del tempo.

Crea immagini container multi-architettura

In questa terza strategia, utilizzerai una pipeline per uso generico per creare immagini container multi-architettura, come mostra il seguente diagramma.

Percorso di creazione dal repository del codice sorgente alla pipeline multi-architettura per uso generico.

Per ogni build, segui questi passaggi:

  1. Scarica il codice sorgente dell'immagine container.
  2. Crea l'immagine container.
  3. Archiviare l'immagine container in un repository di immagini container centralizzato.
  4. Scarica l'immagine container su ogni dispositivo nell'ambiente di runtime quando devi eseguire il deployment di una nuova istanza di quell'immagine.

Il vantaggio principale di questa strategia è che non hai bisogno di eseguire il provisioning e di gestire hardware o strumenti dedicati. Ad esempio, puoi utilizzare le pipeline e gli strumenti di integrazione continua/deployment continuo (CI/CD) esistenti e gli strumenti per creare immagini container multi-architettura. Puoi anche trarre vantaggio dalle migliori prestazioni di un'architettura hardware per uso generico, come x86_64, rispetto a una a risparmio energetico, come quella della famiglia ARM.

Questa strategia potrebbe anche far parte di un'iniziativa più ampia in cui adotti i principi DevOps. Ad esempio, puoi implementare una pipeline CI/CD per hardware specializzato.

Implementazione di una pipeline per la creazione di immagini container multi-architettura

In questa sezione, descriviamo un'implementazione di riferimento di una pipeline CI/CD che segue la terza strategia, ovvero la creazione di immagini container multi-architettura.

L'implementazione del riferimento include i seguenti componenti:

  • Un repository di codice sorgente per gestire il codice sorgente per le immagini container. Ad esempio, potresti utilizzare Cloud Source Repositories o repository GitHub.
  • Un ambiente di runtime CI/CD per creare immagini container, come Cloud Build.
  • una piattaforma per gestire i container e le immagini container che supportano immagini a più architetture, come Docker.
  • Un registro di immagini dei container come Container Registry. Se vuoi archiviare le immagini container più vicino ai nodi in cui sono necessarie, puoi eseguire un registro di immagini container, ad esempio Docker Registry, direttamente nel tuo ambiente attuale.

Questa architettura di riferimento utilizza Moby BuildKit e QEMU per creare immagini di container Docker con più architetture. In questo caso, Moby BuildKit rileva automaticamente le architetture disponibili tramite l'emulazione hardware QEMU e carica automaticamente i programmi binari appropriati che sono registrati nella funzionalità binfmt_misc del kernel Linux.

Il seguente diagramma illustra lo stack tecnico responsabile di ogni build dell'immagine container a più architetture supportata da questa architettura di riferimento.

Componenti correlati per questa architettura di riferimento multi-architettura.

Poiché questa architettura di riferimento utilizza i file manifest delle immagini Docker, non è necessario fornire un tag immagine container per ogni architettura hardware di destinazione; puoi utilizzare lo stesso tag per più architetture. Ad esempio, se crei la versione 1.0.0 di un'immagine container con più architetture, non è necessario un tag univoco per ogni architettura hardware, come 1.0.0-x86_64 o 1.0.0_ARMv7. Utilizzi lo stesso tag 1.0.0 per tutte le architetture hardware che crei e utilizzi i manifest delle immagini Docker per identificare correttamente ogni immagine container.

L'esempio seguente mostra il manifest dell'immagine per l'immagine ufficiale di Alpine Linux, in cui puoi trovare informazioni sulle architetture supportate da una determinata versione dell'immagine container:

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 528,
         "digest": "sha256:ddba4d27a7ffc3f86dd6c2f92041af252a1f23a8e742c90e6e1297bfa1bc0c45",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 528,
         "digest": "sha256:401f030aa35e86bafd31c6cc292b01659cbde72d77e8c24737bd63283837f02c",
         "platform": {
            "architecture": "arm",
            "os": "linux",
            "variant": "v7"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 528,
         "digest": "sha256:2c26a655f6e38294e859edac46230210bbed3591d6ff57060b8671cda09756d4",
         "platform": {
            "architecture": "arm64",
            "os": "linux"
         }
      }
   ]
}

Quando progetti una pipeline automatizzata per la creazione di immagini container, ti consigliamo di includere suite di test complete che convalidano la conformità ai requisiti di ogni immagine container. Ad esempio, potresti utilizzare strumenti come Chef InSpec, Serverspec e RSpec per eseguire suite di test di conformità sulle tue immagini container come uno dei compiti della pipeline di build.

Ottimizzazione della pipeline per la creazione di immagini container

Dopo aver convalidato e consolidato le pipeline per la creazione di immagini container, ottimizzi le pipeline. Migrazione a Google Cloud: ottimizzazione del tuo ambiente contiene indicazioni sull'ottimizzazione dell'ambiente. Descrive un framework di ottimizzazione che puoi adottare per rendere il tuo ambiente più efficiente rispetto allo stato attuale. Seguendo il framework di ottimizzazione, puoi attraversare diverse iterazioni in cui modifichi lo stato dell'ambiente.

Una delle prime attività di ogni iterazione di ottimizzazione consiste nel definire un insieme di requisiti e obiettivi per l'iterazione. Ad esempio, un requisito potrebbe essere quello di modernizzare i processi di deployment, passando da processi di deployment manuali a quelli containerizzati completamente automatizzati. Per ulteriori informazioni sulla modernizzazione dei processi di deployment, consulta Migrazione a Google Cloud: migrazione dai deployment manuali ai deployment containerizzati.

Passaggi successivi