Amazon EKS
- EKS = Elastic Kubernetes Service
- AWS에서 관리형 Kubernetes 클러스터를 시작하는 방법
- K8s는 컨테이너화된(일반적으로 Docker) 애플리케이션의 자동 배포, 확장 및 관리를 위한 오픈소스 시스템
- ECS의 대안으로 비슷한 목표를 가지지만 다른 API를 사용
- EKS는 워커 노드를 배포하려는 경우 EC2를 지원하고 서버리스 컨테이너를 배포하려는 경우 Fargate를 지원
- 사용 사례: 회사가 이미 온프레미스 또는 다른 클라우드에서 K8s를 사용 중이고, K8s를 사용하여 AWS로 마이그레이션하려는 경우
- K8s는 클라우드 독립적 (Azure, GCP 등 모든 클라우드에서 사용 가능)
- EKS 는 오픈소스 k8s 를 수정하지 않고 구동한다.
- EKS 는 4개의 k8s 마이너 버전을 지원한다. 공식문서
Node Types
- Managed Node Groups
- 노드(EC2 인스턴스)를 자동으로 생성하고 관리
- 노드는 EKS가 관리하는 ASG의 일부
- On-Demand 또는 Spot 인스턴스 지원
- Self-Managed Nodes
- 사용자가 직접 생성한 노드를 EKS 클러스터에 등록하고 ASG로 관리
- 사전 구축된 AMI 사용 가능 - Amazon EKS Optimized AMI
- On-Demand 또는 Spot 인스턴스 지원
- AWS Fargate
- 유지 관리 불필요, 노드 관리 불필요
Data Volumes
- EKS 클러스터에 Storage Class manifest를 지정해야 함
- Container Storage Interface (CSI) 호환 드라이버 활용
- 지원 스토리지:
- EBS
- EFS (Fargate와 호환)
- FSx for Lustre
- FSx for NetApp ONTAP
EKS Cluster Endpoint
EKS 는 Node Group 을 통해 Worker Node 를 관리한다. 각 Worker Node 는 On-Demand 와 Spot Instance 로 각 AZ 에 고루 배치된다. 각 Worker Node 의 ENI 는 R53 의 Private Hosted Zone 을 통해 Control Plane 의 API Server 와 통신한다. 운영자는 46E8024.eks.amazonaws.com 과 같은 형태의 Control Plane 의 Public IP 를 통해 kubectl 로 상호작용할 수 있다.
EKS Data Plane Options
Worker Node 를 구성하는 EKS Data Plane 은 크게 3가지로 구분된다.
- Self-Managed Node Group
- Custom AMI 를 이용하고 ASG 를 사용자가 직접 관리한다. OS 에 대한 기본 구성, 패치에 대한 책임은 사용자의 책임 영역에 해당한다.
- Managed Node Group
- 최신의 EKS Optimized AMI 를 사용하며 새로운 AMI 에 대한 배포 및 구버전 AMI 제거 등 모두 자동화하여 AWS 가 처리한다.
- AWS Fargate
Container 네트워킹

Pod 네트워킹

- Pause Container 의 Network Namespace 를 공유
- Pause Container 의 IP 주소를 받아서 공유
- Pod 내 Container 는 localhost 통신
- 동일 Node 에 위치한 타 Pod 와 통신할 경우 Bridge, 다른 Node 에 위치한 타 Pod 와 통신할 경우 CNI
EKS Upgrade
- Control Plane 버전 업그레이드
- Worker Node AMI 업그레이드
- AMI Packer Template 에서 kubelet 버전 업그레이드
- Rolling upgrade 로 새로운 버전의 kubelet 설치된 상태로 클러스터에 조인함
- Add-ons 업그레이드
- aws-vpc-cni, kube-proxy 등
- EKS Upgrade 와 호환이 필요한 추가 컴포넌트 업그레이드
- alpine-k8s, cluster-autoscaler, kube-bench 등
EKS 1.32 to 1.33 Upgrade
EKS 1.33 Breaking changes
K8s 버전 업그레이드 시 항상 API deprecation 이 있는지 확인해야 한다. kubepug 를 활용하면 cluster 에 deprecated 될 API 가 있는지 쉽게 확인할 수 있다.
EKS 1.33 Native Sidecar
k8s 1.33 부터 Native Sidecar 기능이 안정화되어 기본값이 되었는데, istio-proxy 가 2개 생성되는 이슈 발생, values.pilot.env.ENABLE_NATIVE_SIDECARS=false 로 옵션을 제거해주자 정상적으로 사이드카 파드가 생성됨. istiod 에 sidecarInjectorWebhook.templates 으로 istio-proxy 를 gracefully shutdown 하는 커스텀 템플릿이 충돌하는건가…
EKS 1.33 과 AL2/AL2023
EKS 1.33 부터 AL2 기반 EKS Optimized AMI 는 v20251209 를 마지막으로 deprecated 되고 AL2023 기반 AMI 만 제공된다. AL2 기반에서 Kubernetes 1.33 이 이론적으로 안 돌아가는 건 아니지만 containerd 2.x, runc 1.3+, cgroup v2 안정성, seccomp / eBPF 등 직접 다 책임지고 맞춰야한다.
EKS Optimized AMI
amazon-eks-ami/
├── templates/ # Packer 템플릿 및 프로비저닝 스크립트
│ ├── al2/ # Amazon Linux 2 AMI 빌드
│ │ ├── template.json # AL2용 Packer 메인 템플릿
│ │ ├── variables-default.json # AL2 기본 변수 설정
│ │ ├── provisioners/ # AL2 프로비저닝 스크립트
│ │ └── runtime/ # 런타임 구성 파일 (systemd, scripts 등)
│ ├── al2023/ # Amazon Linux 2023 AMI 빌드
│ │ ├── template.json # AL2023용 Packer 메인 템플릿
│ │ ├── variables-default.json # AL2023 기본 변수
│ │ ├── variables-1.28.json # K8s 1.28 전용 변수
│ │ ├── variables-1.29.json # K8s 1.29 전용 변수
│ │ ├── variables-1.30.json # K8s 1.30 전용 변수
│ │ ├── variables-1.31.json # K8s 1.31 전용 변수
│ │ ├── variables-1.32.json # K8s 1.32 전용 변수
│ │ ├── provisioners/ # AL2023 프로비저닝 스크립트
│ │ └── runtime/ # AL2023 런타임 파일
│ ├── shared/ # 공통 프로비저닝 스크립트
│ │ ├── provisioners/
│ │ └── runtime/ # 공통 런타임 파일
├── nodeadm/ # EKS 노드 관리 도구 (Go 프로젝트)
│ ├── go.mod # Go 모듈 정의
│ ├── Makefile # nodeadm 빌드 스크립트
│ ├── cmd/ # 실행 파일 소스
│ ├── api/ # Kubernetes API 정의
│ ├── internal/ # 내부 패키지
│ ├── test/e2e/ # E2E 테스트
│ ├── crds/ # CRD YAML 파일
│ └── vendor/ # 벤더 의존성
├── log-collector-script/ # EKS 로그 수집 도구
│ ├── linux/ # Linux용 로그 수집
│ └── windows/ # Windows용 로그 수집
├── hack/ # 개발 도구 및 스크립트
│ ├── latest-binaries.sh # 최신 바이너리 버전 조회
│ ├── generate-nvidia-open-supported-devices.sh
│ ├── generate-template-variable-doc.py # 변수 문서 자동 생성
│ ├── lint-docs.sh # 문서 린트
│ ├── lint-space-errors.sh # 공백 오류 체크
│ ├── shellcheck # Shell 스크립트 린터
│ ├── shfmt # Shell 포맷터
│ ├── nodeadm-check-generate.sh # nodeadm 코드 생성 검증
│ └── nodeadm-check-vendor.sh # nodeadm 벤더 검증
└── Makefile # 메인 빌드 스크립트
amazon-eks-ami 는 AL2, AL2023, Bottlerocket 각 OS AMI 를 기반으로 EKS Optimized AMI 를 Packer 로 정의한 IaC 레포다. 해당 레포에서 머신이 EKS Worker Node 로 작동하기 위해 필요한 kubelet, kube-proxy, containerd, CNI bootstrap, /etc/eks/bootstrap.sh, systemd unit, OS 별 iptables/nftables 설정 등을 추가하는 자동화 스크립트를 확인할 수 있다.
aws s3 ls s3://amazon-eks/1.33.7 --region us-west-2 --profile saml --recursive
EKS 는 AWS S3 에서 kubelet 바이너리를 가져온다. 때문에 kubernetes_version 말고도 kubernetes_build_date 역시 지정해줘야 하는데 이때 위 커맨드를 통해 확인할 수 있다.
현재 사내에선 AL2 기반의 EKS Worker Node 를 구성하여 사용하고있다. AWS 에선 AL2 기반 EKS Optimized AMI 지원을 2025년 11월 26일부로 중단해서 EKS 1.33 버전부턴 AL2 기반의 AMI 가 공식적으로 존재하지 않는다. 하지만 공식문서에 따르면 AL2 를 기반으로 구성한 Custom Worker Node AMI 의 경우 AL2 의 EOS 인 2026년 6월 30일까지 사용할 수 있다고 한다. 웬만하면 기존에 구성해왔던 방식인 AL2 기반으로 EKS 1.33 Custom Worker Node AMI 를 구성하려고 했으나 containerd 1.7.x 에 존재하는 보안 이슈 때문에 공식적으로 containerd 2.1.5 를 기반으로 작성된 AL2023 AMI 로 Worker Node AMI 를 재구성하기로했다. 어쨌든 Bottlerocket 으로 넘어갈 예정이긴 하다만…
Upgrade from AL2 to AL2023
AL2 와 AL2023 의 주요 차이점으론 Bootstrap 메커니즘의 변경이 있다. 기존 AL2 에선 /etc/eks/bootstrap.sh 스크립트를 EC2 User Data 로 넘겨 kubelet 등 Worker Node 로 작동하기 위한 바이너리들을 실행했는데 AL2023 부턴 Go로 작성된 새로운 도구인 nodeadm 바이너리를 통해 Bootstrap 을 진행한다. 때문에 기존에 User Data 로 넘기던 스크립트를 nodeadm 형식에 맞춰야한다.
#!/bin/bash
/etc/eks/bootstrap.sh my-cluster \
--b64-cluster-ca <base64-ca> \
--apiserver-endpoint <endpoint> \
--kubelet-extra-args '--node-labels=foo=bar'기존 AL2 User Data 는 bootstrap.sh 에 옵션을 추가하여 설정하고 EKS DescribeCluster API 로 필요한 메타데이터를 자동으로 조회했던 반면,
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="BOUNDARY"
--BOUNDARY
Content-Type: application/node.eks.aws
---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
cluster:
name: my-cluster
apiServerEndpoint: https://EXAMPLE.gr7.us-west-2.eks.amazonaws.com
certificateAuthority: <base64-ca>
cidr: 10.100.0.0/16
kubelet:
config:
clusterDNS:
- 172.20.0.10
flags:
- --node-labels=foo=bar
--BOUNDARY--AL2023 User Data (MIME multi-part) 에선 YAML 형태로 설정을 정의하고 대규모 스케일업 시 추가적인 API 호출로 인한 스로틀링 발생을 방지하기 위해 EKS DescribeCluster API 를 호출하는 대신 직접 apiServerEndpoint, certificateAuthority, cidr 등을 필수로 명시하게끔 변경되었다. 특히 cidr 의 경우 기존에 bootstrap.sh 에선 요구하지 않았지만 nodeadm 부터 DNS 설정을 위해 service CIDR 를 직접 주입해주어야한다.
AL2023 AMI 는 systemd 를 통해 nodeadm 을 자동으로 2단계로 실행한다.
nodeadm-config.service: User Data 실행 전에 실행, containerd/kubelet 기본 설정nodeadm-run.service: User Data 실행 후에 실행, 최종 설정 완료
cat > /etc/eks/nodeadm.d/additional-config.yaml << EOF
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
kubelet:
config:
cgroupDriver: cgroupfs
...
EOF추가적인 동적 설정은 /etc/eks/nodeadm.d/ 디렉토리에 YAML/JSON drop-in 파일로 작성할 수 있다.
네트워킹 스택 변경
- AL2: iptables (legacy)
- AL2023: nftables (default), iptables-nft wrapper 제공
- kube-proxy ipvs 모드 사용 시 주의 필요
cgroup 버전 변경
- AL2: cgroup v1
- AL2023: cgroup v2 (unified control group hierarchy)
- cgroupv1 코드는 존재하지만 권장/지원되지 않음, 향후 완전 제거 예정
IMDS (Instance Metadata Service) 요구사항 특정 워크로드가 IMDS 접근이 필요한 경우:
# Launch Template에서 hop limit 설정
resource "aws_launch_template" "eks_nodes" {
metadata_options {
http_endpoint = "enabled"
http_tokens = "required" # IMDSv2 강제
http_put_response_hop_limit = 2 # 컨테이너 접근 허용
}
}- AL2023은 IMDSv2를 기본으로 요구
- 보안 강화: 세션 기반 인증, 1초~6시간 토큰 유효 기간
- Managed Node Group의 기본 hop limit:
- Launch Template 없이 생성: hop limit = 1 (컨테이너는 노드 credential 접근 불가)
- Custom AMI + Launch Template: hop limit = 2 (컨테이너 접근 가능)
- 컨테이너 credential 접근 필요 시: Launch Template에서
HttpPutResponseHopLimit=2설정 - 또는 EKS Pod Identity 사용 권장 (IMDSv2 대신 IAM 역할 직접 할당)