Sincronizzare gli elementi OCI da Artifact Registry

Questa pagina mostra come creare e pubblicare l'immagine in un repository in Artifact Registry con crane e oras.

Puoi configurare Config Sync per la sincronizzazione dalle immagini OCI utilizzando Artifact Registry. Per utilizzare questa funzionalità, devi abilitare le API RootSync e RepoSync.

Informazioni su Artifact Registry

Artifact Registry è un servizio completamente gestito che supporta sia le immagini container sia gli artefatti non container. Ti consigliamo Artifact Registry per l'archiviazione e la gestione delle immagini container su Google Cloud. Esistono molti strumenti disponibili per eseguire il push degli artefatti in Artifact Registry. Ad esempio, puoi eseguire il push di un'immagine Docker, eseguire il push di un grafico Helm o utilizzare la libreria go-containerregistry per lavorare con i container registry. Scegli lo strumento più adatto alle tue esigenze.

Prima di iniziare

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  4. To initialize the gcloud CLI, run the following command:

    gcloud init
  5. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the GKE Enterprise, Config Sync, Artifact Registry APIs:

    gcloud services enable anthos.googleapis.com  anthosconfigmanagement.googleapis.com  artifactregistry.googleapis.com
  8. Install the Google Cloud CLI.

  9. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  10. To initialize the gcloud CLI, run the following command:

    gcloud init
  11. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Make sure that billing is enabled for your Google Cloud project.

  13. Enable the GKE Enterprise, Config Sync, Artifact Registry APIs:

    gcloud services enable anthos.googleapis.com  anthosconfigmanagement.googleapis.com  artifactregistry.googleapis.com
  14. Crea o accedi a un cluster che soddisfi i requisiti per Config Sync e che utilizzi l'ultima versione di Config Sync.
  15. Installa la CLI nomos o esegui l'upgrade all'ultima versione.
  16. (Facoltativo) Se vuoi utilizzare Cosign per verificare le firme delle immagini OCI, installa quanto segue:
    • Cosign per firmare le immagini OCI.
    • OpenSSL per generare le credenziali per il server webhook.
    • Docker per creare ed eseguire il push dell'immagine del server webhook di ammissione.

    Costi

    In questo documento, utilizzi i seguenti componenti fatturabili di Google Cloud:

    Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

    I nuovi Google Cloud utenti potrebbero avere diritto a una prova gratuita.

    Crea un repository Artifact Registry

    In questa sezione, creerai un repository Artifact Registry. Per scoprire di più sulla creazione di repository Artifact Registry, consulta Creare repository.

    1. Crea un repository Artifact Registry:

      gcloud artifacts repositories create AR_REPO_NAME \
         --repository-format=docker \
         --location=AR_REGION \
         --description="Config Sync Helm repo" \
         --project=PROJECT_ID
      

    Sostituisci quanto segue:

    • PROJECT_ID: l'ID progetto dell'organizzazione.
    • AR_REPO_NAME: l'ID del repository.
    • AR_REGION: la posizione regionale o multiregionale del repository.

    Variabili utilizzate nelle seguenti sezioni:

    • FLEET_HOST_PROJECT_ID: se utilizzi Workload Identity Federation for GKE, questo valore è uguale a PROJECT_ID. Se utilizzi la federazione delle identità per i carichi di lavoro del parco risorse per GKE, questo è l'ID progetto del parco risorse a cui è registrato il cluster.
    • GSA_NAME: il nome dell'account di servizio Google personalizzato che vuoi utilizzare per connetterti ad Artifact Registry.
    • KSA_NAME: il account di servizio Kubernetes per il reconciler.
      • Per i repository root, se il nome di RootSync è root-sync, aggiungi root-reconciler. In caso contrario, aggiungi root-reconciler-ROOT_SYNC_NAME.
      • Per i repository dello spazio dei nomi, se il nome RepoSync è repo-sync, aggiungi ns-reconciler-NAMESPACE. In caso contrario, aggiungi ns-reconciler-NAMESPACE-REPO_SYNC_NAME-REPO_SYNC_NAME_LENGTH dove REPO_SYNC_NAME_LENGTH è il numero di caratteri in REPO_SYNC_NAME.

    Concedere l'autorizzazione di lettura

    Utilizza un account di servizio Kubernetes per l'autenticazione ad Artifact Registry completando i seguenti passaggi:

    Concedi il ruolo IAM Lettore Artifact Registry (roles/artifactregistry.reader) all'account di servizio Kubernetes che dispone del pool di federazione delle identità dei carichi di lavoro per GKE:

    gcloud artifacts repositories add-iam-policy-binding AR_REPO_NAME \
       --location=AR_REGION \
       --member="serviceAccount:FLEET_HOST_PROJECT_ID.svc.id.goog[config-management-system/KSA_NAME]" \
       --role=roles/artifactregistry.reader \
       --project=PROJECT_ID
    

    Esegui il push di un'immagine nel repository Artifact Registry

    In questa sezione, crei un'immagine OCI ed esegui il push su Artifact Registry.

    1. Crea un file manifest Namespace:

      cat <<EOF> test-namespace.yaml
      apiVersion: v1
      kind: Namespace
      metadata:
        name: test
      EOF
      
    2. Accedi ad Artifact Registry:

      gcloud auth configure-docker AR_REGION-docker.pkg.dev
      
    3. Pacchettizza ed esegui il push dell'immagine in Artifact Registry:

      crane

      I comandi in questa sezione utilizzano crane per interagire con immagini e registri remoti.

      1. Comprimi il file:

        tar -cf test-namespace.tar test-namespace.yaml
        
      2. Installa lo strumento crane.

      3. Esegui il push dell'immagine in Artifact Registry:

        crane append -f test-namespace.tar -t AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1
        

      oras

      I comandi in questa sezione utilizzano oras per interagire con immagini e registri remoti.

      1. Comprimi il file:

        tar -czf test-namespace.tar.gz test-namespace.yaml
        
      2. Installa lo strumento oras.

      3. Esegui il push dell'immagine in Artifact Registry:

        oras push AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1 test-namespace.tar.gz
        

    Configurare Config Sync per la sincronizzazione dall'immagine

    In questa sezione, creerai un oggetto RootSync e configurerai Config Sync per la sincronizzazione dall'immagine OCI.

    1. Crea un oggetto RootSync con un nome univoco:

      cat <<EOF>> ROOT_SYNC_NAME.yaml
      apiVersion: configsync.gke.io/v1beta1
      kind: RootSync
      metadata:
        name: ROOT_SYNC_NAME
        namespace: config-management-system
      spec:
        sourceFormat: unstructured
        sourceType: oci
        oci:
          image: AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1
          dir: .
          auth: k8sserviceaccount
      EOF
      

      Sostituisci ROOT_SYNC_NAME con il nome dell'oggetto RootSync. Il nome deve essere univoco nel cluster e non deve contenere più di 26 caratteri. Per l'elenco completo delle opzioni durante la configurazione degli oggetti RootSync, vedi Campi RootSync e RepoSync.

    2. Applica l'oggetto RootSync:

      kubectl apply -f ROOT_SYNC_NAME.yaml
      
    3. Verifica che Config Sync stia sincronizzando dall'immagine:

      nomos status --contexts=$(kubectl config current-context)
      

      Dovresti vedere un output simile al seguente esempio:

      Connecting to clusters...
      
      *publish-config-registry
         --------------------
         <root>:root-sync-test   AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1   
         SYNCED                  05e6a6b77de7a62286387cfea833d45290105fe84383224938d7b3ab151a55a1
         Managed resources:
            NAMESPACE   NAME             STATUS    SOURCEHASH
                        namespace/test   Current   05e6a6b
      

      Ora hai sincronizzato correttamente un'immagine con il tuo cluster.

    (Facoltativo) Verifica le firme dell'origine OCI

    A partire dalla versione 1.20.0, Config Sync supporta la verifica dell'autenticità delle immagini di origine OCI prima che le configurazioni vengano applicate ai cluster. Questo metodo utilizza un oggetto ValidatingWebhookConfiguration e un server webhook di convalida per intercettare le richieste di aggiornamento per gli oggetti RootSync e RepoSync. Config Sync aggiorna l'annotazione configsync.gke.io/image-to-sync degli oggetti RootSync e RepoSync dopo aver recuperato correttamente un nuovo digest dell'immagine. Il server webhook di convalida confronta i valori tra la vecchia annotazione e la nuova ed esegue la convalida con uno strumento di convalida come Cosign quando viene rilevata una modifica.

    Configurare un server di verifica della firma

    Per garantire l'autenticità delle origini OCI, è necessario un server HTTP per verificare le firme. Puoi utilizzare gli esempi nel repository di esempi di Config Sync o utilizzare la tua immagine Docker.

    1. Se vuoi utilizzare il campione fornito, completa i seguenti passaggi:

      1. Clona il repository di esempio:

        git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples/
        
      2. Passa alla directory che contiene gli esempi del server di verifica della firma:

        cd anthos-config-management-samples/tree/main/pre-sync/oci-image-verification
        
    2. Per creare un'immagine Docker per il server di verifica della firma ed eseguirne il push in un registro delle immagini, esegui questo comando:

      docker build -t SIGNATURE_VERIFICATION_SERVER_IMAGE_URL:latest . && docker push SIGNATURE_VERIFICATION_SERVER_IMAGE_URL:latest
      

      Sostituisci SIGNATURE_VERIFICATION_SERVER_IMAGE_URL con l'URL dell'immagine del server di verifica della firma.

    Autenticarsi ai servizi

    Per configurare il server di verifica della firma, devi autenticarti in Artifact Registry, nel client Cosign e nel server webhook.

    1. Creare uno spazio dei nomi:

      kubectl create ns signature-verification
      
    2. Per eseguire l'autenticazione ad Artifact Registry con un ServiceAccount Kubernetes, completa i seguenti passaggi:

      1. Crea un ServiceAccount Kubernetes nello spazio dei nomi che hai creato:

        kubectl create sa signature-verification-sa -n signature-verification
        
      2. Aggiungi il binding della policy IAM per il ruolo Artifact Registry Reader (roles/artifactregistry.reader):

        gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \
           --location=REPOSITORY_LOCATION \
           --member="serviceAccount:PROJECT_ID.svc.id.goog[signature-verification/signature-verification-sa]" \
           --role=roles/artifactregistry.reader \
           --project=PROJECT_ID
        

        Sostituisci quanto segue:

        • REPOSITORY_NAME: il nome del repository Artifact Registry in cui memorizzi le immagini OCI.
        • REPOSITORY_LOCATION: la posizione del repository Artifact Registry.
    3. Per eseguire l'autenticazione al client Cosign:

      1. Genera una coppia di chiavi Cosign. Questo comando genera una chiave pubblica e una chiave privata:

        cosign generate-key-pair
        
      2. Archivia la chiave pubblica in un secret Kubernetes nello spazio dei nomi che hai creato:

        kubectl create secret generic cosign-key --from-file=cosign.pub -n signature-verification
        
    4. Per autenticare il server di verifica della firma, completa i seguenti passaggi:

      1. Per criptare la comunicazione all'interno del server di verifica della firma, genera un certificato TLS e una chiave privata con OpenSSL:

        openssl req -nodes -x509 -sha256 -newkey rsa:4096 \
        -keyout tls.key \
        -out tls.crt \
        -days 356 \
        -subj "/CN=signature-verification-service.signature-verification.svc"  \
        -addext "subjectAltName = DNS:signature-verification-service,DNS:signature-verification-service.signature-verification.svc,DNS:signature-verification-service.signature-verification"
        
      2. Archivia le credenziali che hai generato in un secret Kubernetes:

        kubectl create secret tls webhook-tls --cert=tls.crt --key=tls.key -n signature-verification
        
      3. Recupera i contenuti codificati in base64 di tls.cert. Questo è necessario per la configurazione del webhook di convalida che crei nella sezione successiva:

        cat tls.crt | base64 -w 0.
        

    Esegui il deployment del webhook di ammissione

    Puoi utilizzare gli esempi seguenti per creare un deployment per il server di verifica della firma e una configurazione webhook di convalida.

    1. Crea un deployment per il server di verifica della firma salvando il seguente file:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: signature-verification-server
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: signature-verification-server
        template:
          metadata:
            labels:
              app: signature-verification-server
          spec:
            serviceAccountName: signature-verification-sa
            containers:
            - name: signature-verification-server
              command:
              - /signature-verification-server
              image: SIGNATURE_VERIFICATION_SERVER_IMAGE_URL
              imagePullPolicy: Always
              ports:
              - containerPort: 10250
              volumeMounts:
              - name: tls-certs
                mountPath: "/tls"
              - name: cosign-key
                mountPath: "/cosign-key"
            volumes:
            - name: cosign-key
              secret:
                secretName: cosign-key
            - name: tls-certs
              secret:
                secretName: webhook-tls
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: signature-verification-service
      spec:
        ports:
        - port: 10250
          targetPort: 10250
        selector:
          app: signature-verification-server

      Sostituisci SIGNATURE_VERIFICATION_SERVER_IMAGE_URL con l'URL completo dell'immagine del server di verifica della firma.

    2. Applica il deployment al cluster:

      kubectl apply -f signature-verification-deployment.yaml -n signature-verification
      
    3. Crea una configurazione webhook di convalida salvando il seguente file:

      apiVersion: admissionregistration.k8s.io/v1
      kind: ValidatingWebhookConfiguration
      metadata:
        name: image-verification-webhook
      webhooks:
      - name: imageverification.webhook.com
        clientConfig:
          service:
            name: signature-verification-service
            namespace: signature-verification
            path: "/validate"
            port: 10250
          caBundle: CA_BUNDLE
        rules:
        - apiGroups:
          - configsync.gke.io
          apiVersions:
          - v1beta1
          - v1alpha1
          operations:
          - UPDATE
          resources:
          - 'rootsyncs'
          - 'reposyncs'
          scope: '*'
        admissionReviewVersions: ["v1", "v1beta1"]
        sideEffects: None

      Sostituisci CA_BUNDLE con i contenuti codificati in base64 di tls.cert.

    4. Applica la configurazione del webhook di convalida al cluster:

      kubectl apply -f signature-verification-validatingwebhookconfiguration.yaml
      

    Controllare i log per individuare errori di verifica delle immagini

    Una volta configurato il server di verifica delle immagini, tutti i tentativi di sincronizzazione da immagini OCI non firmate dovrebbero non andare a buon fine.

    Per verificare la presenza di errori di verifica della firma, visualizza i log del server di verifica della firma eseguendo i seguenti comandi:

    1. Controlla i log di kubectl:

      kubectl logs deployment  signature-verification-server -n  signature-verification
      

      Gli errori di kubectl relativi alla verifica della firma sono simili ai seguenti:

      main.go:69: error during command execution: no signatures found
      
    2. Controlla i log di Config Sync:

      nomos status
      

      Gli errori di Config Sync relativi alla verifica della firma sono simili ai seguenti:

      Error:   KNV2002: admission webhook "imageverification.webhook.com" denied the request: Image validation failed: cosign verification failed: exit status 10, output: Error: no signatures found
      

    Se non ricevi errori, puoi verificare che l'immagine firmata sia l'oggetto sincronizzato esaminando la configurazione di RootSync o RepoSync:

    RootSync

     kubectl get rootsync ROOTSYNC_NAME -n config-management-system -oyaml
    

    Sostituisci ROOTSYNC_NAME con il nome del tuo RootSync.

    RepoSync

     kubectl get reposync REPOSYNC_NAME -n REPOSYNC_NAMESPACE -oyaml
    

    Sostituisci quanto segue:

    • REPOSYNC_NAME: il nome del tuo RepoSync.
    • REPOSYNC_NAMESPACE: il nome dello spazio dei nomi associato al tuo RepoSync.

    Dovresti vedere l'annotazione configsync.gke.io/image-to-sync aggiunta all'oggetto RootSync o RepoSync. L'annotazione contiene l'URL dell'immagine OCI di origine e l'ultimo digest recuperato da Config Sync.

    Passaggi successivi