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

In dieser Anleitung wird beschrieben, wie Sie mit einem GitHub Actions, Workflow eine ASP.NET Model-View-Controller (MVC)-Webanwendung, die .NET verwendet, in Google Kubernetes Engine (GKE) bereitstellen.

Diese Anleitung richtet sich an Entwickler und DevOps-Entwickler mit Grundkenntnissen in Microsoft .NET, GitHub Actions und GKE. Außerdem benötigen Sie ein GitHub-Konto, um diese Anleitung auszuführen.

Ziele

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

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

Konzeptdiagramm des GitHub Actions-Workflows

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. Verwenden Sie den Preisrechner.

Neuen Google Cloud Nutzern vonsteht 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 in Ihrem Google Cloud -Konto an. Wenn Sie mit Google Cloudnoch nicht vertraut sind, erstellen Sie ein Konto, um die Leistung 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. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Artifact Registry and Google Kubernetes Engine APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Artifact Registry and Google Kubernetes Engine APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the 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 dotnet-docs-samples GitHub-Repository auf.
  2. Klicken Sie auf Fork.
  3. Legen Sie auf der Seite Neuen 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 vor, damit sich GitHub Actions authentifizieren und auf Ressourcen im Google Cloud Projekt zugreifen kann.

Workload Identity-Föderationspool und -Anbieter erstellen

Damit sich GitHub Actions authentifizieren Google Cloud und in GKE bereitstellen kann, verwenden Sie die Workload Identity-Föderation. Mithilfe 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 Workload Identity-Anbieter erforderlich. Wir empfehlen, ein dediziertes Projekt zur Verwaltung von Workload Identity-Pools und -Anbietern zu verwenden. Der Einfachheit halber erstellen Sie in dieser Anleitung den Pool und den Anbieter im selben Projekt wie Ihren GKE-Cluster:

  1. Öffnen Sie die Google Cloud Console.

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

    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 Workload Identity-Poolanbieter 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" \
        --attribute-condition="assertion.repository_owner=='ORGANIZATION'"
    

    Ersetzen Sie ORGANIZATION durch den Namen Ihrer GitHub-Organisation.

Dienstkonto erstellen

  1. Erstellen Sie in Cloud Shell ein Dienstkonto, das von GitHub Actions zum Veröffentlichen von Docker-Images und zum Bereitstellen in GKE verwendet werden kann:

    SERVICE_ACCOUNT=$(gcloud iam service-accounts create github-actions-workflow \
      --display-name "GitHub Actions workflow" \
      --format "value(email)")
    
  2. Weisen Sie dem Dienstkonto die Rolle „ Artifact Registry-Autor“ (roles/artifactregistry.writer) zu, damit GitHub Actions per Push in Artifact Registry übertragen kann:

    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 „ Kubernetes Engine-Entwickler (roles/container.developer) zu, damit GitHub Actions per Push in Artifact Registry übertragen kann:

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

GitHub Actions-Workflow die Verwendung des Dienstkontos erlauben

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

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

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

    Ersetzen Sie OWNER durch Ihren GitHub-Nutzernamen.

  2. Erteilen Sie dem Subjekt 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. Erlauben Sie dem Compute Engine-Standarddienstkonto den 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 mit GitHub Actions die kontinuierliche Integration einrichten. Für jeden Commit, der an das Git-Repository gesendet wird, erstellt ein GitHub Actions-Workflow 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 außerdem 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. Google Cloud
  • Erstellen Sie ein Docker-Image und stellen Sie es in Artifact Registry bereit.
  • Stellen Sie das Docker-Image in GKE bereit.

So erstellen Sie den GitHub Actions-Workflow:

  1. Rufen Sie auf GitHub Ihren Fork des dotnet-docs-samples Repositorys auf.
  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 Bereich Neue Datei committen eine Commit-Nachricht ein, z. B. Add workflow, und klicken Sie auf Neue Datei committen.

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

    Die Ausführung des Workflows kann mehrere Minuten dauern.

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

    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 der Status zu OK wechselt. Dieser Vorgang kann einige Minuten dauern.

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

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 Änderungen am Quellcode verloren.

Projekt löschen

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

    Projekt löschen: Google Cloud

    gcloud projects delete PROJECT_ID

Nächste Schritte