가내수공업 클러스터 - 헤어핀 NAT 이슈 해결

Yany Choi·2024년 6월 1일
0

Kubernetes

목록 보기
3/3

작년 8월 당근 인턴십을 끝내고 개인공부를 위해서 개인랩의 필요성을 절절히 느껴 기존에 사용하던 워크스테이션에 Proxmox를 설치하고 클러스터를 구축했다. 그리고 마침 학교 졸업작품에 만들 서비스를 마이크로서비스로 처음부터 만들고 싶다는 팀원들의 의사에 개인랩을 용도변경했다. 이 과정에서 네트워크 관련 이슈가 있었고, 이것에 대해 얘기하려고 한다.

TL;DR

개인랩을 이전하면서 통신사 공유기가 바뀌었고, 이 과정에서 내부 네트워크에서 외부로 DNAT된 내부 엔드포인트를 접근할 수 없었다.
이러한 상황을 해결하기 위해 내부용 DNS를 구축했고, 이제 내부 대역의 외부 도메인은 공유기의 내부 IP를 가리켜 상황을 해결했다.

배경

처음에는 펜션 (조부모님이 운영하는 펜션, 여기에 CCTV 녹화 시스템 설치한다고 개인랩 관련 머신들이 전부 펜션에 있었다.) 네트워크를 사용해서 운영했으며, 문제가 없었다.

펜션은 동네 전신주에 있는 유플러스 FTTH 관련 단자함이 있는 듯 했으며 거기서 창문을 통해 광케이블이 들어와 모뎀으로 연결되는 듯 했다.

그러나 개인랩에 웹서비스를 올리면 포트포워딩을 많이 해야하고, 이전에 프로젝트를 진행했을 때 공유기 관련 설정을 자주 만져야 하고, 이후 이사갈 가능성이 높아서 펜션에서 집으로 서버를 이관했다. 다행히도 집 또한 유플러스 인터넷도 사용하고 있어 설정을 옮기는데 큰 어려움은 없었다.

이후 Proxmox에 OpenVPN 서버, FRR 라우터, K8s 노드를 7개 (master 3개, worker 4개)까지 띄우기까지도 아무 문제 없었다.
그렇게 ArgoCD, istio를 올리고 cert-manager로 TLS 인증서를 받으려는데...

TLS 인증서 발급을 위한 요청이 열어놓은 요청으로 도착하지 않는다.

문제 파악

cert-manager의 self-check 실패

cert-manager는 ACME 프로토콜을 활용해 쿠버네티스 클러스터 내에서 TLS 인증서 갱신을 손쉽게 해주는 툴이다.

ACME는 ISRG에서 Lets' Encrypt TLS 인증서 갱신을 자동적으로 진행하기 위해 만든 프로토콜이며, 아래처럼 동작한다:

  1. Let's Encrypt에서 cert-manager ACME Client에 랜덤 토큰을 할당한다.
  2. 인증서를 원하는 도메인에http://<도메인>/.well-known/acme-challenge/<토큰> 엔드포인트를 노출한다.
  3. Let's Encrypt에서 해당 엔드포인트를 접근해서 성공하면, 인증이 성공해 인증서를 issue한다.

cert-manager는 프로토콜을 이렇게 구현했다:

  1. Issuer/ClusterIssuer에서 cert-manager ACME Client에 랜덤 토큰을 할당한다.
  2. 인증서를 원하는 서비스를 지정하면 해당 서비스 IP에 http://<도메인>/.well-known/acme-challenge/<토큰> 엔드포인트를 노출하는 Pod를 생성한다.
  3. 내부에서 해당 엔드포인트로 접근해 정상적으로 다음 단계로 넘어갔는지 확인한다.
  4. Issuer/ClusterIssuer에서 해당 엔드포인트를 접근해서 성공하면, 인증이 성공해 인증서를 issue한다.
  5. 이 과정을 Challenge마다 도메인 별로 반복하고, Order 아래의 모든 Challenge가 완료되면 CertificateRequest를 만들고 이에 기반해 CertificateSecret을 생성한다.

그러나 생성된 Pod에서 요청을 전혀 전달받지 못하고 self-check부터 실패하고 있었다.

그러나 트러블슈팅하면서 이상한 점이 있는 것을 발견했는데, 노트북을 핫스팟으로 연결해서 노출된 엔드포인트로 접근할 때 정상적으로 접속이 됐는데, 집 안에서 공유기를 키고 접속하니 접근이 안됐다.

NAT 헤어핀 (NAT loopback)?

문제는 공유기 별로 내부 네트워크에서 DNAT (포트포워딩)으로 노출된 엔드포인트로 접근하는 방식을 처리하는 것에 차이가 있다는 것이었다. 이러한 접근 방식을 처리해주는 것을 NAT 헤어핀 (또는 NAT loopback)이라 하는데, 이 과정에서 dstIP가 내 내부 네트워크일때 패킷을 외부로 보내지 않고 내부로 돌려준다.
이것이 펜션의 유플러스 라우터로는 지원이 됐으나, 집에서는 지원하지 않았다.

해결

결국 해결책은 공유기 대신 패킷을 다시 내부로 돌려줄 방법이 필요했는데, 여기서 가장 빠른 해결책은 내부 네트워크용 DNS 서버를 만드는 것이다.

그러나 집에서 가족들이 다 같이 사용하는 네트워크인데, 내가 맘대로 휘두를 개인랩에 DNS 서버를 구축하면 마음대로 관리하기 힘들 것 같아 집에 남아도는 라즈베리파이에 bind9으로 DNS을 간단하게 구축하고 해결했다.

후기

펜션 공유기가 NAT 헤어핀을 지원했던게 상황판단을 더 느리게 만드는데 일조했다. 이번 일을 겪고 나니 당연하게 여겼던 일들을 의심하는 습관이 좀 더 꼼꼼한 엔지니어를 만들어줄 것 같아 의식적으로 개선하려고 한다.

그리고 통신사 공유기에 대한 마음이 한 층 식었다. 그렇다고 사제 공유기를 쓰자니 통신사 공유기 특유의 속도 증폭 때문에 MAC주소가 바뀌면 속도가 100Mbps를 넘지 못한다고 하니, 앞으로 통신사 공유기들도 좀 개선됐으면 좋겠다.

profile
생각하자

0개의 댓글