Kubernetes에서 Source IP 사용하기

2020, Jun 18    

NodePort

Kubernetes 1.5부터 Type = NodePort를 사용하여 Services로 전송 된 패킷은 기본적으로 소스 NAT입니다.

NodePort가 통신하는 방식은 다음과 같습니다.

Clinet가 node2:nodePort로 패킷을 보낸다. node2는 패킷의 소스 IP 주소 (SNAT)를 자체 IP 주소로 바꿉니다. 패킷이 node1로 라우팅 된 다음 엔드 포인트로 라우팅됩니다. Pod의 응답을 node2로 다시 라우팅됩니다. Pod의 응답을 클라이언트로 다시 전송됩니다.

          client
             \ ^
              \ \
               v \
   node 1 <--- node 2
    | ^   SNAT
    | |   --->
    v |
 endpoint

NodePort에서 Source IP 사용하기

Kubernetes에는 클라이언트 Source IP를 보존할 수 있습니다. service.spec.externalTrafficPolicy 값을 Local 로 설정하면 로컬 엔드 포인트에 대한 요청 만 프록시하고 트래픽을 다른 노드로 전달하지 않으므로 원래 소스 IP 주소를 유지합니다. 만약 로컬 엔드 포인트가 없다면 노드에 보낸 패킷은 드랍됩니다. 패킷 처리 규칙에서 올바른 Source IP에 의존 할 수 있으므로 패킷을 끝점까지 전달할 수 있습니다.

service.spec.externalTrafficPolicy 값이 Local 로 설정된 경우, NodePort 통신방식은 다음과 같습니다.

Clinet가 node2:nodePort로 패킷을 보낸다. Endpoint가 없으므로 패킷은 드랍된다. Clinet가 node1:nodePort에 패킷을 보낸다. node1은 패킷을 올바른 source IP로 엔드 포인트로 라우팅합니다.

        client
       ^ /   \
      / /     \
     / v       X
   node 1     node 2
    ^ |
    | |
    | v
 endpoint

Weave-net 이슈

weave에서 service.spec.externalTrafficPolicy 의 Local 을 지원하지 못하는 문제 발생합니다. weave env에 NO_MASQ_LOCAL 값을 “1”로 설정하면 사용할 수 있습니다. 기본값은 0

https://github.com/weaveworks/weave/issues/2924#issuecomment-407827430

ExternalIP 이슈

service.spec.externalIP를 지정하는 경우, NodePort를 사용하지 않고 ServicePort를 사용하면 SourceIP를 찾아올 수 없습니다. 이유는 externalIP 의 service port를 사용하게 되면 Service externalIP를 바라보며 SourceIP은 꼭 NodePort를 사용해야 Ingress Traffic이 도착합니다.

참고

https://kubernetes.io/docs/tutorials/services/source-ip/