Skip to content

PYOWIKI

IT기술과 인사이트를 함께하는 공간입니다.

  • Home
  • Blog
  • Home
  • Blog

Terraform을 이용한 NKS 클러스터 구축

  1. Home   »  
  2. Terraform을 이용한 NKS 클러스터 구축

Terraform을 이용한 NKS 클러스터 구축

2024-04-252024-05-29 pyowikiCloud, KubernetesTagged Cloud, k8s, Kubernetes, NKS, Terraform, 네이버클라우드, 테라폼

참고자료

  • Ncloud Provider : https://registry.terraform.io/providers/NaverCloudPlatform/ncloud/latest/docs
  • Ncloud Kubernetes Service : https://www.ncloud.com/product/containers/kubernetes
    [출처] 테라폼을 통해 Ncloud Kubernetes Service (NKS) 클러스터 구축하기|작성자 NAVER Cloud Platform

ncloud provider를 통한 kubernetes cluster 생성

  • API 환경 변수 설정 ncloud API를 사용하는데 필요한 인증 정보와 엔드포인트 정보를 환경 변수로 설정합니다. NCLOUD_API_GW는 테라폼에서 직접적으로 사용되지 않지만 NKS 클러스터의 kubeconfig 파일을 생성하는데 사용됩니다.
    export NCLOUD_ACCESS_KEY=ACCESSKEY
    export NCLOUD_SECRET_KEY=SECRETKEY
    export NCLOUD_API_GW=https://ncloud.apigw.ntruss.com

위 방법으로 API 인증 정보를 환경변수로 지정 가능하지만, 저는 여러개의 Terraform환경을 사용중이기 때문에 아래와 같이 ncloud.tf 를 통해 API 인증 정보를 지정하였습니다.

root@D-choimp:~/terraform/nks_choimp# tree .
.
├── infra.tf
└── ncloud.tf

  • ncloud.tf
provider "ncloud" {
  region      = "KR"
  site        = "pub"
  support_vpc = "true"
  access_key = "xx"
  secret_key = "xx"
}

terraform {
  required_providers {
    ncloud = {
      source = "NaverCloudPlatform/ncloud"
      version = ">= 2.3.19"
    }
  }
}

이후 CLI에서 terraform init 명령어를 입력하여 테라폼 초기화를 진행합니다. 초기화를 통해 테라폼은 필요한 provider의 플러그인을 다운로드하고 초기화합니다.

명령어 실행 후 로그를 통해 초기화가 정상적으로 진행 되었는지, 플러그인이 올바르게 설치 되었는지 확인할 수 있습니다.

$ terrraform init

Initializing the backend…

Initializing provider plugins…

  • Finding navercloudplatform/ncloud versions matching “>= 2.3.19″…
  • Installing navercloudplatform/ncloud v2.3.19…
    (생략)
    Terraform has been successfully initialized!
    (생략)

kubernetes cluster 생성을 위한 테라폼 코드 작성

kubernetes cluster를 생성하기 위해서는 상품 별로 아래 리소스가 필요합니다.

  • VPC
  • Subnet
    • Subnet
    • LoadBalancer Subnet
    • NAT G/W Subnet
  • NAT G/W
  • Route Table
  • Ncloud Kubernetes Service
  • Login Key

테스트 환경으로 하나의 파일을 이용하여 단순한 코드로 인프라를 관리할수 있지만,
실무 환경에서는 코드의 재사용성과 유지보수성을 향상시키기 위해 각 리소스를 분리하고 모듈화하여 사용하는 것이 좋습니다.

아래 infra.tf 파일에는 kubernetes cluster를 생성하기 위한 전체 리소스가 기재되어 있으며,
분리된 코드 또한 첨부하였으니 참고하시면 됩니다.

infra.tf

variable "zone" {
  type    = string
  default = "KR-1"
}

resource "ncloud_vpc" "kubernetes_vpc" {
  name            = "choimp-terraform-nks-vpc"
  ipv4_cidr_block = "10.0.0.0/16"
}

resource "ncloud_subnet" "private_node_subnet" {
  vpc_no         = ncloud_vpc.kubernetes_vpc.id
  subnet         = "10.0.1.0/24"
  zone           = var.zone
  network_acl_no = ncloud_vpc.kubernetes_vpc.default_network_acl_no
  subnet_type    = "PRIVATE"
  name           = "terraform-private-node-subnet"
  usage_type     = "GEN"
}

resource "ncloud_subnet" "private_lb_subnet" {
  vpc_no         = ncloud_vpc.kubernetes_vpc.id
  subnet         = "10.0.11.0/24"
  zone           = var.zone
  network_acl_no = ncloud_vpc.kubernetes_vpc.default_network_acl_no
  subnet_type    = "PRIVATE"
  name           = "terraform-private-lb-subnet"
  usage_type     = "LOADB"
}

resource "ncloud_subnet" "public_lb_subnet" {
  vpc_no         = ncloud_vpc.kubernetes_vpc.id
  subnet         = "10.0.12.0/24"
  zone           = var.zone
  network_acl_no = ncloud_vpc.kubernetes_vpc.default_network_acl_no
  subnet_type    = "PUBLIC"
  name           = "terraform-public-lb-subnet"
  usage_type     = "LOADB"
}

resource "ncloud_subnet" "nat_subnet" {
  vpc_no         = ncloud_vpc.kubernetes_vpc.id
  subnet         = "10.0.3.0/24"
  zone           = var.zone
  network_acl_no = ncloud_vpc.kubernetes_vpc.default_network_acl_no
  subnet_type    = "PUBLIC"
  name           = "terraform-nat-subnet"
  usage_type     = "NATGW"
}

resource "ncloud_nat_gateway" "kubernetes_nat_gw" {
  vpc_no    = ncloud_vpc.kubernetes_vpc.id
  subnet_no = ncloud_subnet.nat_subnet.id
  zone      = var.zone
  name      = "terraform-kubernetes-nat-gw"
}

resource "ncloud_route_table" "kubernetes_route_table" {
  vpc_no                = ncloud_vpc.kubernetes_vpc.id
  supported_subnet_type = "PRIVATE"
  name                  = "kubernetes-route-table"
}

resource "ncloud_route" "kubernetes_route" {
  route_table_no         = ncloud_route_table.kubernetes_route_table.id
  destination_cidr_block = "0.0.0.0/0"
  target_type            = "NATGW"
  target_name            = ncloud_nat_gateway.kubernetes_nat_gw.name
  target_no              = ncloud_nat_gateway.kubernetes_nat_gw.id
}

resource "ncloud_route_table_association" "kubernetes_route_table_subnet" {
  route_table_no = ncloud_route_table.kubernetes_route_table.id
  subnet_no      = ncloud_subnet.private_node_subnet.id
}

resource "ncloud_login_key" "kubernetes_loginkey" {
  key_name = "terraform-kubernetes-loginkey"
}

resource "ncloud_nks_cluster" "terraform_cluster" {
  cluster_type         = "SVR.VNKS.STAND.C002.M008.NET.SSD.B050.G002"
  login_key_name       = ncloud_login_key.kubernetes_loginkey.key_name
  name                 = "terraform-cluster"
  lb_private_subnet_no = ncloud_subnet.private_lb_subnet.id
  lb_public_subnet_no  = ncloud_subnet.public_lb_subnet.id
  subnet_no_list       = [ncloud_subnet.private_node_subnet.id]
  vpc_no               = ncloud_vpc.kubernetes_vpc.id
  zone                 = var.zone
}

resource "ncloud_nks_node_pool" "node_pool" {
  cluster_uuid   = ncloud_nks_cluster.terraform_cluster.uuid
  node_pool_name = "terraform-node-1"
  node_count     = 2
  product_code   = "SVR.VSVR.STAND.C002.M008.NET.SSD.B050.G002"
  subnet_no_list = [ncloud_subnet.private_node_subnet.id]
}

코드 분리

ncloud.tf

variable "zone" {
  type    = string
  default = "KR-1"
}

resource "ncloud_vpc" "kubernetes_vpc" {
  name            = "choimp-terraform-nks-vpc"
  ipv4_cidr_block = "10.0.0.0/16"
}

vpc.tf

variable "zone" {
  type    = string
  default = "KR-1"
}

resource "ncloud_vpc" "kubernetes_vpc" {
  name            = "choimp-terraform-nks-vpc"
  ipv4_cidr_block = "10.0.0.0/16"
}

subnet.tf

resource "ncloud_subnet" "private_node_subnet" {
  vpc_no         = ncloud_vpc.kubernetes_vpc.id
  subnet         = "10.0.1.0/24"
  zone           = var.zone
  network_acl_no = ncloud_vpc.kubernetes_vpc.default_network_acl_no
  subnet_type    = "PRIVATE"
  name           = "terraform-private-node-subnet"
  usage_type     = "GEN"
}

resource "ncloud_subnet" "private_lb_subnet" {
  vpc_no         = ncloud_vpc.kubernetes_vpc.id
  subnet         = "10.0.11.0/24"
  zone           = var.zone
  network_acl_no = ncloud_vpc.kubernetes_vpc.default_network_acl_no
  subnet_type    = "PRIVATE"
  name           = "terraform-private-lb-subnet"
  usage_type     = "LOADB"
}

resource "ncloud_subnet" "public_lb_subnet" {
  vpc_no         = ncloud_vpc.kubernetes_vpc.id
  subnet         = "10.0.12.0/24"
  zone           = var.zone
  network_acl_no = ncloud_vpc.kubernetes_vpc.default_network_acl_no
  subnet_type    = "PUBLIC"
  name           = "terraform-public-lb-subnet"
  usage_type     = "LOADB"
}

resource "ncloud_subnet" "nat_subnet" {
  vpc_no         = ncloud_vpc.kubernetes_vpc.id
  subnet         = "10.0.3.0/24"
  zone           = var.zone
  network_acl_no = ncloud_vpc.kubernetes_vpc.default_network_acl_no
  subnet_type    = "PUBLIC"
  name           = "terraform-nat-subnet"
  usage_type     = "NATGW"
}

route_table.tf

resource "ncloud_route_table" "kubernetes_route_table" {
  vpc_no                = ncloud_vpc.kubernetes_vpc.id
  supported_subnet_type = "PRIVATE"
  name                  = "kubernetes-route-table"
}

resource "ncloud_route" "kubernetes_route" {
  route_table_no         = ncloud_route_table.kubernetes_route_table.id
  destination_cidr_block = "0.0.0.0/0"
  target_type            = "NATGW"
  target_name            = ncloud_nat_gateway.kubernetes_nat_gw.name
  target_no              = ncloud_nat_gateway.kubernetes_nat_gw.id
}

resource "ncloud_route_table_association" "kubernetes_route_table_subnet" {
  route_table_no = ncloud_route_table.kubernetes_route_table.id
  subnet_no      = ncloud_subnet.private_node_subnet.id
}

nks.tf

resource "ncloud_nks_cluster" "terraform_cluster" {
  cluster_type         = "SVR.VNKS.STAND.C002.M008.NET.SSD.B050.G002"
  login_key_name       = ncloud_login_key.kubernetes_loginkey.key_name
  name                 = "terraform-cluster"
  lb_private_subnet_no = ncloud_subnet.private_lb_subnet.id
  lb_public_subnet_no  = ncloud_subnet.public_lb_subnet.id
  subnet_no_list       = [ncloud_subnet.private_node_subnet.id]
  vpc_no               = ncloud_vpc.kubernetes_vpc.id
  zone                 = var.zone
}

resource "ncloud_nks_node_pool" "node_pool" {
  cluster_uuid   = ncloud_nks_cluster.terraform_cluster.uuid
  node_pool_name = "terraform-node-1"
  node_count     = 2
  product_code   = "SVR.VSVR.STAND.C002.M008.NET.SSD.B050.G002"
  subnet_no_list = [ncloud_subnet.private_node_subnet.id]
}

nat_gw.tf

resource "ncloud_nat_gateway" "kubernetes_nat_gw" {
  vpc_no    = ncloud_vpc.kubernetes_vpc.id
  subnet_no = ncloud_subnet.nat_subnet.id
  zone      = var.zone
  name      = "terraform-kubernetes-nat-gw"
}

login_key.tf

resource "ncloud_login_key" "kubernetes_loginkey" {
  key_name = "terraform-kubernetes-loginkey"
}

두 코드는 같은 인프라를 생성하는 코드이지만 코드를 분리하여 사용하는 것에는 몇 가지 이점이 있습니다:

  1. 모듈화 및 재사용성: 각 상품에 대한 코드를 별도의 파일로 분리하면 해당 기능을 모듈화하여 필요한 곳에서 재사용할 수 있습니다. 예를 들어, 다른 프로젝트나 환경에서 같은 VPC 구성이 필요할 때 해당 모듈을 가져와 사용할 수 있습니다.
  2. 가독성 및 유지보수: 코드가 각 상품 별로 분리되어 있으면 전체 코드의 가독성이 향상되고 유지보수가 용이해집니다. 특정 상품의 변경 또는 수정이 필요할 때 해당 파일만 수정하면 되므로 다른 부분에 영향을 주지 않습니다.
  3. 협업과 버전 관리: 코드를 분리하면 여러 명의 개발자가 동시에 작업할 때 충돌을 최소화하고 각자의 역할에 맞게 작업할 수 있습니다. 또한, 각 상품에 대한 코드를 개별적으로 관리함으로써 버전 관리가 용이해집니다.
  4. 테스트 용이성: 분리된 코드는 개별적으로 테스트하기 쉽습니다. 각 상품에 대한 단위 테스트 또는 통합 테스트를 수행하여 코드의 신뢰성을 높일 수 있습니다.

이러한 이유들로 코드를 분리하여 사용하는 것이 코드의 가독성, 유지보수성, 재사용성 등을 향상시킬 수 있습니다.

terraform plan (infra)

infra.tf 에 생성할 리소스를 모두 기재하였다면 terraform plan 명령어를 입력하여 생성될 리소스 계획을 확인합니다. 작업 검토 목적으로 진행하는 계획 단계에서는 실제 리소스가 생성되지 않습니다.

$ terraform plan … Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:

  • create

Terraform will perform the following actions: … Plan: 12 to add, 0 to change, 0 to destroy.

terraform plan 수행 시 각 리소스에 대한 세부 사항이 출력됩니다. 의도한 대로 리소스가 생성되는지 확인하고, 문제가 있는 경우 수정을 진행합니다. 리소스가 생성되기 전 단계에서 구성의 정확성을 검증하고 예상되는 변경사항을 미리 파악할 수 있습니다.

다음 내용에서는 kubernetes provider를 통한 워크로드 생성을 소개해 보겠습니다.

글 내비게이션

Previous: [네이버클라우드] Ncloud Kubernetes Service (NKS) 구성 및 실습 Ver.1.27.9 [2]
Next: [AWS] AWS ECS 및 EKS 개념 정리

답글 남기기 응답 취소

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다


Kategorie

  • Certificate
  • Cloud
  • Kubernetes

최신 글

  • Amazon EKS 알아보기: AWS 관리형 쿠버네티스 서비스 완벽 해부
  • [AWS] AWS ECS 및 EKS 개념 정리
  • Terraform을 이용한 NKS 클러스터 구축
  • [네이버클라우드] Ncloud Kubernetes Service (NKS) 구성 및 실습 Ver.1.27.9 [2]
  • [네이버클라우드] Ncloud Kubernetes Service (NKS) 구성 및 실습 Ver.1.27.9 [1]
Proudly powered by WordPress | Theme: goldy-mex by inverstheme.