跳到主要内容

기능별 구현 쿡북: 6개 Gateway API 구현체

📅 작성일: 2026-06-17 | 수정일: 2026-06-17

信息

이 문서는 Gateway API 도입 가이드의 심화 가이드입니다. NGINX Ingress에서 사용하던 8가지 주요 기능을 각 Gateway API 구현체에서 어떻게 구현하는지 YAML 예제로 비교합니다. 솔루션 선정·비교표·의사결정 트리는 본 가이드의 섹션 4를 참조하세요.

개요

이 쿡북은 다음 8가지 기능을 AWS Native(LBC v3), Cilium, NGINX Gateway Fabric, Envoy Gateway, kGateway별로 구현하는 방법을 다룹니다. URL Rewrite와 헤더 조작은 Gateway API v1 표준 기능으로 모든 구현체에서 동일하게 작동합니다.

#기능표준 여부
1인증 (Basic Auth 대체)구현체별 상이
2Rate Limiting구현체별 상이
3IP 제어 (IP Allowlist)구현체별 상이
4URL RewriteGateway API v1 표준
5Header 조작Gateway API v1 표준
6세션 어피니티 (Cookie-based)구현체별 상이
7요청 본문 크기 제한구현체별 상이
8커스텀 에러 페이지구현체별 상이

1. 인증 (Basic Auth 대체)

# AWS LBC v3의 네이티브 JWT 검증
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: jwt-protected-route
namespace: production
spec:
parentRefs:
- name: production-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: ExtensionRef
extensionRef:
group: eks.amazonaws.com
kind: JWTAuthorizer
name: cognito-authorizer
backendRefs:
- name: api-service
port: 8080

---
# JWTAuthorizer CRD (LBC v3 확장)
apiVersion: eks.amazonaws.com/v1
kind: JWTAuthorizer
metadata:
name: cognito-authorizer
spec:
issuer: https://cognito-idp.us-west-2.amazonaws.com/us-west-2_ABC123
audiences:
- api-gateway-client
claimsToHeaders:
- claim: sub
header: x-user-id
- claim: email
header: x-user-email

2. Rate Limiting

제한 사항

AWS Native(LBC v3)는 게이트웨이 레벨의 네이티브 Rate Limiting을 지원하지 않습니다. AWS WAF Rate-based Rule을 사용하여 IP 기반 요청 제한을 구현합니다.

# ALB에 WAF Rate-based Rule 연결
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
annotations:
# Rate limiting WAF ACL ARN
aws.load-balancer.waf-acl-arn: arn:aws:wafv2:us-west-2:123456789012:regional/webacl/rate-limit/a1b2c3d4
spec:
gatewayClassName: aws-alb
listeners:
- name: http
port: 80
protocol: HTTP

ACK(AWS Controllers for Kubernetes)로 WAF Rate-based Rule 생성:

ACK WAFv2 컨트롤러를 사용하면 WAF 리소스를 Kubernetes 매니페스트로 선언적 관리할 수 있습니다.

EKS Capabilities로 ACK 활성화 (권장):

EKS Capabilities(2025년 11월 GA)를 사용하면 ACK 컨트롤러를 AWS 완전 관리형으로 운영할 수 있습니다. 컨트롤러가 AWS 관리 인프라에서 실행되므로 워커 노드에 별도 Pod가 배포되지 않습니다.

# 1. IAM Capability Role 생성
aws iam create-role \
--role-name EKS-ACK-Capability-Role \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "eks.amazonaws.com" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "aws:SourceAccount": "<ACCOUNT_ID>" }
}
}]
}'

# WAFv2 권한 정책 연결
aws iam put-role-policy \
--role-name EKS-ACK-Capability-Role \
--policy-name ACK-WAFv2-Policy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["wafv2:*"],
"Resource": "*"
}]
}'

# 2. EKS 클러스터에 ACK Capability 생성
aws eks create-capability \
--cluster-name my-eks-cluster \
--capability-type ACK \
--capability-configuration '{
"capabilityRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/EKS-ACK-Capability-Role"
}'

# 3. CRD 등록 확인
kubectl get crds | grep wafv2
대안: Helm으로 직접 설치 (비 EKS 환경)

EKS가 아닌 환경이나 컨트롤러를 직접 관리해야 하는 경우 Helm으로 설치할 수 있습니다.

helm install ack-wafv2-controller \
oci://public.ecr.aws/aws-controllers-k8s/wafv2-chart \
--namespace ack-system \
--create-namespace \
--set aws.region=ap-northeast-2

이 방식은 컨트롤러가 워커 노드에 Pod로 배포되며, IRSA(IAM Roles for Service Accounts)로 권한을 관리합니다.

# ACK WAFv2 WebACL - Rate-based Rule 정의
apiVersion: wafv2.services.k8s.aws/v1alpha1
kind: WebACL
metadata:
name: rate-limit-acl
namespace: production
spec:
name: rate-limit-acl
scope: REGIONAL
defaultAction:
allow: {}
rules:
- name: ip-rate-limit
priority: 1
action:
block: {}
statement:
rateBasedStatement:
limit: 500 # 5분간 최대 요청 수 (100~2,000,000,000)
aggregateKeyType: IP # IP 기반 집계
visibilityConfig:
sampledRequestsEnabled: true
cloudWatchMetricsEnabled: true
metricName: ip-rate-limit
visibilityConfig:
sampledRequestsEnabled: true
cloudWatchMetricsEnabled: true
metricName: rate-limit-acl
# 생성된 WebACL ARN을 Gateway에 연결
# WebACL 생성 후 status.ackResourceMetadata.arn 에서 ARN 확인:
# kubectl get webacl rate-limit-acl -n production \
# -o jsonpath='{.status.ackResourceMetadata.arn}'
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
annotations:
aws.load-balancer.waf-acl-arn: <WebACL ARN>
spec:
gatewayClassName: aws-alb
listeners:
- name: http
port: 80
protocol: HTTP
ACK WAFv2 컨트롤러 요구사항
  • ACK WAFv2 컨트롤러에 wafv2:CreateWebACL, wafv2:UpdateWebACL, wafv2:DeleteWebACL, wafv2:GetWebACL 등의 IAM 권한이 필요합니다
  • EKS Capabilities 사용 시: IAM Capability Role에 WAFv2 권한을 연결합니다. 컨트롤러는 AWS 관리 인프라에서 실행됩니다
  • Helm 설치 사용 시: IRSA(IAM Roles for Service Accounts) 또는 EKS Pod Identity를 통해 최소 권한을 부여하세요
  • WebACL과 ALB는 동일 리전에 있어야 합니다

3. IP 제어 (IP Allowlist)

# ALB Ingress에 WAF 연결 (LBC v3)
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
annotations:
aws.load-balancer.waf-acl-arn: arn:aws:wafv2:us-west-2:123456789012:regional/webacl/ip-allowlist/a1b2c3d4
spec:
gatewayClassName: aws-alb
listeners:
- name: http
port: 80
protocol: HTTP

ACK(AWS Controllers for Kubernetes)로 WAF IP Allowlist 생성:

ACK WAFv2 컨트롤러를 사용하면 IPSet과 WebACL을 Kubernetes 매니페스트로 선언적 관리할 수 있습니다.

# 1. ACK WAFv2 IPSet - 허용할 IP 목록 정의
apiVersion: wafv2.services.k8s.aws/v1alpha1
kind: IPSet
metadata:
name: allowed-ips
namespace: production
spec:
name: allowed-ips
scope: REGIONAL
ipAddressVersion: IPV4
addresses:
- "10.0.0.0/8" # VPC 내부
- "192.168.1.0/24" # 사무실 네트워크
- "203.0.113.100/32" # 특정 허용 IP
# 2. ACK WAFv2 WebACL - IPSet 기반 Allowlist 규칙
# IPSet 생성 후 status.ackResourceMetadata.arn 에서 ARN 확인:
# kubectl get ipset allowed-ips -n production \
# -o jsonpath='{.status.ackResourceMetadata.arn}'
apiVersion: wafv2.services.k8s.aws/v1alpha1
kind: WebACL
metadata:
name: ip-allowlist-acl
namespace: production
spec:
name: ip-allowlist-acl
scope: REGIONAL
defaultAction:
block: {} # 기본 차단, 허용 목록만 통과
rules:
- name: allow-trusted-ips
priority: 1
action:
allow: {}
statement:
ipSetReferenceStatement:
arn: <IPSet ARN> # allowed-ips IPSet의 ARN
visibilityConfig:
sampledRequestsEnabled: true
cloudWatchMetricsEnabled: true
metricName: allow-trusted-ips
visibilityConfig:
sampledRequestsEnabled: true
cloudWatchMetricsEnabled: true
metricName: ip-allowlist-acl
# 3. 생성된 WebACL ARN을 Gateway에 연결
# WebACL 생성 후 status.ackResourceMetadata.arn 에서 ARN 확인:
# kubectl get webacl ip-allowlist-acl -n production \
# -o jsonpath='{.status.ackResourceMetadata.arn}'
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
annotations:
aws.load-balancer.waf-acl-arn: <WebACL ARN>
spec:
gatewayClassName: aws-alb
listeners:
- name: http
port: 80
protocol: HTTP
ACK WAFv2 IPSet 관리 팁
  • IPSet의 addresses 필드를 업데이트하면 ACK 컨트롤러가 자동으로 AWS WAF IPSet을 동기화합니다
  • GitOps(ArgoCD/Flux)와 결합하면 IP 변경을 PR 기반으로 관리할 수 있습니다
  • IPSet과 WebACL은 동일 리전에 있어야 하며, wafv2:*IPSet*, wafv2:*WebACL* 권한이 필요합니다 (EKS Capabilities: IAM Capability Role / Helm: IRSA)

4. URL Rewrite

Gateway API 표준

URL Rewrite는 Gateway API v1 표준 기능으로, 모든 구현체에서 동일하게 작동합니다.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-rewrite
namespace: production
spec:
parentRefs:
- name: production-gateway
rules:
# /api/v1/users → /users
- matches:
- path:
type: PathPrefix
value: /api/v1
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: api-service
port: 8080

# /old-api/users → /v2/users
- matches:
- path:
type: PathPrefix
value: /old-api
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /v2
backendRefs:
- name: api-service-v2
port: 8080

5. Header 조작

Gateway API 표준

Header 조작은 Gateway API v1 표준 기능으로, 모든 구현체에서 동일하게 작동합니다.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: header-manipulation
spec:
parentRefs:
- name: production-gateway
rules:
- matches:
- path:
value: /api
filters:
# 요청 헤더 추가
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Custom-Header
value: "gateway-api"
- name: X-Forwarded-Proto
value: "https"
remove:
- Authorization # 기존 Authorization 제거
# 응답 헤더 추가
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: X-Server
value: "gateway-api"
- name: Strict-Transport-Security
value: "max-age=31536000; includeSubDomains"
backendRefs:
- name: api-service
port: 8080
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: sticky-session
annotations:
aws.load-balancer.target-group.stickiness.enabled: "true"
aws.load-balancer.target-group.stickiness.type: "lb_cookie"
aws.load-balancer.target-group.stickiness.duration: "3600"
spec:
parentRefs:
- name: production-gateway
rules:
- backendRefs:
- name: api-service
port: 8080

7. 요청 본문 크기 제한

제한 사항

AWS WAF Rule을 사용하여 요청 본문 크기를 제한합니다 (Console/CloudFormation 설정).

# ALB에 WAF Body Size Limit Rule 연결
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
annotations:
aws.load-balancer.waf-acl-arn: arn:aws:wafv2:us-west-2:123456789012:regional/webacl/body-size-limit/a1b2c3d4
spec:
gatewayClassName: aws-alb
listeners:
- name: http
port: 80
protocol: HTTP

ACK(AWS Controllers for Kubernetes)로 WAF Body Size Rule 생성:

ACK WAFv2 컨트롤러를 사용하면 Body Size 제한 규칙을 Kubernetes 매니페스트로 선언적 관리할 수 있습니다.

# ACK WAFv2 WebACL - Body Size Limit Rule 정의
apiVersion: wafv2.services.k8s.aws/v1alpha1
kind: WebACL
metadata:
name: body-size-limit-acl
namespace: production
spec:
name: body-size-limit-acl
scope: REGIONAL
defaultAction:
allow: {}
rules:
- name: block-large-body
priority: 1
action:
block: {}
statement:
sizeConstraintStatement:
fieldToMatch:
body:
oversizeHandling: MATCH # 오버사이즈 본문도 매칭
comparisonOperator: GT
size: 10485760 # 10MB (바이트 단위)
textTransformations:
- priority: 0
type: NONE
visibilityConfig:
sampledRequestsEnabled: true
cloudWatchMetricsEnabled: true
metricName: block-large-body
visibilityConfig:
sampledRequestsEnabled: true
cloudWatchMetricsEnabled: true
metricName: body-size-limit-acl
# 생성된 WebACL ARN을 Gateway에 연결
# WebACL 생성 후 status.ackResourceMetadata.arn 에서 ARN 확인:
# kubectl get webacl body-size-limit-acl -n production \
# -o jsonpath='{.status.ackResourceMetadata.arn}'
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: production-gateway
annotations:
aws.load-balancer.waf-acl-arn: <WebACL ARN>
spec:
gatewayClassName: aws-alb
listeners:
- name: http
port: 80
protocol: HTTP
단일 WebACL로 규칙 통합

IP Allowlist, Rate Limiting, Body Size 제한을 모두 사용한다면, 별도의 WebACL을 각각 만들 필요 없이 하나의 WebACL에 여러 규칙을 priority로 구분하여 통합할 수 있습니다. ALB당 WebACL은 하나만 연결 가능하므로 통합 관리가 필수입니다.

8. 커스텀 에러 페이지

# ALB의 Fixed Response 액션 사용
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: error-response
namespace: production
annotations:
# ALB action annotation으로 고정 응답 구성
alb.ingress.kubernetes.io/actions.error-503: |
{
"type": "fixed-response",
"fixedResponseConfig": {
"contentType": "text/html",
"statusCode": "503",
"messageBody": "<html><body><h1>Service Under Maintenance</h1><p>Please try again later.</p></body></html>"
}
}
spec:
parentRefs:
- name: production-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /maintenance
backendRefs:
- name: error-503 # annotation에 정의된 액션 이름
kind: Service
port: 503

참고 자료

공식 문서

관련 문서 (내부)