OCI-Artefakte aus Artifact Registry synchronisieren

Auf dieser Seite erfahren Sie, wie Sie Ihr Image mit crane und oras erstellen und in einem Repository in Artifact Registry veröffentlichen.

Sie können Config Sync für die Synchronisierung aus OCI-Images konfigurieren, indem Sie Artifact Registry verwenden. Um diese Funktion verwenden zu können, müssen Sie die RootSync- und RepoSync APIs aktivieren.

Artifact Registry

Artifact Registry ist ein vollständig verwalteter Dienst, der sowohl Container-Images als auch Nicht-Container-Artefakte unterstützt. Wir empfehlen Artifact Registry für die Speicherung und Verwaltung von Container-Images in Google Cloud. Es gibt viele Tools, um Artefakte per Push in Artifact Registry zu übertragen. Sie können beispielsweise ein Docker-Image oder ein Helm-Diagramm per Push hochladen oder die Go-ContainerRegistry-Bibliothek für die Arbeit mit Container-Registries verwenden. Entscheiden Sie sich für das Tool, das für Sie am besten funktioniert.

Hinweise

  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. Erstellen Sie einen Cluster, der die Anforderungen für Config Sync erfüllt und die aktuelle Version von Config Sync verwendet, oder sorgen Sie dafür, dass Sie Zugriff auf einen solchen Cluster haben.
  15. Installieren Sie die nomos-Befehlszeile oder aktualisieren Sie sie auf die neueste Version.
  16. Optional: Wenn Sie Cosign verwenden möchten, um OCI-Image-Signaturen zu prüfen, installieren Sie Folgendes:
    • Cosign zum Signieren von OCI-Images.
    • OpenSSL zum Generieren von Anmeldedaten für den Webhook-Server.
    • Docker zum Erstellen und Übertragen des Admission Webhook-Server-Images per Push.

    Kosten

    In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

    Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.

    Neuen Google Cloud Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

    Artifact Registry-Repository erstellen

    In diesem Abschnitt erstellen Sie ein Artifact Registry-Repository. Weitere Informationen zum Erstellen von Artifact Registry-Repositories finden Sie unter Repositories erstellen.

    1. Erstellen Sie ein Artifact Registry-Repository:

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

    Ersetzen Sie Folgendes:

    • PROJECT_ID: die Projekt-ID der Organisation.
    • AR_REPO_NAME: die ID des Repositorys.
    • AR_REGION: der regionale oder multiregionale Speicherort für das Repository.

    In den folgenden Abschnitten verwendete Variablen:

    • FLEET_HOST_PROJECT_ID: Wenn Sie GKE Workload Identity Federation for GKE verwenden, entspricht dies PROJECT_ID. Wenn Sie Workload Identity Federation for GKE für Flotten verwenden, ist dies die Projekt-ID der Flotte, für die Ihr Cluster registriert ist.
    • GSA_NAME: Name des benutzerdefinierten Google-Dienstkontos, mit dem Sie eine Verbindung zu Artifact Registry herstellen möchten.
    • KSA_NAME: das Kubernetes-Dienstkonto für den Abgleich.
      • Fügen Sie für Stamm-Repositories root-reconciler hinzu, wenn der Name RootSync root-sync ist. Fügen Sie andernfalls root-reconciler-ROOT_SYNC_NAME hinzu.
      • Für Namespace-Repositories gilt: Wenn der RepoSync-Name repo-sync lautet, fügen Sie ns-reconciler-NAMESPACE hinzu. Fügen Sie andernfalls ns-reconciler-NAMESPACE-REPO_SYNC_NAME-REPO_SYNC_NAME_LENGTH hinzu, wobei REPO_SYNC_NAME_LENGTH die Anzahl der Zeichen in REPO_SYNC_NAME ist.

    Berechtigung „Reader“ gewähren

    So authentifizieren Sie sich mit einem Kubernetes-Dienstkonto bei Artifact Registry:

    Weisen Sie dem Kubernetes-Dienstkonto mit dem Workload Identity Federation for GKE-Pool die IAM-Rolle „Artifact Registry-Leser“ (roles/artifactregistry.reader) zu:

    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
    

    Image in das Artifact Registry-Repository hochladen

    In diesem Abschnitt erstellen Sie ein OCI-Image und übertragen es per Push in Artifact Registry.

    1. Erstellen Sie eine Namespace-Manifestdatei:

      cat <<EOF> test-namespace.yaml
      apiVersion: v1
      kind: Namespace
      metadata:
        name: test
      EOF
      
    2. Melden Sie sich bei Artifact Registry an:

      gcloud auth configure-docker AR_REGION-docker.pkg.dev
      
    3. Verpacken Sie das Image und übertragen Sie es per Push in die Artifact Registry:

      crane

      Die Befehle in diesem Abschnitt verwenden crane, um mit Remote-Images und Registries zu interagieren.

      1. Packen Sie die Datei:

        tar -cf test-namespace.tar test-namespace.yaml
        
      2. Sie haben das crane-Tool installiert.

      3. Übertragen Sie das Image per Push an Artifact Registry.

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

      oras

      Die Befehle in diesem Abschnitt verwenden oras, um mit Remote-Images und Registries zu interagieren.

      1. Packen Sie die Datei:

        tar -czf test-namespace.tar.gz test-namespace.yaml
        
      2. Sie haben das oras-Tool installiert.

      3. Übertragen Sie das Image per Push an Artifact Registry.

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

    Config Sync für die Synchronisierung aus Ihrem Image konfigurieren

    In diesem Abschnitt erstellen Sie ein RootSync-Objekt und konfigurieren Config Sync für die Synchronisierung aus dem OCI-Image.

    1. Erstellen Sie ein RootSync-Objekt mit einem eindeutigen Namen:

      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
      

      Ersetzen Sie ROOT_SYNC_NAME durch den Namen Ihres RootSync-Objekts. Der Name darf im Cluster nur einmal vorkommen und darf nicht mehr als 26 Zeichen haben. Eine vollständige Liste der Optionen zum Konfigurieren von RootSync-Objekten finden Sie unter RootSync- und RepoSync-Felder.

    2. Wenden Sie das RootSync-Objekt an:

      kubectl apply -f ROOT_SYNC_NAME.yaml
      
    3. Prüfen Sie, ob Config Sync mit dem Image synchronisiert wird:

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

      Die Ausgabe sollte in etwa wie im folgenden Beispiel aussehen:

      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
      

      Sie haben jetzt erfolgreich ein Image mit Ihrem Cluster synchronisiert.

    Optional: OCI-Quellsignaturen prüfen

    Ab Config Sync-Version 1.20.0 unterstützt Config Sync die Überprüfung der Authentizität von OCI-Quell-Images, bevor Konfigurationen auf Ihre Cluster angewendet werden. Bei dieser Methode werden ein ValidatingWebhookConfiguration-Objekt und ein validierender Webhook-Server verwendet, um Aktualisierungsanfragen für RootSync- und RepoSync-Objekte abzufangen. Config Sync aktualisiert die Annotation configsync.gke.io/image-to-sync der Objekte RootSync und RepoSync, nachdem ein neuer Image-Digest abgerufen wurde. Der validierende Webhook-Server vergleicht die Werte zwischen der alten und der neuen Annotation und führt die Validierung mit einem Validierungstool wie Cosign aus, wenn eine Änderung erkannt wird.

    Server für die Signaturüberprüfung einrichten

    Um die Authentizität Ihrer OCI-Quellen zu gewährleisten, benötigen Sie einen HTTP-Server, um die Signaturen zu überprüfen. Sie können die Beispiele im Config Sync-Beispielrepository verwenden oder Ihr eigenes Docker-Image.

    1. Wenn Sie das bereitgestellte Beispiel verwenden möchten, führen Sie die folgenden Schritte aus:

      1. Klonen Sie das Beispiel-Repository:

        git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples/
        
      2. Wechseln Sie in das Verzeichnis, das die Serverbeispiele für die Signaturprüfung enthält:

        cd anthos-config-management-samples/tree/main/pre-sync/oci-image-verification
        
    2. Führen Sie den folgenden Befehl aus, um ein Docker-Image für den Server zur Signaturprüfung zu erstellen und es in eine Image-Registry zu übertragen:

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

      Ersetzen Sie SIGNATURE_VERIFICATION_SERVER_IMAGE_URL durch die URL Ihres Servers für die Signaturüberprüfung.

    Bei Diensten authentifizieren

    Um Ihren Server für die Signaturprüfung einzurichten, müssen Sie sich bei Artifact Registry, dem Cosign-Client und dem Webhook-Server authentifizieren.

    1. Erstellen Sie einen Namespace:

      kubectl create ns signature-verification
      
    2. So authentifizieren Sie sich mit einem Kubernetes-Dienstkonto bei Artifact Registry:

      1. Erstellen Sie ein Kubernetes-Dienstkonto im erstellten Namespace:

        kubectl create sa signature-verification-sa -n signature-verification
        
      2. Fügen Sie die IAM-Richtlinienbindung für die Rolle „Artifact Registry-Leser“ (roles/artifactregistry.reader) hinzu:

        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
        

        Ersetzen Sie Folgendes:

        • REPOSITORY_NAME: der Name Ihres Artifact Registry-Repositorys, in dem Sie Ihre OCI-Images speichern.
        • REPOSITORY_LOCATION: der Speicherort Ihres Artifact Registry-Repositorys.
    3. So authentifizieren Sie sich beim Cosign-Client:

      1. Generieren Sie ein Cosign-Schlüsselpaar. Mit diesem Befehl werden ein öffentlicher und ein privater Schlüssel generiert:

        cosign generate-key-pair
        
      2. Speichern Sie den öffentlichen Schlüssel in einem Kubernetes-Secret im Namespace, den Sie erstellt haben:

        kubectl create secret generic cosign-key --from-file=cosign.pub -n signature-verification
        
    4. So authentifizieren Sie den Server zur Signaturüberprüfung:

      1. Um die Kommunikation innerhalb des Servers zur Signaturüberprüfung zu verschlüsseln, generieren Sie mit OpenSSL ein TLS-Zertifikat und einen privaten Schlüssel:

        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. Speichern Sie die generierten Anmeldedaten in einem Kubernetes-Secret:

        kubectl create secret tls webhook-tls --cert=tls.crt --key=tls.key -n signature-verification
        
      3. Rufen Sie den Base64-codierten Inhalt von tls.cert ab. Dies ist für die Validierungs-Webhook-Konfiguration erforderlich, die Sie im nächsten Abschnitt erstellen:

        cat tls.crt | base64 -w 0.
        

    Zulassungs-Webhook bereitstellen

    Mit den folgenden Beispielen können Sie eine Bereitstellung für den Server zur Signaturprüfung und eine validierende Webhook-Konfiguration erstellen.

    1. Erstellen Sie eine Bereitstellung für den Server zur Signaturprüfung, indem Sie die folgende Datei speichern:

      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

      Ersetzen Sie SIGNATURE_VERIFICATION_SERVER_IMAGE_URL durch die vollständige URL des Bildes des Servers zur Signaturüberprüfung.

    2. Wenden Sie das Deployment auf den Cluster an:

      kubectl apply -f signature-verification-deployment.yaml -n signature-verification
      
    3. Erstellen Sie eine Validierungs-Webhook-Konfiguration, indem Sie die folgende Datei speichern:

      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

      Ersetzen Sie CA_BUNDLE durch den base64-codierten Inhalt aus tls.cert.

    4. Wenden Sie die validierende Webhook-Konfiguration auf den Cluster an:

      kubectl apply -f signature-verification-validatingwebhookconfiguration.yaml
      

    Logs auf Fehler bei der Bildüberprüfung prüfen

    Nachdem Sie Ihren Server für die Bildüberprüfung eingerichtet haben, sollten alle Versuche, nicht signierte OCI-Bilder zu synchronisieren, fehlschlagen.

    Wenn Sie nach Fehlern bei der Signaturprüfung suchen möchten, rufen Sie die Logs des Servers für die Signaturprüfung mit den folgenden Befehlen auf:

    1. kubectl-Logs prüfen:

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

      Fehler von kubectl im Zusammenhang mit der Signaturbestätigung sehen so aus:

      main.go:69: error during command execution: no signatures found
      
    2. Config Sync-Logs prüfen:

      nomos status
      

      Fehler von Config Sync im Zusammenhang mit der Signaturprüfung sehen so aus:

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

    Wenn keine Fehler auftreten, können Sie bestätigen, dass das signierte Image das Objekt ist, das synchronisiert wird, indem Sie Ihre RootSync- oder RepoSync-Konfiguration prüfen:

    RootSync

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

    Ersetzen Sie ROOTSYNC_NAME durch den Namen Ihres RootSync.

    RepoSync

     kubectl get reposync REPOSYNC_NAME -n REPOSYNC_NAMESPACE -oyaml
    

    Ersetzen Sie Folgendes:

    • REPOSYNC_NAME: der Name Ihres RepoSync.
    • REPOSYNC_NAMESPACE: Der Name des Namespace, der mit Ihrem RepoSync verknüpft ist.

    Die Annotation configsync.gke.io/image-to-sync sollte Ihrem RootSync- oder RepoSync-Objekt hinzugefügt worden sein. Die Annotation enthält die URL des OCI-Quell-Images und den letzten von Config Sync abgerufenen Digest.

    Nächste Schritte