아이엠 !나이롱맨😎
article thumbnail
반응형

테라폼은 Code 로 인프라를 구축할 수 있게 도와주는 IaC Tool 입니다.

특히 AWS 인프라를 구축할 때 참 유용하게 사용할 수 있죠.

 

module 을 제공해주기 때문에 어렵지 않게 VPC, EKS, ELB 를 생성하고 코드를 관리 할 수 있습니다.

 

이번 글에서는 테라폼을 이용해 EKS 를 구축하는 과정에서 겪은 문제점과 이를 해결했던 방법에 대해 이야기 해볼까 합니다.

 

우선 Apply!!


terraform-aws-eks 에 가보면 아주 친절하게 테라폼을 이용해 EKS 를 구축할 수 있는 방법에 대해 알려줍니다.

 

무작정 eks 모듈을 import 하고 example  EKS Best Practices Guides 참고하여 테라폼 코드를 작성했습니다.

 

provider "kubernetes" {
  host                   = module.eks-main.cluster_endpoint
  cluster_ca_certificate = base64decode(module.eks-main.cluster_certificate_authority_data)

  exec {
    api_version = "client.authentication.k8s.io/v1beta1"
    command     = "aws"
    args = ["eks", "get-token", "--cluster-name", module.eks-main.cluster_id, "--profile", "dev"]
  }
}

module "eks-main" {
  source  = "registry.terraform.io/terraform-aws-modules/eks/aws"

  cluster_name    = local.name
  cluster_version = local.cluster_version

  cluster_endpoint_public_access  = false 
  cluster_endpoint_private_access = true

  manage_aws_auth_configmap = true
  aws_auth_users            = [...]
  
  ...
  
}

 

 

인터넷으로 나갈 필요가 없어 private_access 만 true 로 두었습니다.

...
  cluster_endpoint_public_access  = false 
  cluster_endpoint_private_access = true
...

 

 

실행해보죠! 🙏

(한번에 가자!)

 

$ terraform plan
$ terraform apply

 

 

아주 잘만들어 지고 있습니다 😃

 

모든 것이 순탄하게 만들어지고 있다가 갑자기...

Error: The configmap "aws-auth" does not exist

 

라는 문구 뜨더니 failed 되었습니다.

읽어보니 "aws_auth" 라는 configmap 을 찾을 수 없다고 하네요..

 

"aws_auth" 는 EKS 내에서 사용할 AWS IAM 을 등록할 수 있는 configmap 입니다. 누군자 새로운 유저의 접근을 허용하려면 여기에 추가해주면 되죠!

보통 EKS 를 생성하면 자동으로 생성시켜주는 데 왜 찾질 못하는 걸까요..?? 🤨

 

늘 한번에 되면 이상하지..🧐


설렘은 없어지고.. 바로 구글링을 시도해 보았습니다!!

다행히 Issues 에 저와 같은 문제는 겪는 사람들이 많습니다 🤟

 

저랑 완전히 같은 문제입니다. 심지어 코멘트도 69개가 되는 걸 보니 순탄하게 해결할 수 있을거 같아요 😎

 

첫번째 시도 1️⃣


아~ create_aws_auth_configmap = true 를 추가해야 하는군요?

 

👍 이 4개인걸 보니 믿음이 갑니다! 바로 추가해보죠!

 

module "eks-main" {
  source  = "registry.terraform.io/terraform-aws-modules/eks/aws"

  cluster_name    = local.name
  cluster_version = local.cluster_version

  cluster_endpoint_public_access  = false 
  cluster_endpoint_private_access = true
  
  
  create_aws_auth_configmap = true //추가
  manage_aws_auth_configmap = true
  aws_auth_users            = [...]
  
  ...
  
}

 

 

바로 실패해버립니다..

 

 

근데 에러 문구가 좀 바뀌었습니다.

 

이미 존재하는군요...

 

모듈의 코드를 직접 확인해보죠!

 

resource "kubernetes_config_map" "aws_auth" {
  count = var.create && var.create_aws_auth_configmap ? 1 : 0

  metadata {
    name      = "aws-auth"
    namespace = "kube-system"
  }

  data = local.aws_auth_configmap_data

  lifecycle {
    # We are ignoring the data here since we will manage it with the resource below
    # This is only intended to be used in scenarios where the configmap does not exist
    ignore_changes = [data]
  }
}

 

create_aws_auth_configmaptrue 로 주면 kube-system 이라는 네임스페이스에 aws-auth 라는 ConfigMap 을 생성시켜준다고 추측할 수 있겠군요.

 

근데 이미 EKS Cluster 를 생성하면서 내부엔 aws-auth 라는 configmap 이 존재합니다.

resource "kubernetes_config_map_v1_data" "aws_auth" {
  count = var.create && var.manage_aws_auth_configmap ? 1 : 0

  force = true

  metadata {
    name      = "aws-auth"
    namespace = "kube-system"
  }

  data = local.aws_auth_configmap_data

  depends_on = [
    # Required for instances where the configmap does not exist yet to avoid race condition
    kubernetes_config_map.aws_auth,
  ]
}

manage_aws_auth_configmaptrue 로 주면 리소스에 정의된 코드가 실행되는 걸 확인할 수 있습니다.

force 라는 옵션 때문에 기존에 있던 aws-auth재정의 되는 걸 확인할 수 있습니다.

 

첫번째 시도 결과 👎

이미 EKS Cluster 가 생성될 때 aws-auth 가 자동으로 생성되는 걸 확인할 수 있고, 
create_aws_auth_configmap  옵션은 다시 한번 aws-auth 생섬함으로써 중복 에러가 발생하는 걸 확인할 수 있습니다.

 

깃헙에 달린 이 코멘트는 문제를 해결하기엔 부족하군요..

 

두번째 시도 2️⃣


아래로 내리다보면 아래와 같은 코멘트를 확인할 수 있습니다.

 

Make sure you are on VPN or in the network you want to access cluster from

머릿속에 무언가가 스쳐갑니다💡

 

재빨리 공식 문서를 확인해보죠!!

실마리가 보입니다. 저는 위에서 Endpoint 를 private 만 주었습니다.


왜냐하면 DEV 환경은 인터넷을 통해 접근할 필요가 없기 때문이죠. 그리고 저는 새로운 VPC 에 EKS 를 배포하고 있고요 !!

 

감이 오시나요?🤓

 

지금 EKS 가 있는 VPC 는 어느 VPC 와도 Peer or Share 되고 있지 않습니다. 이 말은 완전히 격리된 VPC 라는 거죠. 그림으로 표현하면 이렇습니다.

 

저는 지금 상황으로는 저 격리된 VPC 내에 존재하는 EKS 에 접근할 수 없습니다.

이게 정말인지 검증해보기 위해 생성한 EKS API 서버에 curl 명령어를 실행했습니다.

$ TOKEN=${aws eks get-token --cluster-name <cluster-name>}
$ curl --header "Authorization: Bearer ${TOKEN}" -k -X GET ${APISERVER}/api/v1/namespaces/kube-system/configmaps

 

제 감이 맞다면 응답은 오지 않을 것입니다.

 

curl: (28) Failed to connect to <API Server> 443 after 214968 ms: Connection timed out

예상했던 대로입니다.

 

그러면 어떻게 해야 저 VPC 내에 있는 EKS Api Server 에 접근이 가능할까요?🧐

 

해결?! 🤔


다양한 방법이 있겠지만 저 격리된 VPC 에 접근하기 위해 저는 다음 2가지를 고려해봤습니다.

  1. Bastion Host(Public) 이용해서 접근
  2. TGW 를 이용한 접근

 

여기선 1번 방법을 통해 진행해보겠습니다 😃

(실제로는 2번 방법을 사용했습니다)

 

진행 방법은 아주 간단합니다. EKS 가 배포된 VPC 안에 EC2 를 생성하고 이를 통해 접근합니다.


그림으로 표현하면 이렇게 되겠죠.

Bastion Host 는 퍼블릭에 존재하니 여기로 ssh 한 후 Host 안에서 호출하는 겁니다.

 

그럼 Bastion Host 에 접속하여 다시 한번 명령어를 날려보죠 🔥🔥

$ curl --header "Authorization: Bearer ${TOKEN}" -k -X GET ${APISERVER}/api/v1/namespaces/kube-system/configmaps

 

어.. 근데 이상합니다...

curl: (28) Failed to connect to <API Server> 443 after 214968 ms: Connection timed out

 

예상과 다르게 time out 이 발생합니다.. 😳😳😳😳😳

VPC 내부에 접근해서 curl 명령어를 날리면 못해도 4xx 코드는 올 줄 알았습니다..

 

다시 한번 미궁에 빠집니다 🤔

 

세번째 시도 3️⃣


EKS 자체에 문제가 있는 걸까요? VPC 내부에 있다고 착각하는 걸까요?

 

많은 의문이 들었습니다.. 그러던 중 !!

 

이걸 추가하라는 코멘트를 발견했습니다.

 

아~ 이제 진짜 알았습니다. 해답은 Security Group 에 있었습니다. 👏👏

 

해결!! 😌


그럼 바로 security_group_resource 를 추가해보죠.

 cluster_security_group_additional_rules = {
    ingress = {
      description                = "EKS Cluster allows 443 port to get API call"
      type                       = "ingress"
      from_port                  = 443
      to_port                    = 443
      protocol                   = "TCP"
      cidr_blocks                = ["0.0.0.0/0"] 
      source_node_security_group = false
    }
  }

 

명령어를 실행해보죠. 간장되는 순간입니다 .. 🍾 🍾

$ terraform plan
$ terraform apply

나올게 나왔군요 🌈🌈🌈

 

curl 명령어로 다시 날려보죠 !

$ curl --header "Authorization: Bearer ${TOKEN}" -k -X GET ${APISERVER}/api/v1/namespaces/kube-system/configmaps

 

이번엔 time out 되지 않고 응답값이 왔습니다 !

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "Unauthorized",
  "reason": "Unauthorized",
  "code": 401
}

401 응답 코드지만 EKS Api Server 에 성공적으로 접근했다는 것을 확인할 수 있습니다 😎

 

그럼 다시 가장 처음 발생했던 에러를 확인해볼까요??

Error: The configmap "aws-auth" does not exist

 

이제는 알 수 있습니다.

 

다시는 Error: The configmap "aws-auth" does not exist 를 보지 않으리...!!

 

아무튼 이번 에러도 무사히 해결했다 👍

반응형

article next thumbnail
profile on loading

Loading...