# 1. EFK 스택구축 - 인프라 셋팅

empty·2020년 12월 29일

EFK-STACK

목록 보기
2/6

인프라 셋팅

EKS 클러스터 생성 with Terraform


EFK는 Amazon Kubernetes Service인 EKS에 구축하였다. EKS 클러스터는 아래의 Terraform 을 사용하여 프로비저닝한다.

다행히 나는 AWS에 여분의 크레딧이 남아있어서 비용부담이 안되지만 쌩돈나가게 생겼다면 그냥 GCP 신규가입하면 300달러 주니까 그걸로 하는것도 나쁘지 않은 방법이다.

  • 비용 절감을 위해 EKS클러스터를 구성할 수 있는 최소유형 (t3.medium)으로 생성한다.

    * 온디멘드로 시간당 0.052달러 우리나라 돈으로 57원이고 스팟 인스턴스는 0.014달러 우리나라 돈으로 는 약 15원이다.

리소스가 프로비저닝될 프로바이더 설정

> provider.tf

provider "aws" {
  region = "ap-northeast-2"
}

tf.state파일이 저장될 원격 저장소 설정

> backend.tf

terraform {
  backend "s3" {
    bucket = "seunghyeon-saving-remote-state"
    key = "eks/terraform.tfstate"
    region = "ap-northeast-2"
    encrypt = true
  }
}

EKS 클러스터가 생성될 모든 요소들

> main.tf

############   Local Variable  ######################
# 로컬변수입니다. 클러스터의 이름과 배스천 호스트에 접속가능한 IP대역을 설정해주세요.
locals {
  cluster_name = "seunghyeon-eks"
  region       = "ap-northeast-2"
  bastion-con-ip = ["0.0.0.0/0"]
}

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

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

###################  Create EKS   ###################
# EKS 클러스터를 프로비저닝합니다.
# 비용절감을 위해 On-Demand 노드 하나, Spot-Instance 노드 하나로 구성합니다.
module "eks" {
  source          = "git::https://github.com/terraform-aws-modules/terraform-aws-eks.git?ref=v13.2.1"
  cluster_name    = local.cluster_name
  vpc_id          = module.vpc.aws_vpc_id
  subnets         = module.vpc.private_subnets
  cluster_version = "1.18"
  manage_aws_auth = false

  # EKS Cluster의 보안그룹을 추가시킴
  worker_security_group_id = module.eks.cluster_security_group_id

# This is Important to Use K8S Objects Module's config_path
  write_kubeconfig = true
  config_output_path = pathexpand("~/.kube/kubeconfig_${local.cluster_name}")

  node_groups = [
    {
      name                = "on-demand-1"
      instance_type       = "t3.medium"
      asg_max_size        = 3
      key_name            = aws_key_pair.shin-eks.key_name
      kubelet_extra_args  = "--node-labels=spot=false"
      suspended_processes = ["AZRebalance"]
      additional_tags     = {
        "k8s.io/cluster-autoscaler/enabled" = "true"
      }

      source_security_group_ids = [
        aws_security_group.seunghyeon-bastion-sg.id
      ]
    }
  ]

  worker_groups_launch_template = [
    {
      name                    = "spot-1"
      override_instance_types = ["t3.medium", "t3a.medium"]
      spot_instance_pools     = 5
      asg_max_size            = 5
      asg_desired_capacity    = 1
      key_name                = aws_key_pair.shin-eks.key_name
      kubelet_extra_args      = "--node-labels=node.kubernetes.io/lifecycle=spot"

      # EKS Cluster의 보안그룹을 추가시킴
      additional_security_group_ids = [module.eks.cluster_primary_security_group_id]
      additional_tags = {
        "k8s.io/cluster-autoscaler/enabled" = "true"
      }

      source_security_group_ids = [
        aws_security_group.seunghyeon-bastion-sg.id
      ]
    }
  ]
}



############ Upload  Key Pair ##############
resource "aws_key_pair" "shin-eks" {
  key_name = "shin-eks"
  public_key = file("~/.ssh/project/shin-eks.pub")
}

resource "aws_key_pair" "shin-eks-bastion" {
  key_name = "shin-eks-bastion"
  public_key = file("~/.ssh/project/shin-eks-bastion.pub")
}

############   Create Bastion Host   ################
resource "aws_security_group" "seunghyeon-bastion-sg" {
  name = "seunghyeon-bastion"
  vpc_id = module.vpc.aws_vpc_id

  ingress {
    from_port = 22
    protocol = "tcp"
    to_port = 22
    cidr_blocks = local.bastion-con-ip
  }

  egress {
    from_port = 0
    protocol = "-1"
    to_port = 0
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    "Name" = "seunghyeon-EKS-bastion-sg"
  }
}
resource "aws_instance" "bastion" {
  ami = "ami-027ce4ce0590e3c98"
  instance_type = "t2.micro"
  subnet_id = element(module.vpc.public_subnets, 0)
  key_name = aws_key_pair.shin-eks-bastion.key_name
  vpc_security_group_ids = [
    aws_security_group.seunghyeon-bastion-sg.id
  ]

  tags = {
    "Name" = "seunghyeon-EKS-bastionHost"
  }
}

terraform apply로 프로비저닝을 시작하면 약 15~20분 사이로 EKS클러스터 구성이 완료된다. EKS 클러스터 생성이 완료되었으면 클러스터를 핸들링 하기위해 kubeconfig 파일을 환경변수로 지정해주자.

Kubeconfig 파일 설정

EKS 클러스터가 생성되면 kubeconfig 파일은 $HOME/.kube/kubeconfig_seunghyeon-eks-cluster 로 저장이 된다.

해당 kubeconfig파일의 이름을 config로 변경해주거나 KUBECONFIG 환경변수에 경로를 지정해줘야한다.

# Kubeconfig 파일의 경로를 지정해줌 (택 1)
export KUBECONFIG=$HOME/.kube/kubeconfig_seunghyeon-eks-cluster

# Kubeconfig 파일의 이름을 변경
mv $HOME/.kube/kubeconfig_seunghyeon-eks-cluster $HOME/.kube/config

kubeconfig파일을 지정해주고 나면 EKS클러스터를 컨트롤 할 수 있게 된다.

> k get nodes -o wide
NAME                                               STATUS   ROLES    AGE   VERSION              INTERNAL-IP     EXTERNAL-IP   OS-IMAGE         KERNEL-VERSION                  CONTAINER-RUNTIME
ip-192-168-1-151.ap-northeast-2.compute.internal   Ready    <none>   54m   v1.18.9-eks-d1db3c   192.168.1.151   <none>        Amazon Linux 2   4.14.209-160.335.amzn2.x86_64   docker://19.3.6
ip-192-168-1-25.ap-northeast-2.compute.internal    Ready    <none>   54m   v1.18.9-eks-d1db3c   192.168.1.25    <none>        Amazon Linux 2   4.14.209-160.335.amzn2.x86_64   docker://19.3.6

보안그룹 태그 삭제

Spot-Instance의 보안그룹에 설정되어 있는 태그인 kubernetes.io/cluster/seunghyeon-eks를 삭제해야 한다. 원래 해당 태그는 클러스터의 보안그룹에만 설정이 되어있는데 Terraform 코드에서 Spot-Instance로 EKS를 구성하기 위하여 보안그룹을 하나 더 생성을 해놓은 것이다.

EKS에서는 로드밸런서를 프로비저닝 시 설정되어있는 Tag 기반으로 보안그룹의 Inbound에 해당 로드밸런서의 보안그룹을 허용하게 되는데 만약, 삭제를 안한다면 kubernetes.io/cluster/seunghyeon-eks Tag가 중복이 되면 어느 보안그룹에 추가를 해야할지 못찾게 되어서 로드밸런서가 생성이 안된다.

  • 해당 태그를 삭제하자.

EFK스택을 배포할 인프라 설정은 끝났다.

이제 남은것은 Elasticsearch, Fluentd, Kibana를 배포하고 설정하면 된다.

0개의 댓글