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 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.

Hinweis

  1. Melden Sie sich in Ihrem Google Cloud -Konto an. Wenn Sie mit Google Cloudnoch nicht vertraut sind, erstellen Sie einfach ein Konto, um die Leistungsfähigkeit unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  2. Installieren Sie die Google Cloud CLI.

  3. Wenn Sie einen externen Identitätsanbieter (IdP) verwenden, müssen Sie sich zuerst mit Ihrer föderierten Identität in der gcloud CLI anmelden.

  4. Führen Sie den folgenden Befehl aus, um die gcloud CLI zu initialisieren:

    gcloud init
  5. Google Cloud Projekt erstellen oder auswählen

    Erforderliche Rollen zum Auswählen oder Erstellen eines Projekts

    • Projekt auswählen: Für die Auswahl eines Projekts ist keine bestimmte IAM-Rolle erforderlich. Sie können jedes Projekt auswählen, für das Ihnen eine Rolle zugewiesen wurde.
    • Projekt erstellen: Zum Erstellen eines Projekts benötigen Sie die Rolle „Project Creator“ (roles/resourcemanager.projectCreator), die die Berechtigung resourcemanager.projects.create enthält. Informationen zum Zuweisen von Rollen
    • So erstellen Sie ein Google Cloud Projekt:

      gcloud projects create PROJECT_ID

      Ersetzen Sie PROJECT_ID durch einen Namen für das Google Cloud Projekt, das Sie erstellen.

    • Wählen Sie das von Ihnen erstellte Google Cloud Projekt aus:

      gcloud config set project PROJECT_ID

      Ersetzen Sie PROJECT_ID durch Ihren Google Cloud Projektnamen.

  6. Prüfen Sie, ob die Abrechnung für Ihr Google Cloud Projekt aktiviert ist.

  7. Aktivieren Sie die GKE-, Config Sync- und Artifact Registry-APIs, falls noch nicht geschehen:

    Rollen, die zum Aktivieren von APIs erforderlich sind

    Zum Aktivieren von APIs benötigen Sie die Berechtigung serviceusage.services.enable. Wenn Sie das Projekt erstellt haben, haben Sie diese Berechtigung wahrscheinlich bereits über die Rolle „Inhaber“ (roles/owner). Andernfalls können Sie diese Berechtigung über die Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin) erhalten. Informationen zum Zuweisen von Rollen

    gcloud services enable container.googleapis.com  anthosconfigmanagement.googleapis.com  artifactregistry.googleapis.com
  8. Installieren Sie die Google Cloud CLI.

  9. Wenn Sie einen externen Identitätsanbieter (IdP) verwenden, müssen Sie sich zuerst mit Ihrer föderierten Identität in der gcloud CLI anmelden.

  10. Führen Sie den folgenden Befehl aus, um die gcloud CLI zu initialisieren:

    gcloud init
  11. Google Cloud Projekt erstellen oder auswählen

    Erforderliche Rollen zum Auswählen oder Erstellen eines Projekts

    • Projekt auswählen: Für die Auswahl eines Projekts ist keine bestimmte IAM-Rolle erforderlich. Sie können jedes Projekt auswählen, für das Ihnen eine Rolle zugewiesen wurde.
    • Projekt erstellen: Zum Erstellen eines Projekts benötigen Sie die Rolle „Project Creator“ (roles/resourcemanager.projectCreator), die die Berechtigung resourcemanager.projects.create enthält. Informationen zum Zuweisen von Rollen
    • So erstellen Sie ein Google Cloud Projekt:

      gcloud projects create PROJECT_ID

      Ersetzen Sie PROJECT_ID durch einen Namen für das Google Cloud Projekt, das Sie erstellen.

    • Wählen Sie das von Ihnen erstellte Google Cloud Projekt aus:

      gcloud config set project PROJECT_ID

      Ersetzen Sie PROJECT_ID durch Ihren Google Cloud Projektnamen.

  12. Prüfen Sie, ob die Abrechnung für Ihr Google Cloud Projekt aktiviert ist.

  13. Aktivieren Sie die GKE-, Config Sync- und Artifact Registry-APIs, falls noch nicht geschehen:

    Rollen, die zum Aktivieren von APIs erforderlich sind

    Zum Aktivieren von APIs benötigen Sie die Berechtigung serviceusage.services.enable. Wenn Sie das Projekt erstellt haben, haben Sie diese Berechtigung wahrscheinlich bereits über die Rolle „Inhaber“ (roles/owner). Andernfalls können Sie diese Berechtigung über die Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin) erhalten. Informationen zum Zuweisen von Rollen

    gcloud services enable container.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 auf einen solchen Cluster zugreifen können.
  15. Installieren Sie die nomos-Befehlszeile oder aktualisieren Sie sie auf die neueste Version.
  16. Optional: Wenn Sie Cosign zum Überprüfen von OCI-Image-Signaturen verwenden möchten, 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.

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 Nutzern von Google Cloud 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.

Erstellen Sie ein Artifact Registry-Repository:

gcloud artifacts repositories create AR_REPO_NAME \
   --repository-format=docker \
   --location=AR_REGION \
   --description="Config Sync 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_NUMBER: Wenn Sie GKE Workload Identity Federation for GKE verwenden, entspricht dies der Projektnummer für PROJECT_ID. Wenn Sie Workload Identity Federation for GKE für Flotten verwenden, ist dies die Projektnummer der Flotte, für die Ihr Cluster registriert ist.
  • 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.
  • KUBERNETES_SERVICEACCOUNT: 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.

Leseberechtigung erteilen

Weisen Sie dem Kubernetes-Dienstkonto die Rolle „Artifact Registry-Leser“ (roles/artifactregistry.reader) für das Repository zu:

gcloud artifacts repositories add-iam-policy-binding AR_REPO_NAME \
   --location=AR_REGION \
   --member="principal://iam.googleapis.com/projects/FLEET_HOST_PROJECT_NUMBER/locations/global/workloadIdentityPools/FLEET_HOST_PROJECT_ID.svc.id.goog/subject/ns/config-management-system/sa/KUBERNETES_SERVICEACCOUNT" \
   --role=roles/artifactregistry.reader \
   --project=PROJECT_ID \
   --condition=None

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

Sie können die Authentizität von OCI-Quell-Images überprüfen, 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 ein eigenes Docker-Image nutzen.

  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 Signaturüberprü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 Signaturprüfungsserver zu erstellen und in eine Bildregistrierung 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 Signaturprüfung.

Bei Diensten authentifizieren

Zum Einrichten des Servers für die Signaturprüfung 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. Weisen Sie dem Kubernetes-Dienstkonto die Rolle „Artifact Registry-Leser“ (roles/artifactregistry.reader) für das Repository zu:

      gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \
         --location=REPOSITORY_LOCATION \
         --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/signature-verification/sa/signature-verification-sa" \
         --role=roles/artifactregistry.reader \
         --project=PROJECT_ID \
         --condition=None
      

      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.
      • PROJECT_NUMBER: Ihre Projektnummer.
      • PROJECT_ID: Ihre Projekt-ID.
  3. So authentifizieren Sie sich beim Cosign-Client:

    1. Cosign-Schlüsselpaar generieren 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 für die 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 validierende 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-Images 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. Sehen Sie sich dazu Ihre RootSync- oder RepoSync-Konfiguration an:

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 neuesten von Config Sync abgerufenen Digest.

Nächste Schritte