[K8S] NAT 루프백 문제 분석 (SNAT)

Haruband's CodeBook·2021년 8월 18일
2

k8s

목록 보기
2/9

오늘은 어떤 국가의 지역 클라우드 서비스를 이용하여 쿠버네티스 클러스터를 구축하던 중 발생했던 NAT 루프백 문제(Hairpin NAT)를 파악하고 해결했던 과정에 대해 간단히 소개하고자 한다. 일반적으로는 크게 신경쓰지 않아도 되는 문제인데, 해당 국가의 클라우드 서비스의 설정 오류로 예상치 못하게 문제가 발생하였다.

어떠한 문제가 발생했는가???

필요한 가상머신을 몇 개 할당받고 kubespray 로 쿠버네티스를 설치한 후, 관련 서비스들을 모두 배포하고나서 mongodb, minio, kafka 등이 잘 동작하는 것을 확인한 다음, 클러스터 내부에 있는 젠킨스에서 몇 가지 컨테이너 이미지를 빌드한 후 클러스터 내부 레지스트리로 배포하려고 하는데 갑자기 로그인이 되지 않는 문제가 발생하였다. 레지스트리는 https 를 사용 중이어서 외부 도메인 주소를 이용하여 접근하였다. 다른 모든 서비스는 잘 동작 중이었고, 외부에서는 클러스터 내부 레지스트리로 로그인이 잘 되었기 때문에 내부에서 외부 도메인 주소로 접근하는 것에 문제가 있다고 판단하였다. 지금까지 상황에 대해 간단히 정리해보면 다음과 같다.

  1. 클러스터 내부 IP 주소(Pod/Service)로는 아무 문제 없이 통신이 가능하다.
  2. 외부에서 클러스터 외부 IP 주소로는 아무 문제 없이 통신이 가능하다.
  3. 내부에서 클러스터 외부 IP 주소로만 통신이 불가능하다.

클라우드의 라우터 설정을 열람할 수 없는 상황이어서 정확히 판단할 수는 없었지만, NAT 루프백 문제라고 충분히 의심할 수 있는 상황이었다.

어떻게 문제가 발생했는가???

NAT 루프백 문제인지 정확히 파악하기 위해, node2 에서 node1 의 외부 IP 주소로 curl 을 이용하여 접속할 때 패킷이 전달되는 과정에 대해 자세히 분석해보았다.

클러스터 노드 IP 설정은 다음과 같다고 가정해보자.

  • node1 내부 IP 192.168.10.100
  • node2 내부 IP 192.168.10.101
  • 라우터 내부 IP 192.168.10.1

그리고 라우터에 설정된 DNAT 설정은 다음과 같다고 가정해보자.

  • 169.233.100.10 ==> 192.168.10.100
  • 169.233.100.11 ==> 192.168.10.101

이제 node2 에서 node1 로 패킷이 전달되는 과정을 살펴보자.

  1. node2 에서 출발지 주소(192.168.10.101)와 목적지 주소(169.233.100.10)인 패킷을 송신한다.
  2. 라우터에서 DNAT 설정에 의해 목적지 주소를 192.168.10.100 으로 변경한다.
  3. node1 에서 출발지 주소(192.168.10.101)와 목적지 주소(192.168.10.100)인 패킷을 수신한다.
  4. node1 에서 출발지 주소(192.168.10.100)와 목적지 주소(192.168.10.101)인 응답 패킷을 송신한다.
  5. node2 에서 출발지 주소(192.168.10.100)와 목적지 주소(192.168.10.101)인 응답 패킷을 수신한다.

위의 과정을 살펴보면, node2 에서는 출발지 주소(192.168.10.101)와 목적지 주소(169.233.100.10)로 소켓이 생성되어있는데 응답 패킷의 출발지 주소가 169.233.100.10 이 아닌 192.168.10.100 이기 때문에 응답 패킷을 받지 못하는 문제가 발생한 것이다. 이는 node1 에서 송신한 응답 패킷의 목적지 주소가 192.168.10.101 이기 때문에 응답 패킷이 라우터의 DNAT 역변환 과정을 거치지 않고 바로 node2 로 전달된 것이 원인이다. 즉, 전형적인 NAT 루프백 문제인 것을 확인하였다.

어떻게 문제를 해결했는가???

해당 문제를 해결할 수 있는 방법은 두 가지 정도이다.

  1. 라우터 SNAT 설정 추가
  2. 내부 DNS 설정 추가

첫 번째가 보편적으로 사용되는 NAT 루프백을 해결하는 방식이다. 우리도 첫 번째 방식으로 라우터에 SNAT 설정을 추가하여 해당 문제를 해결하였다. 라우터에 SNAT 설정을 추가한 경우 패킷이 어떻게 전달되는지 살펴보자.

  1. node2 에서 출발지 주소(192.168.10.101)와 목적지 주소(169.233.100.10)인 패킷을 송신한다.
  2. 라우터에서 DNAT 설정에 의해 목적지 주소를 192.168.10.100 으로 변경한다.
  3. 라우터에서 SNAT 설정에 의해 출발지 주소를 192.168.10.1 으로 변경한다.
  4. node1 에서 출발지 주소(192.168.10.1)와 목적지 주소(192.168.10.100)인 패킷을 수신한다.
  5. node1 에서 출발지 주소(192.168.10.100)와 목적지 주소(192.168.10.1)인 응답 패킷을 송신한다.
  6. 라우터에서 SNAT 설정에 의해 목적지 주소를 192.168.10.101 으로 변경한다.
  7. 라우터에서 DNAT 설정에 의해 출발지 주소를 169.233.100.10 으로 변경한다.
  8. node2 에서 출발지 주소(169.233.100.10)와 목적지 주소(192.168.10.101)인 응답 패킷을 수신한다.

이처럼 라우터에 SNAT 설정을 추가하여 응답 패킷을 무조건 라우터가 먼저 받게하면 필요한 역변환 과정을 거치게 되어 해당 문제는 깔끔하게 해결된다. 혹시 라우터를 조작하기 힘든 경우에는 두 번째 해결 방식도 가능하다. 이는 내부 DNS 에 해당 도메인을 외부 IP 주소가 아닌 내부 IP 주소로 등록하여 불필요한 DNAT/SNAT 과정을 거칠 필요가 없게 만드는 것이다.

profile
커널, 컴파일러, 가상화, 컨테이너, 쿠버네티스, ...

0개의 댓글