험난한 Kubernetes 전환기 (2) - Amazon EKS와 Karpenter
작년부터 시작한 Kubernetes 전환 작업이 조금씩 진행되고 있습니다.
이번에는 Azure Kubernetes Service에 이어 Amazon EKS 환경을 구성하며 겪었던 이슈들을 정리해 보았습니다.
2번 타자, AWS
AWS는 사내 주 클라우드 환경으로 사용하고 있습니다. 이미 기존에도 많은 서비스가 AWS 기반이었고, 아무래도 AWS 환경이 많은 개발자에게 익숙하기 때문에 Azure보다는 비교적 수월하게 진행할 수 있을 것이라 기대했습니다.
다만 앞에서 진행한 Azure 환경이 더 우선순위가 높았고, AWS에서는 4월부터 Infra Team EKS 클러스터를 시작으로 Kubernetes 환경을 구축하기 시작했습니다.
Infra Team EKS
Infra Team EKS 클러스터는 다음과 같은 목적을 가지고 구성되었습니다.
- 역할 분리를 명확하게 하고 싶었습니다.
- 팀에서 사용하는 도구들은 특성상 거의 내부에서만 사용되고 외부에는 제한적으로만 노출되기 때문에, 분리해 두는 게 좋다고 생각했습니다.
- 파편화되어 있던 인프라 팀의 관리 범위를 줄이고 싶기도 했습니다.
여기서 배운 점들을 활용하여 이후 EKS 클러스터를 더 쉽게 구성하고 싶었기 때문에, 최대한 많은 것을 조사하고 테스트하는 과정이 있었습니다.
AWS 환경으로 넘어오며 달라진 점이 있다면, Azure 진영에서는 클러스터 구성을 할 때 Terraform 코드를 직접 작성하거나 모듈도 제한적으로 사용했지만, AWS는 모듈이 잘 정리되어 있어 활용하기가 매우 좋았습니다. 특히 terraform-aws-eks 모듈의 Karpenter 예제1를 변형하여 사용했는데, 약간의 수정만으로 초기 환경을 쉽게 구성할 수 있었습니다.
다만 Karpenter는 추가 작업이 필요했는데 이는 나중에 설명하겠습니다.
VPC 구성하기
EKS 클러스터를 구성할 때 가장 신경 썼던 부분은 네트워크 구성이었습니다.
우선 VPC 설정이 필요했는데, 이는 VPC 모듈을 활용하여 구성했습니다. VPC 모듈은 잘 사용하면 네트워크 관련 설정을 상당히 압축할 수 있고, 옵션도 매우 많기 때문에 README를 중심으로 자세하게 확인해 보시는 것을 추천합니다.
EKS에서 사용할 Public, Private 서브넷을 모두 정의하고, 비용 효율성을 위해 Single NAT 구성을 채택했습니다. 또한 이건 Karpenter 예제에도 있는 내용인데, AWS Load Balancer Controller와 Karpenter를 위한 서브넷 태그 설정이 필요합니다.
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = 1
"karpenter.sh/discovery" = var.name
}
특별한 경우가 아니라면 변경될 일이 없겠지만 중요한 부분입니다. 이 부분이 없으면 Load balancer나 Karpenter 노드가 배포되며 자동으로 서브넷을 찾아 연결하지 못하는 문제가 발생합니다.
트래픽 흐름 구성
저희는 기본적으로 2가지 시나리오를 구상했습니다.
- 외부 트래픽: AWS Load Balancer Controller로 생성된 ALB(Application Load Balancer) 사용
- 외부 트래픽 > ALB > Ingress > Service > Pod
- 내부 트래픽: NGINX Ingress Controller + NLB(Network Load Balancer) 사용
- 내부 트래픽 > NLB > NGINX Ingress > Service > Pod
Azure 환경을 구성할 때 외부 로드 밸런서는 L7 로드 밸런서를 사용해야 한다는 점2을 배웠기 때문에 ALB를 사용하였고, 내부 트래픽은 간편하게 NLB + NGINX Ingress Controller를 사용할 수 있도록 했습니다.
이외에 사내 VPN을 내부 통신에 연동하는 작업도 있었지만 이 글의 범위를 벗어나기 때문에 생략하겠습니다.
Karpenter 개선하기
기본적인 구성을 하고, 테스트 앱을 배포해 보면서 네트워크 테스트와 기본적인 Karpenter 동작을 확인했습니다.
이대로 문제가 없다고 생각했지만, 본격적으로 실제 서비스 배포 과정에서 부족한 부분도 있었고, 시행착오도 있었습니다.
그리고 그 중심에는 예제 코드대로만 구성했던 Karpenter가 있었습니다.