Soluzione della sfida di promozione delle immagini in ambienti multipli con ArgoCD

Promoting images in multi-environment scenarios with ArgoCD solution

Quando si progetta l’ambiente cloud, è spesso consigliato configurare più account. Sebbene questo approccio offra indipendenza delle risorse, isolamento, migliore sicurezza, accesso e limiti di fatturazione, comporta anche una serie di problemi. Una delle sfide consiste nell’efficiente promozione e tracciamento delle applicazioni tra diversi ambienti.

L’approccio GitOps, insieme a strumenti come ArgoCD e Kustomize, semplifica il tracciamento e la promozione. Tuttavia, spesso si trascura la promozione delle immagini. Molte aziende adottano un registro immagini condiviso, ma presto diventa appesantito da molte versioni inutilizzate.

Questo articolo esplora un recente percorso in cui abbiamo esaminato il problema della promozione delle immagini e la soluzione innovativa adottata, rispettando sempre i principi di GitOps.

Sfida

Recentemente è stata presentata una situazione in cui un’azienda che utilizza il registro ECR condiviso stava considerando la migrazione verso registri ECR separati per ottenere un migliore rapporto costo-efficacia, una migliore governance e una gestione del ciclo di vita semplificata.

Ecco uno sguardo allo stato attuale dell’infrastruttura e dei flussi di lavoro:

Fonte: Immagine dell'autore.
  • Ogni ambiente ha un account AWS dedicato con il proprio cluster e l’installazione di ArgoCD.
  • Kustomize viene utilizzato per gestire differenze di configurazione tra gli ambienti.
├── infra  │   ├── charts/  └── overlays      ├── dev      │   ├── patch-image.yaml      └── production          ├── patch-image.yaml          └── patch-replicas.yaml
  • Jenkins viene utilizzato per creare continuamente nuove immagini nell’ambiente di sviluppo.

Tuttavia, nessuno degli strumenti fornisce nativamente il supporto per la promozione delle immagini tra i registri ECR, il che ha portato all’esplorazione di soluzioni innovative con alcune considerazioni.

Considerazioni:

  • Promozione selettiva: Il panorama delle applicazioni dell’azienda è composto da moduli e team con diversi tempi di rilascio. Pertanto, è necessario supportare la promozione delle immagini solo per i moduli selezionati in ogni rilascio.
  • Archiviazione ottimizzata: Gli ambienti come la produzione hanno solo bisogno di archiviare le versioni delle immagini promosse, riducendo l’ingombro e ottimizzando l’utilizzo delle risorse.
  • Replicazione dei tag e dei digest delle immagini: La replicazione dei tag e dei digest delle immagini tra i registri ECR è fondamentale per la sicurezza e la tracciabilità.

Soluzioni potenziali

Inizialmente sono state proposte due soluzioni potenziali:

  1. Replicazione cross-account di ECR: ECR di AWS supporta nativamente la replicazione delle immagini tra due account. Tuttavia, al momento non esiste un modo per filtrare le immagini da replicare in base a criteri specifici. In alternativa, AWS consiglia un design basato sugli eventi per replicare selettivamente le immagini in base alle convenzioni di denominazione dei tag. Tuttavia, poiché non siamo a conoscenza delle versioni che verranno promosse, richiede un passaggio aggiuntivo di ritaglio prima della promozione.
  2. Jenkins Promotion Pipeline: Un flusso di lavoro di Jenkins che analizza gli overlay di Kustomize per i tag delle immagini e li replica in modo programmatico.

Entrambe le opzioni sono valide, ma introducono un livello aggiuntivo di complessità nel processo di promozione. Inoltre, è necessario assicurarsi che le immagini siano promosse prima che gli overlay di Kustomize vengano aggiornati.

La strategia vincente: Job PreSync di ArgoCD

In questo scenario, il cliente stava già utilizzando ArgoCD per il rilascio continuo delle modifiche dell’applicazione. Pertanto, abbiamo deciso di affidare anche ad ArgoCD la responsabilità di fornire le immagini all’ambiente di destinazione.

ArgoCD supporta hooks che consentono di eseguire script personalizzati prima o dopo un processo di distribuzione o sincronizzazione.

Fonte: Immagine dell'autore.

1. Autorizzazione del repository ECR: Autorizza l’accesso pull cross-account per le immagini Docker

Per consentire ad ArgoCD di estrarre le immagini dal repository di origine ECR, è necessario aggiungere una policy basata sulle risorse al nostro repository.

// cross-account-ecr-read-policy.json{  "Version": "2012-10-17",  "Statement": [    {      "Sid": "AllowPull",      "Effect": "Allow",      "Principal": {        "AWS": "arn:aws:iam::{DESTINATION_ACCOUNT}:root" // Sostituisci con il tuo account di destinazione      },      "Action": [        "ecr:BatchCheckLayerAvailability",        "ecr:BatchGetImage",        "ecr:GetDownloadUrlForLayer"      ]    }  ]}

Applica la policy ai repository ECR:

aws ecr set-repository-policy --repository-name example --policy-text "file://cross-account-ecr-read-policy.json"// Per più repository:aws ecr describe-repositories --query "repositories[].[repositoryName]" | xargs -I {} aws ecr set-repository-policy --repository-name {} --policy-text "file://cross-account-ecr-read-policy.json"

2. Lavoro PreSync Hook: Copia l’immagine tra gli account

  • Utilizziamo Crane per copiare le immagini senza modificarne il tag e il digest.
  • Il lavoro PreSync Hook è archiviato in git insieme ad altri manifesti dell’applicazione e monitorato da ArgoCD. ArgoCD esegue il lavoro prima di sincronizzare le modifiche.
  • L’account di origine è l’account di Sviluppo o DevOps da cui verranno estratte le immagini.
  • L’account di destinazione è l’ambiente di Produzione o target in cui l’immagine deve essere copiata.
// Esempio di template HelmapiVersion: batch/v1kind: Jobmetadata:  generateName: argo-presync-promote-image-  annotations:    argocd.argoproj.io/hook: PreSyncspec:  template:    spec:      volumes:        - name: creds          emptyDir: {}      initContainers:        - name: aws-creds          image: public.ecr.aws/aws-cli/aws-cli          command:            - sh            - -c            - |              aws ecr get-login-password > /creds/ecr          volumeMounts:            - name: creds              mountPath: /creds      containers:        // Per brevità, ho supposto che tutti i valori di Helm siano disponibili nella root.        - name: promote-image          image: gcr.io/go-containerregistry/crane:debug          command:            - sh            - -c            - |              // Accedi a entrambi i registri ECR              cat /creds/ecr | crane auth login {{.Values.sourceAccount}}.dkr.ecr.us-east-1.amazonaws.com -u AWS --password-stdin              cat /creds/ecr | crane auth login {{.Values.destinationAccount}}.dkr.ecr.us-east-1.amazonaws.com -u AWS --password-stdin              // Copia l'immagine dall'account di origine all'account di destinazione              crane copy {{.Values.image | replace .Values.destinationAccount .Values.sourceAccount}} {{.Values.image}}          volumeMounts:            - name: creds              mountPath: /creds      restartPolicy: Never  backoffLimit: 2

Conclusioni

In conclusione, il team è stato in grado di promuovere immagini su richiesta utilizzando il pre-sync hook. Ciò ha reso la promozione in produzione un singolo passaggio di aggiornamento degli overlay di Kustomize.

Mi piacerebbe conoscere altre opzioni che avete adottato. Ad esempio, un approccio alternativo potrebbe essere quello di utilizzare il controllo di ammissione dinamico di Kubernetes per intercettare e scaricare immagini mancanti su richiesta.