터널이 올라가 있고 API의 프라이빗 주소가 여전히 ping에 응답하는데도 kubectl은 이름 조회에서 실패합니다. 경로는 정상입니다. 클라이언트가 클러스터의 프라이빗 영역을 한 번도 들어본 적 없는 확인자에게 묻고 있습니다. 가장 많이 쓰이는 두 가지 수정은 가상 네트워크의 확인자를 모든 VPN 클라이언트로 푸시하거나, hosts 항목이나 조건부 포워더로 이름을 로컬에 고정하는 것입니다. 둘은 같은 증상을 서로 다른 책임으로 해결하며, 이를 혼동하면 엔드포인트가 다시 만들어질 때마다 hosts 파일을 편집하게 됩니다.

이름 확인과 도달성은 서로 다른 계층에서 실패합니다

무엇이든 바꾸기 전에 조회를 직접 실행하세요. Linux에서는 getent hosts, Windows에서는 nslookup이 클라이언트가 응답을 받는지 알려줍니다. 시간 초과나 NXDOMAIN은 확인자를 가리키고, 잘못된 주소의 응답은 오래된 레코드나 공용 경로로의 유출을 가리킵니다.

그다음 kubectl이 실제로 어느 서버에 연결하는지 확인하세요. kubeconfig 컨텍스트는 URL을 저장하고, VPN 경로는 그 URL을 다시 쓰지 않습니다. 컨텍스트가 공용 엔드포인트를 가리키면 DNS가 완벽해도 명령은 실패합니다.

getent hosts api.internal.example
kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}'
kubectl -v=8 get nodes 2>&1 | head -40

세 번째 신호는 조회 후 실패의 형태입니다. 프라이빗 주소로 확인된 뒤 TCP 시간 초과가 나면 방화벽이나 승인된 네트워크 문제입니다. 공용 주소로 확인되면 질의가 프라이빗 영역을 벗어난 것입니다. 이 세 결과를 분리해서 보세요. 각각 담당자가 다릅니다.

옵션 A: 가상 네트워크 확인자를 터널로 푸시하기

VPN 서버가 가상 네트워크 안에서 실행되면 클라이언트는 서버 호스트와 같은 확인자를 쓸 수 있습니다. OpenVPN Community에서는 서버가 DNS 옵션을 푸시합니다. Access Server도 같은 설정을 관리 화면에 노출하며, DNS 지시문이 프로필 안에 들어 있어 클라이언트는 프로필을 다시 내려받아야 합니다.

# server.conf
push "dhcp-option DNS 10.0.0.4"
push "route 10.0.0.4 255.255.255.255"

경로 줄은 split tunnel 프로필에서 중요합니다. 확인자 주소를 푸시하는 것과 그 주소에 도달하게 만드는 것은 다릅니다. 클러스터 서브넷만 터널을 지나면 10.0.0.4로 가는 질의는 로컬 LAN으로 나가 사라집니다. 확인자용 호스트 경로를 푸시하거나 그 서브넷을 터널에 포함하세요.

받는 쪽에도 정책이 있습니다. 클라이언트 주소 범위에서 도달 가능한 확인자라도 그 범위의 질의를 거부할 수 있고, 가상 네트워크에 연결된 프라이빗 영역은 그 네트워크의 DNS 경로로 들어온 클라이언트에만 응답합니다. 푸시 후 조회가 시간 초과되면 클라이언트를 다시 건드리기 전에 확인자 자체의 로그를 보세요.

클라이언트에서 무엇이 적용됐는지 확인하세요. systemd-resolved Linux에서는 resolvectl status, macOS에서는 scutil --dns, Windows에서는 ipconfig /all입니다. 푸시된 DNS 서버가 나타나지 않으면 프로필이 다시 로드되지 않은 것입니다.

옵션 B: hosts 항목과 조건부 전달

hosts 항목은 가능한 가장 작은 수정이며 가장 잘 깨집니다. 하나의 이름을 한 머신의 한 주소로 매핑하므로 데모에는 맞지만 프라이빗 엔드포인트나 그 IP가 다시 만들어지면 깨집니다. 팀의 다른 사람에게서 실제 공백을 숨기기도 합니다.

조건부 포워더는 모든 클라이언트에 DNS를 푸시하지 않고 더 잘 확장됩니다. dnsmasq는 한 영역을 VNet 확인자로 보내고 나머지는 그대로 둘 수 있습니다. 설정은 server=/cluster.internal/10.0.0.4입니다. Windows DNS에도 조건부 포워더가 있고, Windows 클라이언트는 같은 분할에 NRPT 규칙을 쓸 수 있습니다. 포워더에는 여전히 VNet 확인자로 가는 경로가 필요합니다.

전달은 일반 브라우징을 로컬에 유지하며, split tunnel에서는 이것이 중요합니다. 프라이빗 영역의 질의를 기록할 한 곳과, 포워더 호스트가 옮겨지면 깨질 한 곳을 제공합니다.

편의가 아니라 책임으로 선택하세요

VPN 프로필을 관리하고 API만이 아니라 모든 프라이빗 이름이 동작하길 원한다면 확인자를 푸시하세요. 클라이언트가 나머지 모두를 위해 로컬 DNS를 유지해야 하거나, VPN이 클러스터와 다른 팀의 관리 아래 있다면 포워더를 선택하세요.

hosts 항목은 진단이지 배포가 아닙니다. API에 도달할 수 있음을 증명하는 데 하나를 쓰고, 그다음 제거하고 확인자 경로를 고치세요. 그대로 두면 나중에 경로 질문이 보물찾기가 됩니다. 어떤 옵션을 고르든 영역, 확인자 주소, 질의를 나르는 경로를 적어 두세요.

API 엔드포인트 테스트, 이름만으로는 부족

조회가 성공하면 클러스터 CA로 API의 버전 엔드포인트를 가져오세요. curl --cacert ca.crt https://api.internal.example:6443/version은 TLS와 권한 부여 실패를 DNS와 구분합니다. 403은 이름과 연결이 동작하고 신원은 동작하지 않는다는 뜻입니다.

클라이언트 주소 범위가 클러스터의 승인된 네트워크나 방화벽에서 허용되는지도 확인하세요. 프라이빗 클러스터는 흔히 API 트래픽을 VNet이나 peered 범위에서만 받아들이므로, 다른 풀에서 주소를 할당하는 터널은 네트워크 계층에서 연결되고 API에서 버려집니다.

에스컬레이션할 때 네 가지 사실을 기록하세요. 클라이언트가 사용한 확인자, 그것이 반환한 주소, 선택한 kubeconfig 컨텍스트의 서버 URL, 처음 실패한 작업입니다. 그 기록은 다음 엔지니어에게 DNS, 라우팅, 방화벽 정책 중 무엇을 바꿀지 알려 주고, 다음 hosts 파일 편집을 막습니다.

조회로 시작하고, 영역 소유자에 맞는 확인자 경로를 고른 뒤 엔드포인트를 검증하세요. 셋 다 통과하면 남은 문제는 권한 부여이지 이름 확인이 아닙니다.

관련 글