Esegui il deployment di un'app .NET Framework in Google Kubernetes Engine utilizzando un flusso di lavoro Azioni di GitHub


Questo tutorial descrive come utilizzare un'azione di GitHub, un flusso di lavoro per eseguire il deployment di un'applicazione web ASP.NET Model-View-Controller (MVC) che utilizza .NET Framework a Google Kubernetes Engine (GKE).

Questo tutorial è destinato agli sviluppatori e agli ingegneri DevOps che hanno una conoscenza di base di Microsoft .NET, GitHub Actions e GKE. Devi inoltre avere un account GitHub per eseguire questo tutorial.

Obiettivi

Esegui il deployment di un'applicazione web ASP.NET MVC che utilizza .NET Framework 4 ed esegui su Windows su Google Kubernetes Engine.

Il seguente diagramma mostra il flusso di lavoro Azioni di GitHub per eseguire il deployment di un'applicazione web ASP.NET MVC in Google Kubernetes Engine (GKE).

Diagramma concettuale del flusso di lavoro di azioni GitHub

Questo tutorial mostra come completare le attività seguenti per raggiungere il tuo obiettivo:

  • Crea un repository GitHub
  • Configura l'autenticazione
  • Esegui il deployment di un cluster GKE e di un repository Artifact Registry
  • Crea un flusso di lavoro GitHub Actions

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud possono essere idonei a una prova senza costi aggiuntivi.

Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.

Prima di iniziare

  1. Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  3. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  4. Abilita le API Artifact Registry and Google Kubernetes Engine.

    Abilita le API

  5. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  6. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  7. Abilita le API Artifact Registry and Google Kubernetes Engine.

    Abilita le API

Crea un repository GitHub

Crea un fork del repository dotnet-docs-samples nel tuo account GitHub. Questo passaggio è necessario perché stiamo creando con GitHub Actions.

  1. Vai al repository GitHub dotnet-docs-samples.
  2. Fai clic su Fork.
  3. Nella pagina Crea un nuovo fork, imposta quanto segue:

    • Proprietario - Il tuo account GitHub
    • Nome repository - dotnet-docs-samples
  4. Fai clic su Crea forchetta.

Configura l'autenticazione

Prepara il tuo progetto Google Cloud in modo che le azioni GitHub possano autenticare e accedere alle risorse nel progetto Google Cloud.

Crea un pool e un provider di federazione di Workload Identity

Per consentire alle azioni GitHub di autenticare Google Cloud ed eseguire il deployment in GKE, utilizza la federazione delle identità per i carichi di lavoro. Utilizzando la federazione delle identità per i carichi di lavoro, puoi evitare di archiviare e gestire le chiavi dell'account di servizio per il carico di lavoro di GitHub.

Per utilizzare la federazione delle identità dei carichi di lavoro sono necessari un pool di identità e un provider di carichi di lavoro. Ti consigliamo di utilizzare un progetto dedicato per gestire i pool di identità e i provider di carichi di lavoro. In questo tutorial, per semplificare le cose, crea il pool e il provider nello stesso progetto del tuo cluster GKE:

  1. Apri la console Google Cloud.

  2. Nella console Google Cloud, attiva Cloud Shell.

    Attiva Cloud Shell

    Nella parte inferiore della console Google Cloud viene avviata una sessione di Cloud Shell che mostra un prompt della riga di comando. Cloud Shell è un ambiente shell con Google Cloud CLI già installato e con valori già impostati per il progetto attuale. L'inizializzazione della sessione può richiedere alcuni secondi.

  3. Crea un nuovo pool Workload Identity:

    gcloud iam workload-identity-pools create github-actions \
        --location="global" \
        --description="GitHub Actions tutorial" \
        --display-name="GitHub Actions"
    
  4. Aggiungi azioni GitHub come provider di pool di identità del carico di lavoro:

    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"
    

Crea un account di servizio

  1. In Cloud Shell, crea un account di servizio che GitHub Actions possa utilizzare per pubblicare immagini Docker ed eseguirne il deployment in GKE:

    SERVICE_ACCOUNT=$(gcloud iam service-accounts create github-actions-workflow \
      --display-name "GitHub Actions workflow" \
      --format "value(email)")
    
  2. Concedi il ruolo di autore Artifact Registry (roles/artifactregistry.writer) all'account di servizio per consentire il push delle azioni GitHub ad Artifact Registry:

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
      --member serviceAccount:$SERVICE_ACCOUNT \
      --role roles/artifactregistry.writer
    
  3. Concedi il ruolo sviluppatore Google Kubernetes Engine (roles/container.developer) all'account di servizio per consentire il push delle azioni GitHub ad Artifact Registry:

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

Consenti al flusso di lavoro di GitHub Actions di utilizzare l'account di servizio

Consenti al flusso di lavoro di GitHub Actions di impersonare e utilizzare l'account di servizio:

  1. Inizializzare una variabile di ambiente contenente l'oggetto utilizzato dal flusso di lavoro delle azioni GitHub. Un oggetto è simile a un nome utente che identifica in modo univoco il repository e il ramo GitHub:

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

    Sostituisci OWNER con il tuo nome utente GitHub.

  2. Concedi all'oggetto l'autorizzazione a utilizzare l'identità dell'account di servizio:

    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"
    

Esegui il deployment di un cluster GKE e di un repository Artifact Registry

  1. Crea un repository per le immagini Docker:

    gcloud artifacts repositories create clouddemo \
      --repository-format=docker \
      --location=us-central1
    
  2. Consenti all'account di servizio predefinito di Compute Engine di accedere al 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. Crea il cluster:

    gcloud container clusters create clouddemo-windows \
      --enable-ip-alias \
      --zone us-central1-a
    
    gcloud container node-pools create clouddemo-windows-pool \
      --cluster=clouddemo-windows \
      --image-type=WINDOWS_LTSC_CONTAINERD \
      --no-enable-autoupgrade \
      --machine-type=n1-standard-2 \
      --zone us-central1-a
    

    Il completamento di questo comando potrebbe richiedere diversi minuti.

  4. Recupera il nome e il numero del progetto del cluster:

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

    Questi valori sono necessari in un secondo momento.

Crea un flusso di lavoro GitHub Actions

Ora puoi utilizzare GitHub Actions per configurare l'integrazione continua. Per ogni impegno di cui viene eseguito il push nel repository Git, un flusso di lavoro di azioni GitHub crea il codice e pacchettizza gli artefatti di build in un container Docker. Il container viene quindi pubblicato in Artifact Registry.

Il repository contiene già il seguente 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/windows/servercore/iis:windowsservercore-ltsc2019
EXPOSE 80
SHELL ["powershell", "-command"]

#------------------------------------------------------------------------------
# Add LogMonitor so that IIS and Windows logs are emitted to STDOUT and can be
# picked up by Docker/Kubernetes.
#
# See https://github.com/microsoft/windows-container-tools/wiki/Authoring-a-Config-File
# for details.
#------------------------------------------------------------------------------

ADD https://github.com/microsoft/windows-container-tools/releases/download/v1.1/LogMonitor.exe LogMonitor/
ADD LogMonitorConfig.json LogMonitor/

#------------------------------------------------------------------------------
# Copy publishing artifacts to webroot.
#------------------------------------------------------------------------------

ADD CloudDemo.Mvc/bin/Release/PublishOutput/ c:/inetpub/wwwroot/

#------------------------------------------------------------------------------
# Configure IIS using the helper functions from deployment.ps1.
#------------------------------------------------------------------------------

ADD deployment.ps1 /
RUN . /deployment.ps1; \
	Install-Iis; \
	Register-WebApplication -AppName "CloudDemo"; \
	Remove-Item /deployment.ps1

#------------------------------------------------------------------------------
# Run IIS, wrapped by LogMonitor.
#------------------------------------------------------------------------------

ENTRYPOINT ["C:\\LogMonitor\\LogMonitor.exe", "C:\\ServiceMonitor.exe", "w3svc"]

Il repository contiene anche un manifest Kubernetes:

#
# 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-net4
  annotations:
    cloud.google.com/neg: '{"ingress": false}' # Disable NEG

spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: clouddemo-net4
  type: NodePort

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

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: clouddemo-net4
spec:
  replicas: 2
  selector:
    matchLabels:
      app: clouddemo-net4
  template:
    metadata:
      labels:
        app: clouddemo-net4
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      containers:
      - name: clouddemo-net4
        image: CLOUDDEMO_IMAGE
        ports:
          - containerPort: 80
        livenessProbe:      # Used by deployment controller
          httpGet:
            path: /health
            port: 80
          initialDelaySeconds: 120
          periodSeconds: 5
        readinessProbe:     # Used by Ingress/GCLB
          httpGet:
            path: /health
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
        resources:
          limits:
            memory: 1024Mi
          requests:
            memory: 256Mi

Crea un flusso di lavoro di azioni GitHub che:

  • Esegui l'autenticazione in Google Cloud utilizzando la federazione delle identità dei carichi di lavoro e l'account di servizio creato in precedenza.
  • Crea un'immagine Docker ed esegui il deployment su Artifact Registry.
  • Eseguire il deployment dell'immagine Docker su GKE.

Per creare il flusso di lavoro delle azioni GitHub, procedi nel seguente modo:

  1. Su GitHub, vai al fork del repository dotnet-docs-samples.
  2. Fai clic su Aggiungi file > Crea nuovo file.
  3. Nel campo di testo Assegna un nome al file, inserisci il seguente nome:

    .github/workflows/deploy-gke.yaml
    
  4. Copia il seguente codice nel file:

    name: Build and Deploy to GKE
    
    on:
      push:
        branches:
          - main
    
    env:
      PROJECT_ID: PROJECT_ID
      PROJECT_NUMBER: PROJECT_NUMBER
    
      CLUSTER: clouddemo-windows
      CLUSTER_ZONE: us-central1-a
    
      REPOSITORY: clouddemo
      REPOSITORY_REGION: us-central1
    
      IMAGE: clouddemo
    
    jobs:
      build:
        runs-on: windows-2019  # Matches WINDOWS_LTSC in GKE
        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: Setup MSBuild
          uses: microsoft/setup-msbuild@v1
    
        - name: Setup NuGet
          uses: NuGet/setup-nuget@v1
    
        - name: Restore NuGet packages
          run: nuget restore applications/clouddemo/net4/CloudDemo.Mvc.sln
    
        - name: Build solution
          run: msbuild /t:Rebuild /p:Configuration=Release /p:DeployOnBuild=true /p:PublishProfile=FolderProfile /nologo applications/clouddemo/net4/CloudDemo.Mvc.sln
    
        #
        # 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 }}:$env:GITHUB_SHA" >> $env:GITHUB_ENV
    
        - name: Lock image version in deployment.yaml
          shell: pwsh
          run: (Get-Content applications\clouddemo\net4\deployment.yaml) -replace "CLOUDDEMO_IMAGE","${{ env.IMAGE_TAG }}" | Out-File -Encoding ASCII applications\clouddemo\net4\deployment.yaml
    
        - name: Build Docker image
          run: docker build --tag "${{ env.IMAGE_TAG }}" applications/clouddemo/net4
    
        - 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/net4/deployment.yaml
    

    Sostituisci i seguenti valori:

    • PROJECT_ID: l'ID del progetto che contiene il cluster GKE.
    • PROJECT_NUMBER: il numero del progetto che contiene il cluster GKE.
  5. Nella sezione Esegui il commit di un nuovo file, inserisci un messaggio di commit, ad esempio Add workflow, e fai clic su Commetti nuovo file.

  6. Nel menu, fai clic su Azioni e attendi il completamento del flusso di lavoro.

    Il flusso di lavoro potrebbe richiedere diversi minuti.

  7. Nella console Google Cloud, aggiorna la pagina Servizi e Ingress.

    Vai a Servizi e Ingress

  8. Vai alla scheda In entrata.

  9. Individua il servizio Ingress per il cluster clouddemo e attendi che il suo stato passi a OK. L'operazione potrebbe richiedere alcuni minuti.

  10. Apri il link nella colonna Frontend della stessa riga. Il bilanciatore del carico richiede alcuni minuti per diventare disponibile, quindi l'app CloudDemo potrebbe non caricarsi all'inizio. Quando il bilanciatore del carico è pronto, vedrai l'app CloudDemo con il titolo personalizzato, questa volta in esecuzione nel cluster di produzione.

Esegui la pulizia

Una volta completato il tutorial, puoi eseguire la pulizia delle risorse che hai creato in modo che smettano di utilizzare la quota e vengano addebitati dei costi. Le seguenti sezioni descrivono come eliminare o disattivare queste risorse.

Elimina il repository GitHub

Per eliminare il repository GitHub, consulta la sezione Eliminazione di un repository. L'eliminazione del repository causa la perdita di tutte le modifiche al codice sorgente.

Elimina il progetto

Il modo più semplice per eliminare la fatturazione è eliminare il progetto che hai creato per il tutorial.

    Elimina un progetto Google Cloud:

    gcloud projects delete PROJECT_ID

Passaggi successivi