GKE Project

Terraform 사용하여 GKE Cluster 배포하기

Joon0464 2024. 4. 15. 20:45

 

2024.04.04 - [GKE Project] - Terraform을 사용하여 GKE(Google Kubernetes Engine) 배포

 

이전에 준비했던 사전 설정에 이어서 진행한다.

 

1. API 활성화

우선 GKE Clsuter API와 Compute API 를 활성화 하기 위해 아래 과정을 진행해줍니다.

# 이전 포스팅에서 설정한 config에서 Project id값을 불러와 변수로 설정한다.
$ GCP_PROJECT_ID=$(gcloud config list | grep project | awk '{print $3}')

# 변수 설정을 확인해본다.
$ echo $GCP_PROJECT_ID

# GCP compute, container API 활성화
$ gcloud services enable compute.googleapis.com container.googleapis.com --project=$GCP_PROJECT_ID

 

 

 

2. Service Account 생성 & Secret key 생성

IAM 및 관리자 -> 서비스 계정 -> 서비스 계정 만들기를 클릭한다.
서비스 계정 이름 및 설명을 작성한다.

 

우선 위 3개의 관리자 권한만 추가하고 추후 권한이 필요하면 추가하는 방식으로 진행할 예정입니다.

 

 

생성된 서비스 계정 클
키 -> 키 추가 -> 새 키 만들기 클릭합니다.
JSON을 선택하고 만들기를 클릭합니다.

# 환경변수에 시크릿 키 파일 경로 설정
$ mkdir ~/.gcp
$ echo "export GOOGLE_APPLICATION_CREDENTIALS=/home/joon/.gcp/credential.json" >> ~/.bashrc

# 환경변수 적용 및 확인
$ source ~/.bashrc
$ echo $GOOGLE_APPLICATION_CREDENTIALS
/home/joon/.gcp/credential.json

 

 

3. tfstate 를 저장할 GCS Bucket 생성

$ BUCKET_NAME="hjsong-tfstate-bucket"
$ gsutil mb -p $GCP_PROJECT_ID -l ASIA-NORTHEAST3 gs://$BUCKET_NAME
Creating gs://hjsong-tfstate-bucket/...
$ gsutil versioning set on gs://$BUCKET_NAME
Enabling versioning for gs://hjsong-tfstate-bucket/...

 

backend.tf를 통해 Terraform의 state를 원격 저장소에 저장하도록 설정 가능합니다. backend.tf에서 사용하기 위한 버킷을 gsutil 명령어로 사전에 생성합니다.

 

4. GKE Cluster 생성을 위한 Terraform 코드 작성

# 디렉터리 구조는 아래와 같이 구성하였습니다.
# 재사용성과 유지보수가 용이하도록 모듈화하여 작성하였습니다.

GKE_Terraform_hjsong/
├── backend.tf
├── modules
│   └── gke_cluster
│       ├── main.tf
│       ├── output.tf
│       └── variables.tf
├── production.tf
├── provider.tf
├── terraform.tfvars
└── variables.tf

 

# provider.tf

# gcp 리소스를 테라폼 코드로 작성하기 위해 우선 provider 부터 설정해야 합니다.
# 지정된 credential.json 을 통해 인증을 진행하여 terraform이 gcp에 배포할 수 있습니다.

provider "google" {
  credentials = file("/home/joon/.gcp/credential.json")
  project     = "PROJECT_ID"
  region      = "asia-northeast3"
}

 

 

이어서 모듈 디렉토리 안에 리소스를 정의하기 위한 main.tf를 작성합니다.

# modules/gke_cluster/main.tf

resource "google_container_cluster" "gke_cluster" {
  name     = var.clusterName
  location = var.region # Replace this with your desired region

  enable_shielded_nodes    = "true"
  remove_default_node_pool = true
  initial_node_count       = 1
  node_config {
    disk_size_gb           = var.diskSize
  }

  release_channel {
    channel = "STABLE"
  }

  addons_config {
    http_load_balancing {
      disabled = false
    }
  }

  networking_mode = "VPC_NATIVE"
  ip_allocation_policy {
    cluster_ipv4_cidr_block  = "/16"
    services_ipv4_cidr_block = "/22"
  }

  timeouts {
    create = "20m"
    update = "20m"
  }

  lifecycle {
    ignore_changes = [node_pool]
  }
}

resource "google_container_node_pool" "primary_nodes" {
  name       = "${var.clusterName}-pool"
  location   = var.region # Replace this with your desired region
  cluster    = google_container_cluster.gke_cluster.name
  node_count = 1

  management {
    auto_repair  = true
    auto_upgrade = true
  }

  autoscaling {
    min_node_count = var.minNode
    max_node_count = var.maxNode
  }

  timeouts {
    create = "20m"
    update = "20m"
  }

  node_config {
    preemptible  = true
    machine_type = var.machineType

    oauth_scopes = [
      "https://www.googleapis.com/auth/compute",
      "https://www.googleapis.com/auth/cloud-platform",
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring",
    ]
  }
}

 

 

# modules/gke_cluster/variables.tf

variable "region" {
  description = "Deployment region"
  default = "asia-northeast3"
}
variable "clusterName" {
  description = "Name of our Cluster"
}
variable "diskSize" {
  description = "Node disk size in GB"
}
variable "minNode" {
  description = "Minimum Node Count"
}
variable "maxNode" {
  description = "maximum Node Count"
}
variable "machineType" {
  description = "Node Instance machine type"
}

모듈에서 사용되는 변수를 정의합니다. 변수 값은 tfvars 파일에서 작성합니다.

 

# modules/gke_cluster/output.tf

output "cluster_endpoint" {
  value = google_container_cluster.gke_cluster.endpoint
}

생성되는 리소스의 속성 값을 output.tf 파일을 통해 내보낼 수 있고 내보낸 값을 다른 모듈에서 import하여 사용도 가능합니다.

 

# main.tf

module "gke_cluster" {
  source = "./modules/gke_cluster"
  region       = var.region
  clusterName  = var.clusterName
  diskSize     = var.diskSize
  minNode      = var.minNode
  maxNode      = var.maxNode
  machineType  = var.machineType
}


프로젝트 디렉터리 내에 있는 main.tf 파일은 Terraform을 사용할 때, 루트 모듈에서 terraform plan 또는 terraform apply 명령어를 실행할 때 함께 사용됩니다. 이 모듈은 다른 모듈들을 호출하고, 하나의 모듈에서 출력된 값을 다른 모듈의 입력 값으로 전달하여 모듈들을 연결 가능합니다.

 

# terraform.tfvars

region="asia-northeast3"
clusterName="hjsong-gke-cluster"
diskSize=50
minNode=1
maxNode=2
machineType="e2-medium"

실제 변수에 입력될 값을 정의하는 파일입니다. 이 값을 통해 모듈내에 변수 처리된 곳에 값이 입력되는 방식입니다.

 

# variables.tf

variable "region" {
  description = "Deployment region"
  default = "asia-northeast3"
}
variable "clusterName" {
  description = "Name of our Cluster"
}
variable "diskSize" {
  description = "Node disk size in GB"
}
variable "minNode" {
  description = "Minimum Node Count"
}
variable "maxNode" {
  description = "maximum Node Count"
}
variable "machineType" {
  description = "Node Instance machine type"
}

루트 모듈내에도 동일한 variables.tf 파일을 생성해줍니다. 모듈내의 variables.tf와 루트 모듈내의 variables.tf 의 역할 차이는 다음과 같습니다.

모듈 내 variables.tf 파일의 역할

  • 변수 선언 및 기본값 설정: 모듈 내 variables.tf 파일은 해당 모듈에서 사용할 입력 변수들을 선언하고, 필요한 경우 기본값을 설정합니다. 이를 통해 모듈이 독립적으로 사용될 수 있도록 합니다.
  • 재사용성 증가: 모듈을 다른 프로젝트나 환경에서 재사용할 때, variables.tf 파일에 정의된 입력 변수들을 통해 모듈의 설정을 쉽게 조정할 수 있습니다.

 

모듈을 사용하는 곳(루트 모듈)의 variables.tf 파일의 역할

  • 모듈 구성값 제공: main.tf와 같이 모듈을 사용하는 Terraform 구성 파일에서 variables.tf 파일은 해당 환경이나 프로젝트에 특화된 변수 값을 정의합니다. 이 변수들은 모듈에 전달되어 모듈의 동작을 구성합니다.
  • 환경별 구성 관리: 다양한 환경(예: 개발, 스테이징, 프로덕션)에 대해 각각의 variables.tf 파일을 통해 환경별로 다른 변수 값을 설정할 수 있습니다. 이를 통해 코드의 재사용성을 높이고 환경별 구성 관리를 용이하게 합니다.
# backend.tf

terraform {
 backend "gcs" {
   bucket  = "hjsong-tfstate-bucket"
   prefix  = "terraform/state"
 }
}

마지막으로 tfstate를 저장하고 관리하기 위한 버킷을 backend.tf 파일에 정의합니다. Terraform은 인프라의 현재 상태를 추적하기 위해 상태 파일(tfstate)을 사용합니다. backend.tf 파일에 버킷을 정의하는 것은 이 상태 파일을 안전하고 효율적으로 저장하고 관리하기 위한 방법입니다.