יצירת אשכול ופריסת עומס עבודה באמצעות Terraform

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

במדריך הזה תוכלו לראות במהירות אשכול פעיל של Google Kubernetes Engine ועומס עבודה לדוגמה, שמוגדרים באמצעות Terraform. אחרי שתסיימו את המדריך, תוכלו לעיין בעומס העבודה במסוף Cloud de Confiance , ואז לעבור אל תוכנית הלימודים המעמיקה יותר שלנו, או להתחיל לתכנן וליצור אשכול משלכם שמוכן להפקה. במדריך הזה אנחנו מניחים שאתם כבר מכירים את Terraform.

אם אתם מעדיפים להגדיר את אשכול הדוגמה ואת עומס העבודה ב Cloud de Confiance מסוף, תוכלו לעיין במאמר יצירת אשכול ב Cloud de Confiance מסוף.

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

כדי להפעיל את Kubernetes Engine API:

  1. התקינו את ה-CLI של Google Cloud.

  2. הגדירו שה-CLI של gcloud ישתמש בזהות המאוחדת שלכם.

    איך נכנסים ל-CLI של gcloud באמצעות הזהות המאוחדת?

  3. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  4. יוצרים או בוחרים Cloud de Confiance פרויקט.

    תפקידים שנדרשים כדי לבחור או ליצור פרויקט

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים
    • יוצרים Cloud de Confiance פרויקט:

      gcloud projects create PROJECT_ID

      מחליפים את PROJECT_ID בשם של פרויקט Cloud de Confiance שיוצרים.

    • בוחרים את הפרויקט שיצרתם: Cloud de Confiance

      gcloud config set project PROJECT_ID

      מחליפים את PROJECT_ID בשם הפרויקט ב- Cloud de Confiance .

  5. מוודאים שהחיוב מופעל בפרויקט Cloud de Confiance .

  6. מפעילים את GKE API, אם הוא עדיין לא מופעל:

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, נדרשת ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין בממשק Service Usage' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    gcloud services enable container.googleapis.com
  7. מעניקים תפקידים לחשבון המשתמש. מריצים את הפקודה הבאה לכל אחד מהתפקידים הבאים ב-IAM: roles/container.admin, roles/compute.networkAdmin, roles/iam.serviceAccountUser

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    מחליפים את מה שכתוב בשדות הבאים:

הכנת הסביבה

במדריך הזה תשתמשו ב-Cloud Shell כדי לנהל משאבים שמתארחים ב-Cloud de Confiance by S3NS. ב-Cloud Shell מותקן מראש התוכנה שדרושה למדריך הזה, כולל Terraform,‏ kubectl ו-Google Cloud CLI.

  1. מפעילים סשן Cloud Shell מהמסוף Cloud de Confiance על ידי לחיצה על סמל ההפעלה של Cloud Shell‏ Activate Cloud Shell‏ כפתור ההפעלה של Shell. כך ייפתח סשן בחלונית התחתונה של Cloud de Confiance המסוף.

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

  2. לפני שמריצים פקודות, מגדירים את פרויקט ברירת המחדל ב-CLI של gcloud באמצעות הפקודה הבאה:

    gcloud config set project PROJECT_ID
    

    מחליפים את PROJECT_ID במזהה הפרויקט.

  3. משכפלים את המאגר ב-GitHub:

    git clone https://github.com/terraform-google-modules/terraform-docs-samples.git --single-branch
    
  4. עוברים לספריית העבודה:

    cd terraform-docs-samples/gke/quickstart/autopilot
    

בדיקת קובצי Terraform

‫Cloud de Confiance by S3NS פלאגין שמתממשק עם שירותים חיצוניים הוא פלאגין שמאפשר לכם לנהל ולהקצות Cloud de Confiance משאבים באמצעות Terraform. הוא משמש כגשר בין ההגדרות של Terraform לבין ממשקי API של Cloud de Confiance , ומאפשר להגדיר משאבי תשתית כמו מכונות וירטואליות ורשתות באופן הצהרתי.

האפליקציה לדוגמה והאשכול במדריך הזה מוגדרים בשני קבצי Terraform שמשתמשים בספקי Cloud de Confiance by S3NS וב-Kubernetes.

  1. בודקים את הקובץ cluster.tf:

    cat cluster.tf
    

    הפלט אמור להיראות כך:

    resource "google_compute_network" "default" {
      name = "example-network"
    
      auto_create_subnetworks  = false
      enable_ula_internal_ipv6 = true
    }
    
    resource "google_compute_subnetwork" "default" {
      name = "example-subnetwork"
    
      ip_cidr_range = "10.0.0.0/16"
      region        = "us-central1"
    
      stack_type       = "IPV4_IPV6"
      ipv6_access_type = "INTERNAL" # Change to "EXTERNAL" if creating an external loadbalancer
    
      network = google_compute_network.default.id
      secondary_ip_range {
        range_name    = "services-range"
        ip_cidr_range = "192.168.0.0/24"
      }
    
      secondary_ip_range {
        range_name    = "pod-ranges"
        ip_cidr_range = "192.168.1.0/24"
      }
    }
    
    resource "google_container_cluster" "default" {
      name = "example-autopilot-cluster"
    
      location                 = "us-central1"
      enable_autopilot         = true
      enable_l4_ilb_subsetting = true
    
      network    = google_compute_network.default.id
      subnetwork = google_compute_subnetwork.default.id
    
      ip_allocation_policy {
        stack_type                    = "IPV4_IPV6"
        services_secondary_range_name = google_compute_subnetwork.default.secondary_ip_range[0].range_name
        cluster_secondary_range_name  = google_compute_subnetwork.default.secondary_ip_range[1].range_name
      }
    
      # Set `deletion_protection` to `true` will ensure that one cannot
      # accidentally delete this instance by use of Terraform.
      deletion_protection = false
    }

    בקובץ הזה מתוארים המשאבים הבאים:

  2. בודקים את הקובץ app.tf:

    cat app.tf
    

    הפלט אמור להיראות כך:

    data "google_client_config" "default" {}
    
    provider "kubernetes" {
      host                   = "https://${google_container_cluster.default.endpoint}"
      token                  = data.google_client_config.default.access_token
      cluster_ca_certificate = base64decode(google_container_cluster.default.master_auth[0].cluster_ca_certificate)
    
      ignore_annotations = [
        "^autopilot\\.gke\\.io\\/.*",
        "^cloud\\.google\\.com\\/.*"
      ]
    }
    
    resource "kubernetes_deployment_v1" "default" {
      metadata {
        name = "example-hello-app-deployment"
      }
    
      spec {
        selector {
          match_labels = {
            app = "hello-app"
          }
        }
    
        template {
          metadata {
            labels = {
              app = "hello-app"
            }
          }
    
          spec {
            container {
              image = "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
              name  = "hello-app-container"
    
              port {
                container_port = 8080
                name           = "hello-app-svc"
              }
    
              security_context {
                allow_privilege_escalation = false
                privileged                 = false
                read_only_root_filesystem  = false
    
                capabilities {
                  add  = []
                  drop = ["NET_RAW"]
                }
              }
    
              liveness_probe {
                http_get {
                  path = "/"
                  port = "hello-app-svc"
    
                  http_header {
                    name  = "X-Custom-Header"
                    value = "Awesome"
                  }
                }
    
                initial_delay_seconds = 3
                period_seconds        = 3
              }
            }
    
            security_context {
              run_as_non_root = true
    
              seccomp_profile {
                type = "RuntimeDefault"
              }
            }
    
            # Toleration is currently required to prevent perpetual diff:
            # https://github.com/hashicorp/terraform-provider-kubernetes/pull/2380
            toleration {
              effect   = "NoSchedule"
              key      = "kubernetes.io/arch"
              operator = "Equal"
              value    = "amd64"
            }
          }
        }
      }
    }
    
    resource "kubernetes_service_v1" "default" {
      metadata {
        name = "example-hello-app-loadbalancer"
        annotations = {
          "networking.gke.io/load-balancer-type" = "Internal" # Remove to create an external loadbalancer
        }
      }
    
      spec {
        selector = {
          app = kubernetes_deployment_v1.default.spec[0].selector[0].match_labels.app
        }
    
        ip_family_policy = "RequireDualStack"
    
        port {
          port        = 80
          target_port = kubernetes_deployment_v1.default.spec[0].template[0].spec[0].container[0].port[0].name
        }
    
        type = "LoadBalancer"
      }
    
      depends_on = [time_sleep.wait_service_cleanup]
    }
    
    # Provide time for Service cleanup
    resource "time_sleep" "wait_service_cleanup" {
      depends_on = [google_container_cluster.default]
    
      destroy_duration = "180s"
    }

    בקובץ הזה מתוארים המשאבים הבאים:

(אופציונלי) חשיפת האפליקציה לאינטרנט

קבצי Terraform לדוגמה מתארים אפליקציה עם כתובת IP פנימית, שאפשר לגשת אליה רק מאותו ענן וירטואלי פרטי (VPC) שבו נמצאת אפליקציית הדוגמה. אם רוצים לגשת לממשק האינטרנט של אפליקציית ההדגמה הפועלת מהאינטרנט (לדוגמה, מהמחשב הנייד), צריך לשנות את קובצי Terraform כדי ליצור כתובת IP ציבורית לפני שיוצרים את האשכול. אפשר לעשות את זה באמצעות עורך טקסט ישירות ב-Cloud Shell או באמצעות Cloud Shell Editor.

כדי לחשוף את אפליקציית ההדגמה לאינטרנט:

  1. ב-cluster.tf, משנים את ipv6_access_type מ-INTERNAL ל-EXTERNAL.

    ipv6_access_type = "EXTERNAL"
    
  2. ב-app.tf, מסירים את ההערה networking.gke.io/load-balancer-type כדי להגדיר מאזן עומסים חיצוני.

     annotations = {
       "networking.gke.io/load-balancer-type" = "Internal" # Remove this line
     }
    

יצירת אשכול ופריסת אפליקציה

  1. ב-Cloud Shell, מריצים את הפקודה הבאה כדי לוודא ש-Terraform זמין:

    terraform
    

    הפלט אמור להיראות כך:

    Usage: terraform [global options] <subcommand> [args]
    
    The available commands for execution are listed below.
    The primary workflow commands are given first, followed by
    less common or more advanced commands.
    
    Main commands:
      init          Prepare your working directory for other commands
      validate      Check whether the configuration is valid
      plan          Show changes required by the current configuration
      apply         Create or update infrastructure
      destroy       Destroy previously-created infrastructure
    
  2. מאתחלים את Terraform:

    terraform init
    
  3. מתכננים את ההגדרות של Terraform:

    terraform plan
    
  4. החלת ההגדרות של Terraform

    terraform apply
    

    כשמופיעה בקשה, מזינים yes כדי לאשר את הפעולות. השלמת הפקודה הזו עשויה להימשך כמה דקות. הפלט אמור להיראות כך:

    Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
    

אימות הפעולה של האשכול

כדי לוודא שהאשכול פועל בצורה תקינה:

  1. נכנסים לדף Workloads במסוף Cloud de Confiance :

    כניסה לדף Workloads

  2. לוחצים על עומס העבודה example-hello-app-deployment. יוצג הדף Pod details. בדף הזה מוצג מידע על ה-Pod, כמו הערות, קונטיינרים שפועלים ב-Pod, שירותים שחושפים את ה-Pod ומדדים, כולל שימוש במעבד, בזיכרון ובדיסק.

  3. נכנסים לדף Services & Ingress במסוף Cloud de Confiance :

    כניסה אל Services & Ingress

  4. לוחצים על example-hello-app-loadbalancer LoadBalancer Service. יוצג הדף Service details (דף הפרטים). בדף הזה מוצג מידע על השירות, כמו ה-Pods שמשויכים לשירות והיציאות שבהן השירות משתמש.

  5. בקטע External endpoints (נקודות קצה חיצוניות), לוחצים על הקישור IPv4 או על הקישור IPv6 כדי להציג את השירות בדפדפן. הפלט אמור להיראות כך:

    Hello, world!
    Version: 2.0.0
    Hostname: example-hello-app-deployment-5df979c4fb-kdwgr
    

הסרת המשאבים

כדי לא לצבור חיובים בחשבון Cloud de Confiance על המשאבים שבהם השתמשתם בדף הזה, אתם צריכים למחוק את הפרויקט Cloud de Confiance יחד עם המשאבים.

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

  • ב-Cloud Shell, מריצים את הפקודה הבאה כדי למחוק את משאבי Terraform:

    terraform destroy --auto-approve
    

פתרון בעיות בניקוי

אם מופיעה הודעת שגיאה דומה ל-The network resource 'projects/PROJECT_ID/global/networks/example-network' is already being used by 'projects/PROJECT_ID/global/firewalls/example-network-yqjlfql57iydmsuzd4ot6n5v', מבצעים את הפעולות הבאות:

  1. מוחקים את הכללים של חומת האש:

    gcloud compute firewall-rules list --filter="NETWORK:example-network" --format="table[no-heading](name)" | xargs gcloud --quiet compute firewall-rules delete
    
  2. מריצים מחדש את פקודת Terraform:

    terraform destroy --auto-approve
    

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