하이브리드 노드의 네트워크 트래픽 흐름
하이브리드 노드의 네트워크 트래픽 흐름 (Network traffic flows for hybrid nodes)
이 페이지는 EKS Hybrid Nodes의 네트워크 트래픽 흐름을, 각 트래픽 유형의 종단 간 네트워크 경로를 보여주는 다이어그램과 함께 자세히 설명해요.
다음 트래픽 흐름을 다뤄요.
- 하이브리드 노드
kubelet에서 EKS 컨트롤 플레인으로 - EKS 컨트롤 플레인에서 하이브리드 노드(
kubelet서버)로 - 하이브리드 노드에서 실행되는 Pod에서 EKS 컨트롤 플레인으로
- EKS 컨트롤 플레인에서 하이브리드 노드에서 실행되는 Pod로(웹훅)
- 하이브리드 노드에서 실행되는 Pod 간(Pod-to-Pod)
- 클라우드 노드의 Pod에서 하이브리드 노드의 Pod로(동서 트래픽)
출처: 문서
본문
하이브리드 노드 kubelet에서 EKS 컨트롤 플레인으로
요청
1. kubelet이 요청을 시작
하이브리드 노드의 kubelet이 EKS 컨트롤 플레인과 통신해야 할 때(예: 노드 상태를 보고하거나 Pod 스펙을 가져올 때), 노드 등록 시 제공된 kubeconfig 파일을 사용해요. 이 kubeconfig에는 직접 IP 주소가 아닌 API 서버 엔드포인트 URL(Route53 DNS 이름)이 있어요.
kubelet은 엔드포인트에 대한 DNS 조회를 수행해요(예: https://xxxx...xxxx.gr7.us-west-2.eks.amazonaws.com). 공용 액세스 클러스터에서는 이 주소가 AWS에서 실행 중인 EKS 서비스에 속한 공용 IP 주소(예: 54.239.118.52)로 확인돼요. 그런 다음 kubelet은 이 엔드포인트에 대한 보안 HTTPS 요청을 만들어요. 초기 패킷은 다음과 같아요.
+--------------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.80.0.2 | Src: 52390 (random) | |
| Dst: 54.239.118.52 | Dst: 443 | |
+--------------------+---------------------+-----------------+
2. 로컬 라우터 라우팅
대상 IP가 공용 IP 주소이고 로컬 네트워크의 일부가 아니므로 kubelet은 이 패킷을 기본 게이트웨이(로컬 온프레미스 라우터)로 보내요. 라우터는 대상 IP를 검사하고 공용 IP 주소인지 확인해요.
공용 트래픽의 경우 라우터는 일반적으로 패킷을 인터넷으로 향하는 아웃바운드 트래픽을 처리하는 인터넷 게이트웨이나 경계 라우터로 전달해요. 이는 다이어그램에서 생략되었으며 온프레미스 네트워크 설정 방식에 따라 달라져요. 패킷은 온프레미스 네트워크 인프라를 통과해 결국 인터넷 서비스 제공업체의 네트워크에 도달해요.
3. EKS 컨트롤 플레인으로 전달
패킷은 공용 인터넷과 전송 네트워크를 거쳐 AWS의 네트워크에 도달해요. AWS 네트워크는 패킷을 해당 리전의 EKS 서비스 엔드포인트로 라우팅해요. 패킷이 EKS 서비스에 도달하면 클러스터의 실제 EKS 컨트롤 플레인으로 전달돼요.
이 공용 인터넷을 통한 라우팅은 다른 트래픽 흐름에서 볼 수 있는 프라이빗 VPC 라우팅 경로와는 달라요. 핵심 차이점은 공용 액세스 모드를 사용할 때 온프레미스 kubelet(하지만 Pod는 아님)에서 EKS 컨트롤 플레인으로 가는 트래픽은 VPC를 통과하지 않고 전역 인터넷 인프라를 사용한다는 점이에요.
응답
EKS 컨트롤 플레인이 kubelet 요청을 처리한 후 응답을 다시 보내요.
3. EKS 컨트롤 플레인이 응답을 보냄
EKS 컨트롤 플레인은 응답 패킷을 만들어요. 이 패킷은 공용 IP를 소스로, 하이브리드 노드의 IP를 대상으로 가져요.
+--------------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 54.239.118.52 | Src: 443 | |
| Dst: 10.80.0.2 | Dst: 52390 | |
+--------------------+---------------------+-----------------+
2. 인터넷 라우팅
응답 패킷은 인터넷 서비스 제공업체가 결정한 라우팅 경로를 따라 인터넷을 통해 다시 이동해 온프레미스 네트워크 경계 라우터에 도달해요.
1. 로컬 전달
온프레미스 라우터는 패킷을 받아 대상 IP(10.80.0.2)가 로컬 네트워크에 속한다고 인식해요. 라우터는 로컬 네트워크 인프라를 통해 패킷을 전달해 대상 하이브리드 노드에 도달시키고, kubelet이 응답을 받아 처리해요.
하이브리드 노드 kube-proxy에서 EKS 컨트롤 플레인으로
클러스터에 공용 엔드포인트 액세스를 활성화하면 반환 트래픽은 공용 인터넷을 사용해요. 이 트래픽은 하이브리드 노드의 kube-proxy에서 EKS 컨트롤 플레인으로 시작되며, kubelet에서 EKS 컨트롤 플레인으로 가는 트래픽과 같은 경로를 따라요.
EKS 컨트롤 플레인에서 하이브리드 노드(kubelet 서버)로
요청
1. EKS Kubernetes API 서버가 요청을 시작
EKS Kubernetes API 서버는 노드 객체 상태에서 노드의 IP 주소(10.80.0.2)를 가져와요. 대상 IP가 구성된 원격 노드 CIDR(10.80.0.0/16)에 속하므로, 이 요청을 VPC의 ENI를 통해 라우팅해요. 초기 패킷은 다음과 같아요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.0.0.132 | Src: 67493 (random) | |
| Dst: 10.80.0.2 | Dst: 10250 | |
+-----------------+---------------------+-----------------+
2. VPC 네트워크 처리
패킷은 ENI를 떠나 VPC 네트워킹 계층으로 들어가며, 추가 라우팅을 위해 서브넷의 게이트웨이로 보내져요.
3. VPC 라우트 테이블 조회
EKS 컨트롤 플레인 ENI가 있는 서브넷의 VPC 라우트 테이블에는 원격 노드 CIDR에 대한 특정 라우트(다이어그램에서 두 번째 것)가 있어요. 이 라우팅 규칙에 따라 패킷은 VPC-to-온프레미스 게이트웨이로 보내져요.
4. 경계 간 전송
게이트웨이는 설정된 연결(Direct Connect 또는 VPN 등)을 통해 패킷을 클라우드 경계를 넘어 온프레미스 네트워크로 전달해요.
5. 온프레미스 네트워크 수신
패킷은 하이브리드 노드가 있는 서브넷의 트래픽을 처리하는 로컬 온프레미스 라우터에 도착해요.
6. 최종 전달
로컬 라우터는 대상 IP(10.80.0.2) 주소가 직접 연결된 네트워크에 속한다고 식별하고, 패킷을 대상 하이브리드 노드로 직접 전달해요. kubelet이 요청을 받아 처리해요.
응답
하이브리드 노드의 kubelet이 요청을 처리한 후 동일한 경로를 역방향으로 따라 응답을 다시 보내요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.80.0.2 | Src: 10250 | |
| Dst: 10.0.0.132 | Dst: 67493 | |
+-----------------+---------------------+-----------------+
6. kubelet이 응답을 보냄
하이브리드 노드(10.80.0.2)의 kubelet은 원래 소스 IP를 대상으로 하는 응답 패킷을 만들어요. 대상이 로컬 네트워크에 속하지 않으므로 호스트의 기본 게이트웨이인 로컬 라우터로 보내져요.
5. 로컬 라우터 라우팅
라우터는 대상 IP(10.0.0.132)가 10.0.0.0/16에 속하며, 이는 AWS로 연결되는 게이트웨이를 가리키는 라우트가 있다고 결정해요.
4. 경계 간 반환
패킷은 동일한 온프레미스-to-VPC 연결(Direct Connect 또는 VPN 등)을 통해 다시 이동하며 클라우드 경계를 역방향으로 건너요.
3. VPC 라우팅
패킷이 VPC에 도착하면 라우트 테이블이 대상 IP가 VPC CIDR에 속한다고 식별해요. 패킷은 VPC 내에서 라우팅돼요.
2. VPC 네트워크 전달
VPC 네트워킹 계층은 패킷을 EKS 컨트롤 플레인 ENI(10.0.0.132)가 있는 서브넷으로 전달해요.
1. ENI 수신
패킷은 Kubernetes API 서버에 연결된 EKS 컨트롤 플레인 ENI에 도달해 왕복을 완료해요.
하이브리드 노드에서 실행되는 Pod에서 EKS 컨트롤 플레인으로
CNI NAT 없음
요청
Pod는 일반적으로 kubernetes 서비스를 통해 Kubernetes API 서버와 통신해요. 서비스 IP는 클러스터의 서비스 CIDR의 첫 번째 IP예요. 이 규칙 덕분에 CoreDNS가 사용 가능해지기 전에 실행해야 하는 Pod(예: CNI)도 API 서버에 도달할 수 있어요. 요청은 대상으로 서비스 IP를 가지고 Pod를 떠나요. 예를 들어 서비스 CIDR이 172.16.0.0/16이면 서비스 IP는 172.16.0.1이 돼요.
1. Pod가 요청을 시작
Pod는 임의의 소스 포트에서 API 서버 포트(443)의 kubernetes 서비스 IP(172.16.0.1)로 요청을 보내요. 패킷은 다음과 같아요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.85.1.56 | Src: 67493 (random) | |
| Dst: 172.16.0.1 | Dst: 443 | |
+-----------------+---------------------+-----------------+
2. CNI 처리
CNI는 대상 IP가 자신이 관리하는 Pod CIDR에 속하지 않는다고 감지해요. 아웃바운드 NAT가 비활성화되어 있으므로 CNI는 패킷을 수정하지 않고 호스트 네트워크 스택으로 전달해요.
3. 노드 네트워크 처리
패킷은 노드의 네트워크 스택에 들어가며, netfilter 훅이 kube-proxy가 설정한 iptables 규칙을 트리거해요. 여러 규칙이 다음 순서로 적용돼요.
패킷은 먼저 각 서비스의 ClusterIP와 포트와 일치하는 규칙이 있는 KUBE-SERVICES 체인을 만나요.
일치하는 규칙은 kubernetes 서비스(즉 172.16.0.1:443으로 향하는 패킷)의 KUBE-SVC-XXX 체인으로 점프하며, 이 체인에는 로드 밸런싱 규칙이 있어요.
로드 밸런싱 규칙은 컨트롤 플레인 ENI IP(10.0.0.132 또는 10.1.23) 중 하나의 KUBE-SEP-XXX 체인을 무작위로 선택해요.
선택된 KUBE-SEP-XXX 체인에는 대상 IP를 서비스 IP에서 선택된 IP로 변경하는 실제 규칙이 있어요. 이를 DNAT(Destination Network Address Translation)라고 불러요.
이 규칙들이 적용된 후, 선택된 EKS 컨트롤 플레인 ENI의 IP가 10.0.0.132라고 가정하면 패킷은 다음과 같아요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.85.1.56 | Src: 67493 (random) | |
| Dst: 10.0.0.132 | Dst: 443 | |
+-----------------+---------------------+-----------------+
노드는 대상 IP가 로컬 네트워크에 없으므로 패킷을 기본 게이트웨이로 전달해요.
4. 로컬 라우터 라우팅
로컬 라우터는 대상 IP(10.0.0.132)가 VPC CIDR(10.0.0.0/16)에 속한다고 결정하고, 이를 AWS로 연결되는 게이트웨이로 전달해요.
5. 경계 간 전송
패킷은 설정된 연결(Direct Connect 또는 VPN 등)을 통해 클라우드 경계를 건너 VPC로 이동해요.
6. VPC 네트워크 전달
VPC 네트워킹 계층은 패킷을 EKS 컨트롤 플레인 ENI(10.0.0.132)가 있는 올바른 서브넷으로 라우팅해요.
7. ENI 수신
패킷은 Kubernetes API 서버에 연결된 EKS 컨트롤 플레인 ENI에 도달해요.
응답
EKS 컨트롤 플레인이 요청을 처리한 후 Pod로 응답을 다시 보내요.
7. API 서버가 응답을 보냄
EKS Kubernetes API 서버는 원래 소스 IP를 대상으로 하는 응답 패킷을 만들어요. 패킷은 다음과 같아요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.0.0.132 | Src: 443 | |
| Dst: 10.85.1.56 | Dst: 67493 | |
+-----------------+---------------------+-----------------+
대상 IP가 구성된 원격 Pod CIDR(10.85.0.0/16)에 속하므로 서브넷의 라우터를 다음 홉으로 하여 VPC의 ENI를 통해 보내요.
6. VPC 라우팅
VPC 라우트 테이블에는 원격 Pod CIDR(10.85.0.0/16)에 대한 항목이 있어 이 트래픽을 VPC-to-온프레미스 게이트웨이로 보내요.
5. 경계 간 전송
게이트웨이는 설정된 연결(Direct Connect 또는 VPN 등)을 통해 패킷을 클라우드 경계를 넘어 온프레미스 네트워크로 전달해요.
4. 온프레미스 네트워크 수신
패킷은 로컬 온프레미스 라우터에 도착해요.
3. 노드로 전달
라우터의 테이블에는 10.80.0.2를 다음 홉으로 하는 10.85.1.0/24 항목이 있어 패킷을 우리 노드로 전달해요.
2. 노드 네트워크 처리
패킷이 노드의 네트워크 스택에서 처리되면서, conntrack(netfilter의 일부)이 패킷을 Pod가 처음 설정한 연결과 일치시켜요. DNAT가 원래 적용되었으므로 conntrack은 소스 IP를 EKS 컨트롤 플레인 ENI의 IP에서 kubernetes 서비스 IP로 다시 작성해 DNAT을 역전시켜요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 172.16.0.1 | Src: 443 | |
| Dst: 10.85.1.56 | Dst: 67493 | |
+-----------------+---------------------+-----------------+
1. CNI 처리
CNI는 대상 IP가 자신의 네트워크에 있는 Pod에 속한다고 식별하고, 패킷을 올바른 Pod 네트워크 네임스페이스로 전달해요.
이 흐름은 Remote Pod CIDR이 VPC에서 각 Pod를 호스팅하는 특정 노드까지 제대로 라우팅 가능해야 하는 이유를 보여줘요. 전체 반환 경로가 클라우드와 온프레미스 네트워크 양쪽에서 Pod IP의 올바른 라우팅에 의존하기 때문이에요.
CNI NAT 사용
이 흐름은 CNI NAT가 없는 경우와 매우 유사하지만 한 가지 핵심 차이점이 있어요. CNI가 패킷을 노드의 네트워크 스택으로 보내기 전에 소스 NAT(SNAT)를 적용해요. 이렇게 하면 패킷의 소스 IP가 노드의 IP로 바뀌어, 추가 라우팅 구성 없이도 패킷이 노드로 다시 라우팅될 수 있어요.
요청
1. Pod가 요청을 시작
Pod는 임의의 소스 포트에서 EKS Kubernetes API 서버 포트(443)의 kubernetes 서비스 IP(172.16.0.1)로 요청을 보내요. 패킷은 다음과 같아요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.85.1.56 | Src: 67493 (random) | |
| Dst: 172.16.0.1 | Dst: 443 | |
+-----------------+---------------------+-----------------+
2. CNI 처리
CNI는 대상 IP가 자신이 관리하는 Pod CIDR에 속하지 않는다고 감지해요. 아웃바운드 NAT가 활성화되어 있으므로 CNI는 패킷에 SNAT를 적용해 소스 IP를 노드의 IP로 변경한 후 노드의 네트워크 스택으로 전달해요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.80.0.2 | Src: 67493 (random) | |
| Dst: 172.16.0.1 | Dst: 443 | |
+-----------------+---------------------+-----------------+
참고: CNI와
iptables는 명확성을 위해 예시에서 별도 블록으로 표시되지만, 실제로는 일부 CNI가 NAT 적용에iptables를 사용할 수 있어요.
3. 노드 네트워크 처리
여기서 kube-proxy가 설정한 iptables 규칙은 이전 예시와 동일하게 동작하며 패킷을 EKS 컨트롤 플레인 ENI 중 하나로 로드 밸런싱해요. 이제 패킷은 다음과 같아요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.80.0.2 | Src: 67493 (random) | |
| Dst: 10.0.0.132 | Dst: 443 | |
+-----------------+---------------------+-----------------+
노드는 대상 IP가 로컬 네트워크에 없으므로 패킷을 기본 게이트웨이로 전달해요.
4. 로컬 라우터 라우팅
로컬 라우터는 대상 IP(10.0.0.132)가 VPC CIDR(10.0.0.0/16)에 속한다고 결정하고 AWS로 연결되는 게이트웨이로 전달해요.
5. 경계 간 전송
패킷은 설정된 연결(Direct Connect 또는 VPN 등)을 통해 클라우드 경계를 건너 VPC로 이동해요.
6. VPC 네트워크 전달
VPC 네트워킹 계층은 패킷을 EKS 컨트롤 플레인 ENI(10.0.0.132)가 있는 올바른 서브넷으로 라우팅해요.
7. ENI 수신
패킷은 Kubernetes API 서버에 연결된 EKS 컨트롤 플레인 ENI에 도달해요.
응답
EKS 컨트롤 플레인이 요청을 처리한 후 Pod로 응답을 다시 보내요.
7. API 서버가 응답을 보냄
EKS Kubernetes API 서버는 원래 소스 IP를 대상으로 하는 응답 패킷을 만들어요. 패킷은 다음과 같아요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.0.0.132 | Src: 443 | |
| Dst: 10.80.0.2 | Dst: 67493 | |
+-----------------+---------------------+-----------------+
대상 IP가 구성된 원격 노드 CIDR(10.80.0.0/16)에 속하므로 서브넷의 라우터를 다음 홉으로 하여 VPC의 ENI를 통해 보내요.
6. VPC 라우팅
VPC 라우트 테이블에는 원격 노드 CIDR(10.80.0.0/16)에 대한 항목이 있어 이 트래픽을 VPC-to-온프레미스 게이트웨이로 보내요.
5. 경계 간 전송
게이트웨이는 설정된 연결(Direct Connect 또는 VPN 등)을 통해 패킷을 클라우드 경계를 넘어 온프레미스 네트워크로 전달해요.
4. 온프레미스 네트워크 수신
패킷은 로컬 온프레미스 라우터에 도착해요.
3. 노드로 전달
로컬 라우터는 대상 IP(10.80.0.2) 주소가 직접 연결된 네트워크에 속한다고 식별하고, 패킷을 대상 하이브리드 노드로 직접 전달해요.
2. 노드 네트워크 처리
패킷이 노드의 네트워크 스택에서 처리되면서, conntrack(netfilter의 일부)이 패킷을 Pod가 처음 설정한 연결과 일치시키고, DNAT가 원래 적용되었으므로 소스 IP를 EKS 컨트롤 플레인 ENI의 IP에서 kubernetes 서비스 IP로 다시 작성해 이를 역전시켜요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 172.16.0.1 | Src: 443 | |
| Dst: 10.80.0.2 | Dst: 67493 | |
+-----------------+---------------------+-----------------+
1. CNI 처리
CNI는 이 패킷이 이전에 SNAT를 적용한 연결에 속한다고 식별해요. SNAT를 역전시켜 대상 IP를 다시 Pod의 IP로 변경해요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 172.16.0.1 | Src: 443 | |
| Dst: 10.85.1.56 | Dst: 67493 | |
+-----------------+---------------------+-----------------+
CNI는 대상 IP가 자신의 네트워크에 있는 Pod에 속한다고 감지하고, 패킷을 올바른 Pod 네트워크 네임스페이스로 전달해요.
이 흐름은 CNI NAT이 Pod CIDR에 대한 추가 라우팅 없이도 패킷을 노드로 다시 라우팅할 수 있게 하여 구성을 단순화하는 방법을 보여줘요.
EKS 컨트롤 플레인에서 하이브리드 노드에서 실행되는 Pod로 (웹훅)
이 트래픽 패턴은 웹훅에서 가장 흔히 볼 수 있어요. EKS 컨트롤 플레인이 하이브리드 노드의 Pod에서 실행되는 웹훅 서버로 직접 연결을 시작해야 하는 경우예요. 예로는 리소스 검증 또는 변형 프로세스 중 API 서버가 호출하는 validating 및 mutating admission webhook이 있어요.
요청
1. EKS Kubernetes API 서버가 요청을 시작
클러스터에 웹훅이 구성되고 관련 API 작업이 이를 트리거하면, EKS Kubernetes API 서버는 웹훅 서버 Pod로 직접 연결해야 해요. API 서버는 먼저 웹훅과 연결된 Service 또는 Endpoint 리소스에서 Pod의 IP 주소를 조회해요.
웹훅 Pod가 IP 10.85.1.23의 하이브리드 노드에서 실행되고 있다고 가정하면, EKS Kubernetes API 서버는 웹훅 엔드포인트로 HTTPS 요청을 만들어요. 대상 IP 10.85.1.23이 구성된 원격 Pod CIDR(10.85.0.0/16)에 속하므로 초기 패킷은 VPC의 EKS 컨트롤 플레인 ENI를 통해 보내져요. 패킷은 다음과 같아요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.0.0.132 | Src: 41892 (random) | |
| Dst: 10.85.1.23 | Dst: 8443 | |
+-----------------+---------------------+-----------------+
2. VPC 네트워크 처리
패킷은 EKS 컨트롤 플레인 ENI를 떠나 서브넷의 라우터를 다음 홉으로 하여 VPC 네트워킹 계층으로 들어가요.
3. VPC 라우트 테이블 조회
EKS 컨트롤 플레인 ENI가 있는 서브넷의 VPC 라우트 테이블에는 원격 Pod CIDR(10.85.0.0/16)에 대한 특정 라우트가 있어요. 이 라우팅 규칙은 패킷을 VPC-to-온프레미스 게이트웨이(예: Direct Connect 또는 VPN 연결용 Virtual Private Gateway)로 보내요.
Destination Target
10.0.0.0/16 local
10.85.0.0/16 vgw-id (VPC-to-onprem gateway)
4. 경계 간 전송
게이트웨이는 설정된 연결(Direct Connect 또는 VPN 등)을 통해 패킷을 클라우드 경계를 넘어 온프레미스 네트워크로 전달해요. 패킷은 이 연결을 통과하는 동안 원래 소스 및 대상 IP 주소를 유지해요.
5. 온프레미스 네트워크 수신
패킷은 로컬 온프레미스 라우터에 도착해요. 라우터는 라우팅 테이블을 참조해 10.85.1.23 주소에 도달하는 방법을 결정해요. 이렇게 하려면 온프레미스 네트워크에 트래픽을 적절한 하이브리드 노드로 보내는 Pod CIDR에 대한 라우트가 있어야 해요.
이 경우 라우터의 라우트 테이블에는 10.85.1.0/24 서브넷이 IP 10.80.0.2의 하이브리드 노드를 통해 도달 가능하다는 항목이 있어요.
Destination Next Hop
10.85.1.0/24 10.80.0.2
6. 노드로 전달
라우팅 테이블 항목에 따라 라우터는 패킷을 하이브리드 노드(10.80.0.2)로 전달해요. 패킷이 노드에 도착하면 EKS Kubernetes API 서버가 보냈을 때와 동일하며, 대상 IP는 여전히 Pod의 IP예요.
7. CNI 처리
노드의 네트워크 스택은 패킷을 받고, 대상 IP가 노드 자신의 IP가 아님을 확인해 처리하기 위해 CNI로 전달해요. CNI는 대상 IP가 이 노드에서 로컬로 실행 중인 Pod에 속한다고 식별하고, 적절한 가상 인터페이스를 통해 패킷을 올바른 Pod로 전달해요.
Original packet -> node routing -> CNI -> Pod's network namespace
Pod의 웹훅 서버는 요청을 받아 처리해요.
응답
웹훅 Pod가 요청을 처리한 후 동일한 경로를 역방향으로 따라 응답을 다시 보내요.
7. Pod가 응답을 보냄
웹훅 Pod는 자신의 IP를 소스로, 원래 요청자(EKS 컨트롤 플레인 ENI)를 대상으로 하는 응답 패킷을 만들어요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.85.1.23 | Src: 8443 | |
| Dst: 10.0.0.132 | Dst: 41892 | |
+-----------------+---------------------+-----------------+
CNI는 이 패킷이 외부 네트워크(로컬 Pod가 아님)로 간다고 식별하고, 원래 소스 IP를 유지한 채 노드의 네트워크 스택으로 패킷을 전달해요.
6. 노드 네트워크 처리
노드는 대상 IP(10.0.0.132)가 로컬 네트워크에 없다고 결정하고 기본 게이트웨이(로컬 라우터)로 패킷을 전달해요.
5. 로컬 라우터 라우팅
로컬 라우터는 라우팅 테이블을 참조해 대상 IP(10.0.0.132)가 VPC CIDR(10.0.0.0/16)에 속한다고 결정해요. AWS로 연결되는 게이트웨이로 패킷을 전달해요.
4. 경계 간 전송
패킷은 동일한 온프레미스-to-VPC 연결을 통해 다시 이동해 클라우드 경계를 역방향으로 건너요.
3. VPC 라우팅
패킷이 VPC에 도착하면 라우트 테이블이 대상 IP가 VPC 내 서브넷에 속한다고 식별해요. 패킷은 이에 따라 VPC 내에서 라우팅돼요.
2 및 1. EKS 컨트롤 플레인 ENI 수신
패킷은 EKS Kubernetes API 서버에 연결된 ENI에 도달해 왕복을 완료해요. API 서버는 웹훅 응답을 받고 이 응답에 따라 원래 API 요청 처리를 계속해요.
이 트래픽 흐름은 원격 Pod CIDR이 제대로 구성되고 라우팅되어야 하는 이유를 보여줘요.
- VPC에는 온프레미스 게이트웨이를 가리키는 원격 Pod CIDR에 대한 라우트가 있어야 해요.
- 온프레미스 네트워크에는 트래픽을 해당 Pod를 호스팅하는 특정 노드로 보내는 Pod CIDR에 대한 라우트가 있어야 해요.
이 라우팅 구성이 없으면 하이브리드 노드의 Pod에서 실행되는 웹훅 및 기타 유사한 서비스는 EKS 컨트롤 플레인에서 도달할 수 없어요.
하이브리드 노드에서 실행되는 Pod 간 (Pod-to-Pod)
이 섹션은 서로 다른 하이브리드 노드에서 실행되는 Pod가 서로 통신하는 방식을 설명해요. 이 예시는 CNI가 캡슐화에 VXLAN을 사용한다고 가정하며, 이는 Cilium이나 Calico 같은 CNI에서 흔합니다. 전체 프로세스는 Geneve나 IP-in-IP 같은 다른 캡슐화 프로토콜에서도 유사해요.
요청
1. Pod A가 통신 시작
Node 1의 Pod A(10.85.1.56)는 Node 2의 Pod B(10.85.2.67)로 트래픽을 보내려 해요. 초기 패킷은 다음과 같아요.
+------------------+-----------------+-------------+-----------------+
| Ethernet Header | IP Header | TCP/UDP | Payload |
| Src: Pod A MAC | Src: 10.85.1.56 | Src: 43721 | |
| Dst: Gateway MAC | Dst: 10.85.2.67 | Dst: 8080 | |
+------------------+-----------------+-------------+-----------------+
2. CNI가 패킷을 가로채고 처리
Pod A의 패킷이 네트워크 네임스페이스를 떠나면 CNI가 이를 가로채요. CNI는 라우팅 테이블을 참조해 다음을 결정해요.
- 대상 IP(
10.85.2.67)가 Pod CIDR에 속함 - 이 IP는 로컬 노드에 없고 Node 2(
10.80.0.3)에 속함 - 패킷을 VXLAN으로 캡슐화해야 함
캡슐화 결정은 중요해요. 기본 물리 네트워크는 Pod CIDR을 직접 라우팅하는 방법을 모르고, 노드 IP 간의 트래픽을 라우팅하는 방법만 알기 때문이에요.
CNI는 원래 패킷 전체를 VXLAN 프레임 안에 캡슐화해요. 이는 새로운 헤더로 "패킷 안의 패킷"을 효과적으로 만들어요.
+-----------------+----------------+--------------+------------+---------------------------+
| Outer Ethernet | Outer IP | Outer UDP | VXLAN | Original Pod-to-Pod |
| Src: Node1 MAC | Src: 10.80.0.2 | Src: Random | VNI: 42 | Packet (unchanged |
| Dst: Router MAC | Dst: 10.80.0.3 | Dst: 8472 | | from above) |
+-----------------+----------------+--------------+------------+---------------------------+
이 캡슐화에 대한 핵심 사항:
- 외부 패킷은 Node 1(
10.80.0.2)에서 Node 2(10.80.0.3)로 주소가 지정됨 - UDP 포트
8472는 Cilium이 기본적으로 사용하는 VXLAN 포트 - VXLAN Network Identifier(VNI)는 이 패킷이 속한 오버레이 네트워크를 식별
- 원래 패킷 전체(Pod A의 IP를 소스로, Pod B의 IP를 대상으로)가 내부에 그대로 보존
캡슐화된 패킷은 이제 Node 1의 일반 네트워킹 스택에 들어가 다른 패킷과 동일한 방식으로 처리돼요.
- 노드 네트워크 처리: Node 1의 네트워크 스택은 대상(
10.80.0.3)을 기준으로 패킷을 라우팅해요. - 로컬 네트워크 전달: 두 노드가 동일한 레이어 2 네트워크에 있으면 패킷이 Node 2로 직접 전송돼요. 다른 서브넷에 있으면 패킷이 먼저 로컬 라우터로 전달돼요.
- 라우터 처리: 라우터는 라우팅 테이블을 기준으로 패킷을 전달해 Node 2로 전달해요.
3. 수신 노드 처리
캡슐화된 패킷이 Node 2(10.80.0.3)에 도착하면:
- 노드의 네트워크 스택이 이를 받아 VXLAN 패킷(UDP 포트
4789)으로 식별해요. - 패킷은 처리를 위해 CNI의 VXLAN 인터페이스로 전달돼요.
4. VXLAN 역캡슐화
Node 2의 CNI가 VXLAN 패킷을 처리해요.
- 외부 헤더(Ethernet, IP, UDP, VXLAN)를 제거해요.
- 원래 내부 패킷을 추출해요.
- 패킷은 이제 원래 형태로 돌아와요.
+------------------+-----------------+-------------+-----------------+
| Ethernet Header | IP Header | TCP/UDP | Payload |
| Src: Pod A MAC | Src: 10.85.1.56 | Src: 43721 | |
| Dst: Gateway MAC | Dst: 10.85.2.67 | Dst: 8080 | |
+------------------+-----------------+-------------+-----------------+
Node 2의 CNI는 대상 IP(10.85.2.67)를 검사하고:
- 이 IP가 로컬 Pod에 속한다고 식별해요.
- 적절한 가상 인터페이스를 통해 패킷을 라우팅해요.
- 패킷을 Pod B의 네트워크 네임스페이스로 전달해요.
응답
Pod B가 Pod A에 응답하면 전체 프로세스가 역방향으로 발생해요.
- Pod B는 Pod A(
10.85.1.56)로 패킷을 보내요. - Node 2의 CNI는 대상이 Node 1(
10.80.0.2)이 되도록 VXLAN으로 캡슐화해요. - 캡슐화된 패킷이 Node 1로 전달돼요.
- Node 1의 CNI가 이를 역캡슐화하고 원래 응답을 Pod A로 전달해요.
클라우드 노드의 Pod에서 하이브리드 노드의 Pod로 (동서 트래픽)
요청
1. Pod A가 통신 시작
EC2 노드의 Pod A(10.0.0.56)는 Hybrid Node의 Pod B(10.85.1.56)로 트래픽을 보내려 해요. 초기 패킷은 다음과 같아요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.0.0.56 | Src: 52390 (random) | |
| Dst: 10.85.1.56 | Dst: 8080 | |
+-----------------+---------------------+-----------------+
VPC CNI를 사용하면 Pod A는 VPC CIDR에서 IP를 가지며 EC2 인스턴스의 ENI에 직접 연결돼요. Pod의 네트워크 네임스페이스는 VPC 네트워크에 연결되어 있으므로 패킷은 VPC 라우팅 인프라에 직접 들어가요.
2. VPC 라우팅
VPC 라우트 테이블에는 Remote Pod CIDR(10.85.0.0/16)에 대한 특정 라우트가 있어 이 트래픽을 VPC-to-온프레미스 게이트웨이로 보내요.
Destination Target
10.0.0.0/16 local
10.85.0.0/16 vgw-id (VPC-to-onprem gateway)
이 라우팅 규칙에 따라 패킷은 온프레미스 네트워크로 연결되는 게이트웨이로 보내져요.
3. 경계 간 전송
게이트웨이는 설정된 연결(Direct Connect 또는 VPN 등)을 통해 패킷을 클라우드 경계를 넘어 온프레미스 네트워크로 전달해요. 패킷은 이 전송 동안 원래 소스 및 대상 IP 주소를 유지해요.
4. 온프레미스 네트워크 수신
패킷은 로컬 온프레미스 라우터에 도착해요. 라우터는 라우팅 테이블을 참조해 10.85.1.56 주소에 도달하기 위한 다음 홉을 결정해요. 온프레미스 라우터에는 트래픽을 적절한 하이브리드 노드로 보내는 Pod CIDR에 대한 라우트가 있어야 해요.
라우터의 테이블에는 10.85.1.0/24 서브넷이 IP 10.80.0.2의 하이브리드 노드를 통해 도달 가능하다는 항목이 있어요.
Destination Next Hop
10.85.1.0/24 10.80.0.2
5. 노드 네트워크 처리
라우터는 패킷을 하이브리드 노드(10.80.0.2)로 전달해요. 패킷이 노드에 도착하면 여전히 Pod A의 IP를 소스로, Pod B의 IP를 대상으로 갖고 있어요.
6. CNI 처리
노드의 네트워크 스택은 패킷을 받고, 대상 IP가 자신의 IP가 아니므로 처리하기 위해 CNI로 전달해요. CNI는 대상 IP가 이 노드에서 로컬로 실행 중인 Pod에 속한다고 식별하고, 적절한 가상 인터페이스를 통해 패킷을 올바른 Pod로 전달해요.
Original packet -> node routing -> CNI -> Pod B's network namespace
Pod B는 패킷을 받아 필요에 따라 처리해요.
응답
6. Pod B가 응답을 보냄
Pod B는 자신의 IP를 소스로, Pod A의 IP를 대상으로 하는 응답 패킷을 만들어요.
+-----------------+---------------------+-----------------+
| IP Header | TCP Header | Payload |
| Src: 10.85.1.56 | Src: 8080 | |
| Dst: 10.0.0.56 | Dst: 52390 | |
+-----------------+---------------------+-----------------+
CNI는 이 패킷이 외부 네트워크로 향한다고 식별하고 이를 노드의 네트워크 스택으로 전달해요.
5. 노드 네트워크 처리
노드는 대상 IP(10.0.0.56)가 로컬 네트워크에 속하지 않는다고 결정하고 기본 게이트웨이(로컬 라우터)로 패킷을 전달해요.
4. 로컬 라우터 라우팅
로컬 라우터는 라우팅 테이블을 참조해 대상 IP(10.0.0.56)가 VPC CIDR(10.0.0.0/16)에 속한다고 결정해요. AWS로 연결되는 게이트웨이로 패킷을 전달해요.
3. 경계 간 전송
패킷은 동일한 온프레미스-to-VPC 연결을 통해 다시 이동해 클라우드 경계를 역방향으로 건너요.
2. VPC 라우팅
패킷이 VPC에 도착하면 라우팅 시스템이 대상 IP가 VPC 내 서브넷에 속한다고 식별해요. 패킷은 Pod A를 호스팅하는 EC2 인스턴스 쪽으로 VPC 네트워크를 통해 라우팅돼요.
1. Pod A가 응답 수신
패킷은 EC2 인스턴스에 도착하고 연결된 ENI를 통해 Pod A로 직접 전달돼요. VPC CNI는 VPC의 Pod에 오버레이 네트워킹을 사용하지 않으므로 추가 역캡슐화가 필요 없어요. 패킷은 원래 헤더를 그대로 유지한 채 도착해요.
이 동서 트래픽 흐름은 원격 Pod CIDR이 양방향에서 제대로 구성되고 라우팅 가능해야 하는 이유를 보여줘요.
- VPC에는 온프레미스 게이트웨이를 가리키는 원격 Pod CIDR에 대한 라우트가 있어야 해요.
- 온프레미스 네트워크에는 트래픽을 해당 Pod를 호스팅하는 특정 노드로 보내는 Pod CIDR에 대한 라우트가 있어야 해요.
더 알아보기 (Learn more)
-
Kubernetes 개념
-
하이브리드 노드 nodeadm