개요
Amazon EKS에서 Ingress를 여러 개 사용할 때 생기는 비용 문제를 해결하고, AWS Load Balancer Controller의 Ingress Grouping 기능으로 Application Load Balancer(ALB)를 효율적으로 공유하는 방법을 알아보겠습니다.
문제 상황
기본 Ingress 동작
Kubernetes에서 Ingress는 클러스터 외부에서 내부 서비스에 접근할 수 있도록 HTTP/HTTPS 라우팅을 제공하는 API 객체입니다. AWS Load Balancer Controller를 사용하면 Ingress 리소스가 생성될 때마다 자동으로 ALB가 프로비저닝됩니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service
port:
number: 80
비용 문제
마이크로서비스 아키텍처에서는 여러 서비스가 각자 Ingress를 가지게 되고, 그러면 아래와 같은 문제가 생깁니다.
- 각 Ingress마다 별도의 ALB 생성: Ingress 하나당 ALB 하나가 생성됨
- 높은 운영 비용: ALB는 시간당 요금이 부과되므로 불필요한 ALB가 많아질수록 비용 증가
- 관리 복잡성: 여러 ALB를 개별적으로 관리해야 하는 부담
Ingress Grouping이란?
Ingress Grouping은 여러 Ingress 리소스가 하나의 ALB를 공유할 수 있게 해 주는 AWS Load Balancer Controller의 기능입니다.
Ingress Grouping으로 두 Namespace의 Ingress가 ALB 하나를 공유
Ingress Grouping으로 두 Namespace의 Ingress가 ALB 하나를 공유
그림 관계를 글로 읽기
- blue-green-ns의 blue-green-ingress가 group.name app-color-lb를 쓴다.
- orange-purple-ns의 orange-purple-ingress도 같은 group.name을 쓴다.
- AWS Load Balancer Controller가 두 Ingress 규칙을 자동 병합해 ALB 하나에 적용한다. 두 Ingress의 ADDRESS가 같다.
- ALB의 /blue, /green 규칙은 blue-green-ns의 blue-service, green-service로 간다.
- ALB의 /orange, /purple 규칙은 orange-purple-ns의 orange-service, purple-service로 간다.
주요 특징
- 단일 ALB 공유: 여러 Ingress가 하나의 ALB를 공유
- 네임스페이스 간 공유 가능: 서로 다른 네임스페이스의 Ingress들도 그룹화 가능
- 자동 규칙 병합: 컨트롤러가 자동으로 Ingress 규칙들을 병합하여 ALB에 적용
- 비용 절감: ALB 개수가 줄어 비용이 직접 절감됨
사전 준비사항 및 설치
Ingress Grouping을 사용하려면 몇 가지 필수 구성요소를 미리 설치하고 설정해야 합니다.
1. EKS 클러스터 요구사항
기본 요구사항
- EKS 클러스터: Kubernetes 1.19 이상
- 노드 그룹: EC2 또는 Fargate (또는 혼합)
- VPC 설정: 최소 2개 이상의 가용 영역에 서브넷 구성
# EKS 클러스터 생성 (eksctl 사용 예시)
eksctl create cluster \
--name my-cluster \
--region us-west-2 \
--nodegroup-name standard-workers \
--node-type m5.large \
--nodes 3 \
--nodes-min 1 \
--nodes-max 4 \
--managed
2. AWS Load Balancer Controller 설치
Ingress Grouping은 AWS Load Balancer Controller v2.0 이상에서 지원됩니다.
2-1. IAM 정책 생성
먼저 AWS Load Balancer Controller가 사용할 IAM 정책을 생성합니다.
# IAM 정책 다운로드
curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.7.2/docs/install/iam_policy.json
# IAM 정책 생성
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document file://iam_policy.json
2-2. IAM 역할 및 서비스 계정 생성
# OIDC 공급자 생성 (한 번만 실행)
eksctl utils associate-iam-oidc-provider --region=us-west-2 --cluster=my-cluster --approve
# 서비스 계정 생성 및 IAM 역할 연결
eksctl create iamserviceaccount \
--cluster=my-cluster \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--role-name AmazonEKSLoadBalancerControllerRole \
--attach-policy-arn=arn:aws:iam::ACCOUNT-ID:policy/AWSLoadBalancerControllerIAMPolicy \
--approve
2-3. Helm을 통한 Controller 설치
# Helm 차트 레포지토리 추가
helm repo add eks https://aws.github.io/eks-charts
helm repo update
# AWS Load Balancer Controller 설치
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=my-cluster \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=us-west-2 \
--set vpcId=vpc-xxxxxxxx
2-4. 설치 확인
# Controller 팟 상태 확인
kubectl get deployment -n kube-system aws-load-balancer-controller
# 로그 확인
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller
3. VPC 및 서브넷 설정
3-1. 서브넷 태깅
ALB가 올바른 서브넷에 생성되도록 서브넷에 태그를 설정해야 합니다.
# 퍼블릭 서브넷 태깅 (인터넷 대면 ALB용)
aws ec2 create-tags \
--resources subnet-12345678 subnet-87654321 \
--tags Key=kubernetes.io/role/elb,Value=1
# 프라이빗 서브넷 태깅 (내부 ALB용)
aws ec2 create-tags \
--resources subnet-abcdefgh subnet-hgfedcba \
--tags Key=kubernetes.io/role/internal-elb,Value=1
# 클러스터별 태깅 (여러 클러스터 사용 시)
aws ec2 create-tags \
--resources subnet-12345678 subnet-87654321 \
--tags Key=kubernetes.io/cluster/my-cluster,Value=shared
3-2. 보안 그룹 설정 확인
# 클러스터 보안 그룹에 태그 추가 (필요시)
aws ec2 create-tags \
--resources sg-xxxxxxxxx \
--tags Key=kubernetes.io/cluster/my-cluster,Value=owned
4. 필수 어노테이션 및 IngressClass 설정
4-1. IngressClass 생성 (Kubernetes 1.18+)
# ingress-class.yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: alb
spec:
controller: ingress.k8s.aws/alb
kubectl apply -f ingress-class.yaml
4-2. 기본 설정 검증
# AWS Load Balancer Controller 버전 확인
kubectl get deployment aws-load-balancer-controller -n kube-system -o yaml | grep image:
# 서비스 계정 확인
kubectl get serviceaccount aws-load-balancer-controller -n kube-system -o yaml
# IAM 역할 확인
kubectl describe serviceaccount aws-load-balancer-controller -n kube-system
5. 설치 검증을 위한 테스트
5-1. 간단한 테스트 애플리케이션 배포
# test-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-app
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: test-app
template:
metadata:
labels:
app: test-app
spec:
containers:
- name: app
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: test-service
namespace: default
spec:
type: NodePort
selector:
app: test-app
ports:
- port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
namespace: default
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-service
port:
number: 80
# 테스트 앱 배포
kubectl apply -f test-app.yaml
# Ingress 상태 확인
kubectl get ingress test-ingress
# ALB 생성 확인
kubectl describe ingress test-ingress
6. 문제 해결 가이드
6-1. 일반적인 문제들
문제 1: Controller Pod가 시작되지 않음
# 서비스 계정 권한 확인
kubectl describe serviceaccount aws-load-balancer-controller -n kube-system
# IAM 역할 정책 확인
aws iam list-attached-role-policies --role-name AmazonEKSLoadBalancerControllerRole
문제 2: ALB가 생성되지 않음
# Controller 로그 확인
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller
# 서브넷 태그 확인
aws ec2 describe-subnets --subnet-ids subnet-12345678 --query 'Subnets[*].Tags'
문제 3: 권한 부족 오류
# IAM 정책이 최신인지 확인
aws iam get-policy-version \
--policy-arn arn:aws:iam::ACCOUNT-ID:policy/AWSLoadBalancerControllerIAMPolicy \
--version-id v1
6-2. 설치 완료 체크리스트
- [ ] EKS 클러스터가 정상 작동 중
- [ ] AWS Load Balancer Controller v2.0+ 설치 완료
- [ ] IAM 정책 및 서비스 계정 설정 완료
- [ ] 서브넷에 적절한 태그 설정 완료
- [ ] IngressClass 리소스 생성 완료
- [ ] 테스트 Ingress로 ALB 생성 확인 완료
실습: Ingress Grouping 구현
이제 사전 준비가 끝났으니 Ingress Grouping을 실제로 구현해 보겠습니다.
1. 기본 환경 준비
먼저 두 개의 네임스페이스에 각각 애플리케이션을 배포합니다.
# 네임스페이스 생성
kubectl create namespace blue-green-ns
kubectl create namespace orange-purple-ns
2. 애플리케이션 배포
각 네임스페이스에 색상별 애플리케이션을 배포합니다.
# blue-green-ns 네임스페이스의 애플리케이션
apiVersion: apps/v1
kind: Deployment
metadata:
name: blue-app
namespace: blue-green-ns
spec:
replicas: 2
selector:
matchLabels:
app: blue-app
template:
metadata:
labels:
app: blue-app
spec:
containers:
- name: blue-app
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: blue-service
namespace: blue-green-ns
spec:
type: NodePort
selector:
app: blue-app
ports:
- port: 80
targetPort: 80
3. Ingress Grouping 설정
가장 중요한 부분인 Ingress Grouping 설정입니다. alb.ingress.kubernetes.io/group.name 어노테이션을 사용합니다.
# blue-green-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: blue-green-ingress
namespace: blue-green-ns
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/group.name: app-color-lb # 그룹 이름 지정
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /blue
pathType: Prefix
backend:
service:
name: blue-service
port:
number: 80
- path: /green
pathType: Prefix
backend:
service:
name: green-service
port:
number: 80
# orange-purple-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: orange-purple-ingress
namespace: orange-purple-ns
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/group.name: app-color-lb # 동일한 그룹 이름
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /orange
pathType: Prefix
backend:
service:
name: orange-service
port:
number: 80
- path: /purple
pathType: Prefix
backend:
service:
name: purple-service
port:
number: 80
4. 결과 확인
배포 후 Ingress 상태를 확인해 보면 두 Ingress가 동일한 ALB 주소를 공유하는 것을 볼 수 있습니다.
kubectl get ingress -A
NAMESPACE NAME ADDRESS
blue-green-ns blue-green-ingress k8s-appcolorlb-xxx.elb.amazonaws.com
orange-purple-ns orange-purple-ingress k8s-appcolorlb-xxx.elb.amazonaws.com
고급 설정
1. 그룹 순서 제어 (Group Order)
Ingress 규칙의 평가 순서를 제어하려면 group.order 어노테이션을 사용합니다.
metadata:
annotations:
alb.ingress.kubernetes.io/group.name: my-group
alb.ingress.kubernetes.io/group.order: '10' # 낮은 숫자가 우선순위 높음
2. 그룹 이름 규칙
- 길이: 63자 이하
- 구성: 소문자, 숫자,
-,.만 사용 가능 - 시작/끝: 문자 또는 숫자로 시작하고 끝나야 함
# 올바른 예시
alb.ingress.kubernetes.io/group.name: my-app-group
alb.ingress.kubernetes.io/group.name: production.web-services
# 잘못된 예시
alb.ingress.kubernetes.io/group.name: -my-group- # 잘못된 시작/끝
alb.ingress.kubernetes.io/group.name: My_Group # 대문자와 언더스코어 사용 불가
보안 고려사항
1. 신뢰 경계(Trust Boundary)
동일한 Ingress Group에 속한 모든 사용자는 같은 신뢰 경계 내에 있어야 합니다. 다른 사용자가 동일한 그룹 이름을 사용하여 Ingress를 생성하면 기존 규칙을 덮어쓸 수 있습니다.
2. 그룹 이름 충돌 방지
# 권장: 명확하고 고유한 이름 사용
alb.ingress.kubernetes.io/group.name: team-a-production-services
# 비권장: 일반적인 이름 사용
alb.ingress.kubernetes.io/group.name: my-group
3. RBAC 설정
Ingress 리소스에 대한 적절한 RBAC 정책을 설정하여 권한이 있는 사용자만 특정 그룹에 접근할 수 있도록 제한해야 합니다.
제한사항 및 주의사항
1. ALB 규칙 제한
- 기본 제한: ALB 리스너당 최대 100개의 규칙
- 성능 영향: 규칙이 많아질수록 성능에 영향을 줄 수 있음
- 모니터링: 규칙 수를 지속적으로 모니터링해야 함
2. 충돌 해결
기본적으로 Ingress 간의 규칙 순서는 네임스페이스/이름의 사전적 순서로 결정됩니다. 명시적인 순서 제어를 위해서는 group.order를 사용해야 합니다.
3. 디버깅 복잡성
여러 Ingress가 하나의 ALB를 공유하므로 문제 발생 시 원인 파악이 복잡할 수 있습니다.
모니터링 및 트러블슈팅
1. AWS Load Balancer Controller 로그 확인
kubectl logs -f -n kube-system -l app.kubernetes.io/instance=aws-load-balancer-controller
2. ALB 규칙 확인
# ALB ARN 확인
ALB_ARN=$(aws elbv2 describe-load-balancers --query 'LoadBalancers[?contains(LoadBalancerName, `k8s-mygroup`)].LoadBalancerArn' --output text)
# 리스너 규칙 확인
LISTENER_ARN=$(aws elbv2 describe-listeners --load-balancer-arn $ALB_ARN --query 'Listeners[0].ListenerArn' --output text)
aws elbv2 describe-rules --listener-arn $LISTENER_ARN
3. Ingress 상태 확인
kubectl describe ingress <ingress-name> -n <namespace>
실제 사용 사례
1. 마이크로서비스 환경
# API Gateway 패턴
alb.ingress.kubernetes.io/group.name: api-gateway
# /api/users -> user-service
# /api/orders -> order-service
# /api/products -> product-service
2. 환경별 분리
# 개발 환경
alb.ingress.kubernetes.io/group.name: dev-services
# 스테이징 환경
alb.ingress.kubernetes.io/group.name: staging-services
# 프로덕션 환경
alb.ingress.kubernetes.io/group.name: prod-services
비용 절감 효과
예시 계산
- 기존 방식: 10개 서비스 = 10개 ALB = 월 $200+ (ALB 시간당 $0.0225 × 24시간 × 30일 × 10개)
- Ingress Grouping: 10개 서비스 = 2개 ALB = 월 $40+ (그룹별로 분할)
- 절약 효과: 월 $160+ 절약 (약 80% 비용 절감)
마무리
Ingress Grouping을 쓰면 Amazon EKS에서 ALB 비용을 크게 절감할 수 있습니다. 특히 마이크로서비스 아키텍처를 사용하는 환경이라면 꼭 고려해야 할 기능입니다.
핵심 포인트:
alb.ingress.kubernetes.io/group.name어노테이션으로 간단히 설정- 네임스페이스 간 Ingress 공유 가능
- 상당한 비용 절감 효과
- 보안 고려사항과 제한사항 숙지 필요
- 적절한 모니터링과 관리 필요
다음에는 Target Group Binding을 활용한 고급 로드밸런싱 패턴도 다뤄 보겠습니다.