פריסת אפליקציית ‎ .NET Framework ב-Google Kubernetes Engine באמצעות תהליך עבודה של GitHub Actions

במדריך הזה נסביר איך להשתמש בתהליך עבודה של GitHub Actions כדי לפרוס אפליקציית אינטרנט של ASP.NET Model-View-Controller ‏ (MVC) שמשתמשת ב-‎.NET Framework ב-Google Kubernetes Engine ‏ (GKE).

המדריך הזה מיועד למפתחים ולמהנדסי DevOps שיש להם ידע בסיסי ב-Microsoft .NET, ב-GitHub Actions וב-GKE. כדי לבצע את ההדרכה הזו, צריך גם חשבון ב-GitHub.

מטרות

פריסת אפליקציית אינטרנט של ASP.NET MVC שמשתמשת ב-‎ .NET Framework 4 ופועלת ב-Windows אל Google Kubernetes Engine.

בתרשים הבא מוצג תהליך העבודה של GitHub Actions לפריסת אפליקציית אינטרנט של ASP.NET MVC ב-Google Kubernetes Engine ‏ (GKE).

תרשים מושגי של תהליך העבודה של פעולות GitHub

במדריך הזה מוסבר איך לבצע את הפעולות הבאות כדי להשיג את היעד שלכם:

  • יצירת מאגר ב-GitHub
  • הגדרת אימות
  • פריסת אשכול GKE ומאגר Artifact Registry
  • יצירת תהליך עבודה של GitHub Actions

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

כדי להעריך את ההוצאות בהתאם לתחזית השימוש שלכם, אתם יכולים להיעזר במחשבון העלויות.

משתמשים חדשים של Google Cloud ? יכול להיות שאתם זכאים לתקופת ניסיון בחינם.

כשמסיימים את המשימות שמתוארות במסמך הזה אפשר למחוק את המשאבים שיצרתם כדי להימנע מחיובים נוספים. מידע נוסף זמין בקטע הסרת המשאבים.

לפני שמתחילים

  1. נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  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

יוצרים העתק של מאגר dotnet-docs-samples בחשבון GitHub. השלב הזה נדרש כי אנחנו משתמשים ב-GitHub Actions.

  1. עוברים למאגר dotnet-docs-samples ב-GitHub.
  2. לוחצים על Fork.
  3. בדף Create a new fork, מגדירים את האפשרויות הבאות:

    • בעלים – החשבון שלכם ב-GitHub
    • שם המאגרdotnet-docs-samples
  4. לוחצים על Create fork (יצירת הסתעפות).

הגדרת אימות

מכינים את הפרויקט כך ש-GitHub Actions יוכל לאמת את עצמו ולגשת למשאבים בפרויקט. Google Cloud Google Cloud

יצירה של ספק ומאגר זהויות של עומסי עבודה

כדי לאפשר לפעולות GitHub לבצע אימות Google Cloud ולפרוס ל-GKE, משתמשים באיחוד שירותי אימות הזהות של עומסי עבודה. שימוש באיחוד שירותי אימות הזהות של עומסי עבודה מאפשר לכם להימנע מהצורך לאחסן ולנהל מפתחות של חשבונות שירות עבור עומס העבודה של GitHub Actions.

כדי להשתמש באיחוד שירותי אימות הזהות של עומסי עבודה, צריך ליצור מאגר זהויות של עומסי עבודה וספק זהויות של עומסי עבודה. מומלץ להשתמש בפרויקט ייעודי לניהול מאגרי זהויות וספקים של עומסי עבודה. במדריך הזה, כדי לפשט את התהליך, ניצור את המאגר ואת הספק באותו פרויקט שבו נמצא אשכול GKE:

  1. פותחים את מסוף Google Cloud .

  2. במסוף Google Cloud , מפעילים את Cloud Shell.

    הפעלת Cloud Shell

    בחלק התחתון של Google Cloud המסוף יתחיל סשן של Cloud Shell ותופיע הודעה של שורת הפקודה. Cloud Shell היא סביבת מעטפת שבה ה-CLI של Google Cloud מותקן ומוגדרים ערכים לפרויקט הקיים. הסשן יופעל תוך כמה שניות.

  3. יצירת מאגר זהויות חדש של עומסי עבודה:

    gcloud iam workload-identity-pools create github-actions \
        --location="global" \
        --description="GitHub Actions tutorial" \
        --display-name="GitHub Actions"
    
  4. הוספת GitHub Actions כספק של מאגר זהויות של עומסי עבודה:

    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'"
    

    מחליפים את ORGANIZATION בשם ארגון GitHub שלכם.

יצירה של חשבון שירות

  1. ב-Cloud Shell, יוצרים חשבון שירות ש-GitHub Actions יכול להשתמש בו כדי לפרסם תמונות Docker ולפרוס אותן ב-GKE:

    SERVICE_ACCOUNT=$(gcloud iam service-accounts create github-actions-workflow \
      --display-name "GitHub Actions workflow" \
      --format "value(email)")
    
  2. מקצים את התפקיד 'בעל הרשאת כתיבה ב-Artifact Registry' (roles/artifactregistry.writer) לחשבון השירות כדי לאפשר לפעולות GitHub לשלוח אל Artifact Registry:

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
      --member serviceAccount:$SERVICE_ACCOUNT \
      --role roles/artifactregistry.writer
    
  3. מקצים את תפקיד המפתח של Google Kubernetes Engine (roles/container.developer) לחשבון השירות כדי לאפשר לפעולות GitHub לשלוח אל Artifact Registry:

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

מתן הרשאה לתהליך העבודה של GitHub Actions להשתמש בחשבון השירות

מתן הרשאה לתהליך העבודה של GitHub Actions להתחזות לחשבון השירות ולהשתמש בו:

  1. מאתחלים משתנה סביבה שמכיל את הנושא שמשמש את תהליך העבודה של GitHub Actions. נושא דומה לשם משתמש שמזהה באופן ייחודי את המאגר וההסתעפות ב-GitHub:

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

    מחליפים את OWNER בשם המשתמש שלכם ב-GitHub.

  2. נותנים לנושא הרשאה להתחזות לחשבון השירות:

    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 ומאגר Artifact Registry

  1. יוצרים מאגר לתמונות Docker:

    gcloud artifacts repositories create clouddemo \
      --repository-format=docker \
      --location=us-central1
    
  2. מתן אפשרות לחשבון השירות של Compute Engine שמוגדר כברירת מחדל לגשת למאגר:

    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. יוצרים את האשכול:

    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
    

    יכול להיות שיעברו כמה דקות עד שהפקודה הזו תסתיים.

  4. מקבלים את שם הפרויקט ואת מספר הפרויקט של האשכול:

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

    תצטרכו את הערכים האלה בהמשך.

יצירת תהליך עבודה של GitHub Actions

מעכשיו אפשר להשתמש ב-GitHub Actions כדי להגדיר שילוב רציף. לכל קומיט שנדחף למאגר Git, תהליך עבודה של GitHub Actions בונה את הקוד ואורז את תוצרי הבנייה במאגר Docker. לאחר מכן מאגר התגים מתפרסם ב-Artifact Registry.

המאגר כבר מכיל את קובץ ה-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"]

המאגר מכיל גם מניפסט של 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

יוצרים תהליך עבודה של GitHub Actions שמבצע את הפעולות הבאות:

  • מתבצע אימות ל- Google Cloud באמצעות איחוד שירותי אימות הזהות של עומסי עבודה וחשבון השירות שיצרתם קודם.
  • יצירת קובץ אימג' של Docker ופריסתו ב-Artifact Registry.
  • פורסים את קובץ אימג' של Docker ב-GKE.

כדי ליצור את תהליך העבודה של GitHub Actions:

  1. ב-GitHub, עוברים למאגר המחובר dotnet-docs-samples.
  2. לוחצים על הוספת קובץ > יצירת קובץ חדש.
  3. בתיבת הטקסט Name your file (מתן שם לקובץ), מזינים את השם הבא:

    .github/workflows/deploy-gke.yaml
    
  4. מעתיקים את הקוד הבא לקובץ:

    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
    

    מחליפים את הערכים הבאים:

    • PROJECT_ID: מזהה הפרויקט שמכיל את אשכול GKE.
    • PROJECT_NUMBER: מספר הפרויקט שמכיל את אשכול GKE.
  5. בקטע Commit new file (ביצוע שינוי בקובץ חדש), מזינים הודעת שינוי, למשל, Add workflow ולוחצים על Commit new file (ביצוע שינוי בקובץ חדש).

  6. בתפריט, לוחצים על פעולות וממתינים לסיום תהליך העבודה.

    יכול להיות שיחלפו כמה דקות עד שהתהליך יסתיים.

  7. במסוף Google Cloud , מרעננים את הדף Services & Ingress.

    כניסה אל Services & Ingress

  8. עוברים לכרטיסייה Ingress.

  9. מחפשים את שירות ה-Ingress של אשכול clouddemo ומחכים שהסטטוס שלו ישתנה ל-Ok. הפעולה עשויה להימשך כמה דקות.

  10. פותחים את הקישור בעמודה Frontends באותה שורה. יכול להיות שיעברו כמה דקות עד שמאזן העומסים יהיה זמין, ולכן יכול להיות שהאפליקציה CloudDemo לא תיטען בהתחלה. כמאזן העומסים יהיה מוכן, תראו את האפליקציה CloudDemo עם הכותרת המותאמת אישית, והפעם היא תפעל באשכול הייצור.

הסרת המשאבים

כשמסיימים את המדריך, אפשר למחוק את המשאבים שיצרתם, כדי שהם יפסיקו להשתמש במכסה ולצבור חיובים. הסעיפים הבאים נסביר איך למחוק או להשבית את המשאבים האלו.

מחיקת המאגר ב-GitHub

הוראות למחיקת מאגר ב-GitHub מופיעות במאמר מחיקת מאגר. מחיקת המאגר תגרום לאובדן של כל השינויים בקוד המקור.

מחיקת הפרויקט

הדרך הקלה ביותר לבטל את החיוב היא למחוק את הפרויקט שיצרתם בשביל המדריך.

    כדי למחוק Google Cloud פרויקט:

    gcloud projects delete PROJECT_ID

המאמרים הבאים