Kontinuierliches Deployment in der Google Kubernetes Engine (GKE) mit Cloud Build

1. Übersicht

In diesem Lab richten Sie mit Cloud Build eine Continuous-Delivery-Pipeline für GKE ein. In diesem Lab erfahren Sie, wie Sie Cloud Build-Jobs für verschiedene Git-Ereignisse auslösen. Außerdem wird ein einfaches Muster für automatisierte Canary-Releases in GKE erläutert.

Führen Sie die folgenden Schritte aus:

  • GKE-Anwendung erstellen
  • Bereitstellungen für Git-Zweige automatisieren
  • Bereitstellungen für den Hauptzweig von Git automatisieren
  • Bereitstellungen für Git-Tags automatisieren

2. Hinweis

Für diesen Leitfaden benötigen Sie ein Google Cloud-Projekt. Sie können ein neues Projekt erstellen oder ein Projekt auswählen, das Sie bereits erstellt haben:

  1. Wählen Sie ein Google Cloud-Projekt aus oder erstellen Sie eines.

ZUR SEITE „PROJEKTAUSWAHL“

  1. Aktivieren Sie die Abrechnung für Ihr Projekt.

Abrechnung aktivieren

3. Umgebung vorbereiten

  1. Erstellen Sie Umgebungsvariablen zur Verwendung in dieser Anleitung:
    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
    export ZONE=us-central1-b
    export CLUSTER=gke-progression-cluster
    export APP_NAME=myapp
    
  2. Aktivieren Sie die folgenden APIs:
    • Resource Manager
    • GKE
    • Cloud Source Repositories
    • Cloud Build
    • Container Registry
    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        sourcerepo.googleapis.com \
        cloudbuild.googleapis.com \
        containerregistry.googleapis.com \
        --async
    
  3. Klonen Sie die Beispielquelle und wechseln Sie zum Lab-Verzeichnis:
    git clone https://github.com/GoogleCloudPlatform/software-delivery-workshop.git gke-progression
    
    cd gke-progression/labs/gke-progression
    rm -rf ../../.git
    
  4. Ersetzen Sie Platzhalterwerte im Beispiel-Repository durch Ihre PROJECT_ID:In diesem Schritt erstellen Sie Instanzen der verschiedenen Konfigurationsdateien, die nur für Ihre aktuelle Umgebung gelten.Führen Sie den folgenden Befehl aus, um ein Beispiel für die zu aktualisierenden Vorlagen anzusehen.
    cat k8s/deployments/dev/frontend-dev.yaml.tmpl
    
    Führen Sie die Variablenersetzung aus, indem Sie den Befehl followign ausführen.
    for template in $(find . -name '*.tmpl'); do envsubst '${PROJECT_ID} ${ZONE} ${CLUSTER} ${APP_NAME}' < ${template} > ${template%.*}; done
    
    Führen Sie den folgenden Befehl aus, um sich nach der Ersetzung ein Beispiel der Datei anzusehen.
    cat k8s/deployments/dev/frontend-dev.yaml
    
  5. Wenn Sie Git in Cloud Shell noch nicht verwendet haben, legen Sie die Werte für user.name und user.email fest, die Sie verwenden möchten:
    git config --global user.email "YOUR_EMAIL_ADDRESS"
    git config --global user.name "YOUR_USERNAME"
    
  6. Speichern Sie den Code aus dem Beispiel-Repository in Cloud Source Repositories:
    gcloud source repos create gke-progression
    git init
    git config credential.helper gcloud.sh
    git remote add gcp https://source.developers.google.com/p/$PROJECT_ID/r/gke-progression
    git branch -m main
    git add . && git commit -m "initial commit"
    git push gcp main
    
  7. Erstellen Sie den GKE-Cluster.
    gcloud container clusters create ${CLUSTER} \
        --project=${PROJECT_ID} \
        --zone=${ZONE}
    
  8. Gewähren Sie Cloud Build-Berechtigungen für Ihren Cluster.Cloud Build stellt die Anwendung in Ihrem GKE-Cluster bereit und benötigt die entsprechenden Berechtigungen.
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
        --role=roles/container.developer
    

Ihre Umgebung ist bereit!

4. GKE-Anwendung erstellen

In diesem Abschnitt erstellen Sie die erste Produktionsanwendung, die Sie in dieser Anleitung verwenden, und stellen sie bereit.

  1. Erstellen Sie die Anwendung mit Cloud Build:
    gcloud builds submit --tag gcr.io/$PROJECT_ID/$APP_NAME:1.0.0 src/
    
  2. Manuell in Canary- und Produktionsumgebungen bereitstellen:Erstellen Sie die Produktions- und Canary-Deployments und -Dienste mithilfe der kubectl apply-Befehle.
    kubectl create ns production
    kubectl apply -f k8s/deployments/prod -n production
    kubectl apply -f k8s/deployments/canary -n production
    kubectl apply -f k8s/services -n production
    
    Der hier bereitgestellte Dienst leitet den Traffic sowohl an die Canary- als auch an die Produktionsbereitstellung weiter.
  3. Überprüfen Sie die Anzahl der ausgeführten Pods. Prüfen Sie, ob vier Pods für das Frontend ausgeführt werden, darunter drei für den Produktionstraffic und einen für Canary-Releases. Das bedeutet, dass Änderungen an Ihrem Canary-Release nur einen von vier Nutzern (25%) betreffen.
    kubectl get pods -n production -l app=$APP_NAME -l role=frontend
    
  4. Rufen Sie die externe IP-Adresse für die Produktionsdienste ab.
    kubectl get service $APP_NAME -n production
    
    Sobald der Load-Balancer die IP-Adresse zurückgibt, fahren Sie mit dem nächsten Schritt fort
  5. Speichern Sie die externe IP-Adresse zur späteren Verwendung.
    export PRODUCTION_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=production services $APP_NAME)
    
  6. Anwendung überprüfen Prüfen Sie die Versionsausgabe des Dienstes. Sie sollte Hello World v1.0 lesen.
    curl http://$PRODUCTION_IP
    

Glückwunsch! Sie haben die Beispiel-App bereitgestellt. Als Nächstes richten Sie Trigger für die kontinuierliche Bereitstellung Ihrer Änderungen ein.

5. Bereitstellungen für Git-Zweige automatisieren

In diesem Abschnitt richten Sie einen Trigger ein, der beim Commit eines beliebigen Zweigs als main einen Cloudbuild-Job ausführt. Die hier verwendete Cloud Build-Datei erstellt automatisch einen Namespace und ein Deployment für alle vorhandenen oder neuen Branches. So können Entwickler ihren Code vor der Integration in den Hauptzweig in der Vorschau anzeigen.

  1. Trigger einrichten:Die Hauptkomponente dieses Triggers ist die Verwendung des branchName-Parameters für den Abgleich mit main und des invertRegex-Parameters, der auf „true“ gesetzt ist und das branchName-Muster so ändert, dass alles mit anderen als main abgeglichen wird. Zur Orientierung finden Sie die folgenden Zeilen in build/branch-trigger.json.
      "branchName": "main",
      "invertRegex": true
    
    Außerdem erstellen die letzten Zeilen der mit diesem Trigger verwendeten Cloud Build-Datei einen Namespace, der nach dem Zweig benannt ist, der den Job ausgelöst hat. Anschließend werden die Anwendung und der Dienst innerhalb des neuen Namespace bereitgestellt. Zur Orientierung finden Sie die folgenden Zeilen in build/branch-cloudbuild.yaml
      kubectl get ns ${BRANCH_NAME} || kubectl create ns ${BRANCH_NAME}
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/deployments/dev
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/services
    
    Nachdem Sie nun die verwendeten Mechanismen kennen, erstellen Sie den Trigger mit dem folgenden gcloud-Befehl.
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/branch-trigger.json
    
  2. Wenn Sie den Trigger prüfen möchten, rufen Sie in der Console die Seite Cloud Build-Trigger auf.Zur Seite „Trigger“
  3. Erstellen Sie einen neuen Zweig:
    git checkout -b new-feature-1
    
  4. Passe den Code an v1.1Edit src/app.py an und ändere die Antwort von 1.0 in 1.1
    @app.route('/')
    def hello_world():
        return 'Hello World v1.1'
    
    .
  5. Übernehmen Sie die Änderung und übertragen Sie sie per Push an das Remote-Repository:
    git add . && git commit -m "updated" && git push gcp new-feature-1
    
  6. Wenn Sie den laufenden Build prüfen möchten, rufen Sie in der Console die Seite „Cloud Build-Verlauf“ auf. Builds aufrufen Fahren Sie nach Abschluss des Builds mit dem nächsten Schritt fort.
  7. Rufen Sie die externe IP-Adresse für den neu bereitgestellten Zweigdienst ab.
    kubectl get service $APP_NAME -n new-feature-1
    
    Sobald der Load-Balancer die IP-Adresse zurückgibt, fahren Sie mit dem nächsten Schritt fort
  8. Speichern Sie die externe IP-Adresse zur späteren Verwendung.
    export BRANCH_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=new-feature-1 services $APP_NAME)
    
  9. Anwendung überprüfen Die Versionsausgabe des Dienstes überprüfen. Sie sollte Hello World v1.0 lesen.
    curl http://$BRANCH_IP
    

6. Bereitstellungen für den Hauptzweig von Git automatisieren

Es ist üblich, Code vor der Veröffentlichung des Codes in der Produktion für einen kleinen Teil des Live-Traffics freizugeben, bevor der gesamte Traffic zur neuen Codebasis migriert wird.

In diesem Abschnitt implementieren Sie einen Trigger, der aktiviert wird, wenn Code an den Haupt-Branch übergeben wird. Der Trigger stellt das Canary-Deployment bereit, das 25% des gesamten Live-Traffics an die neue Version empfängt.

  1. Richten Sie den Trigger für den Hauptzweig ein:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/main-trigger.json
    
  2. Rufen Sie in der Console die Seite Cloud Build-Trigger auf, um den neuen Trigger zu überprüfen.Zur Seite „Trigger“
  3. Führen Sie den Zweig mit der Hauptzeile zusammen und übertragen Sie ihn per Push in das Remote-Repository:
    git checkout main
    git merge new-feature-1
    git push gcp main
    
  4. Wenn Sie den laufenden Build prüfen möchten, rufen Sie in der Console die Seite „Cloud Build-Verlauf“ auf. Builds aufrufen Fahren Sie nach Abschluss des Builds mit dem nächsten Schritt fort.
  5. Überprüfen Sie mehrere Antworten vom Server. Führen Sie den folgenden Befehl aus und beachten Sie, dass etwa 25% der Antworten die neue Antwort von Hello World v1.1 enthalten.
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    Wenn du fortfahren möchtest, drücke Ctrl+c, um die Schleife zu verlassen.

7. Bereitstellungen für Git-Tags automatisieren

Nachdem das Canary-Deployment mit einer kleinen Teilmenge des Traffics validiert wurde, geben Sie das Deployment für den Rest des Live-Traffics frei.

In diesem Abschnitt richten Sie einen Trigger ein, der aktiviert wird, wenn Sie ein Tag im Repository erstellen. Der Trigger kennzeichnet das Image mit dem entsprechenden Tag und stellt die Aktualisierungen dann in der Produktion bereit. So wird sichergestellt, dass 100% des Traffics auf das getaggte Image zugreifen.

  1. Richten Sie den Tag-Trigger ein:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/tag-trigger.json
    
  2. Rufen Sie in der Console die Seite Cloud Build-Trigger auf, um den neuen Trigger zu überprüfen.Zur Seite „Trigger“
  3. Erstellen Sie ein neues Tag und übertragen Sie es per Push in das Remote-Repository:
    git tag 1.1
    git push gcp 1.1
    
  4. Wenn Sie den laufenden Build prüfen möchten, rufen Sie in der Console die Seite Cloud Build-Verlauf auf.Builds aufrufen
  5. Überprüfen Sie mehrere Antworten vom Server. Führen Sie den folgenden Befehl aus und beachten Sie, dass 100% der Antworten die neue Antwort von Hello World v1.1 enthalten. Dies kann einen Moment dauern, da die neuen Pods in GKE bereitgestellt und eine Systemdiagnose durchgeführt werden.
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    Wenn du fortfahren möchtest, drücke Ctrl+c, um die Schleife zu beenden. Sie haben in Cloud Build CI/CD-Trigger für Branches und Tags erstellt, um Ihre Anwendungen in GKE bereitzustellen.

8. Bereinigen

Projekt löschen

  1. Rufen Sie in der Cloud Console die Seite Ressourcen verwalten auf.
  2. Wählen Sie in der Projektliste das Projekt aus, das Sie löschen möchten, und klicken Sie auf Löschen.
  3. Geben Sie im Dialogfeld die Projekt-ID ein und klicken Sie auf Beenden, um das Projekt zu löschen.