SWUFORCE/기술 보고서

Kubernetes의 네트워크 이슈를 해결할 수 있는 network-node-manager

hmyang444 2026. 5. 10. 00:32

https://tech.kakao.com/posts/426

 

Kubernetes의 네트워크 이슈를 해결할 수 있는 network-node-manager - tech.kakao.com

안녕하세요, 클라우드플랫폼팀 ssup이라고 합니다. Kubernetes 기반 Ku...

tech.kakao.com

*해당 글을 참고해서 정리했습니다.

 

 

 

 

카카오 사내의 Kubernetes Platform에서 다양한 네트워크 이슈들이 발생했다.

이 네트워크 이슈들을 해결하기 위해 Kubernetes의 Cluster를 구성하는 노드의 네트워크 설정을 관리하는 

Network-Node-Manager를 개발했다고 한다. 

 

Network-Node-Manager

Kubernetes Cluster를 구성하는 노드들의 네트워크 설정을 관리하는 컨트롤러

- Connection reset issue between pod and out of cluster

- External-IP access issue with IPVS proxy mode 

이 두가지의 문제를 해결할 수 있음

 

[출처] Kakao tech Architecture

<network-node-manager의 구조>

1) DaemonSet --> 클러스트의 모든 노드에 배포되어 동작함 

2) network-node-manager는 host network namespace에서 네트워크 권한을 갖고 동작함 

--> 즉, privilege를 가진 network-node-manager는 모든 노드의 네트워크 설정 변경이 가능함

3) network-node-manager는 k8s api server에게 Watch 요청을 통해 특정 object의 변화를 감시하고, 감시한 결과에 따라 설정을 변경함

 

Connection reset issue between pod and out of cluster

client pod와 밖에 있는 클러스트 사이의 연결 끊김 문제

client pod와 외부 server가 통신하다가 갑자기 client pod 내부에서 "connection reset by peer"  에러가 발생하면서,

TCP 통신이 갑자기 리셋되는 문제가 발생한다. 

**보통 pod가 서버에게 큰 data를 전송하는 과정에서 발생

 

#client pod와 외부 서버와의 통신 과정(참고)

(1) pod가 overlay network를 이용하는 경우, 클라이언트가 서버에게 전송한 요청 패킷은 node에서 SNAT가 된다.

*overlay network: 물리 네트워크 위에 사용하는 가상 컴퓨터 네트워크

*SNAT: 출발지 IP 주소를 변환하는 NAT 방식

 

(2) 패킷의 SrcIP는 client pod 의 주소가 아니라 node의 주소로 변환된다. 

Why?? pod의 IP주소는 kubernetes cluster 내부에서만 유효한 IP이기 때문에 외부 서버가 알 수 있는 IP로 변경줘야 함

 

(3) 요청 Packet의 SNAT는 Kubenetes Cluster의 네트워크를 담당하는 kube-proxy 또는 CNI (Container Netowkr) Plugin이  설정한 iptables의 MASQUERADE Rule을 통해서 실행된다.

 

(4) 요청 패킷을 받은 서버는 해당 패킷의 SrcIP를 확인하고 응답을 node에게 전송한다.

 

(5) 이 응답 패킷은 client pod가 받아야 하는 거니까, node에서 응답 패킷은 DNAT가 된다.

*DNAT: 목적지 IP를 node에서 client로 변경해줌

 

(6) 응답패킷이 client pod로 전달된다.

 

 

#client pod와 밖에 있는 클러스트 사이의 연결 끊김 문제

(1) 외부 서버 응답 패킷이 외적인 요소로 out of order가 되어서 전송이 된다면!!

문제가 전혀 없는 패킷이지만, conntrack의 버그로 인해 패킷은 invalid 패킷으로 간주된다.

*conntrack: network connection 정보를 관리하는 것

*iptable: 유효하지 않는 패킷에 대해 암묵적인 DNAT를 수행하지 않음 --> No DNAT 

 

(2) 응답 패킷은 pod가 아니라 node에게 전달된다.

 

(3) node는 패킷을 처리하다가 알 수 없는 무효 패킷을 발견하고, 패킷의 출발지주소로 connection reset 요청을 전송한다.

 

(4) connection reset을 받은 서버는 connection을 종료하고 TCP프로토콜에 의해 다시 connection reset 요청을 전송한다.

--> three-hand-shake

 

(5) 서버의 요청은 정상적으로 DNAT 되어 pod로 전송되어 "connection reset by peer"가 뜨게 되는 것이다. 

 

정리:  conntrack 버그로 인해서 Node가 Pod가 받아야 할 Packet을 대신 받고, Node가 전송한 Connection Reset 요청이 Client Pod와 Server Pod의 Connection을 종료시키게 된다.

 

 

본 Issue를 우회하기 하는 가장 직관적인 방법

- Node로 잘못 전달되는 외부의 Server의 응답 Packet을 차단하는 방법

--->> network-node-manager가 설정한 iptables의 Filter Rule에 의해서 Node로 잘못 전달되는 Packet을 차단하여, Node에서 Connection Reset 요청을 막는 과정이 있다. 

$ iptables -t filter -nvL
...
Chain INPUT (policy ACCEPT 3229 packets, 597K bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 NMANAGER_INPUT  all  -- *      *       0.0.0.0/0            0.0.0.0/0
...
Chain NMANAGER_INPUT (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 NMANAGER_DROP_INVALID_INPUT  all  -- *      *       0.0.0.0/0            0.0.0.0/0
Chain NMANAGER_DROP_INVALID_INPUT (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  -- *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID

--> 패킷이 drop되는 drop rule이 설정되어있음(ctstate INVALID) 

 

 

External-IP Access Issue with IPVS Proxy Mode

Kubernetes Cluster에서 kube-proxy의 IPVS Mode를 이용 시, Kubernetes Cluster 내부의 Client Pod에서 ExternalTrafficPolicy Local 설정과 함께 생성된 LoadBalancer Service의 External-IP로 통신하지 못하는 문제가 존재한다.

 

이슈 발생 상황

(1) LoadBalancer Service는 ExternalTrafficPolicy가 Local로 설정되어 있고 Service Pod A/B를 EndPoint로 갖고 있다.

--> 즉, Client Pod에서 LoadBalancer Service의 External-IP 또는 Cluster-IP로 접근 시 Service Pod A/B와 통신하게 된다.

 

(2) Service Pod A/B 모두 Node A에 존재하고 있기 때문에, Node A에 존재하는 kube-proxy는 IPVS Rule에 LoadBalancer Service의 External-IP, NodePort를 통해서 전달된 Packet을 Service Pod A/B로 전달하도록 설정한다.

 

(3) Node B에는 Service Pod가 존재하지 않기 때문에 LoadBalancer Service의 External-IP, NodePort를 통해서 전달된 Packet을 Drop 하도록 설정한다.

 

(4) Load Balancer는 LoadBalancer Service의 NodePort 또는 External-IP를 통해서 Node에 존재하는 Service Pod의 Health Check를 수행// Load Balancer는 Health Check에 실패하는 Node에게는 Packet을 전송하지 않는다. 

 

본 Issue를 우회하기 하는 가장 직관적인 방법

- network-node-manager는 Client Pod에서 LoadBalancer Service의 External-IP로 전송하는 Packet을 DNAT 하여 Cluster-IP로 변경하는 방법