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 Google Cloud consola de 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 Google Cloud consola, consulta Crea un clúster en la Google Cloud consola.

Antes de comenzar

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

  1. Accede a tu Google Cloud cuenta de. Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
  2. Instala Google Cloud CLI.

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

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

    gcloud init
  5. Crea o selecciona un Google Cloud proyecto.

    Roles necesarios para seleccionar o crear un proyecto

    • Seleccionar un proyecto: La selección de un proyecto no requiere un rol de IAM específico. Puedes seleccionar cualquier proyecto en el que se te haya otorgado un rol.
    • Crear un proyecto: Para crear un proyecto, necesitas el rol de creador de proyectos (roles/resourcemanager.projectCreator), que contiene el resourcemanager.projects.create permiso. Obtén información para otorgar roles.
    • Crea un proyecto de: Google Cloud

      gcloud projects create PROJECT_ID

      Reemplaza PROJECT_ID por un nombre para el Google Cloud proyecto de que estás creando.

    • Selecciona el Google Cloud proyecto de que creaste:

      gcloud config set project PROJECT_ID

      Reemplaza PROJECT_ID por el nombre de tu Google Cloud proyecto de.

  6. Verifica que la facturación esté habilitada para tu Google Cloud proyecto.

  7. Habilita la API de GKE:

    Roles necesarios para habilitar las APIs

    Para habilitar las APIs, necesitas el rol de IAM de administrador de Service Usage (roles/serviceusage.serviceUsageAdmin), que contiene el serviceusage.services.enable permiso. Obtén información para otorgar roles.

    gcloud services enable container.googleapis.com
  8. Instala Google Cloud CLI.

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

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

    gcloud init
  11. Crea o selecciona un Google Cloud proyecto.

    Roles necesarios para seleccionar o crear un proyecto

    • Seleccionar un proyecto: La selección de un proyecto no requiere un rol de IAM específico. Puedes seleccionar cualquier proyecto en el que se te haya otorgado un rol.
    • Crear un proyecto: Para crear un proyecto, necesitas el rol de creador de proyectos (roles/resourcemanager.projectCreator), que contiene el resourcemanager.projects.create permiso. Obtén información para otorgar roles.
    • Crea un proyecto de: Google Cloud

      gcloud projects create PROJECT_ID

      Reemplaza PROJECT_ID por un nombre para el Google Cloud proyecto de que estás creando.

    • Selecciona el Google Cloud proyecto de que creaste:

      gcloud config set project PROJECT_ID

      Reemplaza PROJECT_ID por el nombre de tu Google Cloud proyecto de.

  12. Verifica que la facturación esté habilitada para tu Google Cloud proyecto.

  13. Habilita la API de GKE:

    Roles necesarios para habilitar las APIs

    Para habilitar las APIs, necesitas el rol de IAM de administrador de Service Usage (roles/serviceusage.serviceUsageAdmin), que contiene el serviceusage.services.enable permiso. Obtén información para otorgar roles.

    gcloud services enable container.googleapis.com
  14. Otorga roles a tu cuenta de usuario. Ejecuta el siguiente comando una vez para cada uno de los siguientes roles de IAM: roles/container.admin, roles/compute.networkAdmin, roles/iam.serviceAccountUser

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

    Reemplaza lo siguiente:

    • PROJECT_ID: ID del proyecto
    • USER_IDENTIFIER: Es el identificador de tu cuenta de usuario de . Por ejemplo, myemail@example.com.
    • ROLE: Es el rol de IAM que otorgas a tu cuenta de usuario.

Prepare el entorno

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

  1. Para iniciar una sesión de Cloud Shell desde la Google Cloud consola de, 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 Google Cloud consola de.

    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 Google Cloud proveedor es un complemento que te permite administrar y aprovisionar Google Cloud recursos con Terraform. Sirve como un puente entre las opciones de configuración de Terraform y las Google Cloud APIs, lo que te permite definir recursos de infraestructura, como máquinas virtuales y redes, de manera declarativa.

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 interna habilitada.
    • 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 google_container_cluster referencia.
  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 para el 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 muestra. 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 en su lugar 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 a través de la eliminación de la networking.gke.io/load-balancer-type anotación.

     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. Accede a la página Cargas de trabajo de la Google Cloud consola de:

    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. Accede a la página Ingress y Service de la Google Cloud consola de:

    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 Google Cloud cuenta de por los recursos que usaste en esta página, borra el Google Cloud proyecto de que tiene los recursos.

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

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

    terraform destroy --auto-approve
    

Soluciona 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?