Cloud NAT 문제 해결

이 가이드는 워크로드 (포드 또는 VM)가 Cloud NAT를 사용하여 외부 네트워크에 액세스할 수 없는 이유를 진단하는 데 도움이 됩니다. 개발자는 주로 CloudNatGateway 리소스와 상호작용합니다. 이 리소스의 상태는 디버깅을 위한 기본 정보 소스입니다.

시작하기 전에

Cloud NAT 구성을 문제 해결하려면 다음이 필요합니다.

  • 필요한 ID 및 액세스 역할입니다. 프로젝트 IAM 관리자에게 다음 역할 중 하나 또는 둘 다를 부여해 달라고 요청하세요.
    • Cloud NAT 뷰어 (cloud-nat-viewer): 이 역할은 Cloud NAT 리소스에 대한 읽기 전용 액세스를 제공합니다. 이 역할은 문제 진단을 시작하는 데 도움이 됩니다.
    • Cloud NAT 개발자 (cloud-nat-developer): 이 역할은 애플리케이션 운영자가 할당된 프로젝트 내에서 Cloud NAT 객체를 생성, 읽기, 업데이트, 삭제 (CRUD)하는 데 필요한 권한을 제공합니다. 이 역할을 사용하면 이 페이지에 설명된 여러 수정사항을 실행할 수 있습니다.
    • 일부 특정 진단 조치 및 수정에는 추가 역할이 필요할 수 있습니다.

초기 진단

오류 코드를 살펴보기 전에 기본 리소스가 있고 연결 가능한지 확인하세요.

명령어:

kubectl get cloudnatgateway GATEWAY_NAME -n PROJECT_NAMESPACE -o yaml

다음을 바꿉니다.

  • GATEWAY_NAME: CloudNatGateway 리소스의 이름입니다.
  • PROJECT_NAMESPACE: 프로젝트의 네임스페이스입니다.

상태 조건 확인: 정상 게이트웨이에는 다음 조건이 True로 설정되어 있어야 합니다.

  • Ready: 전반적인 상태입니다.
  • SubnetsReady: IP 풀 구성이 유효합니다.
  • PerimeterConfigurationReady: 업스트림 네트워크 인프라가 구성됩니다.
  • EgressRoutesReady: 포드의 라우팅 정책이 활성 상태입니다.

이러한 값이 False인 경우 상태 출력에서 reasonmessage 필드를 확인하고 다음 섹션의 표를 참고하세요.

오류 코드 참조 및 해결

kubectl get cloudnatgateway에서 반환하는 오류 코드는 세 가지 기본 카테고리로 분류됩니다.

서브넷 오류 (SubnetsReady이 False임)

이 조건은 게이트웨이에 할당된 IP 주소 풀에 문제가 있음을 나타냅니다.

오류 코드 의미 해결 단계
CloudNATSelectorFieldOverlapsCode 구성 충돌 이 게이트웨이의 workloadSelector가 프로젝트의 다른 게이트웨이와 동일한 워크로드와 일치합니다. 트래픽을 결정론적으로 라우팅할 수 없습니다.
  1. 프로젝트의 모든 Cloud NAT 게이트웨이를 나열합니다. kubectl get cloudnatgateway
  2. 이 게이트웨이의 workloadSelector를 다른 게이트웨이와 비교합니다.
  3. 하나의 포드/VM이 두 개 이상의 게이트웨이에 의해 선택되지 않도록 라벨을 수정합니다.
CloudNATSubnetRefsFieldInvalidCode

잘못된 서브넷입니다. subnetRefs에 지정된 서브넷을 사용할 수 없습니다. 일반적인 이유:

  • 서브넷이 존재하지 않습니다.
  • 서브넷이 Ready 상태가 아닙니다.
  • 서브넷이 Leaf 유형이 아닙니다.
  1. 서브넷이 있는지 확인합니다. kubectl get subnet <SUBNET_NAME>
  2. 서브넷 상태가 Ready인지 확인합니다.
  3. 서브넷 typeLeaf인지 확인합니다 (Cloud NAT는 루트 또는 루프백 서브넷을 사용할 수 없음).
CloudNATSubnetAlreadyInUseCode 서브넷 충돌 요청한 서브넷이 이미 다른 Cloud NAT 게이트웨이에 '소유'되어 있습니다. 서브넷은 한 번에 하나의 게이트웨이에만 연결할 수 있습니다.
  1. 이 게이트웨이에 다른 서브넷을 선택하세요.
  2. 또는 먼저 다른 게이트웨이에서 서브넷을 삭제합니다.
UNETAPIServerErrorCode 시스템 오류 컨트롤러가 API 서버와 통신하여 서브넷을 검증할 수 없습니다. 조치: 일시적인 플랫폼 문제일 수 있습니다. 문제가 계속되면 플랫폼 관리자에게 문의하세요.

경계 구성 오류 (PerimeterConfigurationReady이 False임)

이 조건은 경계 게이트웨이의 상태를 반영합니다.

오류 코드 의미 해결 단계
NET-E0305 구성 충돌 (위와 동일) 선택기가 중복되면 시스템에서 올바른 라우팅 그룹을 계산할 수 없습니다.
  1. 프로젝트의 모든 Cloud NAT 게이트웨이를 나열합니다. kubectl get cloudnatgateway
  2. 이 게이트웨이의 workloadSelector를 다른 게이트웨이와 비교합니다.
  3. 하나의 포드/VM이 두 개 이상의 게이트웨이에 의해 선택되지 않도록 라벨을 수정합니다.
NET-E0301 리소스 소진 / 노드 장애. 시스템에서 구성을 만들었지만 정상적인 물리 노드에 이그레스 IP를 할당할 수 없습니다. 이는 일반적으로 서브넷에 IP가 부족하거나 게이트웨이 노드가 다운되었음을 의미합니다.
  1. [서브넷](/distributed-cloud/hosted/docs/latest/gdch/platform/pa-user/subnets-overview) 사용량을 확인합니다. 가득 차 있나요?
  2. 서브넷에 사용 가능한 IP가 있고 Ready인 경우 플랫폼 측 인프라 장애 (예: 사용 가능한 정상 게이트웨이 노드가 없음)를 나타냅니다. 조치: 플랫폼 관리자에게 문의합니다.
NET-E0001 시스템 오류 컨트롤러 통신 실패입니다. 조치: 플랫폼 관리자에게 문의합니다.

이그레스 경로 오류 (EgressRoutesReady이 False임)

이 조건은 클러스터 내부의 라우팅 정책 상태를 반영합니다.

오류 코드 의미 해결 단계
NET-E0305 구성 충돌 (위와 동일)
  1. 프로젝트의 모든 Cloud NAT 게이트웨이를 나열합니다. kubectl get cloudnatgateway
  2. 이 게이트웨이의 workloadSelector를 다른 게이트웨이와 비교합니다.
  3. 하나의 포드/VM이 두 개 이상의 게이트웨이에 의해 선택되지 않도록 라벨을 수정합니다.
NET-E0304 프로그래밍 실패. 시스템에서 특정 게이트웨이 IP의 라우팅 규칙 (BPF)을 프로그래밍하지 못했습니다.

작업: 내부 프로그래밍 오류 또는 상태 불일치입니다.

  1. 게이트웨이를 사소하게 업데이트 (예: 라벨 수정)하여 조정이 트리거되도록 합니다.
  2. 문제가 계속되면 플랫폼 관리자에게 문의하세요.

그 외 자주 발생하는 문제

게이트웨이 상태가 Ready: True이지만 트래픽이 계속 실패하는 경우 다음과 같은 일반적인 잘못된 구성을 확인하세요.

프로젝트 수준 권한 누락

프로젝트에 트래픽 이그레스 권한이 명시적으로 부여되어야 합니다.

  • 확인: 프로젝트 리소스에 networking.gdc.goog/enable-default-egress-allow-to-outside-the-org: "true" 라벨이 있나요?
  • 해결 방법: 프로젝트 관리자에게 이 라벨을 적용해 달라고 요청하세요.

VM 주석 누락 (가상 머신만 해당)

VM은 표준 포드 이그레스 경로를 우회하므로 Cloud NAT를 사용하려면 명시적인 안내가 필요합니다.

  • 확인: VM의 VirtualMachineExternalAccess (VMEA) 객체에 egress.networking.gke.io/use-cloud-nat: "true" 주석이 있나요?
  • 수정: VMEA 객체에 주석을 추가합니다.

Standard 클러스터 노드 이그레스

Standard 클러스터를 실행하는 경우 노드 자체에 이그레스 권한이 필요합니다.

  • 확인: Cluster 객체에 cluster.gdc.goog/enable-node-egress-to-outside-the-org: "true" 라벨이 있나요?
  • 해결: 플랫폼 관리자에게 클러스터 객체에 라벨을 지정해 달라고 요청하세요.

기본 이그레스 NAT와 Cloud NAT 충돌

일반적인 구성 오류는 워크로드가 기존 기본 이그레스 NAT 메커니즘을 사용하도록 구성되어 있는 동시에 Cloud NAT 게이트웨이에 의해 선택될 때 발생합니다. 이 조합은 데이터 영역이 충돌하는 라우팅 명령어를 수신하여 패킷 손실이나 비결정적 라우팅 동작을 초래하는 충돌을 야기합니다.

포드 충돌 진단

Pod의 경우 특정 라벨을 추가하여 기본 이그레스 NAT를 사용 설정하는 것이 일반적입니다. Pod는 Cloud NAT 게이트웨이의 타겟이면서 이 라벨을 가질 수 없습니다.

  1. 타겟 포드 식별: 연결 문제가 있는 포드의 라벨을 가져옵니다.

    kubectl get pod <POD_NAME> -n <NAMESPACE> --show-labels
    
  2. 충돌하는 라벨 확인:

    • Cloud NAT 선택: 포드의 라벨이 네임스페이스에 있는 CloudNatGatewayworkloadSelector와 일치하나요?
    • 기본 이그레스 라벨: 포드에 egress.networking.gke.io/enabled: "true" 라벨이 있나요?

    조건: 둘 다 참이면 충돌이 발생합니다.

  3. 해결 방법: Cloud NAT가 독점 제어를 인계받을 수 있도록 포드 (또는 상위 배포/StatefulSet)에서 기존 기본 이그레스 라벨을 삭제합니다.

VM 충돌 진단

가상 머신의 경우 메커니즘이 다릅니다. VirtualMachineExternalAccess (VMEA) 객체가 있는 VM은 기본 액세스를 위해 구성되는 경우가 많습니다. Cloud NAT를 사용하려면 기본 경로를 사용 중지하고 Cloud NAT 경로를 사용 설정하는 주석을 추가하여 명시적으로 선택해야 합니다.

  1. VMEA 식별: VM과 연결된 VirtualMachineExternalAccess 객체를 찾습니다.

    kubectl get vmea -n <NAMESPACE>
    
  2. 누락된 주석 확인:

    • Cloud NAT 선택: VM의 라벨이 CloudNatGateway와 일치하나요?
    • 선택 주석: 주석 egress.networking.gke.io/use-cloud-nat: "true"의 VMEA를 확인합니다.

    조건: VM이 게이트웨이와 일치하지만 이 주석이 없으면 트래픽이 기본 이그레스 시스템과 충돌합니다.

  3. 해결 방법: VMEA 객체에 주석을 추가합니다.

    kubectl annotate vmea <VMEA_NAME> -n <NAMESPACE> egress.networking.gke.io/use-cloud-nat="true"