Terraform으로 EKS Cluster 프로비전(1) - VPC 생성

empty·2020년 9월 8일
0

EKS

목록 보기
2/6
post-thumbnail

클러스터 구성 전 고려사항

1. VPC의 DNS 구성

  • 인터넷 게이트웨이로 구성된 서브넷 내에 퍼블릭 또는 탄력적 IP 주소가있는 노드는 VPC 외부에서 수신을 허용합니다. VPC에는 DNS 호스트 이름 및 DNS 확인 지원이 있어야한다. 그렇지 않으면 작업자 노드가 클러스터에 등록 할 수 없다.

2. 태그지정

  • VPC관련 모든 리소스 (서브넷 포함)
    • Key : kubernetes.io/<cluster-name>
    • Value : shared
      • 해당 태그를 지정해야 클러스터가 VPC로 통신을 할 수 있다.
  • Public Subnet
    • Key : kubernetes.io/role/elb
    • Value : 1
  • Private Subnet
    • Key : kubernetes.io/role/internal-elb
    • Value : 1

Architecture

하나의 Cluster가 될 VPC를 생성하고 그 VPC안에 3개의 가용영역을 둔다. 그 가용영역 안에는 Public Subnet, Private Subnet이 존재하게 된다. 또 Public Subnet안에는 Bastion Host와 NAT Gateway가 존재한다.

  • Public Subnet과 Private Subnet은 각각의 AZ(a,b,c)에 배치가 되고 역할은 다음과 같다.
    • Public Subnet
      • VPN/Bastion Host, ELB, Bastion Host와 같은 퍼블릭 IP 주소가 필요한 리소스
    • Private Subnet
      • 실제 워커노드가 배치되는 서브넷
      • 웹 서버 및 DB 인스턴스와 같은 프라이빗 인스턴스

EKS Cluster 작업순서

  1. VPC 생성
  2. Bastion Host 생성
  3. EKS Cluster 생성 (Module 사용)
  • 클러스터를 구성시켜주는 모듈을 직접 이해하는 것이 백번 낫겠지만 복잡하므로 다음기회에 알아보는걸로

정리

  • VPC (Cluster)

    • AZ A (Worker Node)
      • Public Subnets A
        • NAT Gateway
        • Bastion Host
      • Private_Subnets A
    • AZ B (Worker Node)
      • Public Subnets B
      • Private_Subnets B
    • AZ C (Worker Node)
      • Public Subnets C
      • Private_Subnets C

    이 후 추가적으로 Bastion Host 추가, Cluster Scailing 예정

VPC 구성순서

  1. VPC 생성
  2. Public, Private Subnet 생성
  3. IGW 생성
  4. EIP 생성
  5. NAT Gateway 생성
    • Public Subnet에 연결
    • 생성된 EIP 연결
  6. Route Table 생성
    • Public Route Table - IGW
    • Private Route Table - NAT Gateway
  7. Route Table 라우팅
    • Public Route Table 라우팅
    • Private Route Table 라우팅

공통사항

리소스들의 tag설정은 EKS 구성에 필요한 Key + 자신이 식별할 수 있는 aws_default_name을 변수로 받아와 merge로 합치게 되면서 아래와 같이 리소스를 생성하게 된다.

1. VPC

사용된 리소스

  • aws_vpc

사용된 옵션

  • cidr_block
  • enable_dns_hostnames
  • enable_dns_support
  • instance_tenancy
  • tags
# Create VPC
resource "aws_vpc" "PR-TEST-VPC" {
  cidr_block           = var.aws_vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true
  instance_tenancy     = "default"

  tags = merge(var.global_tags,
  {
    "Name" = format("%s-%s", var.aws_default_name, "EKS-VPC")
  })
}

cidr_block은 변수로 처리하였고 모듈을 정의하는 곳에서 CIDR을 설정하게 된다. enable_dns_hostnamesenable_dns_support를 활성화 하여 워커노드가 생성되면 DNS 호스트 이름을 받게 설정하여 DNS 통신이 가능하게끔 설정한다.

2. Public/Private Subnets

사용된 리소스

  • aws_subnet (private, public)

사용되는 옵션

  • count
  • cidr_block
  • vpc_id
  • map_public_ip_on_launch
  • availability_zone
  • tags
# Setting Subnet
# Create Public Subnet
resource "aws_subnet" "PR-TEST-PUBSUB" {
  count             = length(var.aws_public_subnets)
  cidr_block        = var.aws_public_subnets[count.index]
  vpc_id            = aws_vpc.PR-TEST-VPC.id
  # EKS node group에 자동으로 IP 할당을 해주기위함.
  map_public_ip_on_launch = true

  availability_zone = var.aws_azs[count.index]
  tags = merge(var.global_tags,
  {
    "Name" = format("%s-%s", var.aws_default_name, "EKS-PUBLIC${count.index + 1}")
    "kubernetes.io/role/elb"= 1
  })
}

# Create Private Subnet
resource "aws_subnet" "PR-TEST-PRISUB" {
  count             = length(var.aws_private_subnets)
  cidr_block        = var.aws_private_subnets[count.index]
  vpc_id            = aws_vpc.PR-TEST-VPC.id
  availability_zone = var.aws_azs[count.index]
  tags = merge(var.global_tags,
  {
    "Name" = format("%s-%s", var.aws_default_name, "EKS-PRIVATE${count.index + 1}")
    "kubernetes.io/role/internal-elb"= 1
  })
}
  • count는 정의된 변수만큼 count를 채웠고 그 수만큼 차례대로 cidr_block에서 ip를 list형식에서 빼와서 부여받기로 정의하였다.

  • vpc_id로 서브넷을 vpc로 연결한다.

  • Public subnet에서는 map_public_ip_on_launch = true을 설정하여 워커노드가 생성되는 즉시 자동으로 eip를 할당받게 설정하였다.

  • availability_zone도 정의된 변수만큼 count를 채웠고 a,b,c의 가용영역에 연결한다.

  • 마찬가지로 태그를 지정한다. "EKS-PRIVATE${count.index + 1}"부분은 Subnet을 구분하기 위한 설정이다.
    ex) EKS-PRIVATE1, EKS-PRIVATE2 ... 처럼 구분하게 하기 위해 count 함수를 사용하였다.


3. IGW 생성

사용되는 리소스

  • aws_internet_gateway

사용되는 옵션

  • vpc_id
  • tags
# Create IGW
resource "aws_internet_gateway" "PR-TEST-IGW" {
  vpc_id = aws_vpc.PR-TEST-VPC.id

  tags = merge(var.global_tags,
  {
    "Name" = format("%s-%s", var.aws_default_name, "EKS-IGW")
  })
}
  • vpc_id로 연결할 vpc를 정의

4. EIP 생성

사용되는 리소스

  • aws_eip

사용되는 옵션

  • count
  • vpc
# Create EIP for Nat Gateway
resource "aws_eip" "EIP" {
  vpc   = true
}
  • vpc를 true로 설정하여 vpc연결을 활성화 한다.

5. NAT Gateway 생성

사용되는 리소스

  • aws_nat_gateway

사용되는 옵션

  • allocation_id
  • subnet_id
  • tags
# Create Nat Gateway
resource "aws_nat_gateway" "PR-TEST-NG" {
  allocation_id = aws_eip.EIP.id
  subnet_id     = aws_subnet.PR-TEST-PUBSUB.0.id

  tags = merge(var.global_tags,
  {
    "Name" = format("%s-%s", var.aws_default_name, "EKS-NATGW")
  })
}
  • NAT Gateway의 ip를 allocation_id로 eip를 할당한다.

6. Route Table 생성

사용되는 리소스

  • aws_route_table

사용되는 옵션

  • vpc_id
  • route{
    • cidr_block
    • gateway_id (public route table)
    • nat_gateway_id (private route table)
      }
  • tags
  • count (private route table)

6-1 Public Route Table

# Create Public Route Table
resource "aws_route_table" "PR-TEST-PUBROUTE" {
  vpc_id = aws_vpc.PR-TEST-VPC.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.PR-TEST-IGW.id
  }

  tags = merge(var.global_tags,
  {
    "Name" = format("%s-%s", var.aws_default_name, "EKS-PUBLIC-ROUTE")
  })
}
  • vpc_id로 라우트 테이블을 vpc에 연결한다.
  • route { }를 사용하여 라우팅을 설정한다.
    • cidr_block로 대상을 지정하고
    • gateway_id로 연결할 게이트웨이 id를 지정한다.
  • 마찬가지로 tags 설정

6-2. Private Route Table

# Create Private Route Table !!!
resource "aws_route_table" "PR-TEST-PRIROUTE" {
  vpc_id = aws_vpc.PR-TEST-VPC.id
  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.PR-TEST-NG.id
  }

  tags = merge(var.global_tags,
  {
    "Name" = format("%s-%s", var.aws_default_name, "EKS-PRIVATE-ROUTE")
  })
}
  • vpc_id로 라우트 테이블을 vpc에 연결한다.
  • route {}를 사용하여 라우팅을 설정한다.
    • cidr_block로 대상을 지정하고
    • nat_gateway_id를 설정하여 NAT Gateway를 연결하는데 이 때 count.index 사용하여 Route Table을 생성하여 각각 라우팅 되게 설정한다.
      • 따라서 NAT Gateway를 3개를 지정하였으면 3개가 만들어짐

7. Route Table 라우팅

사용되는 리소스

  • aws_route_table_association

사용되는 옵션

  • count
  • route_table_id
  • subnet_id

7-1. Public Table

# Create Public Route Table Routing
resource "aws_route_table_association" "PR-TEST-PUBROUTING" {
  count = length(var.aws_public_subnets)

  route_table_id = aws_route_table.PR-TEST-PUBROUTE.id
  subnet_id      = aws_subnet.PR-TEST-PUBSUB.*.id[count.index]
}

7-2. Private Table

# Create Private Route Table Routing
resource "aws_route_table_association" "PR-TEST-PRIROUTING" {
  count = length(var.aws_private_subnets)

  route_table_id = aws_route_table.PR-TEST-PRIROUTE.id
  subnet_id      = aws_subnet.PR-TEST-PRISUB.*.id[count.index]
}
  • count를 Public Subnet의 수만큼 받아온다.
  • route_table_id로 라우팅할 Public Route Table을 선택한다.
  • 라우팅 될 퍼블릭 서브넷을 모두 subnet_id로 선택한다.
    • 이렇게 설정이됨

변수파일

variable "aws_vpc_cidr" {
  description = "vpc의 cidr을 정의"
}

variable "aws_public_subnets" {
  description = "퍼블릭 서브넷들을 정의"
}

variable "aws_private_subnets" {
  description = "프라이빗 서브넷들을 정의"
}

variable "aws_region" {
  description = "리소스 생성할 지역 정의"
  type = string
}

variable "aws_azs" {
  description = "가용영역 정의"
}

# Naming
variable "global_tags" {
  description = "EKS 생성을 위한 태깅"
  type = map(string)
}

variable "aws_default_name" {
  type = string
  description = "리소스에 붙을 고유한 default 이름을 정의"
}

Usage Sample

###################  Create VPC   ###################
module "vpc" {
  source = "git::https://github.com/SeungHyeonShin/terraform.git//modules/eks-vpc?ref=v1.0.1"

  aws_vpc_cidr        = "192.168.0.0/16"
  aws_private_subnets = ["192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24"]
  aws_public_subnets  = ["192.168.11.0/24", "192.168.12.0/24", "192.168.13.0/24"]
  aws_region          = local.region
  aws_azs             = ["ap-northeast-2a", "ap-northeast-2b", "ap-northeast-2c"]
  aws_default_name    = "seunghyeon"
  global_tags = {
    "kubernetes.io/cluster/${local.cluster_name}" = "shared"
  }
}

전체 리소스

  • aws_vpc
  • aws_subnet
  • aws_internet_gateway
  • aws_eip
  • aws_nat_gateway
  • aws_route_table
  • aws_route_table_association

보완 할 사항

tags를 좀 더 명확하게 알아볼 수 있게

Reference

0개의 댓글