Terraform을 사용하여 GKE 클러스터 만들기 및 워크로드 배포


이 빠른 시작에서는 Google Kubernetes Engine(GKE) Autopilot 클러스터를 만들고 Terraform을 사용하여 워크로드를 배포하는 방법을 알아봅니다.

코드형 인프라(IaC)는 코드를 사용하여 소프트웨어 인프라 리소스를 관리하고 프로비저닝하는 방식입니다. Terraform은 GKE를 포함한 다양한 Cloud 서비스를 지원하는 널리 사용되는 오픈소스 IaC 도구입니다. GKE 플랫폼 관리자는 Terraform을 사용하여 Kubernetes 클러스터 구성을 표준화하고 DevOps 워크플로를 간소화할 수 있습니다. 자세한 내용은 GKE에 대한 Terraform 지원을 참조하세요.

목표

  • IPv6 Virtual Private Cloud(VPC) 네트워크 만들기
  • GKE Autopilot 클러스터 만들기
  • 클러스터에 워크로드 배포
  • 서비스를 사용하여 워크로드 노출

시작하기 전에

다음 단계에 따라 Kubernetes Engine API를 사용 설정합니다.

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  3. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  4. GKE API 사용 설정

    API 사용 설정

  5. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  6. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  7. GKE API 사용 설정

    API 사용 설정

  8. 프로젝트에 다음 역할이 있는지 확인합니다. roles/container.admin, roles/compute.networkAdmin, roles/iam.serviceAccountUser

    역할 확인

    1. Google Cloud 콘솔에서 IAM 페이지로 이동합니다.

      IAM으로 이동
    2. 프로젝트를 선택합니다.
    3. 주 구성원 열에서 이메일 주소가 있는 행을 찾습니다.

      이메일 주소가 열에 없으면 역할이 없는 것입니다.

    4. 이메일 주소가 있는 행에 대해 역할 열에서 역할 목록에 필요한 역할이 있는지 확인합니다.

    역할 부여

    1. Google Cloud 콘솔에서 IAM 페이지로 이동합니다.

      IAM으로 이동
    2. 프로젝트를 선택합니다.
    3. 액세스 권한 부여를 클릭합니다.
    4. 새 주 구성원 필드에 이메일 주소를 입력합니다.
    5. 역할 선택 목록에서 역할을 선택합니다.
    6. 역할을 추가로 부여하려면 다른 역할 추가를 클릭하고 각 역할을 추가합니다.
    7. 저장을 클릭합니다.

Terraform 기본사항을 잘 알고 있어야 합니다. 다음 리소스를 사용할 수 있습니다.

환경 준비

이 튜토리얼에서는 Cloud Shell을 사용하여 Google Cloud에서 호스팅되는 리소스를 관리합니다. Cloud Shell에는 Terraform, kubectl, Google Cloud CLI를 포함하여 이 튜토리얼에 필요한 소프트웨어가 사전에 설치되어 있습니다.

  1. Cloud Shell 활성화 아이콘 Cloud Shell 활성화 셸 활성화 버튼를 클릭하여 Google Cloud 콘솔에서 Cloud Shell 세션을 시작합니다. 그러면 Google Cloud 콘솔 하단 창에서 세션이 시작됩니다.

    이 가상 머신과 연결된 서비스 사용자 인증 정보가 자동으로 생성되므로 서비스 계정 키를 설정하거나 다운로드할 필요가 없습니다.

  2. 명령어를 실행하기 전에 다음 명령어를 사용하여 gcloud CLI에서 기본 프로젝트를 설정합니다.

    gcloud config set project PROJECT_ID
    

    여기서 PROJECT_ID프로젝트 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 파일 검토

Google Cloud Provider는 HashiCorp의 코드형 인프라(IaC) 도구인 Terraform을 사용하여 Google Cloud 리소스를 관리하고 프로비저닝할 수 있게 해주는 플러그인입니다. Terraform 구성과 Google Cloud API 사이의 브리지 역할을 하므로 선언적 방식으로 가상 머신 및 네트워크와 같은 인프라 리소스를 정의할 수 있습니다.

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

    이 파일은 다음 리소스를 설명합니다.

    • 샘플 컨테이너 이미지가 포함된 배포
    • LoadBalancer 유형의 서비스. 이 서비스는 포트 80에서 배포를 노출합니다. 애플리케이션을 인터넷에 노출하려면 networking.gke.io/load-balancer-type 주석을 삭제하여 외부 부하 분산기를 구성합니다.

클러스터 만들기 및 애플리케이션 배포

  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. Google Cloud 콘솔에서 워크로드 페이지로 이동합니다.

    워크로드로 이동

  2. example-hello-app-deployment 워크로드를 클릭합니다. 포드 세부정보 페이지가 표시됩니다. 이 페이지에는 주석, 포드에서 실행되는 컨테이너, 포드를 노출하는 서비스, 측정항목(예: CPU, 메모리, 디스크 사용량)과 같은 포드에 대한 정보가 표시됩니다.

  3. Google Cloud 콘솔에서 서비스 및 인그레스 페이지로 이동합니다.

    서비스 및 인그레스로 이동

  4. example-hello-app-loadbalancer LoadBalancer 서비스를 클릭합니다. 서비스 세부정보 페이지가 표시됩니다. 이 페이지에는 서비스와 연결된 포드 및 서비스에서 사용하는 포트와 같은 서비스에 대한 정보가 표시됩니다.

  5. 외부 엔드포인트 섹션에서 IPv4 링크 또는 IPv6 링크를 클릭하여 브라우저에서 서비스를 봅니다. 출력은 다음과 비슷합니다.

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

삭제

이 페이지에서 사용한 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 다음 단계를 수행합니다.

이 페이지에서 사용한 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 다음 단계를 수행합니다.

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
    

다음 단계

  • Google Cloud Provider 문서에서 google_container_clustergoogle_container_node_pool 리소스를 살펴봅니다. 이 페이지에서는 Google이 Terraform에서 지원하는 GKE 클러스터 및 노드 풀 구성의 인수와 속성을 설명합니다.
  • Terraform GKE 모듈 GitHub 저장소의 독자적인 구성 샘플을 참조하세요.