Published on

Azure Private Endpoint DNS 꼬임으로 NXDOMAIN 해결하기

Authors

서론

Azure Private Endpoint(이하 PE)를 붙였는데 애플리케이션이 갑자기 NXDOMAIN(존재하지 않는 도메인)으로 실패하는 경우가 있습니다. 더 난감한 건 같은 VNet 안에서는 되다가, 다른 VNet/온프레미스/허브-스포크 일부 구간에서만 깨지거나, 어떤 클라이언트는 되고 어떤 클라이언트는 안 되는 “DNS 꼬임” 형태로 나타난다는 점입니다.

이 글은 PE를 붙인 뒤 특정 FQDN이 NXDOMAIN으로 떨어지는 상황을 전제로, 어디에서 DNS가 끊기는지(클라이언트 → 재귀 DNS → 조건부 포워더 → Azure 제공 DNS/Private DNS Zone) 체인을 분해해 진단하고, 가장 흔한 구성 실수(Private DNS Zone 미연결, 잘못된 포워딩, 레코드/존 충돌, 캐시)까지 포함해 복구하는 방법을 정리합니다.

> 네트워크/프라이빗 링크 계열 DNS 이슈는 “어디서 어떤 이름이 어떤 IP로 해석되어야 하는지”를 끝까지 추적하는 게 핵심입니다. 비슷한 결의 트러블슈팅으로는 EKS Pod STS AssumeRole 타임아웃 - NAT·PrivateLink·DNS 글도 참고가 됩니다.

NXDOMAIN이 의미하는 것: “접근 차단”이 아니라 “이름 해석 실패”

먼저 NXDOMAIN은 방화벽/NSG/라우팅 문제가 아니라 DNS가 해당 이름을 ‘없다’고 답한 상태입니다.

  • SERVFAIL: DNS 서버가 오류(권한/포워딩/타임아웃)
  • NXDOMAIN: 상위/권한 서버가 “그 이름은 존재하지 않음”
  • NOERROR + 빈 답: 존재하지만 레코드 없음(상황에 따라)

PE 시나리오에서 NXDOMAIN은 보통 아래 중 하나입니다.

  1. Private DNS Zone이 없거나, VNet 링크가 빠짐
  2. 온프레 DNS(또는 커스텀 DNS)가 Azure Private DNS로 조건부 포워딩을 안 함
  3. 같은 존에 Public/Private 레코드가 섞이거나, 다른 DNS 서버가 ‘없다(NXDOMAIN)’를 먼저 응답
  4. 클라이언트/리졸버 캐시가 꼬여서 계속 NXDOMAIN을 재사용

기본 구조 이해: PE + Private DNS Zone이 하는 일

예를 들어 Storage Account에 Private Endpoint를 붙이면, 원래는

  • mystorage.blob.core.windows.net → Public IP

이어야 하는데, PE 환경에서는

  • mystorage.blob.core.windows.netPrivate IP(예: 10.x.x.x)

로 해석되어야 합니다.

이를 위해 Azure는 보통 다음을 사용합니다.

  • Private DNS Zone: privatelink.blob.core.windows.net
  • A 레코드: mystorage10.x.x.x
  • 그리고 중요한 연결: VNet에서 mystorage.blob.core.windows.net 질의가 오면 CNAME 체인을 통해 mystorage.privatelink.blob.core.windows.net로 이어지고, 최종적으로 사설 IP를 받게 됨

여기서 핵심은 질의가 Private DNS Zone까지 도달해야 한다는 점입니다.

재현/진단 1: 클라이언트에서 “어느 DNS 서버에 물어보는지”부터 고정

NXDOMAIN 진단은 무조건 “어느 DNS 서버가 NXDOMAIN을 줬는지”를 확인해야 합니다.

Linux에서 확인

# 현재 사용 중인 DNS 서버 확인
cat /etc/resolv.conf

# 특정 DNS 서버를 지정해서 질의
nslookup mystorage.blob.core.windows.net 168.63.129.16

# dig로 더 자세히
dig @168.63.129.16 mystorage.blob.core.windows.net +noall +answer +authority +comments
  • 168.63.129.16은 Azure에서 자주 등장하는 내부 리졸빙 경로(플랫폼 IP)로, VM이 Azure 제공 DNS를 사용하도록 구성되어 있을 때 의미가 있습니다.
  • 하지만 VNet DNS를 커스텀 DNS로 바꿨다면, 실제로는 온프레 DNS/도메인 컨트롤러/자체 BIND로 질의가 나갑니다. 이 경우 @168.63.129.16으로 찍어보면 “Azure 쪽은 정상이네?”라는 착시가 생길 수 있으니, 반드시 실제 리졸버에도 물어봐야 합니다.

Windows에서 확인

ipconfig /all

Resolve-DnsName mystorage.blob.core.windows.net
Resolve-DnsName mystorage.blob.core.windows.net -Server 10.0.0.4

여기서 특정 DNS 서버(예: 10.0.0.4)가 NXDOMAIN을 주면, 문제는 클라이언트가 아니라 그 DNS 서버의 포워딩/존 구성입니다.

재현/진단 2: Private DNS Zone과 VNet 링크부터 점검

Azure Portal/CLI에서 아래를 확인합니다.

  • Private DNS Zone이 존재하는가?
  • 해당 Zone에 A 레코드가 생성되어 있는가?
  • Private DNS Zone이 문제 구간의 VNet과 Virtual network link로 연결되어 있는가?

Azure CLI 예시

# Private DNS Zone 목록
az network private-dns zone list -o table

# 특정 존 레코드 확인 (예: blob)
az network private-dns record-set a list \
  -g <rg> -z privatelink.blob.core.windows.net -o table

# VNet 링크 확인
az network private-dns link vnet list \
  -g <rg> -z privatelink.blob.core.windows.net -o table

흔한 실수

  • PE를 만들 때 “Integrate with private DNS zone”을 체크하지 않았거나, 다른 RG/구독에 Zone이 있는데 링크가 누락됨
  • 허브 VNet에만 링크하고 스포크 VNet에는 링크하지 않았는데, 스포크에서 직접 Azure 제공 DNS로 질의하는 구조라면 스포크는 NXDOMAIN

진단 3: 커스텀 DNS(온프레/VM DNS) 사용 시 조건부 포워딩이 핵심

VNet DNS 서버를 커스텀으로 지정해 둔 경우(Active Directory DNS, BIND, Infoblox 등), Azure Private DNS Zone은 자동으로 참조되지 않습니다.

이때 정답은 보통 둘 중 하나입니다.

  1. Azure DNS Private Resolver를 도입하고, 온프레/커스텀 DNS에서 조건부 포워딩
  2. 커스텀 DNS 서버 자체에 privatelink.* 존을 호스팅하거나 포워딩 체인을 구성

조건부 포워딩 대상 도메인(대표 예시)

서비스마다 PrivateLink 존이 다릅니다.

  • Storage Blob: privatelink.blob.core.windows.net
  • Storage File: privatelink.file.core.windows.net
  • Key Vault: privatelink.vaultcore.azure.net
  • Azure SQL: privatelink.database.windows.net
  • Container Registry: privatelink.azurecr.io

NXDOMAIN이 나는 FQDN이 무엇인지에 따라, 어떤 privatelink 존을 포워딩해야 하는지가 달라집니다.

대부분의 Azure PaaS는 공개 FQDN(xxx.blob.core.windows.net)이 CNAME으로 사설 존(xxx.privatelink.blob.core.windows.net)으로 이어지는 구조입니다. 즉, 커스텀 DNS가 CNAME을 따라가다가 privatelink.blob.core.windows.net를 해석하지 못하면 NXDOMAIN/SERVFAIL이 납니다.

진단 4: NXDOMAIN 캐시(특히 systemd-resolved, nscd, 브라우저) 제거

DNS에서 NXDOMAIN도 캐시됩니다. 설정을 고쳤는데도 계속 NXDOMAIN이 나오는 경우가 많습니다.

Linux 캐시 플러시

# systemd-resolved
sudo resolvectl flush-caches

# nscd 사용 시
sudo systemctl restart nscd

Windows 캐시 플러시

ipconfig /flushdns

또한 애플리케이션 런타임(Java DNS 캐시 TTL, .NET DNS 캐시, Envoy/CoreDNS 캐시 등)도 영향을 줄 수 있으니, 재현 환경에서는 프로세스 재시작까지 포함하는 것이 안전합니다.

대표 원인별 해결책

1) Private DNS Zone 링크 누락: “되는 VNet”과 “안 되는 VNet”이 갈림

증상

  • 허브 VNet의 VM에서는 정상
  • 스포크 VNet의 VM에서는 NXDOMAIN

해결

  • privatelink.<service> Private DNS Zone을 스포크 VNet에도 링크합니다.
  • 허브-스포크에서 DNS를 중앙집중형으로 쓰는 경우, 스포크의 DNS 서버가 허브에 있더라도 “질의가 결국 어떤 리졸버로 가는지”를 기준으로 링크/포워딩을 맞춥니다.

2) 커스텀 DNS에서 포워딩 누락: Azure 밖(온프레/다른 클라우드)에서 주로 발생

증상

  • Azure VM(기본 DNS 사용)은 정상
  • 온프레미스/사내망/ExpressRoute 구간에서 NXDOMAIN

해결

  • 온프레 DNS에 privatelink.* 조건부 포워더를 추가하고, 대상은 Azure DNS Private Resolver(권장) 또는 Azure 내 포워딩 VM(DNS Forwarder)로 지정합니다.

> 네트워크 경로는 열려 있는데 이름 해석만 실패하는 유형은, 클라우드가 달라도 자주 반복됩니다. DNS/프라이빗 링크가 결합된 장애 패턴은 EKS에서 503 Service Unavailable 원인 10분 진단처럼 “레이어별로 잘라 확인”하는 접근이 유효합니다.

3) Public DNS로 새어나감(split-brain 실패): 어떤 리졸버는 Public을, 어떤 리졸버는 NXDOMAIN

증상

  • 어떤 서버는 Public IP로 해석(접속은 타임아웃/403/인증서 오류 등으로 변형)
  • 어떤 서버는 NXDOMAIN

해결

  • 사설망에서 해당 서비스 FQDN이 반드시 사설 IP로 해석되도록, 리졸빙 경로를 단일화합니다.
  • 커스텀 DNS가 있다면, privatelink 존 포워딩이 정확한지 확인하고, 필요 시 *.core.windows.net을 무리하게 포워딩하지 말고 최소 단위(privatelink 존)만 포워딩합니다.

4) 잘못된 존/레코드 수동 생성: A 레코드가 다른 IP를 가리킴

증상

  • NXDOMAIN은 아닌데 사설 IP가 엉뚱함
  • 혹은 레코드가 삭제/재생성되며 간헐적

해결

  • 가능하면 PE 생성 시 Private DNS Zone 자동 통합을 사용하고, 레코드를 수동으로 관리해야 한다면 변경 이력을 명확히 남깁니다.
  • 동일 이름 레코드가 다른 Zone(다른 RG/구독)에도 존재하지 않는지 점검합니다.

빠른 체크리스트(운영자용)

1분 내 확인

  • 클라이언트가 실제로 질의하는 DNS 서버는 어디인가?
  • 그 DNS 서버가 NXDOMAIN을 주는가?

10분 내 확인

  • privatelink.<service> Private DNS Zone 존재/레코드 존재/링크 존재?
  • 커스텀 DNS라면 privatelink.<service> 조건부 포워딩 존재?

30분 내 확인

  • 허브-스포크/온프레-클라우드 경로에서 “어느 리졸버가 권한을 갖는지” 체인 문서화
  • 캐시 플러시 후 재현

마무리: NXDOMAIN은 ‘DNS 설계 불일치’의 신호

Azure Private Endpoint의 DNS 문제는 단순히 “레코드 하나 추가”로 끝나는 경우도 있지만, 실제 운영 환경에서는 VNet 링크, 커스텀 DNS, 조건부 포워딩, 캐시, 중앙 DNS 패턴이 얽히면서 NXDOMAIN이 발생합니다. 해결의 핵심은 다음 두 문장으로 요약됩니다.

  1. NXDOMAIN을 준 DNS 서버를 특정하고
  2. 그 서버가 privatelink 존을 올바르게 해석하도록(VNet 링크 또는 조건부 포워딩) 경로를 맞춘다.

비슷하게 “네트워크는 열렸는데 특정 클라우드 엔드포인트만 이상하다”는 패턴은 다른 환경에서도 반복됩니다. 프라이빗 링크/DNS가 얽힌 트러블슈팅 감각을 확장하려면 EKS Pod STS AssumeRole 타임아웃 - NAT·PrivateLink·DNS도 함께 읽어보는 것을 권합니다.