Block 2: 네트워킹 & Hybrid Nodes Gateway

누가 세션을 열고, Pod CIDR은 어떻게 도달하며, Gateway는 언제 쓰는가

연결이 먼저, 쿠버네티스는 그다음

Hybrid Nodes 사전 조건: RemoteNetworkConfig, VPC 라우팅 테이블, 사설 연결, 온프렘 라우팅 테이블
그림의 Gateway = VGW/TGW 같은 사설 연결 게이트웨이입니다. 뒤에 나올 Hybrid Nodes Gateway와는 다른 물건입니다.
사설 연결
Direct Connect 또는 Site-to-Site VPN. 공용 인터넷 경로와 사설 경로를 구분해 설계
권장 품질
대역폭 ≥100 Mbps, RTT ≤200 ms (AWS 일반 권장, 보장값 아님)
양방향 route
VPC → remote node/Pod CIDR, 온프렘 → VPC CIDR. 한쪽만 있으면 join 후 logs/exec가 막힘

CIDR 설계: 겹치면 모든 게 막힌다

  • Remote node CIDR 최대 15개, remote Pod CIDR 최대 15개
  • IPv4 전용, RFC1918 또는 CGNAT(100.64.0.0/10) 범위
  • node/Pod CIDR끼리, 그리고 VPC, Service CIDR과도 겹치지 않을 것
  • 기존 클러스터에도 remote network 구성을 추가할 수 있음 (생성 시점 전용 아님)
    "remoteNetworkConfig": { "remoteNodeNetworks": [{ "cidrs": ["10.80.0.0/16"] }], "remotePodNetworks": [{ "cidrs": ["10.85.0.0/16"] }] }
  • Pod CIDR을 라우팅 가능하게 만들지(BGP/static) 결정, webhook, Cloud↔Hybrid Pod 통신이 여기에 달림
  • Cilium cluster-pool: 기존 항목, MaskSize 변경 금지, 확장은 새 항목 추가 (Cilium 문서 기준)

443은 안에서 열고, 10250은 밖에서 온다

Hybrid Nodes 고수준 네트워크: EKS CP, CP ENI, VPC, VPC 엔드포인트, 온프렘 노드와 라우터
그림 속 Gateway도 사설 연결 게이트웨이입니다 (Hybrid Nodes Gateway 아님).
온프렘이 연다 (outbound)
kubelet, Pod → Kubernetes API, TCP 443. 노드가 먼저 연결을 시작
AWS가 연다 (inbound)
CP → kubelet TCP 10250 (logs/exec/port-forward), CP → webhook Pod의 실제 설정 port
응답 허용 ≠ 신규 inbound 허용
443 세션의 stateful return이 10250 신규 연결을 열어 주지 않음. 별도 방화벽 규칙 필요

kubelet과 CP, 세션 방향이 다르다

kubelet에서 EKS 컨트롤 플레인으로: public endpoint 경로와 private endpoint 경로
public/private 중 하나를 선택: 경로가 다르므로 endpoint 설정에 따라 방화벽, DNS가 달라집니다. EKS 관리 PrivateLink(eks)와 Kubernetes API endpoint는 별개입니다.
한 줄 정리
443은 온프렘이 열고, 10250은 CP가 엽니다, 같은 노드라도 방화벽 규칙의 방향이 다릅니다.

Pod→API: Service 변환과 SNAT

Pod에서 EKS 컨트롤 플레인으로: CNI NAT 있음/없음 경로
그림은 kube-proxy/iptables 기준의 설명용입니다. Cilium eBPF kube-proxy replacement에서는 처리 방식이 다르고, 번호도 보편적 hook 순서가 아닙니다.
SNAT 있음
응답이 node 주소로 돌아오고 conntrack이 역변환. Pod CIDR return route 불필요
SNAT 없음
Pod 주소 그대로 나가므로 VPC → Pod CIDR return route 필요 (routable Pod 설계)
Service IP를 쓰는 Pod는 선택한 API endpoint로의 Service 변환이 먼저 일어남

웹훅: CP가 Pod IP로 직접 들어온다

EKS 컨트롤 플레인에서 webhook Pod로: VPC 라우팅, 사설 연결, 온프렘 라우터, CNI
Pod CIDR route가 있어야 합니다. CP ENI → VPC route → 사설 연결 → 온프렘 라우터 → node → Pod. 포트는 실제 설정한 webhook port이며 "8443 이상 전체"가 아닙니다.
한 줄 정리
CP가 Pod에 닿지 못하면 해당 webhook 호출이 실패합니다, Pod route를 만들거나(BGP/static/Gateway) webhook을 cloud에 두세요.

Pod 간 통신: VXLAN과 Cloud↔Hybrid

node 1
Pod A
10.85.1.x
Cilium VXLAN encap
→ UDP 8472 →
underlay (outer packet)
src node 1 IP
dst node 2 IP
→
node 2
Cilium decap
Pod B
10.85.2.x
outer packet은 node IP로 라우팅됩니다. 캡슐화 운반만을 위해 underlay에 Pod CIDR route가 필요하지는 않습니다(같은 L2 node끼리는 router hop 없이 직접 통신할 수도 있음). IPv4 VXLAN overhead 50바이트 → MTU 1500이면 1450 예시. 이 UDP 8472는 direct routing, Gateway 두 모드 모두에서 필요합니다.
한 줄 정리
UDP 8472는 어느 모드에서든 열려 있어야 합니다 (hybrid 노드 간 VXLAN).

라우팅 선택: static, BGP, Gateway

비교 항목static routeCilium BGP v2Gateway
Pod CIDR 도달 방법온프렘 라우터에 node별 prefix를 수동 등록Cilium이 Pod CIDR을 라우터에 광고pod CIDR당 VPC route 1건 → leader ENI + VXLAN
온프렘 라우터 변경필요 (route 유지, drift 추적)필요 (peering, ASN, prefix filter)Pod CIDR route는 불필요 (node IP, UDP 8472은 필요)
CNI 제약지원되는 routable Pod 설계Cilium BGP Control PlaneAWS Cilium VTEP + l7Proxy=false
HA / 처리량네트워크 팀 설계, 라우터/링크 한계네트워크 팀 설계, 라우터/링크 한계Lease active-standby, 활성 Gateway 1대 한계
정리(제거)소유한 route 정리소유한 route/peering 정리Helm 제거해도 VPC route는 남음
BGP 우선
라우터 팀이 BGP를 운영할 수 있고 노드가 늘어날 환경. AWS 가이드가 권장하는 방식
static은 소규모, 고정 환경
노드, Pod CIDR 변경 때마다 수동 갱신과 장애 추적 부담
Gateway는 라우터 변경이 어려울 때
VTEP/l7Proxy=false 제약과 추가 hop을 수용할 수 있다면

Cilium BGP v2: Pod CIDR만 광고

hybrid 노드를 선택해 라우터와 peering (localASN = Cilium node, peerASN = 온프렘 라우터)

apiVersion: cilium.io/v2alpha1 kind: CiliumBGPClusterConfig metadata: name: hybrid-bgp-config spec: nodeSelector: matchLabels: eks.amazonaws.com/compute-type: hybrid bgpInstances: - name: hybrid-instance localASN: 65001 peers: - name: on-prem-router peerASN: 65000 peerAddress: 10.80.1.1 peerConfigRef: name: on-prem-peer

timer와 graceful restart, 광고 selector 연결

apiVersion: cilium.io/v2alpha1 kind: CiliumBGPPeerConfig metadata: name: on-prem-peer spec: timers: holdTimeSeconds: 90 keepAliveTimeSeconds: 30 gracefulRestart: enabled: true restartTimeSeconds: 120 families: - afi: ipv4 safi: unicast advertisements: matchLabels: advertise: hybrid-pods

Pod CIDR만 광고 (Service, LB IP는 별도 설계)

apiVersion: cilium.io/v2alpha1 kind: CiliumBGPAdvertisement metadata: name: hybrid-pod-cidrs labels: advertise: hybrid-pods spec: advertisements: - advertisementType: PodCIDR

Helm values로 BGP Control Plane 활성화 후 상태 확인

bgpControlPlane: enabled: true operator: rollOutPods: true
cilium bgp peers cilium bgp routes

Gateway는 Pod CIDR 라우팅 숙제를 던다

GA 2026-04-21 오픈소스 (Apache-2.0) Gateway 추가 요금 없음 선택 사항
가능하게 해 주는 흐름
CP → webhook
hybrid Pod의 webhook 호출
Cloud ↔ Hybrid Pod
양방향 Pod IP 통신
ALB/NLB IP target
VPC → hybrid Pod 등록
AMP managed collector
private cluster endpoint 필요
솔직한 한계
설치만으로 모든 조건이 충족되지 않음, route, return path, TLS, 방화벽은 별도 검증
AWS Cilium + VTEP, l7Proxy=false 필요 (Cilium Ingress/Gateway API/L7 policy와 같은 설치에서 충돌)
VXLAN은 암호화 없음, 클러스터당 1개, 활성 Gateway 1대가 처리량 한계

Gateway 데이터 플레인: 한 경로로 읽기

Amazon VPC① VPC
Cloud Pod / CP / ALB
dst = Hybrid Pod IP
route table
hybrid pod CIDR마다 1건 → leader ENI
(ReplaceRoute)
→
Amazon EC2② Gateway leader (EC2)
hybrid_vxlan0, VNI 2
UDP 8472, IP 없음
CiliumNode watch →
로컬 FDB, ARP, onlink route
→
AWS Direct Connect
AWS Site-to-Site VPN
DX/VPN
③ 온프렘
Cilium agent (VTEP)
decap
Hybrid Pod
역방향
leader가 CiliumVTEPConfig hybrid-gateway(tunnelEndpoint, cidr, mac)를 갱신 → Cilium이 VPC CIDR 목적지를 VXLAN으로 leader에 전송
두 종류의 상태
AWS route는 pod CIDR당 1건(노드가 늘어도 그대로), 노드별 터널 정보는 각 replica가 CiliumNode watch로 로컬에서 갱신

Gateway HA: active/standby, scale-up

① 갱신 실패
leader가 Lease 갱신 못함
renew deadline 2s
→
② 인계
Lease 만료 3s
standby가 획득 (retry 1s)
→
③ route
ReplaceRoute →
새 leader ENI
→
④ VTEP
CiliumVTEPConfig
IP, MAC 갱신
3–5초는 가이드, 보장 아님
AWS 안내 예상치. AWS 블로그 측정은 약 6.2초. API, route, Cilium, 앱 복구를 실제로 검증
replica는 처리량이 아님
standby는 터널 상태만 warm 유지. 처리량은 인스턴스 크기를 키워(scale-up) 해결
2 AZ에 2대
chart는 host 분리 필수, AZ 분리 선호. AWS 가이드: 10–100 노드 c6in.xlarge, 더 크면 c6in.2xlarge/4xlarge

Gateway 설치: 노드→IAM→VTEP→Helm

Auto Mode NodeClass의 source/dest check 해제 (필드 발췌)

# NodeClass.spec advancedNetworking: sourceDestCheck: DisabledPrimaryENI

NodePool 쪽은 Gateway 노드에 label을 붙입니다 (chart nodeLabel과 일치)

# 노드 label hybrid-gateway-node: "true"

NodePool은 label hybrid-gateway-node: "true"와 taint hybrid-gateway-node:NoSchedule을 사용합니다(전체 manifest는 AWS getting-started 문서). 관리형/자체 관리 노드는 primary ENI source/dest check를 별도로 끄고 autoMode.enabled=false

aws eks create-pod-identity-association \ --cluster-name "$CLUSTER_NAME" --namespace eks-hybrid-nodes-gateway \ --service-account eks-hybrid-nodes-gateway --role-arn "$GATEWAY_ROLE_ARN" \ --no-disable-session-tags # 필요 권한 4개: ec2:DescribeRouteTables, DescribeInstances, CreateRoute, ReplaceRoute kubectl -n kube-system set env daemonset/aws-node \ AWS_VPC_K8S_CNI_EXCLUDE_SNAT_CIDRS="$SNAT_EXCLUDE_CIDRS"

SNAT_EXCLUDE_CIDRS는 기존 제외 범위와 모든 hybrid Pod CIDR의 합집합입니다. Auto Mode는 aws-node DaemonSet이 없고, serviceAccount.annotations는 1.0.2에서 무시됩니다.

helm upgrade cilium oci://public.ecr.aws/eks/cilium/cilium \ --version "$CILIUM_VERSION" --namespace kube-system --reuse-values \ --set vtep.enabled=true --set l7Proxy=false kubectl -n kube-system rollout restart daemonset/cilium kubectl -n kube-system get configmap cilium-config \ -o jsonpath='{.data.enable-vtep}{"\n"}{.data.enable-l7-proxy}{"\n"}' # 기대 출력: true / false

AWS Cilium 최소 버전: 1.17.13-1, 1.18.8-1, 1.19.2-1. Cilium minor를 바꾸는 업그레이드에서는 --reuse-values를 주의하세요.

# values.yaml (podCIDRs, routeTableIDs는 CSV 문자열) vpcCIDR: "10.226.0.0/16" # 예시 값 podCIDRs: "10.85.0.0/16" routeTableIDs: "rtb-0abc123456789def0,rtb-0def456789abc1230" replicas: 2 nodeLabel: hybrid-gateway-node autoMode: enabled: false # Auto Mode 노드는 true
helm upgrade --install eks-hybrid-nodes-gateway \ oci://public.ecr.aws/eks/eks-hybrid-nodes-gateway \ --version 1.0.2 --namespace eks-hybrid-nodes-gateway --create-namespace \ --values values.yaml

Gateway 운영: 관측과 제약

메트릭 (포트 10080 /metrics)의미 / 쓰는 법
hybrid_gateway_leader_is_activereplica의 leader 여부. sum()이 1이어야 하며 route 성공의 증거는 아님
hybrid_gateway_hybrid_nodes_configuredreplica별 로컬 구성 노드 수 (leader+standby 합산 금지)
hybrid_gateway_vxlan_{tx,rx}_{bytes,packets}_totalCounter, rate()로 처리량 확인
hybrid_gateway_aws_route_table_update_errors_totalCounter, increase(…[5m])로 최근 실패만 판단
health는 TCP 8088 /healthz, /readyz. chart는 Service, ServiceMonitor, PDB를 만들지 않으므로 직접 구성하고, readiness만으로 forwarding 성공을 판단하지 마세요.
한 줄 정리
설치, 제거는 결국 route 소유권 문제입니다, 바꾸기 전에 table, CIDR, target을 기록하세요.

방화벽 규칙: 모드별로 달라진다

Flow포트시작 주체
Node/Pod → Kubernetes APITCP 443 (실제 endpoint)온프렘
CP ENI → kubeletTCP 10250AWS (inbound)
CP → webhook/aggregated API Pod실제 설정한 TCP portAWS (inbound)
DNS client ↔ 실제 resolverUDP/TCP 53구성별
hybrid 노드 간 Cilium VXLANUDP 8472 (Geneve 선택 시 UDP 6081)노드
Cilium healthTCP 4240 (+ICMP)노드
VPN을 쓰면 UDP 500/4500. 광범위한 허용(10.0.0.0/8 등)이나 인증 없는 kubelet 10255는 열지 마세요.
한 줄 정리
먼저 '누가 시작하는가'로 방향을 정하고, 모드별 추가 포트만 더하세요.

VPC 엔드포인트: 쓰는 만큼만

eks
DescribeCluster 등 EKS 관리 API (Kubernetes API endpoint와 다름)
ssm, ssmmessages
SSM 하이브리드 활성화를 쓸 때 (SSM provider)
rolesanywhere
IAM Roles Anywhere provider를 쓸 때
한 줄 정리
엔드포인트 목록은 provider와 사용 기능을 정한 뒤에 확정하세요.

Block 2 Quiz (1/2)

Q1: kubectl logs, exec가 동작하려면 온프렘 방화벽에서 무엇을 허용해야 하는가?
Q2: UDP 8472 규칙은 언제 필요한가?

Block 2 Quiz (2/2)

Q3: helm uninstall 후 Gateway가 남기는 것은?
Q4: Gateway와 BGP 선택에 대한 설명으로 맞는 것은?

공식 문서로 이어가기

네트워킹 요구 사항
docs.aws.amazon.com/eks/latest/userguide/hybrid-nodes-networking.html
CNI, Cilium BGP
…/hybrid-nodes-cni.html
…/hybrid-nodes-cilium-bgp.html
Webhook 배치
…/hybrid-nodes-webhooks.html
Gateway 문서
…/hybrid-nodes-gateway-overview.html
…/hybrid-nodes-gateway-getting-started.html
…/hybrid-nodes-gateway-operations.html
Gateway 소스
github.com/aws/eks-hybrid-nodes-gateway
AWS Containers 블로그
Simplify hybrid Kubernetes networking with Amazon EKS Hybrid Nodes gateway

Thank You

Block 2: 네트워킹 & Gateway 완료

← 목차로 돌아가기 다음: 노드 부트스트랩 →