[CloudNeta] EKS 워크샵 스터디 (4) - 부록: 코드 살펴보기
이번 배포도 운영진 분들께서 작성하신 코드로 살펴볼 예정입니다. 먼저 코드를 살펴볼까요.
➜ tree 4w
4w
├── aws_lb_controller_policy.json
├── eks.tf
├── externaldns_controller_policy.json
├── outputs.tf
├── var.tf
└── vpc.tf
terraform-aws-modules 라는 테라폼 레지스트리를 주로 살펴봅니다.
모듈 사용은 가이드대로 하면 되지만, 가끔 입력값에 의문이 있을 때가 있습니다.
그럴 때는 코드를 보고 작동원리를 보아 해당 변수가 어떻게 삽입되고 쓰이는지 보아야 합니다. (경험상 그게 가장 빨랐습니다)
코드를 살펴봅시다
이번 주차에서는 EKS Security를 다루기 위한 실습 환경을 구성합니다. 3주차 대비 변경점을 중심으로 살펴봅니다.
1. var.tf — 변수 정의
쿠버네티스 클러스터 설정값, 워커노드 스펙, 네트워크 설정이 주가 됩니다.
- 클러스터 베이스명:
myeks - 쿠버네티스 버전:
1.35 - 워커노드:
t3.medium, 2대, 30GiB 볼륨 - 배포 리전:
ap-northeast-2(서울), AZ 3개 (2a,2b,2c) - VPC CIDR:
192.168.0.0/16, public/private 각 3개 서브넷 (/22단위)
SSH 관련 변수(KeyName, ssh_access_cidr)가 주석 처리되었습니다. 이번 주차부터 SSM Session Manager로 접속하므로 SSH 키가 불필요해졌습니다.
2. vpc.tf — VPC 네트워크 구성
terraform-aws-modules/vpc/aws 모듈(v6.5)을 사용해 VPC를 구성합니다.
- 서브넷: public 3개 + private 3개 (3 AZ)
- NAT Gateway:
single_nat_gateway = true— 실습 환경이므로 비용 최적화를 위해 단일 NAT GW 사용 - DNS:
enable_dns_support,enable_dns_hostnames활성화 — EKS와 Private Hosted Zone 해석에 필요 - Public IP 자동할당:
map_public_ip_on_launch = true
EKS 서브넷 태그도 설정합니다:
| 서브넷 | 태그 | 용도 |
|---|---|---|
| public | kubernetes.io/role/elb = 1 |
인터넷 대면 ALB/NLB 배치 |
| private | kubernetes.io/role/internal-elb = 1 |
내부 로드밸런서 배치 |
이 태그는 AWS Load Balancer Controller가 어떤 서브넷에 로드밸런서를 생성할지 결정하는 데 사용됩니다.
3. eks.tf — EKS 클러스터, SG, IAM, 애드온 (핵심 파일)
가장 큰 파일입니다. AWS 프로바이더 설정, SG, IAM 정책, EKS 클러스터 및 노드그룹, 애드온을 모두 포함합니다.
Security Group
node_group_sg: 워커노드용 SGallow_sshrule: 이름과 달리 VPC CIDR 내에서 모든 프로토콜/포트 접근 허용 (protocol = "-1")
IAM Policy
aws_lb_controller_policy: AWS LB Controller용 IAM 정책 (JSON 파일에서 로드)external_dns_policy: ExternalDNS용 IAM 정책 (JSON 파일에서 로드)
EKS 모듈 주요 설정
terraform-aws-modules/eks/aws 모듈(v21.x)을 사용합니다.
- IRSA 활성화:
enable_irsa = true— OIDC 프로바이더 생성, Pod에 IAM Role 연결 가능 - 엔드포인트: public + private 모두 활성화 — VPC 내부/외부 양쪽에서 API 서버 접근 가능
- 컨트롤 플레인 로그: 5종 전체 활성화 (
api,scheduler,authenticator,controllerManager,audit) - 클러스터 생성자 admin 권한:
enable_cluster_creator_admin_permissions = true
관리형 노드그룹 (primary)
- AMI:
AL2023_x86_64_STANDARD(Amazon Linux 2023) - 오토스케일링: min=1, desired=2, max=4
- IMDSv2 강제:
http_tokens = "required",http_put_response_hop_limit = 2
파드에서 IMDS 엔드포인트(169.254.169.254)까지 컨테이너 네트워크를 거치면 hop이 1 추가됩니다. hop limit이 1이면 파드에서 IMDS에 접근할 수 없으므로, 파드가 인스턴스 메타데이터를 사용해야 하는 경우 2로 설정합니다.
- IAM Role 추가 정책: ExternalDNS 정책 +
AmazonSSMManagedInstanceCore(SSM 접속용) - 노드 라벨:
tier = primary - AL2023 cloud-init userdata:
dnf update및 디버깅 도구 설치 (tree,bind-utils,tcpdump,nvme-cli,links,sysstat,ipset,htop)
aws_lb_controller_policy는 IAM 리소스로 생성되지만, 노드그룹의 iam_role_additional_policies에서는 주석 처리되어 있습니다. 이는 노드의 Instance Profile이 아닌 IRSA를 통해 LB Controller의 ServiceAccount에 직접 연결하려는 의도로 보입니다.
EKS 애드온 (7개)
| 애드온 | 용도 | 비고 |
|---|---|---|
coredns |
클러스터 DNS | |
kube-proxy |
노드 레벨 네트워킹 | |
vpc-cni |
AWS VPC CNI 플러그인 | before_compute = true — 노드 조인 전 준비 |
metrics-server |
리소스 메트릭 (HPA/VPA용) | |
external-dns |
K8s Service/Ingress → Route 53 동기화 | policy = "sync", txtOwnerId = 클러스터명 |
eks-pod-identity-agent |
AWS Pod Identity | IRSA와 병행 가능한 차세대 인증 |
cert-manager |
TLS 인증서 관리 |
eks-pod-identity-agent가 새로 추가되었습니다. 이번 주차에서 IRSA와 Pod Identity를 모두 실습하기 위한 구성입니다.
4. IAM 정책 JSON 파일
aws_lb_controller_policy.json
AWS Load Balancer Controller용 IAM 정책입니다. ALB/NLB, 타겟그룹, SG, Cognito, ACM, WAF/Shield 등 광범위한 권한을 포함합니다.
- 태그 기반 조건:
elbv2.k8s.aws/cluster태그로 컨트롤러가 자신이 생성한 리소스만 관리하도록 스코핑 - AWS 공식 권장 정책 기반
externaldns_controller_policy.json
ExternalDNS용 IAM 정책입니다. LB Controller 정책 대비 매우 간결합니다.
route53:ChangeResourceRecordSets,ListResourceRecordSets,ListTagsForResources— hosted zone 스코프route53:ListHostedZones— 리소스 레벨 제한 불가하므로*스코프
5. outputs.tf — 출력값
terraform apply 완료 후 aws eks update-kubeconfig 명령어를 출력합니다.
aws eks --region ap-northeast-2 update-kubeconfig --name myeks
구동해봅시다
3주차와 달리 SSH 키 설정이 필요 없습니다. SSM Session Manager로 접속하므로 환경변수 설정 없이 바로 배포합니다.
terraform init
terraform plan
nohup sh -c "terraform apply -auto-approve" > create.log 2>&1 &
tail -f create.log
배포가 완료되었다면 kubeconfig를 갱신합니다:
# kubeconfig 갱신
$ aws eks update-kubeconfig --region ap-northeast-2 --name myeks
Added new context arn:aws:eks:ap-northeast-2:...:cluster/myeks to /home/l4in/.kube/config
# context 이름을 myeks로 변경
kubectl config rename-context $(cat ~/.kube/config | grep current-context | awk '{print $2}') myeks