ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Terraform | EKS 만들어 보기
    Iac 2022. 1. 28. 16:58

    테라폼을 이용하여 EKS를 생성하는 방법을 정리해 보려고 합니다.

    EKS를 구성하고 있는 각각의 테라폼 리소스를 이용하여 만들 수 도 있지만 테라폼에서 제공하는 EKS모듈을 이용하면 보다 쉽게 만들 수 있습니다.

    Terraform EKS Module

     

    github의 example에 들어가 보시면 example이 존재합니다.

    Terrarom EKS Module Example

     

    예시로는 테라폼에서 제공하는 노드 그룹을 전부 이용하는 예제가 제공되고 있습니다.

    간단하게 실습용으로 만들 것이기 때문에 제공하는 example보다는 간소화해서 만들어보도록 하겠습니다.

     

    만들기 전에 기본적인 설정들을 정리하도록 하겠습니다.

    EKS를 만들기 위해서 추가적으로 awscli2, kubectl, helm(CA(cluster-autoscaler 설치))이 필요합니다.

     

    먼저 AWS Provider설정을 합니다.

    # main.tf
    provider "aws" {
      region = var.region
    
      default_tags {
        tags = {
          Terraform = "true"
          Project   = "${var.cluster_name}-project"
        }
      }
    }
    

    Region과 생성된 리소스들에 대해서 지정함 default tag를 작성합니다.

     

    EKS등에서 사용될 variables를 생성합니다.

    # variables.tf
    variable "region" {
      default = "ap-northeast-2"
    }
    
    variable "azs" {
      description = "A list of availability zones names or ids in the region"
      type = list(string)
      default = ["ap-northeast-2a", "ap-northeast-2c"]
    }
    
    variable "cluster_name" {
      description = "Cluster Name"
      type = string
      default = null
    }
    
    variable "cluster_version" {
      description = "Cluster Version"
      type = string
      default = null
    }
    
    variable "vpc_cidr" {
      description = "VPC CIDR Range"
      type = string
      default = null
    }
    
    variable "vpc_name" {
      description = "VPC Name"
      type = string
      default = null
    }
    

     

    # terraform.auto.tfvars
    vpc_name     = "ray-vpc"
    vpc_cidr     = "192.168.0.0/16"
    
    cluster_name     = "my-cluster"
    cluster_version  = "1.21"
    

    테라폼 실행 시 해당 파일에 작성한 변수명과 일치하는 variables에 맞게 사용됩니다.

    위의 파일들이 준비가 되었으면 먼저 새로운 VPC를 생성할 수 있도록 작성합니다.

     

    VPC 또한 테라폼에서 제공하는 모듈을 이용하면 손쉽게 만들 수 있습니다.

    # vpc.tf
    module "vpc" {
      source = "terraform-aws-modules/vpc/aws"
    
      name = var.vpc_name
      azs  = var.azs
      cidr = var.vpc_cidr
    
      # NAT게이트웨이를 생성합니다.
      enable_nat_gateway = true
      # NAT게이트웨이를 1개만 생성합니다.
      single_nat_gateway = true
    
      public_subnets = [for index in range(2):
                          cidrsubnet(var.vpc_cidr, 4, index)]
    
      private_subnets = [for index in range(2):
                          cidrsubnet(var.vpc_cidr, 4, index + 2)]
    }
    

    cidrsubnet 서브넷 cidr을 나눠주기 위해 사용됩니다.

     

    EKS를 생성합니다.

    data "aws_caller_identity" "current" {}
    
    locals {
      node_group_name        = "${var.cluster_name}-node-group"
      iam_role_policy_prefix = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:policy"
    }
    
    module "eks" {
      # 모듈 사용
      source = "terraform-aws-modules/eks/aws"
    
      cluster_name    = var.cluster_name
      cluster_version = var.cluster_version
    
      cluster_endpoint_private_access = true
      cluster_endpoint_public_access  = true
    
      vpc_id          = module.vpc.vpc_id
      subnet_ids      = module.vpc.private_subnets
      
      # 관리형 노드 그룹 사용 (기본 설정)
      eks_managed_node_group_defaults = {
        ami_type               = "AL2_x86_64" # 
        disk_size              = 10           # EBS 사이즈
        instance_types         = ["t2.small"]
        # vpc_security_group_ids = [aws_security_group.additional.id]
        vpc_security_group_ids = []
    		
    		# cluster-autoscaler에 사용 될 IAM 등록
        iam_role_additional_policies = ["${local.iam_role_policy_prefix}/${module.iam_policy_autoscaling.name}"]
      }
    
      # 관리형 노드 그룹 사용 (노드별 추가 설정)
      eks_managed_node_groups = {
        ("${var.cluster_name}-node-group") = {
          # node group 스케일링
          min_size     = 1 # 최소
          max_size     = 3 # 최대
          desired_size = 2 # 기본 유지
    
          # 생성된 node에 labels 추가 (kubectl get nodes --show-labels로 확인 가능)
          labels = {
            ondemand = "true"
          }
    
          # 생성되는 인스턴스에 tag추가
          tags = {
            "k8s.io/cluster-autoscaler/enabled" : "true"
            "k8s.io/cluster-autoscaler/${var.cluster_name}" : "true"
          }
        }
      }
    }
    

    테라폼 EKS모듈(현재 18.2.3 버전)에서는 3가지의 node group을 제공합니다.

    AWS EKS에서 제공하는 Node Group은 여기에서 확일 할 수 있습니다.

     

    Node Group에 사용될 IAM Policy를 생성합니다. (cluster-autoscaler를 사용하기 위함입니다.)

    module "iam_policy_autoscaling" {
      source = "terraform-aws-modules/iam/aws//modules/iam-policy"
    
      name = "${var.cluster_name}-cluster-autoscaler"
      path = "/"
      description = "Autoscaling policy for cluster ${var.cluster_name}"
    
      policy      = data.aws_iam_policy_document.worker_autoscaling.json
    }
    
    data "aws_iam_policy_document" "worker_autoscaling" {
      statement {
        sid    = "eksWorkerAutoscalingAll"
        effect = "Allow"
    
        actions = [
          "autoscaling:DescribeAutoScalingGroups",
          "autoscaling:DescribeAutoScalingInstances",
          "autoscaling:DescribeLaunchConfigurations",
          "autoscaling:DescribeTags",
          "ec2:DescribeLaunchTemplateVersions",
        ]
    
        resources = ["*"]
      }
    
      statement {
        sid    = "eksWorkerAutoscalingOwn"
        effect = "Allow"
    
        actions = [
          "autoscaling:SetDesiredCapacity",
          "autoscaling:TerminateInstanceInAutoScalingGroup",
          "autoscaling:UpdateAutoScalingGroup",
        ]
    
        resources = ["*"]
    
        condition {
          test     = "StringEquals"
          variable = "autoscaling:ResourceTag/kubernetes.io/cluster/${var.cluster_name}"
          values   = ["owned"]
        }
    
        condition {
          test     = "StringEquals"
          variable = "autoscaling:ResourceTag/k8s.io/cluster-autoscaler/enabled"
          values   = ["true"]
        }
      }
    }

    Cluster Autoscaler가 IAM 역할을 사용하기 위해 필요한 권한입니다.

     

    여기까지 작성 후 테라폼 명령을 이용하여 생성하도록 합니다.

    terraform init
    
    terraform plan
    
    terraform apply
    

     

    kubecofing설정

    EKS를 생성하게 되면 생성한 IAM User에 대해서 system:master 권한을 갖게 됩니다.

    따라서 초기 설정을 위해서 system:master로 클러스터에 접속하게 되는데 이때, 다음 명령을 통해 해당 User에 대해서

     

    EKS 클러스터에 접속할 수 있는 토큰을 발급하여 사용하도록 하는 kubeconfig를 생성합니다.

    # EKS생성에 사용된 IAM configure를 이용해야합니다. (~/.aws)
    aws eks --region ap-northeast-2 update-kubeconfig --name my-cluster
    

     

    생성된 kubeconfig 예시

    # ~/.kube/kubeconfig
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: ********==
        server: https://********.***.ap-northeast-2.eks.amazonaws.com
      name: arn:aws:eks:ap-northeast-2:********:cluster/my-cluster
    contexts:
    - context:
        cluster: arn:aws:eks:ap-northeast-2:********:cluster/my-cluster
        user: arn:aws:eks:ap-northeast-2:********:cluster/my-cluster
      name: arn:aws:eks:ap-northeast-2:********:cluster/my-cluster
    current-context: arn:aws:eks:ap-northeast-2:********:cluster/my-cluster
    kind: Config
    preferences: {}
    users:
    - name: arn:aws:eks:ap-northeast-2:********:cluster/my-cluster
      user:
        exec:
          apiVersion: client.authentication.k8s.io/v1alpha1
          args:
          - --region
          - ap-northeast-2
          - eks
          - get-token
          - --cluster-name
          - my-cluster
          command: aws
          env:
          - name: AWS_PROFILE
            value: my-aws-profile
    

    kubeconfig가 생성되면 다음과 같은 config가 생성된 걸 확인할 수 있습니다.

     

    kubectl을 이용하여 해당 EKS Api서버로 요청이 잘 가는지 확인합니다.

    # 생성된 EKS의 Node 확인
    kubectl get nodes
    
    # 만약 연결이 되지 않는 경우 kubeconfig가 제대로 지정 되지 않았을 수 도 있습니다.
    export KUBECONFIG="~/.kube/{해당 config파일}"
    

     

    마지막으로 EKS 사용량에 따라 node group의 node들이 스케일링이 가능해지도록 CA(cluster-autoscaler)를 설치합니다.

     

    먼저 CA(cluster-autoscaler)에 사용될 values.yaml을 생성합니다.

    # values.yaml
    autoDiscovery:
      clusterName: my-cluster # eks cluster name
    
    awsRegion: ap-northeast-2 # eks region
    
    extraArgs:
      logtostderr: true
      stderrthreshold: info
      v: 4
      expander: random
      scale-down-enabled: true # 사용량이 적을경우 scale-down허용
    

    각각의 옵션은 여기서 확인할 수 있습니다.

     

    마지막으로 Helm install을 통해 CA(cluster-autoscaler)를 설치합니다.

    helm repo add autoscaler <https://kubernetes.github.io/autoscaler>
    
    helm repo update
    
    helm install cluster-autoscaler autoscaler/cluster-autoscaler --values=./valuse.yaml
    

     

    'Iac' 카테고리의 다른 글

    Terraform | Terraform State  (0) 2022.01.23
    Terraform | Terraform 버전관리  (0) 2022.01.21
    Terraform | Terraform 이란  (0) 2022.01.20
Designed by Tistory.