앞선 ECS 편과 같은 애플리케이션을 이번에는 EKS 로 올려 보는 실습 기록이다. `eksctl` 로 간단히 만드는 대신 내부 동작을 이해하려고 VPC 부터 Terraform 으로 직접 정의하고, Fargate 노드·ALB Ingress 까지 붙여 외부 노출을 완성한다.
핵심 포인트- 쿠버네티스는 AWS 구조와 독립적이라, 클러스터 안에서 정의한 로드 밸런서·볼륨이 실제로는 ALB·EBS 로 만들어진다. 그 연결은 서브넷 태그로 이뤄진다.
- 서브넷에 `kubernetes.io/cluster/<name>: shared`, 프라이빗에 `kubernetes.io/role/internal-elb: 1`, 퍼블릭에 `kubernetes.io/role/elb: 1` 을 붙여야 로드 밸런서가 제자리에 배치된다.
- 리소스 하나로 끝나는 ECS 와 달리 EKS 는 클러스터 역할, 클러스터, Fargate 파드 실행 역할, Fargate 프로필까지 나눠 정의해야 한다.
- Fargate 노드만 쓰면 coredns 파드가 뜨지 않아 CoreDNS 설정을 따로 수정해야 하고, 컨테이너에 IAM 권한을 주려면 OIDC 공급자 생성이 필요하다.
- 외부 노출은 `Ingress` 리소스로 하되, 그 전에 AWS Load Balancer Controller 를 설치하고 IAM 정책·역할·서비스 계정을 연결해야 한다.
상세 정리- VPC 구성: 두 개의 AZ(ap-northeast-2a/c)에 퍼블릭·프라이빗 서브넷을 두는 구조는 ECS 편과 같고, CIDR 은 10.194.0.0/16 에 /24 네 개를 쓴다.
- Terraform 으로 VPC, 기본 라우트 테이블·보안 그룹 이름 지정, 인터넷 게이트웨이, 퍼블릭 라우팅 테이블과 기본 경로를 차례로 정의한다.
- 퍼블릭 서브넷은 배치되는 서비스에 공개 IP 를 자동 부여하도록 설정하고, count 로 AZ 수만큼 생성한 뒤 라우팅 테이블에 연결한다.
- 프라이빗 서브넷의 아웃바운드는 NAT 게이트웨이를 거친다. NAT 는 고정 IP(EIP)가 필요하고 자신은 퍼블릭 서브넷에 있어야 한다.
- EKS 클러스터: `AmazonEKSClusterPolicy` 와 `AmazonEKSVPCResourceController` 를 포함한 클러스터 역할을 먼저 만들고 클러스터를 정의한다.
- Fargate: `AmazonEKSFargatePodExecutionRolePolicy` 를 포함한 실행 역할을 만들고, default·kube-system 네임스페이스의 파드에 적용되는 Fargate 프로필을 붙인다. 프로필에는 프라이빗 서브넷만 지정할 수 있다.
- 접속 준비: kubeconfig 를 생성해 클러스터 상태를 조회한다. 이때 기본으로 떠야 할 coredns 파드가 없는 것이 눈에 띄고, Fargate 전용 구성에 맞게 CoreDNS 를 수정해 해결한다.
- 애플리케이션 배포: ECR 저장소를 만들어 이미지를 올리고, 파드 → 레플리카셋 → 디플로이먼트 순으로 왜 상위 리소스가 필요한지(확장, 갱신 시 레플리카셋 교체) 짚으며 매니페스트를 적용한다.
- 기동 확인: 보통 5분 안에, 빠르면 1분 안에 Running 으로 바뀌고 포트 포워딩으로 HTTP 응답을 확인한다.
- 외부 노출: L7 로드 밸런싱을 위해 `Ingress` 를 쓰며, ALB 를 다룰 IAM 정책과 역할을 만들고 그 역할에 연결된 쿠버네티스 서비스 계정을 생성한 뒤 AWS Load Balancer Controller 를 설치한다.
- 결과적으로 쿠버네티스 매니페스트만으로 ALB 가 생성되고 `k8s-default-...elb.amazonaws.com` 주소로 응답을 받는다.
- 후기: EKS 는 ECS 보다 확실히 복잡하지만 세세한 제어가 가능하고 AWS 특화 개념이 아니라는 점을 장점으로 꼽는다. 이번 글에는 수동 단계가 남아 있어 다음에 Terraform 으로 더 자동화하겠다고 예고한다.
왜 읽나ECS 는 써 봤지만 EKS 는 처음인 개발자에게 왜 이만큼 많은 리소스가 필요한지를 Terraform 코드와 함께 이해시켜 준다.