배운 내용/클라우드 교육

2월13일 - 테라폼으로 NKS 클러스터 구축하기

JooJY 2024. 2. 13. 17:15

https://blog.naver.com/n_cloudplatform/223323963232

 

테라폼을 통해 Ncloud Kubernetes Service (NKS) 클러스터 구축하기

네이버 클라우드 플랫폼은 사용자 분들께서 클라우드 리소스를 효율적으로 관리할 수 있도록 콘솔, API,...

blog.naver.com


accesskey, secretkey는 ncp 마이페이지 >> 계정관리 >> 인증키 관리에서 보고 변경

리눅스에 접속 후 CLI 환경에서 그냥 입력하면 된다. 

아래 방법은 휘발성이라서 매번 export 해야 한다.

export NCLOUD_ACCESS_KEY=ACCESSKEY << 변경 필요
export NCLOUD_SECRET_KEY=SECRETKEY << 변경 필요
export NCLOUD_API_GW=https://ncloud.apigw.ntruss.com

# 예시
export NCLOUD_ACCESS_KEY=865EC5FF2
export NCLOUD_SECRET_KEY=F229503E021A56AE0
export NCLOUD_API_GW=https://ncloud.apigw.ntruss.com

https://guide.ncloud-docs.com/docs/k8s-iam-auth-kubeconfig

여기 보면 인증키 설정 방법이 여러개인데 

사용자 환경 홈 디렉터리의 .ncloud 폴더에 configure 파일 << 이 방법을 쓰도록 하자.

 

IAM 인증 kubeconfig 생성/업데이트

 

guide.ncloud-docs.com


아무 폴더 만든 후 폴더로 이동

폴더 안에 provider.tf 파일을 생성

# provider.tf

provider "ncloud" {
  region      = "KR"
  site        = "pub"
  support_vpc = "true"
}

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

해당 폴더로 이동 후 CLI 환경에서 terraform init 명령어를 입력하여 테라폼 초기화를 진행

terraform init

리소스를 생성하기 위하여 infra.tf 파일에 모든 리소스를 기재합니다.

infra.tf 파일 생성

 

variable 설정

# infra.tf

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

vpc 생성

# infra.tf

#######vpc########################
resource "ncloud_vpc" "kubernetes_vpc" {
  name            = "kubernetes-vpc"
  ipv4_cidr_block = "10.0.0.0/16"
}

 

node용 프라이빗 서브넷, LB를 위해 퍼블릭, 프라이빗 서브넷, nat용 퍼블릭 서브넷 (총 4개) 생성

# infra.tf

#######subnet########################
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           = "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           = "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           = "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           = "nat-subnet"
  usage_type     = "NATGW"
}

 nat 생성, 라우팅 테이블 설정

# infra.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      = "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
}

클러스터 생성 및 노드풀 생성

# infra.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]
}

로그인키 설정

# infra.tf

#######login_key################################
resource "ncloud_login_key" "kubernetes_loginkey" {
  key_name = "kubernetes-loginkey"
}

여기까지 작성 후 terraform plan 명령어 입력

terraform plan

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

 

terraform plan이 문제 없이 되면 terraform apply로 생성 시작, yes 입력해야 함.

terraform apply

nks 생성하는데 40분 정도 걸린다...

콘솔에서 제대로 다 생성이 되었는지 확인한다.

여기까지 infra 구축은 끝임.


클러스터가 정상적으로 운영 중이라면 간단한 파드를 배포하여 클러스터의 기능을 테스트 할 수 있습니다. 직접 클러스터에 접근하여 진행 할 수도 있으나, 테라폼을 활용하여 파드를 배포하도록 하겠습니다.

여기서 주의 할 점은 콘솔에서 뭔가를 수정하면 싱크가 깨져서 테라폼이 더이상 적용되지 않는다.

테라폼으로 모든 것을 해결하는 것이 좋다.

 

provider.tf 파일을 수정하여 kubernetes provider를 설정합니다.

# provider.tf

provider "ncloud" {
  region      = "KR"
  site        = "pub"
  support_vpc = "true"
}

terraform {
  required_providers {
    ncloud = {
      source = "NaverCloudPlatform/ncloud"
      version = ">= 2.3.19"
    }
#### 여기 추가하기###
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = ">= 2.24.0"
    }
#####################
  }
}

#### 여기 추가하기###
provider "kubernetes" {
  host                   = data.ncloud_nks_kube_config.kube_config.host
  cluster_ca_certificate = base64decode(data.ncloud_nks_kube_config.kube_config.cluster_ca_certificate)
  exec {
    api_version = "client.authentication.k8s.io/v1beta1"
    args        = ["token", "--clusterUuid", ncloud_nks_cluster.terraform_cluster.uuid, "--region", "KR"]
    command     = "ncp-iam-authenticator"
  }
}
#####################

수정 후 다시 terraform init을 해준다.

terraform init

kubernetes provider 초기화 후 워크로드를 배포하고 Pod와 Service를 생성합니다. 생성된 Service를 통해 공인, 사설 타입의 로드밸런서가 생성되는지 확인합니다. 로드밸런서를 통해 VPC 내부, 외부 트래픽을 클러스터로 라우팅할 수 있으며 동작을 확인할 수 있습니다.

https://registry.terraform.io/providers/NaverCloudPlatform/ncloud/latest/docs/resources/nks_node_pool

 

Terraform Registry

 

registry.terraform.io

workloads.tf 파일을 생성한다.

솔직히 아래 코드 어떻게 짜는 건지 이해를 못하겠다.

 

data "ncloud_nks_kube_config" "kube_config" {
  cluster_uuid = ncloud_nks_cluster.terraform_cluster.uuid
}

resource "null_resource" "create_kubeconfig" {
  depends_on = [ncloud_nks_cluster.terraform_cluster]

  provisioner "local-exec" {
    command = "ncp-iam-authenticator update-kubeconfig --clusterUuid ${self.triggers.cluster_uuid} --region ${self.triggers.region}"

    environment = {
      CLUSTER_UUID = data.ncloud_nks_kube_config.kube_config.cluster_uuid
      REGION       = "KR"
    }
  }
  triggers = {
    cluster_uuid = data.ncloud_nks_kube_config.kube_config.cluster_uuid
    region       = "KR"
  }
}

resource "kubernetes_pod" "nginx" {
  metadata {
    name = "nginx-example"
    labels = {
      app = "nginx"
    }
  }

  spec {
    container {
      image = "nginx:latest"
      name  = "nginx"

      port {
        container_port = 80
      }
    }
  }
}

resource "kubernetes_service" "nginx_public" {
  metadata {
    name = "nginx-service-public"

    annotations = {
      "service.beta.kubernetes.io/ncloud-load-balancer-internal" = "false"
    }
  }

  spec {
    selector = {
      app = kubernetes_pod.nginx.metadata[0].labels.app
    }

    port {
      port        = 80
      target_port = 80
    }

    type = "LoadBalancer"
  }
}

resource "kubernetes_service" "nginx_private" {
  metadata {
    name = "nginx-service-private"

    annotations = {
      "service.beta.kubernetes.io/ncloud-load-balancer-internal" = "true"
    }
  }

  spec {
    selector = {
      app = kubernetes_pod.nginx.metadata[0].labels.app
    }

    port {
      port        = 80
      target_port = 80
    }

    type = "LoadBalancer"
  }
}

https://guide.ncloud-docs.com/docs/k8s-iam-auth-ncp-iam-authenticator

 

ncp-iam-authenticator 설치

 

guide.ncloud-docs.com

리눅스에서 ncp-iam-authenticator 설치를 해야 한다.


아무튼 terraform plan을 한다.

terraform plan

했는데 오류가 떠서 terraform init -upgrade 이걸 해줌.

terraform init -upgrade

 

업그레이드 후 다시 plan 하니 잘 된다.


plan이 제대로 되면 apply도 해준다.

terraform apply

apply가 제대로 끝나면 잘 되었나 확인해야 한다.

배포된 워크로드 확인

쿠버네티스 사용할 때 모든 설정은 kubeconfig 파일에 저장된다.

위의 workloads.tf에서 생성된 kubeconfig 파일을 확인해보자.

cat ~/.kube/config

내용이 엄청 많다. 

쿠버 노드를 확인해보자.

kubectl get nodes

쿠버 pod를 확인해보자.

Running 상태가 되어야 한다.

kubectl get pods

외부 ip를 받았는지 확인해보자.

kubectl get svc


nginx에 접속되는지 확인해보자.

콘솔 -> 로드밸런서 -> 퍼블릭 로드밸런서 접속 정보를 크롬에 복사

이렇게 nginx 화면이 나오면 된다.


테라폼으로 만든 걸 모두 삭제해보자.

terraform destroy

한방에 모두 삭제 된다.

혹시 콘솔에서 테라폼으로 만든 것을 수정하면 안될 수 있으니 주의!