.NET-Anwendung mit einem GitHub Actions-Workflow in Google Kubernetes Engine bereitstellen


In dieser Anleitung wird beschrieben, wie Sie einen GitHub Actions-Workflow verwenden, um eine ASP.NET Model-View-Controller (MVC)-Webanwendung mithilfe von .NET in Google Kubernetes Engine (GKE) bereitzustellen.

Diese Anleitung richtet sich an Entwickler und DevOps-Entwickler, die Grundkenntnisse zu Microsoft .NET, GitHub Actions und GKE haben. Sie benötigen außerdem ein GitHub-Konto, um diese Anleitung auszuführen.

Lernziele

ASP.NET Core-Webanwendung mit .NET 6.0 bereitstellen, die unter Linux in der Google Kubernetes Engine ausgeführt wird

Das folgende Diagramm zeigt den GitHub-Aktionen-Workflow zum Bereitstellen einer ASP.NET MVC-Webanwendung in Google Kubernetes Engine (GKE).

Konzeptionelles Diagramm des GitHub-Aktionsworkflows

In dieser Anleitung erfahren Sie, wie Sie die folgenden Aufgaben ausführen, um Ihr Ziel zu erreichen:

  • GitHub-Repository erstellen
  • Authentifizierung konfigurieren
  • GKE-Cluster und Artifact Registry-Repository bereitstellen
  • GitHub Actions-Workflow erstellen

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.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Hinweis

  1. Melden Sie sich bei Ihrem Google Cloud-Konto an. Wenn Sie mit Google Cloud noch nicht vertraut sind, erstellen Sie 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. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  3. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  4. Artifact Registry and Google Kubernetes Engine APIs aktivieren.

    Aktivieren Sie die APIs

  5. Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

    Zur Projektauswahl

  6. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  7. Artifact Registry and Google Kubernetes Engine APIs aktivieren.

    Aktivieren Sie die APIs

GitHub-Repository erstellen

Erstellen Sie einen Fork des Repositorys dotnet-docs-samples in Ihrem GitHub-Konto. Dieser Schritt ist erforderlich, da wir mit GitHub Actions erstellen.

  1. Rufen Sie das GitHub-Repository dotnet-docs-samples auf.
  2. Klicken Sie auf Fork.
  3. Legen Sie auf der Seite Fork erstellen Folgendes fest:

    • Inhaber: Ihr GitHub-Konto
    • Repository-Name: dotnet-docs-samples
  4. Klicken Sie auf Fork erstellen.

Authentifizierung konfigurieren

Bereiten Sie Ihr Google Cloud-Projekt so vor, dass GitHub Actions Ressourcen im Google Cloud-Projekt authentifizieren und darauf zugreifen können.

Föderationspool und Anbieter von Workload Identity erstellen

Verwenden Sie die Arbeitslast-Identitätsföderation, um GitHub-Aktionen zu authentifizieren und Google Cloud in GKE bereitzustellen. Mit der Workload Identity-Föderation können Sie vermeiden, dass Dienstkontoschlüssel für Ihre GitHub Actions-Arbeitslast gespeichert und verwaltet werden müssen.

Für die Verwendung der Workload Identity-Föderation sind ein Workload Identity-Pool und ein Anbieter erforderlich. Wir empfehlen, ein dediziertes Projekt zum Verwalten von Workload Identity-Pools und -Anbietern zu verwenden. In dieser Anleitung erstellen wir der Einfachheit halber den Pool und den Anbieter im selben Projekt wie der GKE-Cluster:

  1. Öffnen Sie die Google Cloud Console.

  2. Aktivieren Sie Cloud Shell in der Google Cloud Console.

    Cloud Shell aktivieren

    Unten in der Google Cloud Console wird eine Cloud Shell-Sitzung gestartet und eine Eingabeaufforderung angezeigt. Cloud Shell ist eine Shell-Umgebung, in der das Google Cloud CLI bereits installiert ist und Werte für Ihr aktuelles Projekt bereits festgelegt sind. Das Initialisieren der Sitzung kann einige Sekunden dauern.

  3. Erstellen Sie einen neuen Workload Identity-Pool:

    gcloud iam workload-identity-pools create github-actions \
        --location="global" \
        --description="GitHub Actions tutorial" \
        --display-name="GitHub Actions"
    
  4. Fügen Sie GitHub Actions als Anbieter von Workload Identity-Pools hinzu:

    gcloud iam workload-identity-pools providers create-oidc github-actions-oidc \
        --location="global" \
        --workload-identity-pool=github-actions \
        --issuer-uri="https://token.actions.githubusercontent.com/" \
        --attribute-mapping="google.subject=assertion.sub"
    

Dienstkonto erstellen

  1. Erstellen Sie in Cloud Shell ein Dienstkonto, mit dem GitHub Actions Docker-Images veröffentlichen und in GKE bereitstellen kann:

    SERVICE_ACCOUNT=$(gcloud iam service-accounts create github-actions-workflow \
      --display-name "GitHub Actions workflow" \
      --format "value(email)")
    
  2. Gewähren Sie dem Dienstkonto die Rolle „Artifact Registry-Autor“ (roles/artifactregistry.writer), damit GitHub-Aktionen in Artifact Registry übertragen werden können.

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
      --member serviceAccount:$SERVICE_ACCOUNT \
      --role roles/artifactregistry.writer
    
  3. Weisen Sie dem Dienstkonto die Rolle „Google Kubernetes Engine-Entwickler“ (roles/container.developer) zu, damit GitHub-Aktionen an Artifact Registry übertragen werden können.

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
      --member serviceAccount:$SERVICE_ACCOUNT \
      --role roles/container.developer
    

Dem GitHub Actions-Workflow erlauben, das Dienstkonto zu verwenden

Erlauben Sie dem GitHub Actions-Workflow, die Identität des Dienstkontos zu übernehmen und das Dienstkonto zu verwenden:

  1. Initialisieren Sie eine Umgebungsvariable, die das Thema enthält, das vom GitHub Actions-Workflow verwendet wird. Ein Betreff ähnelt einem Nutzernamen, der das GitHub-Repository und den Zweig eindeutig identifiziert:

    SUBJECT=repo:OWNER/dotnet-docs-samples:ref:refs/heads/main
    

    Ersetzen Sie OWNER durch Ihren GitHub-Nutzernamen.

  2. Gewähren Sie dem Inhaber die Berechtigung, die Identität des Dienstkontos zu übernehmen:

    PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value core/project) --format='value(projectNumber)')
    
    gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT \
      --role=roles/iam.workloadIdentityUser \
      --member="principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/github-actions/subject/$SUBJECT"
    

GKE-Cluster und Artifact Registry-Repository bereitstellen

  1. Erstellen Sie ein Repository für Docker-Images:

    gcloud artifacts repositories create clouddemo \
      --repository-format=docker \
      --location=us-central1
    
  2. Gewähren Sie dem Compute Engine-Standarddienstkonto Zugriff auf das Repository:

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
      --member=serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --role=roles/artifactregistry.reader
    
  3. Erstellen Sie den Cluster:

    gcloud container clusters create clouddemo-linux \
      --enable-ip-alias \
      --zone us-central1-a
    

    Die Ausführung dieses Befehls kann mehrere Minuten dauern.

  4. Rufen Sie den Projektnamen und die Projektnummer des Clusters ab:

    echo "Project ID: $(gcloud config get-value core/project)"
    echo "Project Number: $(gcloud projects describe $(gcloud config get-value core/project) --format=value\(projectNumber\))"
    

    Sie benötigen diese Werte später.

GitHub Actions-Workflow erstellen

Sie können jetzt GitHub-Aktionen verwenden, um die Continuous Integration einzurichten. Für jeden Commit, der an das Git-Repository gesendet wird, erstellt ein GitHub-Aktionsworkflow den Code und verpackt die Build-Artefakte in einen Docker-Container. Der Container wird dann in Artifact Registry veröffentlicht.

Das Repository enthält bereits das folgende Dockerfile:

#
# Copyright 2020 Google LLC
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

FROM mcr.microsoft.com/dotnet/aspnet:6.0
EXPOSE 8080

#------------------------------------------------------------------------------
# Copy publishing artifacts.
#------------------------------------------------------------------------------

WORKDIR /app
COPY CloudDemo.MvcCore/bin/Release/net6.0/publish/ /app/

ENV ASPNETCORE_URLS=http://0.0.0.0:8080

#------------------------------------------------------------------------------
# Run application in Kestrel.
#------------------------------------------------------------------------------

ENTRYPOINT ["dotnet", "CloudDemo.MvcCore.dll"]

Das Repository enthält auch ein Kubernetes-Manifest:

#
# Copyright 2020 Google LLC
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

apiVersion: v1
kind: Service
metadata:
  name: clouddemo-netcore
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: clouddemo-netcore
  type: NodePort

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: clouddemo-netcore
spec:
  defaultBackend:
    service:
      name: clouddemo-netcore
      port:
        number: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: clouddemo-netcore
spec:
  replicas: 2
  selector:
    matchLabels:
      app: clouddemo-netcore
  template:
    metadata:
      labels:
        app: clouddemo-netcore
    spec:
      containers:
      - name: clouddemo-netcore
        image: CLOUDDEMO_IMAGE
        ports:
          - containerPort: 8080
        livenessProbe:      # Used by deployment controller
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:     # Used by Ingress/GCLB
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 3
          periodSeconds: 5
        resources:
          limits:
            memory: 1024Mi
          requests:
            memory: 256Mi

Erstellen Sie einen GitHub Actions-Workflow, der Folgendes ausführt:

  • Authentifizieren Sie sich mit der Workload Identity-Föderation und dem zuvor erstellten Dienstkonto bei Google Cloud.
  • Docker-Image erstellen und in Artifact Registry bereitstellen
  • das Docker-Image in GKE bereitstellen

So erstellen Sie den GitHub Actions-Workflow:

  1. Wechseln Sie auf GitHub zu der Verzweigung des Repositorys dotnet-docs-samples.
  2. Klicken Sie auf Datei hinzufügen > Neue Datei erstellen.
  3. Geben Sie im Textfeld Datei benennen den folgenden Namen ein:

    .github/workflows/deploy-gke.yaml
    
  4. Kopieren Sie den folgenden Code in die Datei:

    name: Build and Deploy to GKE
    
    on:
      push:
        branches:
          - main
    
    env:
      PROJECT_ID: PROJECT_ID
      PROJECT_NUMBER: PROJECT_NUMBER
    
      CLUSTER: clouddemo-linux
      CLUSTER_ZONE: us-central1-a
    
      REPOSITORY: clouddemo
      REPOSITORY_REGION: us-central1
    
      IMAGE: clouddemo
    
    jobs:
      build:
        runs-on: ubuntu-latest
        permissions:
          id-token: write
          contents: read
    
        steps:
        - name: Checkout
          uses: actions/checkout@v3
    
        #
        # Authenticate to Google Cloud using workload identity federation
        #
        - id: 'auth'
          name: 'Obtain access token by using workload identity federation'
          uses: 'google-github-actions/auth@v0'
          with:
            create_credentials_file: true
            token_format: access_token
            workload_identity_provider: projects/${{ env.PROJECT_NUMBER }}/locations/global/workloadIdentityPools/github-actions/providers/github-actions-oidc
            service_account: github-actions-workflow@${{ env.PROJECT_ID }}.iam.gserviceaccount.com
    
        - name: Connect to Artifact Registry
          run: |-
            echo ${{ steps.auth.outputs.access_token }} | docker login -u oauth2accesstoken --password-stdin https://${{ env.REPOSITORY_REGION }}-docker.pkg.dev
    
        - name: Connect to GKE
          uses: google-github-actions/get-gke-credentials@v0
          with:
            cluster_name: ${{ env.CLUSTER }}
            location: ${{ env.CLUSTER_ZONE }}
    
        #
        # Build the .NET code
        #
        - name: Build solution
          run: |-
            dotnet publish applications/clouddemo/netcore/CloudDemo.MvcCore.sln \
                --configuration Release \
                --framework net6.0
    
        #
        # Build the Docker image and push it to Artifact Registry
        #
        - name: Create image tag
          run: echo "IMAGE_TAG=${{ env.REPOSITORY_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE }}:$GITHUB_SHA" >> $GITHUB_ENV
    
        - name: Lock image version in deployment.yaml
          run: sed -i 's|CLOUDDEMO_IMAGE|${{ env.IMAGE_TAG }}|g' applications/clouddemo/netcore/deployment.yaml
    
        - name: Build Docker image
          run: docker build --tag "${{ env.IMAGE_TAG }}" applications/clouddemo/netcore
    
        - name: Publish Docker image to Google Artifact Registry
          run: docker push "${{ env.IMAGE_TAG }}"
    
        #
        # Deploy to GKE
        #
        - name: Deploy to GKE
          run: kubectl apply -f applications/clouddemo/netcore/deployment.yaml
        

    Ersetzen Sie die folgenden Werte:

    • PROJECT_ID: die Projekt-ID des Projekts, das den GKE-Cluster enthält.
    • PROJECT_NUMBER: die Projektnummer des Projekts, das den GKE-Cluster enthält.
  5. Geben Sie im Abschnitt Commit für neue Datei eine Commit-Nachricht ein, z. B. Add workflow, und klicken Sie auf Commit für neue Datei.

  6. Klicken Sie im Menü auf Aktionen und warten Sie, bis der Workflow abgeschlossen ist.

    Der Workflow kann einige Minuten dauern.

  7. Aktualisieren Sie in der Google Cloud Console die Seite Dienste und eingehenden Traffic.

    Zu "Dienste & Ingress"

  8. Rufen Sie den Tab Ingress auf.

  9. Suchen Sie den Dienst für eingehenden Traffic für den Cluster clouddemo und warten Sie, bis sein Status zu OK wechselt. Dieser Vorgang kann einige Minuten dauern.

  10. Öffnen Sie den Link in der Spalte Frontends derselben Zeile. Es dauert einige Minuten, bis der Load-Balancer verfügbar ist. Die CloudDemo-Anwendung wird daher möglicherweise zuerst nicht geladen. Wenn der Load-Balancer bereit ist, sehen Sie die CloudDemo-App mit dem benutzerdefinierten Titel, diesmal im Produktionscluster.

Bereinigen

Nachdem Sie die Anleitung abgeschlossen haben, können Sie die erstellten Ressourcen bereinigen, damit sie keine Kontingente mehr nutzen und keine Gebühren mehr anfallen. In den folgenden Abschnitten erfahren Sie, wie Sie diese Ressourcen löschen oder deaktivieren.

GitHub-Repository löschen

Informationen zum Löschen des GitHub-Repositorys finden Sie unter Repository löschen. Wenn Sie das Repository löschen, gehen alle Quellcodeänderungen verloren.

Projekt löschen

Am einfachsten vermeiden Sie weitere Kosten, wenn Sie das zum Ausführen der Anleitung erstellte Projekt löschen.

    Google Cloud-Projekt löschen:

    gcloud projects delete PROJECT_ID

Nächste Schritte