Terraform을 사용하여 GCE에서 컨테이너를 실행하는 가장 쉬운 방법

최근에 저는 데이터베이스를 통해 게시된 작업을 수신하는 작업자를 개발했습니다. 이를 위해 Django Q을 사용했습니다. 개발을 마쳤을 때 프로덕션에서 어떻게 활성화할지 궁금해지기 시작했습니다. 내 전체 스택이 개인 프로젝트를 위해 GCP에 있기 때문에 컨테이너 이미지를 사용하여 Google Compute Engine과 함께 배포하는 흥미로운 방법을 찾았습니다. Terraform 의 도움으로 어떻게 하면 꽤 빨리 할 수 ​​있는지 봅시다.

시작하기 전에 알아야 할 몇 가지 제한 사항



이 솔루션에 시간을 할애하기 전에 주의해야 할 some limitations 이 있습니다. 특히 다음 두 가지는 문제를 일으킬 수 있습니다.
  • 각 VM 인스턴스에 대해 하나의 컨테이너만 배포할 수 있습니다. VM 인스턴스당 여러 컨테이너를 배포해야 하는 경우 Google Kubernetes Engine을 고려하세요.
  • 액세스 권한이 있는 공용 저장소 또는 개인 Container Registry 저장소에서만 컨테이너를 배포할 수 있습니다. 다른 개인 리포지토리는 지원되지 않습니다.

  • 이 예에서는 Container Registry의 비공개 이미지를 사용하고 이를 위해 이를 읽고 다운로드할 수 있는 사용자가 필요합니다.

    Container Registry에서 이미지를 다운로드할 수 있는 서비스 계정을 만드는 방법



    create a service account with Terraform 할 수도 있지만 명령줄을 계속 사용하겠습니다. 계정을 만들기 위해 다음을 발행할 수 있습니다.

    gcloud iam service-accounts create custom-gce-dealer \
    --display-name "Custom GCE Dealer"
    


    컨테이너 레지스트리에 사용되는 스토리지를 확인해야 합니다. artifacts.agrabah-project.appspot.com라고 가정해 보겠습니다. 그런 다음 서비스 계정에 대해 생성된 ID를 사용하여 다음 명령어를 실행할 수 있습니다.

    gsutil iam ch \
    serviceAccount:[email protected]:roles/storage.objectViewer \
    gs://artifacts.agrabah-project.appspot.com
    


    이것이 컨테이너 레지스트리에서 이미지를 체크아웃하는 데 필요한 전부입니다.

    Terraform 매니페스트



    module that handles the metadata needed to set up the container configuration for the resource google_compute_instance을 찾았습니다. 이것을 사용하여 우리만의 모듈을 만들어 봅시다. 따라서 우리의 main.tf 파일은 방대하거나 이해하기 어렵지 않습니다. 먼저 다음 구조로 프로젝트를 시작하겠습니다.

    root-folder-of-your-project/ <--- Main project
    │
    ├── gce-with-container/  <--- Our custom module
    |   |
    │   ├── main.tf
    │   └── variables.tf
    │
    ├── main.tf <--- We'll use gce-with-container here
    ├── terraform.tfvars <--- Values for what we defined in variables.tf
    ├── variables.tf <--- terraform.tfvars has the values for each defined variables
    └── versions.tf  <-- Here you will find the terraform block which specifies the required provider version and required Terraform version for this configuration
    


    커스텀 모듈



    폴더gce-with-container에는 맞춤 모듈이 포함되어 있습니다. 직접 만들기 위해 all the examples available on terraform-google-container-vm 확인했습니다. main.tf가 어떻게 정의되어 있는지 살펴보겠습니다.

    locals {
      # https://www.terraform.io/docs/language/values/locals.html
      instance_name = format("%s-%s", var.instance_name, substr(md5(module.gce-container.container.image), 0, 8))
    
      env_variables = [for var_name, var_value in var.env_variables : {
        name = var_name
        value = var_value
      }]
    }
    
    ####################
    ##### CONTAINER SETUP
    
    module "gce-container" {
      # https://github.com/terraform-google-modules/terraform-google-container-vm
      source = "terraform-google-modules/container-vm/google"
      version = "~> 2.0"
    
      container = {
        image = var.image
        command = var.custom_command
        env = local.env_variables
        securityContext = {
          privileged : var.privileged_mode
        }
        tty : var.activate_tty
      }
    
      restart_policy = "Always"
    }
    
    ####################
    ##### COMPUTE ENGINE
    
    resource "google_compute_instance" "vm" {
      name = local.instance_name
      # gcloud compute machine-types list | grep micro | grep us-central1-a
      # e2-micro / 2 / 1.00
      # f1-micro / 1 / 0.60
      # gcloud compute machine-types list | grep small | grep us-central1-a
      # e2-small / 2 / 2.00
      # g1-small / 1 / 1.70
      machine_type = "f1-micro"
      # If true, allows Terraform to stop the instance to update its properties.
      allow_stopping_for_update = true
    
      boot_disk {
        initialize_params {
          image = module.gce-container.source_image
        }
      }
    
      network_interface {
        network = var.network_name
    
        access_config {}
      }
    
      metadata = {
        gce-container-declaration = module.gce-container.metadata_value
      }
    
      labels = {
        container-vm = module.gce-container.vm_container_label
      }
    
      service_account {
        email = var.client_email
        scopes = [
          "https://www.googleapis.com/auth/cloud-platform",
        ]
      }
    }
    


    몇 가지 맞춤 변수(variables.tf 파일 참조)와 환경 변수 구성을 더 쉽게 만드는 도우미(locals.env_variables 참조)를 만들었습니다.

    메인 프로젝트



    루트 폴더에 있는 main.tf 파일에는 공급자(variables.tfterraform.tfvars 참조)를 구성하는 상용구 부분과 이전에 만든 모듈이 있습니다. 내가 제공한 컨테이너 이미지의 Dockerfile에 이미 CMD entry이 있기 때문에 변수custom_command만 사용하고 있습니다. 따라서 재정의해야 합니다.

    provider "google" {
      project = var.project
      credentials = file(var.credentials_file)
      region = var.region
      zone = var.zone
    }
    
    module "gce-worker-container" {
      source = "./gce-with-container"
    
      image = "gcr.io/${var.project}/jafar@sha256:6b71cebad455dae81af9fcb87a4c8b5bca2c2b6b2c09cec21756acd0f1ae7cec"
      privileged_mode = true
      activate_tty = true
      custom_command = [
        "./scripts/start-worker.sh"
      ]
      env_variables = {
        Q_CLUSTER_WORKERS = "2"
        DB_HOST = "your-database-host"
        DB_PORT = "5432"
        DB_ENGINE = "django.db.backends.postgresql"
        DB_NAME = "db_production"
        DB_SCHEMA = "jafar_prd"
        DB_USER = "role_jafar_prd"
        DB_PASS = "this-is-my-honest-password"
        DB_USE_SSL = "True"
      }
      instance_name = "jafar-worker"
      network_name = "default"
      # This has the permission to download images from Container Registry
      client_email = "custom-gce-dealer@${var.project}.iam.gserviceaccount.com"
    }
    


    그게 다야! 루트 폴더에서 terraform init를 입력한 다음 terraform apply를 입력한 다음 확인합니다. 생성된 VM에 접속하여 docker logs 명령을 통해 모든 것이 정상인지 확인하는 것이 좋습니다.



    이미지gcr.io/gce-containers/konlet:v.0.11-latest가 있는 컨테이너가 보이면 걱정할 필요가 없습니다 👀. 본인이 설정한 것을 다운받는 작업 😅.

    이 기사에서는 Terraform v0.14.9를 사용했습니다. You can check the entire code out on GitHub . 테스트 후 실행terraform destroy하는 것을 잊지 마세요! 다음에 만나요✌.

    좋은 웹페이지 즐겨찾기