테라폼은 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_configmap 을 true 로 주면 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_configmap 을 true 로 주면 리소스에 정의된 코드가 실행되는 걸 확인할 수 있습니다.
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가지를 고려해봤습니다.
- Bastion Host(Public) 이용해서 접근
- 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 를 보지 않으리...!!
아무튼 이번 에러도 무사히 해결했다 👍
'트러블 빵야' 카테고리의 다른 글
[Github Action] 타노스는 이런 느낌일까? RUNNER_TOKEN must be set (7) | 2023.02.20 |
---|---|
[Kubernetes] 친한 듯, 안 친한 Pod 와 Goofys (2) | 2023.02.12 |