[aws] eks, karpenter, Terraform

아키텍처로 본 EKS 구성

  • Control Plane > Worker Nodes 는 ENI 로 통신
  • 워커노드 > Control Plane 로드밸런서를 통해 통신
  • 사용자 > Control Plane 으로 kubectl를 사용
  • 고객 > Worker Nodes 로드밸런서를 통해 통신

img.png

Worker Node는 어떻게 구성?

  • 가용성을 위해서는 2개 이상의 가용영역에 노드를 구성
  • 보안을 위해 Private Subnet에 구성
  • S3에 대용량의 데이터 접근이 있는 경우 S3 게이트웨이 엔드포인트 구성 필요

img_1.png

노드 관리 방법

  • 종류 : AutoScaling 그룹, Fargate, Karpenter, 3rd Party …
    Pod을 실행할 Node가 부족할 때? img_2.png

Karpenter는 더 빠르게 노드를 할당 받을 수 있다 img_3.png

IaC가 뭔가요?

  • 인프라스트럭처 관리를 소프트웨어 개발과 유사한 방식으로 다루는 접근 방식
  • 종류 : Terraform, Pulumi, AWS CloudFormation…

Terraform 실행 환경 구성

  • Terraform 설치용 EC2 구성 à Cloud 9 사용 (Linux Server + Editor + @)
  • Terraform CLI 설치 (링크)
  • AWS CLI 설치 (링크) (cloud9 에 설치 되어 있어서 따로 실행 할 일 없음)
  • IAM Policy 및 Role 생성

Terraform 설치용 EC2 구성 à Cloud 9 사용 (Linux Server + Editor + @)

  • aws console 접속
  • cloud9 검색

img_4.png

  • create environment(환경생성) 클릭!!
  • 이름, ec2 종류, 플랫폼 선택후 생성!!

img_5.png

  • 생성 완료후 ec2에서도 조회가 된다.

  • 시작은 open 을 누르면 시작이 된다.

img_6.png img_7.png

  • Terraform CLI 설치 링크를 통해 cloud9 cli 설치를 진행 한다.

img_8.png

  • 설치 완료 후 terraform 버전 확인으로 설치 확인 진행
terraform -version
  • aws cli는 기본적으로 설치 되어 있다.
aws --version
  • Role을 적용하기 위해 cloud9에 임시적으로 인증정보를 가져오게 되어 있는 설정을 꺼준다.

img_9.png

img_10.png

  • 하기 경로에 크레덴셜이 있는지 확인하고 있으면 삭제해 준다.(보통 없음)

img_11.png

  • IAM > Roles(역할) > Create role(역할 생성)

img_12.png

  • 다음으로 필요 권한을 준다. 다음에서 역할 이름 기입 후 생성해 준다.

img_13.png

  • 생성된 롤을 연결해 준다.

img_14.png

  • 기 생성된 롤 적용후 cli에서 확인해 준다. 기본적인 설정 완료.
aws sts get-caller-identity

img_15.png

Terraform 명령어

  • terraform init
  • terraform plan : 생성될 자원들 미리 확인
  • terraform apply : 자원 생성 및 수정(수정시 변경된 내용을 확인 받게 된다)
  • terraform destroy : 자원 삭제
cd ~
# 입력시 나오는 environment 폴더가 좌측 창의 경로
ls

EKS 생성

  • 폴더 생성 후 main.tf 생성
  • terraform init
  • 클러스터 접속
    • kubectl 도구 설치(링크)
      • Install kubectl binary with curl on Linux 부분 하위 입력(설치 경로는 utils로 따로 잡아준다.)
      • Install kubectl 부분 하위 입력
      • kubectl version 입력하여 설치 확인
    • kubeconfig 설정
aws eks --region <REGION> update-kubeconfig --name <CLUSTER_NAME>
  • 노드확인
    kubectl get node
    

Terraform base source

provider "aws" {
  region = local.region
}

provider "kubernetes" {
  host                   = module.eks.cluster_endpoint
  cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
  token                  = data.aws_eks_cluster_auth.this.token
}

data "aws_eks_cluster_auth" "this" {
  name = module.eks.cluster_name
}

data "aws_availability_zones" "available" {}

locals {
  name   = basename(path.cwd)
  region = "ap-northeast-2"

  vpc_cidr = "10.0.0.0/16"
  azs      = slice(data.aws_availability_zones.available.names, 0, 3)

  tags = {
    Cluster  = local.name
  }
}

################################################################################
# Cluster
################################################################################

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 19.16"

  cluster_name                   = local.name
  cluster_version                = "1.27"
  cluster_endpoint_public_access = true

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  eks_managed_node_groups = {
    default_node_group = {
      instance_types = ["t3.medium"]

      min_size     = 2
      max_size     = 10
      desired_size = 2
    }
  }

  tags = local.tags
}

################################################################################
# Supporting Resoruces
################################################################################

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.0"

  name = local.name
  cidr = local.vpc_cidr

  azs             = local.azs
  public_subnets  = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
  private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)]
    
  enable_nat_gateway = true
  single_nat_gateway = true

  public_subnet_tags = {
    "kubernetes.io/role/elb" = 1
  }

  private_subnet_tags = {
    "kubernetes.io/role/internal-elb" = 1
  }

  tags = local.tags
}

Terraform rds

provider "aws" {
  region = local.region
}

provider "kubernetes" {
  host                   = module.eks.cluster_endpoint
  cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
  token                  = data.aws_eks_cluster_auth.this.token
}

data "aws_eks_cluster_auth" "this" {
  name = module.eks.cluster_name
}

data "aws_availability_zones" "available" {}

locals {
  name   = basename(path.cwd)
  region = "ap-northeast-2"

  vpc_cidr = "10.0.0.0/16"
  azs      = slice(data.aws_availability_zones.available.names, 0, 3)

  tags = {
    Cluster  = local.name
  }
}

################################################################################
# Cluster
################################################################################

module "eks" {
  source  = "terraform-aws-modules/eks/aws"
  version = "~> 19.16"

  cluster_name                   = local.name
  cluster_version                = "1.27"
  cluster_endpoint_public_access = true

  vpc_id     = module.vpc.vpc_id
  subnet_ids = module.vpc.private_subnets

  eks_managed_node_groups = {
    default_node_group = {
      instance_types = ["t3.small"]

      min_size     = 1
      max_size     = 3
      desired_size = 2
    }
  }

  tags = local.tags
}

module "db" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "demodb"

  engine            = "mysql"
  engine_version    = "5.7"
  instance_class    = "db.t3.micro"
  allocated_storage = 5

  db_name  = "demodb"
  username = "user"
  port     = "3306"
  password = "CHANGE_PASSWORD"
  
  manage_master_user_password = false
  
  skip_final_snapshot    = true
  
  vpc_security_group_ids = [module.security_group.security_group_id]

  maintenance_window = "Mon:00:00-Mon:03:00"
  backup_window      = "03:00-06:00"

  tags = {
    Owner       = "user"
    Environment = "dev"
  }

  # DB subnet group
  db_subnet_group_name   = module.vpc.database_subnet_group

  # DB parameter group
  family = "mysql5.7"

  # DB option group
  major_engine_version = "5.7"

  # Database Deletion Protection
  deletion_protection = false

  parameters = [
    {
      name  = "character_set_client"
      value = "utf8mb4"
    },
    {
      name  = "character_set_server"
      value = "utf8mb4"
    }
  ]

}

module "security_group" {
  source  = "terraform-aws-modules/security-group/aws"
  version = "~> 5.0"

  name        = local.name
  description = "Complete MySQL example security group"
  vpc_id      = module.vpc.vpc_id

  # ingress
  ingress_with_cidr_blocks = [
    {
      from_port   = 3306
      to_port     = 3306
      protocol    = "tcp"
      description = "MySQL access from within VPC"
      cidr_blocks = module.vpc.vpc_cidr_block
    },
  ]

  tags = local.tags
}

################################################################################
# Supporting Resoruces
################################################################################

module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.0"

  name = local.name
  cidr = local.vpc_cidr

  azs             = local.azs
  public_subnets   = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k)]
  private_subnets  = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 3)]
  database_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 6)]

  create_database_subnet_group = true

  enable_nat_gateway = true
  single_nat_gateway = true

  public_subnet_tags = {
    "kubernetes.io/role/elb" = 1
  }

  private_subnet_tags = {
    "kubernetes.io/role/internal-elb" = 1
  }

  tags = local.tags
}

© 2023 Lee. All rights reserved.