일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 내일배움카드
- Layer 2
- 패스트캠퍼스
- linux domain
- CoreDNS
- PV
- k8s
- MegabyteSchool
- DNS
- MariaDB
- dns forward
- 국비지원교육
- RDB
- L2 통신
- systemd-resolved
- reclaim
- ssh tunneling
- 메가바이트스쿨
- L2 통작
- 127.0.0.53
- PVC
- 개발자취업부트캠프
- linux dns
- Spring boot
- ARP
- Today
- Total
hoonii2
[terraform] EKS 배포 본문
1. 개요
aws document 와 terraform aws provider 를 참고하여 EKS 를 배포하고 구성요소 이해를 목적으로 합니다.
이해와 학습이 목적이므로 terraform module 을 사용하지 않고 직접 리소스를 작성하여 구성합니다.
배포 목적 아키텍처는 다음과 같습니다.
- 각 subnet 의 태그는 EKS 에서 올바른 서브넷을 검색하기 위해 필수 요구사항입니다.
( 관련 문서 링크는 아래 6.subnets.tf 에 기재하였습니다. )
- 추후 Ingress 동작 및 private subnet 의 외부 통신을 위해 public subnet 을 구성했습니다.
2. locals.tf
# locals.tf
locals {
env = "dev"
region = "ap-northeast-2"
zone1 = "ap-northeast-2a"
zone2 = "ap-northeast-2b"
eks_name = "hoonDemo"
eks_version = "1.30"
}
- env 를 통해 "dev", "staging", "production" 등의 환경을 명시합니다.
- 서로 다른 AZ 로 고가용성 EKS 환경을 배포합니다.
- EKS 내 k8s 버전은 최신 버전으로 명시했습니다.
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/kubernetes-versions.html#available-versions
Amazon EKS Kubernetes 버전 - Amazon EKS
컨트롤 플레인을 업데이트하는 경우 Fargate 노드를 직접 업데이트해야 합니다. Fargate 노드를 업데이트하려면 노드가 나타내는 Fargate Pod를 삭제하고 Pod를 다시 배포합니다. 새 Pod는 클러스터와 동
docs.aws.amazon.com
3. providers.tf
# providers.tf
provider "aws" {
region = local.region
}
terraform {
required_version = ">=1.9.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.56.1"
}
}
}
- terraform 최신 stable 버전을 사용했습니다.
https://github.com/hashicorp/terraform/releases
Releases · hashicorp/terraform
Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared ...
github.com
- terraform aws provider 최신 버전을 사용했습니다.
https://registry.terraform.io/providers/hashicorp/aws/latest/docs
Terraform Registry
registry.terraform.io
4. vpc.tf
# vpc.tf
resource "aws_vpc" "hoon_vpc" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "${local.env}-vpc"
}
}
- "Name" 태그를 통해 aws 리소스의 이름을 명시할 수 있습니다.
https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/Using_Tags.html ( 태그 지정 리소스 목록 )
Amazon EC2 리소스 태깅 - Amazon Elastic Compute Cloud
리소스를 삭제한 후에도 해당 태그가 콘솔, API 및 CLI 출력에 잠시 동안 표시될 수 있습니다. 이러한 태그는 리소스에서 서서히 연결이 해제되고 영구적으로 삭제됩니다.
docs.aws.amazon.com
5. igw.tf
# igw.tf
resource "aws_internet_gateway" "hoon_igw" {
vpc_id = aws_vpc.hoon_vpc.id
tags = {
Name = "${local.env}-igw"
}
}
- 외부 인터넷 통신을 위한 igw 를 생성합니다.
6. subnets.tf
# subnets.tf
resource "aws_subnet" "private_subnet1" {
vpc_id = aws_vpc.hoon_vpc.id
cidr_block = cidrsubnet(aws_vpc.hoon_vpc.cidr_block, 3, 1)
availability_zone = local.zone1
tags = {
"Name" = "${local.env}-private-${local.zone1}"
"kubernetes.io/role/internal-elb" = "1"
}
}
resource "aws_subnet" "private_subnet2" {
vpc_id = aws_vpc.hoon_vpc.id
cidr_block = cidrsubnet(aws_vpc.hoon_vpc.cidr_block, 3, 2)
availability_zone = local.zone2
tags = {
"Name" = "${local.env}-private-${local.zone2}"
"kubernetes.io/role/internal-elb" = "1"
}
}
resource "aws_subnet" "public_subnet1" {
vpc_id = aws_vpc.hoon_vpc.id
cidr_block = cidrsubnet(aws_vpc.hoon_vpc.cidr_block, 3, 3)
availability_zone = local.zone1
map_public_ip_on_launch = true
tags = {
"Name" = "${local.env}-public-${local.zone1}"
"kubernetes.io/role/elb" = "1"
}
}
resource "aws_subnet" "public_subnet2" {
vpc_id = aws_vpc.hoon_vpc.id
cidr_block = cidrsubnet(aws_vpc.hoon_vpc.cidr_block, 3, 4)
availability_zone = local.zone2
map_public_ip_on_launch = true
tags = {
"Name" = "${local.env}-public-${local.zone2}"
"kubernetes.io/role/elb" = "1"
}
}
- 각 AZ 에 public / private subnet 을 생성합니다.
- EKS subnet 생성 시 private 은 "kubernetes.io/role/internal-elb" = "1", public 은 "kubernetes.io/role/elb" = "1" 를 필요로 합니다.
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/network-load-balancing.html
Amazon EKS의 네트워크 로드 밸런싱 - Amazon EKS
이전 버전과의 호환성을 위해 service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip" 주석이 여전히 지원됩니다. 그러나 service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip" 대신 새 로드 밸런서에 이전 주석을
docs.aws.amazon.com
- cidrsubnet 함수를 통해 자동으로 서브넷팅합니다.
https://developer.hashicorp.com/terraform/language/functions/cidrsubnet
cidrsubnet - Functions - Configuration Language | Terraform | HashiCorp Developer
The cidrsubnet function calculates a subnet address within a given IP network address prefix.
developer.hashicorp.com
7. nat.tf
# nat.tf
resource "aws_eip" "nat" {
domain = "vpc"
tags = {
Name = "${local.env}-nat"
}
}
resource "aws_nat_gateway" "nat" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public_subnet1.id
tags = {
Name = "${local.env}-nat"
}
depends_on = [aws_internet_gateway.hoon_igw]
}
- private subnet 의 외부 의존성 다운로드 등을 위한 외부 통신 용 nat gateway 를 생성합니다.
- nat gw 동작은 igw 에 의존하므로 igw 이후 생성하도록 depends_on 설정합니다. ( 테라폼 권장 사항 )
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/nat_gateway
Terraform Registry
registry.terraform.io
8. routes.tf
resource "aws_route_table" "hoon_private_rt" {
vpc_id = aws_vpc.hoon_vpc.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat.id
}
tags = {
Name = "${local.env}-hoon_private_rt"
}
}
resource "aws_route_table" "hoon_public_rt" {
vpc_id = aws_vpc.hoon_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.hoon_igw.id
}
tags = {
Name = "${local.env}-hoon_public_rt"
}
}
resource "aws_route_table_association" "private_subnet1" {
subnet_id = aws_subnet.private_subnet1.id
route_table_id = aws_route_table.hoon_private_rt.id
}
resource "aws_route_table_association" "private_subnet2" {
subnet_id = aws_subnet.private_subnet2.id
route_table_id = aws_route_table.hoon_private_rt.id
}
resource "aws_route_table_association" "public_subnet1" {
subnet_id = aws_subnet.public_subnet1.id
route_table_id = aws_route_table.hoon_public_rt.id
}
resource "aws_route_table_association" "public_subnet2" {
subnet_id = aws_subnet.public_subnet2.id
route_table_id = aws_route_table.hoon_public_rt.id
}
- public subnet 은 igw 를, private subnet 은 nat gw 로 외부 통신을 하도록 라우팅 테이블을 구성합니다.
- 이후 각 subnet 을 private / public 용도에 맞게 연결합니다.
9. eks.tf
# eks.tf
resource "aws_iam_role" "hoon_eks_role" {
name = "${local.env}-${local.eks_name}-eks_cluster"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Alllow"
Principal = {
Service = "eks.amazonaws.com"
}
}
]
})
}
resource "aws_iam_role_policy_attachment" "hoon_eks_attach" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.hoon_eks_role.name
}
resource "aws_eks_cluster" "hoon_eks_cluster" {
name = "${local.env}-${local.eks_name}"
version = local.eks_version
role_arn = aws_iam_role.hoon_eks_role.arn
vpc_config {
endpoint_private_access = false
endpoint_public_access = true
subnet_ids = [
aws_subnet.private_subnet1.id,
aws_subnet.private_subnet2.id
]
}
access_config {
authentication_mode = "API"
bootstrap_cluster_creator_admin_permissions = true
}
depends_on = [aws_iam_role_policy_attachment.hoon_eks_attach]
}
- terraform aws provider 를 참고했습니다.
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_cluster
Terraform Registry
registry.terraform.io
- aws 문서를 참고하여 eks cluster iam role 을 부여합니다.
( 혹은 최소 권한 원칙을 원하는 경우 아래 문서를 참고해 Custom Policy 를 만들어 사용할 수 있습니다 )
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/service_IAM_role.html
Amazon EKS 클러스터 IAM 역할 - Amazon EKS
이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.
docs.aws.amazon.com
- jsonencode 를 사용하여 iam role 을 선언합니다.
https://developer.hashicorp.com/terraform/language/functions/jsonencode
jsonencode - Functions - Configuration Language | Terraform | HashiCorp Developer
The jsonencode function encodes a given value as a JSON string.
developer.hashicorp.com
10. nodes.tf
# nodes.tf
resource "aws_iam_role" "hoon_nodes_role" {
name = "${local.env}-${local.eks_name}-hoon_nodes"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Action = "sts:AssumeRole",
Effect = "Allow",
Principal = {
Service = "ec2.amazonaws.com"
}
}
]
})
}
resource "aws_iam_role_policy_attachment" "hoon_nodes_worker_attach" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.hoon_nodes_role.name
}
resource "aws_iam_role_policy_attachment" "hoon_nodes_cni_attach" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.hoon_nodes_role.name
}
resource "aws_iam_role_policy_attachment" "hoon_nodes_ecr_attach" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.hoon_nodes_role.name
}
resource "aws_eks_node_group" "hoon_node_group" {
cluster_name = aws_eks_cluster.hoon_eks_cluster.name
version = local.eks_version
node_group_name = "hoon_node_group"
node_role_arn = aws_iam_role.hoon_nodes_role.arn
subnet_ids = [
aws_subnet.private_subnet1.id,
aws_subnet.private_subnet2.id
]
capacity_type = "ON_DEMAND"
instance_types = ["t3.large"]
scaling_config {
desired_size = 1
max_size = 10
min_size = 0
}
update_config {
max_unavailable = 1
}
labels = {
role = "hoon_node_group"
}
depends_on = [
aws_iam_role_policy_attachment.hoon_nodes_cni_attach,
aws_iam_role_policy_attachment.hoon_nodes_ecr_attach,
aws_iam_role_policy_attachment.hoon_nodes_worker_attach
]
lifecycle {
ignore_changes = [scaling_config[0].desired_size]
}
}
- terraform aws provider 를 참고했습니다.
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_node_group
Terraform Registry
registry.terraform.io
- aws 문서를 참고하여 node iam role 을 부여합니다.
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/create-node-role.html
Amazon EKS 노드 IAM 역할 - Amazon EKS
이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.
docs.aws.amazon.com
- EKS 3가지 노드 타입 중 관리형 노드그룹을 사용합니다.
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/create-managed-node-group.html
관리형 노드 그룹 생성 - Amazon EKS
관리형 노드 그룹을 처음 생성할 때 사용자 정의 시작 템플릿을 사용하지 않는 경우 나중에 노드 그룹에 대해 시작 템플릿을 사용하지 마세요. 사용자 정의 시작 템플릿을 지정하지 않은 경우
docs.aws.amazon.com
- 온디맨드 인스턴스로 서비스 중단을 방지하고 auto-scaling 을 구성합니다.
- ignore-change 를 통해 auto-scaling 시 terraform 의 desire 값이 mismatch 충돌되는 것을 방지합니다.
Terraform Registry
registry.terraform.io
11. 확인 및 배포
terraform init > plan > apply 를 통해 상태를 확인하고 배포합니다.
'개념 공부 > (DevOps) 01. IaC' 카테고리의 다른 글
[terraform] EC2 EBS 증설 (0) | 2024.06.27 |
---|---|
[terraform] EC2 최신 AMI ID 연결 (0) | 2024.06.26 |