Crea un clúster y, luego, implementa una carga de trabajo con Terraform

Un clúster de Kubernetes, que proporciona procesamiento, almacenamiento, herramientas de redes y otros servicios para aplicaciones, de manera similar a un centro de datos virtual. Las apps y sus servicios asociados que se ejecutan en Kubernetes se denominan cargas de trabajo.

En este instructivo, podrás ver rápidamente un clúster de Google Kubernetes Engine en ejecución y una carga de trabajo de muestra, todo configurado con Terraform. Luego, puedes explorar la carga de trabajo en la consola de Google Cloud antes de continuar con nuestra ruta de aprendizaje más detallada o comenzar a planificar y crear tu propio clúster listo para la producción. En este instructivo, se supone que ya conoces Terraform.

Si prefieres configurar tu clúster y carga de trabajo de muestra en la consola de Google Cloud , consulta Crea un clúster en la consola de Google Cloud .

Antes de comenzar

Sigue los pasos que se indican a continuación para habilitar la API de Kubernetes Engine:

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Si usas un proveedor de identidad externo (IdP), primero debes acceder a gcloud CLI con tu identidad federada.

  4. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  5. Create or select 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 (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

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

  7. Enable the GKE API:

    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.

    gcloud services enable container.googleapis.com
  8. Install the Google Cloud CLI.

  9. Si usas un proveedor de identidad externo (IdP), primero debes acceder a gcloud CLI con tu identidad federada.

  10. Para inicializar gcloud CLI, ejecuta el siguiente comando:

    gcloud init
  11. Create or select 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 (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

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

  13. Enable the GKE API:

    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.

    gcloud services enable container.googleapis.com
  14. Grant roles to your user account. Run the following command once for each of the following IAM roles: roles/container.admin, roles/compute.networkAdmin, roles/iam.serviceAccountUser

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

    Replace the following:

    • PROJECT_ID: Your project ID.
    • USER_IDENTIFIER: The identifier for your user account. For example, myemail@example.com.
    • ROLE: The IAM role that you grant to your user account.
  15. Prepare el entorno

    En este instructivo, usarás Cloud Shell para administrar recursos alojados enGoogle Cloud. Cloud Shell tiene preinstalado el software que necesitas para este instructivo, incluidos Terraform, kubectl y la CLI de Google Cloud.

    1. Para iniciar una sesión de Cloud Shell desde la Google Cloud consola, haz clic en el ícono de activación de Cloud Shell Activar Cloud Shell Botón de activar Shell. Esto inicia una sesión en el panel inferior de la consola de Google Cloud .

      Las credenciales de servicio asociadas a esta máquina virtual son automáticas, por lo que no tienes que configurar ni descargar una clave de cuenta de servicio.

    2. Antes de ejecutar comandos, configura tu proyecto predeterminado en gcloud CLI con el siguiente comando:

      gcloud config set project PROJECT_ID
      

      Reemplaza PROJECT_ID por el ID del proyecto.

    3. Clona el repositorio de GitHub:

      git clone https://github.com/terraform-google-modules/terraform-docs-samples.git --single-branch
      
    4. Cambia al directorio de trabajo:

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

    Revisa los archivos de Terraform

    El proveedorGoogle Cloud es un complemento que te permite administrar y aprovisionar recursos Google Cloud con Terraform. Sirve como puente entre las configuraciones de Terraform y las APIs de Google Cloud , lo que te permite definir de forma declarativa recursos de infraestructura, como máquinas virtuales y redes.

    El clúster y la app de muestra para este instructivo se especifican en dos archivos de Terraform que usan los proveedores de Google Cloud y Kubernetes.

    1. Revisa el archivo cluster.tf:

      cat cluster.tf
      

      El resultado es similar al que se muestra a continuación:

      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
      }

      En este archivo, se describen los siguientes recursos:

      • google_compute_network: Una red de VPC con IPv6 interno habilitado.
      • google_compute_subnetwork: Una subred de pila doble.
      • google_container_cluster: Un clúster de modo Autopilot de pila doble ubicado en us-central1. El parámetro de configuración deletion_protection controla si puedes usar Terraform para borrar este clúster. Si estableces el valor en el campo deletion_protection en false, Terraform puede borrar el clúster. Para obtener más información, consulta la referencia de google_container_cluster.
    2. Revisa el archivo app.tf:

      cat app.tf
      

      El resultado es similar a este:

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

      En este archivo, se describen los siguientes recursos:

    (Opcional) Expón la aplicación a Internet

    Los archivos de Terraform del ejemplo describen una aplicación con una dirección IP interna, a la que solo se puede acceder desde la misma nube privada virtual (VPC) que la app de ejemplo. Si deseas acceder a la interfaz web de la app de demo en ejecución desde Internet (por ejemplo, desde tu laptop), modifica los archivos de Terraform para crear una dirección IP pública antes de crear el clúster. Puedes hacerlo con un editor de texto directamente en Cloud Shell o con el editor de Cloud Shell.

    Para exponer la aplicación de demostración a Internet, haz lo siguiente:

    1. En cluster.tf, cambia ipv6_access_type de INTERNAL a EXTERNAL.

      ipv6_access_type = "EXTERNAL"
      
    2. En app.tf, configura un balanceador de cargas externo quitando la anotación networking.gke.io/load-balancer-type.

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

    Crea un clúster y, luego, implementa una aplicación

    1. En Cloud Shell, ejecuta este comando para verificar que Terraform esté disponible:

      terraform
      

      El resultado debería ser similar al siguiente ejemplo:

      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. Inicializa Terraform mediante este comando:

      terraform init
      
    3. Planifica la configuración de Terraform:

      terraform plan
      
    4. Aplica la configuración de Terraform

      terraform apply
      

      Cuando se te solicite, ingresa yes para confirmar las acciones. Este comando puede tardar varios minutos en completarse. El resultado es similar al siguiente:

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

    Verifica que el clúster funcione

    Haz lo siguiente para confirmar que tu clúster se ejecute de forma correcta:

    1. Ve a la página Cargas de trabajo en la consola de Google Cloud :

      Ir a Cargas de trabajo

    2. Haz clic en la carga de trabajo example-hello-app-deployment. Se mostrará la página de detalles del Pod. En esta página, se muestra información sobre el Pod, como las anotaciones, los contenedores que se ejecutan en el Pod, los objetos Service que exponen el Pod y las métricas que incluyen el uso de CPU, memoria y disco.

    3. Ve a la página Ingress y Service en la consola de Google Cloud :

      Ir a Ingress y Service

    4. Haz clic en el objeto Service LoadBalancer de example-hello-app-loadbalancer. Se mostrará la página de detalles de Service. En esta página, se muestra información sobre el objeto Service, como los Pods asociados con el Service y los puertos que usa el Service.

    5. En la sección Extremos externos, haz clic en el vínculo IPv4 o en el vínculo IPv6 para ver tu Service en el navegador. El resultado es similar a lo siguiente:

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

    Limpia

    Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que se usaron en esta página, borra el proyecto de Google Cloud que tiene los recursos.

    Si planeas realizar instructivos adicionales o explorar más tu muestra, espera hasta terminar para realizar este paso de limpieza.

    • En Cloud Shell, ejecuta el siguiente comando para borrar los recursos de Terraform:

      terraform destroy --auto-approve
      

    Soluciona problemas de errores de limpieza

    Si ves un mensaje de error similar a The network resource 'projects/PROJECT_ID/global/networks/example-network' is already being used by 'projects/PROJECT_ID/global/firewalls/example-network-yqjlfql57iydmsuzd4ot6n5v', haz lo siguiente:

    1. Borra las reglas de firewall:

      gcloud compute firewall-rules list --filter="NETWORK:example-network" --format="table[no-heading](name)" | xargs gcloud --quiet compute firewall-rules delete
      
    2. Vuelve a ejecutar el comando de Terraform:

      terraform destroy --auto-approve
      

    ¿Qué sigue?