Google Distributed Cloud 네트워킹 문제 해결

이 페이지에서는 Google Distributed Cloud의 네트워킹 문제를 해결하는 방법을 설명합니다. 추천 도구와 함께 일반 문제 해결 정보와 안내가 제공됩니다. MetalLB에 대한 DNS 문제 해결 정보와 몇 가지 일반적인 문제도 포함됩니다.

추가 지원이 필요하면 Cloud Customer Care에 문의하세요.

네트워크 연결 문제 해결

GKE Enterprise 네트워킹은 물리적 네트워크 인프라를 사용합니다. 예를 들어 MetalLB에는 Gratuitous ARP를 인정하는 스위치가 사용되고, 경계 게이트웨이 프로토콜(BGP)를 사용하는 조합된 부하 분산에는 라우터 기능이 사용됩니다. 또한 모든 라우터가 서로 원활하게 통신할 수 있어야 합니다. GKE 클러스터에 네트워킹 문제가 발생하면 문제가 GKE Enterprise 구성요소 또는 자체 인프라에서 발생했는지 식별해야 합니다.

먼저 문제의 범위를 확인한 후 영향을 받는 구성요소를 식별합니다. 문제의 범위는 주체(문제가 시작된 위치), 대상(문제의 대상), 네트워크 계층 중 하나일 수 있습니다.

주체의 범위는 다음 중 하나일 수 있습니다.

  • 클러스터 전체의 모든 노드(또는 hostNetwork 포드)
  • 클러스터 전체의 모든 포드
  • 단일 노드 또는 노드 집합의 모든 포드
  • 동일 배포 또는 DaemonSet의 모든 포드
  • 클러스터 외부의 클라이언트

대상의 범위는 다음 중 하나 이상일 수 있습니다.

  • 동일 클러스터의 다른 모든 포드 IP 주소
  • 동일 노드의 다른 모든 포드 IP 주소
  • 동일 클러스터의 ClusterIP 서비스 VIP
  • 동일 클러스터의 LoadBalancer 서비스 VIP
  • 인그레스 레이어 7 LoadBalancer(Istio).
  • 동일 클러스터의 다른 노드
  • 내부 DNS 이름(예: *.svc.cluster.local)
  • 외부 DNS 이름(예: google.com)
  • 클러스터 외부의 항목
  • 인터넷의 항목

네트워크 계층는 다음 중 하나 이상일 수 있습니다.

  • 이웃 시스템, ARP, NDP와 같은 레이어 2 링크 레이어 문제
  • 레이어 3 IP 주소 라우팅 문제
  • 레이어 4 TCP 또는 UDP 엔드포인트 문제
  • 레이어 7 HTTP 또는 HTTPS 문제
  • DNS 변환 문제

문제의 범주를 이해하면 해당 문제에 관련된 구성요소와 문제가 발생한 레이어를 식별하는 데 도움이 됩니다. 일부 문제는 일시적이기 때문에 문제가 발생할 때 정보를 수집하는 것이 중요합니다. 시스템이 복구된 후의 스냅샷에는 근본 원인 분석을 위해 충분한 정보가 포함되지 않습니다.

인그레스 문제

주체가 클러스터 외부의 클라이언트이고 LoadBalancer 서비스 연결이 실패한 경우에는 North-South 연결 문제입니다. 다음 다이어그램은 작동 예시에서 수신 트래픽이 왼쪽에서 오른쪽으로 스택을 통과하고 오른쪽에서 왼쪽으로 스택을 통해 트래픽 이동을 다시 반환하는 것을 보여줍니다.

부하 분산기를 통해 anetd/kube-proxy로 그리고 다시 백엔드로 사용자로부터 물리적 인프라로 전송되는 인그레스 트래픽

이러한 트래픽 흐름에 문제가 있으면 다음 문제 해결 플로우 차트를 사용해서 문제의 위치를 식별할 수 있습니다.

패킷이 환경을 통과할 때 수행되는 각 단계를 검토하여 네트워크 인그레스 문제 해결 과정 중 적합한 조치 및 연결이 존재하는지 확인

이 플로우 차트에서 다음 문제 해결 안내는 문제가 있는 위치를 확인하는 데 도움이 됩니다.

  • 패킷이 클라이언트를 떠나나요? 그렇지 않으면 네트워크 인프라 문제일 수 있습니다.
  • MetalLB를 사용 중인가요? 그렇다면 패킷이 LB 노드에 도착하고 ARP가 올바르게 전송되나요? 그렇지 않으면 네트워크 인프라 문제일 수 있습니다.
  • F5 BIG-IP를 사용 중인가요? 그렇다면 F5 문제가 있는지 확인했나요?
  • 네트워크 주소 변환(NAT)이 올바르게 수행되었나요? 그렇지 않으면 kube-proxy/Dataplane V2 문제일 수 있습니다.
  • 패킷이 워커 노드에 도착하나요? 그렇지 않으면 Dataplane v2 포드 간 문제일 수 있습니다.
  • 패킷이 포드에 도착하나요? 그렇지 않으면 Dataplane v2 로컬 전달 문제일 수 있습니다.

다음 섹션에서는 트래픽 흐름이 올바르게 수행되는지 확인하기 위해 각 스테이지의 문제 해결 단계를 제공합니다.

패킷이 클라이언트를 떠나나요?

패킷이 클라이언트를 올바르게 떠나서 물리적 네트워크 인프라에 구성된 라우터를 통과하는지 확인합니다.

  1. tcpdump를 사용해서 대상 서비스를 향해 클라이언트를 떠날 때 패킷을 확인합니다.

    tcpdump -ni any host SERVICE_VIP and port SERVICE_PORT
    

    트래픽이 송신되지 않으면 이것이 문제의 원인입니다.

패킷이 LoadBalancer 노드에 도착하나요?

MetalLB를 부하 분산기로 사용하는 경우:

  1. metallb-controller 로그를 보고 부하 분산기 노드가 서비스 VIP를 제공하는지 확인합니다.

    kubectl -n kube-system logs -l app=metallb --all-containers=true | grep SERVICE_VIP
    
  2. SSH를 사용해서 노드에 연결합니다.

  3. MetalLB 노드의 경우 tcpdump를 사용해서 트래픽을 검토합니다.

    tcpdump -ni any host SERVICE_VIP and port SERVICE_PORT
    

    ManualLB의 경우 트래픽은 모든 노드에 도착할 수 있습니다. 부하 분산기 구성에 따라 노드를 하나 또는 여러 개 선택할 수 있습니다. tcpdump를 사용해서 트래픽을 검토합니다.

    tcpdump -ni any host NODE_IP and port NODE_PORT
    

    MetalLB가 패킷을 노드에 전달하기 전에 NAT를 수행하지 않기 때문에 명령어가 부하 분산기 유형에 따라 다릅니다.

    트래픽이 어떤 노드로도 이동하지 않으면 이것이 문제의 원인입니다.

F5 BIG-IP 문제가 있나요?

F5 BIG-IP 문제를 해결하려면 F5 서비스가 트래픽을 수신하지 않음에서 다음 섹션 중 하나를 참조하세요.

ARP가 올바르게 전송되었나요?

MetalLB의 부하 분산기 노드에는 서비스 VIP 공지를 위해 ARP가 사용됩니다. ARP 응답이 올바르게 전송되었지만 트래픽이 수신되지 않으면 물리적 네트워킹 인프라에 문제가 있다는 신호입니다. 이 문제의 일반적인 원인 중 하나는 일부 고급 데이터 영역 학습 기능이 소프트웨어 정의 네트워크(SDN) 솔루션에서 ARP 응답을 무시한다는 것입니다.

  1. tcpdump를 사용해서 ARP 응답을 감지합니다.

    tcpdump -ni any arp
    

    문제가 발생한 VIP를 공지하는 메시지를 찾습니다.

  2. MetalLB의 경우 Gratuitous ARP를 전송하지 않습니다. 응답이 표시되는 빈도는 top of rack(ToR) 스위치와 같은 다른 기기가 ARP 요청을 전송하는 시간에 따라 달라집니다.

NAT가 수행되나요?

Dataplane v2/kube-proxy는 대상 VIP를 백엔드 포드 IP 주소로 변환하기 위해 목적지 네트워크 주소 변환(대상 NAT 또는 DNAT)을 수행합니다. 부하 분산기의 백엔드인 노드를 알고 있으면 SSH를 사용해서 이 노드에 연결합니다.

  1. tcpdump를 사용해서 서비스 VIP가 올바르게 변환되었는지 확인합니다.

    tcpdump -ni any host BACKEND_POD_IP and port CONTAINER_PORT
    
  2. Dataplane v2의 경우 추가로 anetd 포드에 연결하고 임베딩된 Cilium 디버그 도구를 사용할 수 있습니다.

    cilium monitor --type=drop
    

자세한 내용은 Dataplane v2/Cilium 문제에 대한 다음 섹션 중 하나를 참조하세요.

패킷이 워커 노드에 도착하나요?

워커 노드에서 패킷이 외부 인터페이스에서 도착한 후 포드로 전달됩니다.

  1. tcpdump를 사용해서 패킷이 일반적으로 eth0 또는 ens192라는 외부 인터페이스에 도착하는지 확인합니다.

    tcpdump -ni any host BACKEND_POD_IP and port CONTAINER_PORT
    
Google Distributed Cloud의 경우 패킷이 터널에서 캡슐화됩니다. 패킷이 캡슐화 해제되면 cilium_geneve라는 네트워크 인터페이스에서 나타납니다.

일반적인 서비스 백엔드에는 서로 다른 노드에 걸쳐서 여러 포드가 포함되기 때문에 문제가 있는 노드를 문제 해결하는 것이 어려울 수 있습니다. 일반적인 해결 방법은 일부 패킷이 결국 도착할 수 있도록 문제를 충분히 오랫동안 캡처하거나 백엔드 수를 1로 제한하는 것입니다.

패킷이 작업 노드에 전혀 도착하지 않으면 네트워크 인프라 문제임을 나타냅니다. 네트워킹 인프라팀에 문의해서 LoadBalancer 노드와 워커 노드 사이에 패킷이 손실되는 이유를 확인하세요. 일반적인 문제에는 다음이 포함됩니다.

  • 소프트웨어 정의 네트워크(SDN) 로그를 확인합니다. 경우에 따라 SDN에서는 세분화, 잘못된 체크섬, 스푸핑 방지 등의 여러 이유로 패킷이 손실될 수 있습니다.
  • geneve 패킷 UDP 포트 6081을 필터링하는 방화벽 규칙

패킷이 노드의 외부 인터페이스 또는 터널 인터페이스에 도착하면 이를 대상 포드로 전달해야 합니다. 포드가 호스트 네트워킹 포드이면 포드가 노드와 네트워크 네임스페이스를 공유하기 때문에 이 단계가 필요하지 않습니다. 그렇지 않으면 추가 패킷 전달이 필요합니다.

각 포드에는 파이프처럼 작동하는 가상 이더넷 인터페이스 쌍이 포함됩니다. 인터페이스의 한쪽 끝에 전송되는 패킷은 인터페이스의 다른 끝에서 수신됩니다. 인터페이스 중 하나가 포드의 네트워크 네임스페이스로 이동하고 이름이 eth0으로 변경됩니다. 다른 인터페이스는 호스트 네임스페이스에 유지됩니다. CNI마다 다른 스키마가 포함됩니다. Dataplane v2의 경우 인터페이스 이름이 일반적으로 lxcxxxx로 지정됩니다. 이름에는 lxc17lxc18과 같이 연속적인 인터페이스 번호가 포함됩니다. tcpdump를 사용해서 패킷이 포드에 도착하는지 확인하거나 인터페이스를 지정할 수도 있습니다.

  tcpdump -ni lcxxxx host BACKEND_POD_IP and port CONTAINER_PORT

패킷이 노드에 도착하지만 포드에 도착하지 않으면 다음과 같이 라우팅 테이블을 확인합니다.

  ip route

일반적으로 각 포드는 포드 IP 주소를 lxc 인터페이스로 전달하는 라우팅 항목을 포함해야 합니다. 항목이 누락되었으면 일반적으로 CNI 데이터 경로에 오류가 있음을 의미합니다. 근본 원인을 확인하려면 CNI DaemonSet 로그를 확인합니다.

이그레스 문제

트래픽이 포드에 수신될 경우 동일한 트래픽이 포드를 나갈 때 문제가 발생할 수 있습니다. 다음 다이어그램은 작동 예시에서 수신 트래픽이 왼쪽에서 오른쪽으로 스택을 통과하는 것을 보여줍니다.

호스트의 외부 인터페이스를 통해 포드에서 물리적 인프라로 이동하고 다시 외부 서비스로 이동하는 이그레스 트래픽

  1. 발신 패킷을 노드의 IP 주소로 정확하게 매스커레이드하려면 레이어 4에서 외부 서비스를 검사합니다.

    소스 네트워크 주소 변환(소스 NAT 또는 SNAT)를 사용해서 패킷의 소스 IP 주소를 포드 IP 주소에서 노드 IP 주소로 매핑해야 합니다. Dataplane v2에서 이 프로세스는 외부 인터페이스에 로드되는 ebpf를 통해 수행됩니다.

    tcpdump를 사용해서 소스 IP 주소가 포드 IP 주소에서 노드 IP 주소로 올바르게 변환되었는지 확인합니다.

    tcpdump -ni EXTERNAL_INTERFACE host EXTERNAL_IP and port EXTERNAL_PORT
    

    tcpdump로 패킷이 올바르게 매스커레이드되지만 원격 서비스가 응답하지 않는 것으로 확인되면 인프라에서 외부 서비스 연결을 확인합니다.

  2. 발신 패킷이 노드 IP 주소로 올바르게 매스커레이드된 경우에는 tcpdump를 사용해서 외부 호스트(레이어 3) 연결을 확인합니다.

    tcpdump -ni EXTERNAL_INTERFACE host EXTERNAL_IP and icmp
    

    tcpdump를 실행하는 것과 동시에 포드 중 하나에서 핑을 수행합니다.

    kubectl exec POD_NAME ping EXTERNAL_IP
    

    핑 응답이 표시되지 않으면 인프라에서 외부 서비스에 대한 연결을 확인합니다.

클러스터 내 문제

포드 간 연결 문제의 경우 문제 범위를 노드로 제한하도록 시도합니다. 종종 노드 그룹이 다른 노드 그룹과 통신할 수 없는 경우가 있습니다.

  1. Dataplane v2에서 현재 노드에서 동일 클러스터에 있는 다른 모든 노드로의 노드 연결을 확인합니다. anetd 포드 내부에서 상태를 확인합니다.

    cilium status --all-health
    

네트워크 계층 문제

연결 문제가 발생하는 네트워크 계층를 식별하는 것이 중요한 단계입니다. '소스에서 대상으로의 연결 문제'와 같은 오류 메시지는 애플리케이션 오류, 라우팅 문제, DNS 문제 등 해당 문제를 확인하는 데 충분한 도움이 되지 않습니다. 문제가 발생한 레이어를 확인하는 것이 올바른 구성요소를 수정하는 데 도움이 됩니다.

많은 경우에 오류 메시지는 문제가 발생하는 레이어를 직접적으로 나타냅니다. 다음 예시는 네트워크 계층 질문을 해결하는 데 도움이 됩니다.

  • HTTP 오류는 레이어 7 문제임을 나타냅니다.
    • HTTP 코드 40x, 50x, TLS 핸드셰이크 오류는 모든 것이 레이어 4에서 정상적으로 작동함을 의미합니다.
  • '피어에서 연결 재설정' 오류는 레이어 4 문제임을 나타냅니다.
    • 원격 소켓이 현재 연결 상태와 일치하지 않아서 RESET 패킷을 전송하는 경우가 많습니다. 이러한 동작은 연결 추적 또는 NAT의 오류 때문일 수 있습니다.
  • '호스트 경로 없음''연결 시간 초과' 오류는 일반적으로 레이어 3 또는 레이어 2 문제입니다.
    • 이러한 오류는 패킷을 대상으로 올바르게 라우팅할 수 없음을 나타냅니다.

유용한 문제 해결 도구

네트워크 관련 DaemonSet는 노드에서 실행되며 연결 문제의 원인일 수 있습니다. 그러나 잘못된 노드 구성, top of rack(ToR) 스위치, 스파인 라우터, 방화벽도 문제를 일으킬 수 있습니다. 다음 도구를 사용하여 문제 범위나 레이어를 확인하고 GKE Enterprise 노드 또는 물리적 인프라 문제인지 확인할 수 있습니다.

핑은 레이어 3(IP 레이어)에서 작동하며 소스와 대상 사이의 경로를 확인합니다. 핑이 대상에 도착하지 않으면 종종 문제가 레이어 3에 있음을 의미합니다.

하지만 모든 IP 주소에 핑을 수행할 수 있지는 않습니다. 예를 들어 일부 부하 분산기 VIP는 순수한 레이어 4 부하 분산기인 경우 핑을 수행할 수 없습니다. ClusterIP 서비스는 VIP가 핑 응답을 반환할 수 없는 하나의 예시입니다. 레이어 4에서 이 서비스는 사용자가 VIP:port와 같이 포트 번호를 지정할 때만 핑 응답을 반환합니다.

Google Distributed Cloud의 BGPLB 및 MetalLB 부하 분산기는 모두 레이어 3에서 작동합니다. 핑을 사용해서 연결을 확인할 수 있습니다. F5는 다르지만 이것도 ICMP를 지원합니다. 핑을 사용해서 F5 VIP 연결을 확인할 수 있습니다.

Arping

Arping은 핑과 비슷하지만 레이어 2에서 작동합니다. 애플리케이션 오류 메시지는 레이어 2 및 레이어 3 문제 간에 유사성을 보이는 경우가 많습니다. Arping과 핑은 이러한 문제를 구분하는 데 도움이 될 수 있습니다. 예를 들어 소스와 대상이 동일한 서브넷에 있지만 대상에 arping을 수행할 수 없으면 레이어 2 문제입니다.

arping <ip>가 성공하면 대상의 MAC 주소가 반환됩니다. 레이어 2에서 이 주소는 물리적 인프라 문제를 나타내는 경우가 많습니다. 이 문제는 노드 간 물리적 스위치인 경우가 많습니다.

Arping은 또한 IP 주소 충돌을 감지할 수 있습니다. IP 주소 충돌은 동일한 서브넷에서 동일한 IP 주소를 사용하도록 구성되었을 때 또는 VIP가 다른 물리적 머신에 사용될 때 발생합니다. IP 주소 충돌이 있으면 문제 해결이 어려운 간헐적인 문제가 발생할 수 있습니다. arping <ip>가 MAC 주소 항목을 2개 이상 반환할 경우 IP 주소 충돌이 있음을 나타냅니다.

arping으로부터 MAC 주소를 가져온 후에는 https://maclookup.app/을 사용해서 MAC 주소의 제조업체를 조회할 수 있습니다. 모든 제조업체는 MAC 프리픽스를 소유하므로, 이 정보를 사용해서 동일한 IP 주소를 사용하려고 시도 중인 기기를 확인할 수 있습니다. 예를 들어 VMware은 00:50:56 블록을 소유하므로, MAC 주소 00:50:56:xx:yy:zz는 vSphere 환경의 VM입니다.

iproute2

iproute2ip CLI에는 다음과 같은 여러 유용한 하위 명령어가 포함됩니다.

  • ip r: 경로 테이블을 출력합니다.
  • ip n: IP 주소와 MAC 주소 매핑을 위한 인접 항목 테이블을 출력합니다.
  • ip a: 머신의 모든 인터페이스를 출력합니다.

인접 항목 테이블에서 경로 또는 항목이 누락된 경우 노드에서 연결 문제가 발생할 수 있습니다. Anetd는 경로 테이블 및 인접 항목 테이블을 관리합니다. 이러한 테이블의 구성이 잘못되면 연결 문제가 발생할 수 있습니다.

Dataplane v2를 위한 Cilium/Hubble CLI

anetd 포드에는 연결 문제를 위해 여러 유용한 디버깅 도구가 있습니다.

  • cilium monitor --type=drop
    • anetd/Cilium에서 삭제된 모든 패킷의 로그를 출력합니다.
  • hubble observe
    • anetd의 ebpf 스택을 통과하는 모든 패킷을 출력합니다.
  • cilium status --all-health
    • 노드 간 연결 상태를 포함하여 Cilium 상태를 출력합니다. 각 anetd 포드는 클러스터의 다른 모든 노드 상태를 확인하고 노드 간 연결 문제를 확인하는 데 도움이 될 수 있습니다.

Iptable

Iptable은 많은 Kubernetes 구성요소 및 하위 시스템에 사용됩니다. kube-proxy는 iptable을 사용해서 서비스 변환을 구현합니다.

  1. iptable 수준의 네트워크 문제 해결을 위해서는 다음 명령어를 사용합니다.

    iptables -L -v | grep DROP
    

    삭제 규칙을 검토하고 패킷 수와 바이트 수를 통해 시간에 따라 증가하는지 여부를 확인합니다.

Tcpdump

Tcpdump는 많은 네트워크 트래픽 데이터를 발생시키는 강력한 패킷 캡처 도구입니다. 일반적인 방법은 소스와 대상 모두에서 tcpdump를 실행하는 것입니다. 소스 노드를 떠날 때는 패킷이 캡처되지만 대상 노드에서 패킷이 캡처되지 않으면 중간에 어떤 이유로 패킷이 삭제되었음을 의미합니다. 이러한 동작은 일반적으로 물리적 인프라에서 어떤 이유로 인해 패킷이 잘못 삭제됨을 나타냅니다.

DNS 문제 해결

DNS 변환 문제는 두 가지 주요 카테고리로 나뉩니다.

  • 클러스터 내 DNS 서버를 사용하는 일반 포드
  • 클러스터 내 DNS 서버를 사용하지 않는 호스트-네트워크 포드 또는 노드

다음 섹션에서는 클러스터 DNS 아키텍처에 대한 일부 정보와 이러한 카테고리 중 하나의 문제 해결을 시작하기 전에 유용한 팁을 제공합니다.

클러스터 DNS 아키텍처

클러스터 DNS 서비스는 클러스터에서 DNS 요청을 해결합니다. CoreDNS는 이 서비스를 모든 버전의 Google Distributed Cloud에 제공합니다.

각 클러스터에는 최소 2개 이상의 coredns 포드가 존재하며, 여기에는 클러스터 크기에 따라 DNS 포드 수를 동적으로 조절하는 자동 확장 처리가 포함됩니다. 또한 모든 백엔드 coredns 포드 간에 요청을 부하 분산하는 kube-dns라는 서비스도 있습니다.

대부분의 포드에는 kube-dns 서비스 IP 주소로 구성된 업스트림 DNS가 포함되고 포드는 coredns 포드 중 하나에 DNS 요청을 전송합니다. DNS 요청은 다음 대상 중 하나로 그룹화할 수 있습니다.

  • cluster.local 도메인에 대한 요청의 경우 클러스터의 서비스 또는 포드를 참조하는 클러스터 내 DNS 이름입니다.
    • CoreDNS는 api-server에서 클러스터의 모든 서비스 및 포드를 감시하고 유효한 cluster.local 도메인의 경우 요청에 응답합니다.
  • 요청이 cluster.local 도메인에 해당하지 않으면 외부 도메인에 해당합니다.
    • CoreDNS는 요청을 업스트림 네임서버로 전달합니다. 기본적으로 CoreDNS는 실행되는 노드에 구성된 업스트림 네임서버를 사용합니다.

자세한 내용은 DNS 작동 방식과 Kubernetes에서의 구성 방식 개요를 참조하세요.

DNS 문제 해결 도움말

DNS 문제 해결을 위해서는 dignslookup 도구를 사용할 수 있습니다. 이러한 도구를 사용하면 DNS 요청을 전송해서 DNS 변환이 올바르게 작동하는지 테스트할 수 있습니다. 다음 예시는 dignslookup을 사용해서 DNS 변환 문제를 확인하는 방법을 보여줍니다.

  • dig 또는 nslookup을 사용해서 google.com에 대해 요청을 전송합니다.

    dig google.com
    nslookup google.com
    
  • dig를 사용해서 kubernetes.default.svc.cluster.local에 대해 요청을 192.168.0.10 서버로 전송합니다:

    dig @192.168.0.10 kubernetes.default.svc.cluster.local
    
  • 또한 nslookup을 사용해서 이전 dig 명령어와 동일한 DNS 조회를 수행할 수 있습니다.

    nslookup kubernetes.default.svc.cluster.local 192.168.0.10
    

    dig 또는 nslookup 명령어의 출력을 검토합니다. 잘못된 응답이 수신되거나 응답이 수신되지 않으면 DNS 변환 문제를 나타냅니다.

일반 포드

DNS 문제 디버그를 위한 첫 번째 단계는 요청이 coredns 포드에 도달하는지 확인하는 것입니다. 일반적인 클러스터 연결 문제는 워크로드가 전송하는 트래픽의 첫 번째 유형이 DNS 레코드이기 때문에 DNS 문제로 표시되는 경우가 많습니다.

애플리케이션에서 오류 메시지를 검토합니다. io timeout 또는 비슷한 오류는 응답이 없고 일반적인 네트워크 연결 문제가 있음을 나타냅니다.

NXDOMAIN 또는 SERVFAIL과 같은 DNS 오류 코드가 포함된 오류 메시지는 클러스터 내 DNS 서버에 연결되었지만 서버가 도메인 이름을 변환하지 못했음을 나타냅니다.

  • NXDOMAIN 오류는 DNS 서버에 도메인이 없음을 나타냅니다. 애플리케이션이 요청하는 도메인 이름이 유효한지 확인하세요.
  • SERVFAIL 또는 REFUSED 오류는 DNS 서버가 응답을 보냈지만 도메인을 변환할 수 없거나 존재 안함을 확인할 수 없었음을 나타냅니다. 자세한 내용은 coredns 포드 로그를 확인하세요.

다음 명령어를 사용해서 kube-dns 서비스의 IP 주소를 찾을 수 있습니다.

kubectl -n kube-system get svc kube-dns

DNS가 작동하지 않는 포드에서 이전 섹션에 설명된 대로 dig 또는 nslookup을 사용하여 이 IP 주소로 DNS 요청을 전송해보세요.

  • 이러한 요청이 작동하지 않으면 각 coredns 포드의 IP 주소로 요청을 전송해보세요.
  • 특정 포드만 작동하고 다른 포드는 작동하지 않으면 눈에 띄는 패턴이 있는지 확인합니다. 예를 들어 coredns 포드와 동일한 노드에 있는 포드에 대해서는 DNS 변환이 작동하지만 여러 노드에 걸쳐 있을 때는 문제가 발생하는지 조사합니다. 이러한 동작은 일부 클러스터 내 연결 문제를 나타낼 수 있습니다.

CoreDNS가 외부 도메인 이름을 변환할 수 없으면 호스트-네트워크 포드 문제 해결을 위해 다음 섹션을 참조하세요. CoreDNS는 호스트 네트워크 포드와 같이 작동하며 이름 변환을 위해 노드의 업스트림 DNS 서버를 사용합니다.

호스트-네트워크 포드 또는 노드

호스트-네트워크 포드와 노드는 클러스터 내 DNS 서비스가 아니라 DNS 변환을 위해 노드에 구성된 네임서버를 사용합니다. OS에 따라 이 네임서버는 /etc/resolv.conf 또는 /run/systemd/resolve/resolv.conf에 구성됩니다. 이 구성은 cluster.local 도메인 이름을 변환할 수 없음을 의미합니다.

호스트-네트워크 이름 변환에 문제가 있으면 이전 섹션의 문제 해결 단계에 따라 업스트림 네임서버에 대해 DNS가 올바르게 작동하는지 테스트합니다.

모든 노드에 동일한 서버 집합이 구성되었는지 확인합니다. 다른 네임서버가 구성된 경우 서로 다른 노드에서 DNS 변환이 일치하지 않을 수 있습니다. dig 또는 nslookup을 사용해서 서로 요청을 전송하여 각 네임서버가 개별적으로 작동하는지 확인합니다. 일부 네임서버만 작동하고 다른 네임서버는 작동하지 않으면 이 유형의 일치하지 않는 DNS 변환 오류가 표시됩니다.

일반적인 네트워크 문제

다음 섹션에서는 발생 가능한 일반적인 네트워킹 문제에 대해 자세히 설명합니다. 문제 해결을 위해 적절한 문제 해결 안내를 따르세요. 추가 지원이 필요하면 Cloud Customer Care에 문의하세요.

Dataplane v2/Cilium

일반적인 오류: [PUT /endpoint/{id}][429] putEndpointIdTooManyRequests

이 오류는 비율 제한으로 인해 포드 생성 이벤트가 Cilium 에이전트에서 거부되었음을 의미합니다. 각 노드에 대해 Cilium에는 PUT 엔드포인트에 대한 동시 요청이 4개로 제한됩니다. 하나의 노드에 요청이 갑자기 많이 수행될 때 이러한 동작이 예상됩니다. Cilium 에이전트는 지연된 요청을 처리해야 합니다.

GKE Enterprise 1.14 이상에서는 노드 용량에 따라 비율 제한이 자동으로 조정됩니다. 비율 제한은 보다 합리적인 숫자로 수렴될 수 있으며, 더 강력한 노드의 경우 비율 제한이 더 높아집니다.

일반적인 오류: Ebpf map size is full

Dataplane v2는 eBFP 맵에 상태를 저장합니다. 상태에는 서비스, 연결 추적, 포드 ID, 네트워크 정책 규칙이 포함됩니다. 맵이 가득 차면 에이전트가 항목을 삽입할 수 없고, 그 결과 컨트롤 플레인과 데이터 영역 사이에 불일치가 발생합니다. 예를 들어 서비스 맵에는 64k 항목 제한이 있습니다.

  1. eBFP 맵 항목과 현재 크기를 확인하려면 bpftool을 사용합니다. 다음 예시는 부하 분산기 맵을 확인합니다.

    bpftool map dump pinned \
    /sys/fs/bpf/tc/globals/cilium_lb4_services_v2 | tail -n -1
    
    bpftool map dump pinned \ /sys/fs/bpf/tc/globals/cilium_lb4_backends_v2 | tail -n -1
    
  2. 맵이 64k 제한에 가까우면 맵을 삭제합니다. 다음 예시는 부하 분산기 맵을 삭제합니다.

    bpftool map dump pinned /sys/fs/bpf/tc/globals/cilium_lb4_services_v2 | \
        awk '{ print "0x"$2, "0x"$3, "0x"$4, "0x"$5, "0x"$6, "0x"$7, "0x"$8, "0x"$9, "0x"$10, "0x"$11, "0x"$12, "0x"$13}' | \
        head -n -1 | \
        xargs -L 1 bpftool map delete pinned /sys/fs/bpf/tc/globals/cilium_lb4_services_v2 key
    
    bpftool map dump pinned /sys/fs/bpf/tc/globals/cilium_lb4_backends_v2 | \
        awk '{ print "0x"$2, "0x"$3, "0x"$4, "0x"$5 }' | \
        head -n -1 | \
        xargs -L 1 bpftool map delete pinned /sys/fs/bpf/tc/globals/cilium_lb4_backends_v2 key
    
  3. eBFP 맵에 상태를 다시 채우려면 anetd를 다시 시작합니다.

NetworkPluginNotReady 오류로 인해 준비되지 않은 노드

노드에서 CNI 포드가 실행되지 않으면 다음과 비슷한 오류가 표시될 수 있습니다.

  "Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized

또한 이 노드는 다음 예시와 비슷한 오류와 함께 준비되지 않음 상태가 될 수 있습니다.

  "Network plugin not installed"

노드가 초기화되면 노드가 Ready로 표시되기 전 여러 이벤트가 수행되도록 kubelet이 기다립니다. kubelet이 검사하는 이벤트 중 하나는 컨테이너 네트워크 인터페이스(CNI) 플러그인이 설치되었는지 확인하는 것입니다. CNI 플러그인 설치는 초기화 컨테이너를 활용해서 anetd에 의해 수행됩니다. 이 컨테이너는 CNI 바이너리 및 CNI 구성을 모두 호스트의 필요한 디렉터리에 설치합니다.

이 문제를 해결하려면 이러한 포드가 노드에서 실행되지 않는 이유를 확인합니다. 일반적으로 이 오류는 네트워크 문제로 인한 것이 아닙니다. 이러한 포드는 호스트 네트워크에서 실행되므로 네트워크 종속성이 없습니다.

  1. anetd 포드 상태를 확인합니다. 다음 문제 해결 단계를 검토해서 문제 원인을 확인합니다.

    • 포드가 Crashlooping 상태이면 로그를 보고 포드가 올바르게 실행되지 않는 이유를 확인합니다.
    • 포드가 Pending 상태이면 kubectl describe를 사용하고 포드 이벤트를 검토합니다. 예를 들어 포드에 볼륨과 같은 리소스가 누락되었을 수 있습니다.
    • 포드가 Running 상태이면 로그 및 구성을 확인합니다. 일부 CNI 구현은 Cilium에서와 같이 CNI 설치 사용 중지 옵션을 제공합니다.
    • anetd에는 custom-cni-conf라는 구성 옵션이 있습니다. 이 설정이 true로 구성되었으면 anetd가 해당 CNI 바이너리를 설치하지 않습니다.

F5 서비스가 트래픽을 수신하지 않음

F5 서비스로 트래픽이 전달되지 않으면 다음 문제 해결 단계를 검토합니다.

  1. F5 BIG-IP의 모든 파티션이 관리자 또는 사용자 클러스터 중 하나의 클러스터에 구성되었는지 확인합니다. 파티션 하나가 여러 다른 클러스터에 공유된 경우에는 간헐적으로 연결이 중단될 수 있습니다. 이러한 동작은 2개의 클러스터가 동일 파티션에 대해 서로 제어 권한을 잡아서 상대 클러스터로부터 서비스를 삭제하려고 시도하기 때문입니다.

  2. 다음 2개의 포드가 실행 중인지 확인합니다. 실행 중이 아닌 포드는 오류를 나타냅니다.

    Load-balancer-f5
    K8s-bigip-ctlr-deployment-577d57985d-vk9wj
    

    GKE Enterprise에서 소유한 Load-balancer-f5로 모든 LoadBalancer 유형 서비스에 ConfigMap을 만듭니다. ConfigMap은 결국 bigip 컨트롤러에서 사용됩니다.

  3. 각 서비스의 각 포트에 대해 ConfigMap이 있는지 확인합니다. 예를 들어 다음 포트 구성을 고려하세요.

    Kube-server-443-tcp     2   31h
    Kube-server-8132-tcp        2   31h
    

    kube-server 서비스는 다음 예시와 비슷하게 표시됩니다.

    Kube-server LoadBalancer  10.96.232.96  21.1.7.16   443:30095/TCP,8132:32424/TCP  31h
    

    ConfigMap의 데이터 섹션에는 다음 예시에 표시된 것처럼 프런트엔드 VIP와 포트가 포함됩니다.

    data: '{"virtualServer":{"backend":{"serviceName":"kube-apiserver","servicePort":443,"healthMonitors":[{"protocol":"tcp","interval":5,"timeout":16}]},"frontend":{"virtualAddress":{"bindAddr":"21.1.7.16","port":443},"partition":"herc-b5bead08c95b-admin","balance":"ratio-member","mode":"tcp"}}}'
      schema: f5schemadb://bigip-virtual-server_v0.1.7.json
    
  4. BIG-IP 인스턴스 로그 및 측정항목을 확인합니다. ConfigMap이 올바르게 구성되었지만 BIG-IP 인스턴스가 구성을 따르지 않으면 F5 문제일 수 있습니다. BIG-IP 인스턴스 내에서 발생하는 문제의 경우 문제 진단 및 문제 해결을 위해 F5 지원팀에 연락하세요.

너무 많은 동시 연결로 인한 NAT 오류

클러스터의 특정 노드에 대해 노드 IP 주소는 클러스터 외부의 주소로 라우팅된 패킷에 대해 네트워크 주소 변환(NAT)을 제공합니다. 마찬가지로 인바운드 패킷이 번들 부하 분산(spec.loadBalancer.mode: bundled)을 사용하도록 구성된 부하 분산 노드에 진입할 때 소스 네트워크 주소 변환(SNAT)은 패킷을 IP 노드 주소로 라우팅하며 그런 다음에 패킷이 백엔드 포드로 전달됩니다.

Google Distributed Cloud에서 사용하는 NAT의 포트 범위는 32768-65535입니다. 이 범위에 따라 해당 노드에서 프로토콜별 병렬 연결 수가 32,767로 제한됩니다. 각 연결에는 conntrack 테이블의 항목이 필요합니다. 단기 지속 연결이 너무 많으면 conntrack 테이블에 NAT용 포트가 부족해집니다. 가비지 수집기가 오래된 항목을 삭제하지만 삭제가 즉각적이지 않습니다.

노드 연결 수가 32,767에 근접하면 NAT가 필요한 연결에서 패킷 손실이 보이기 시작합니다.

이 문제의 영향을 받는지 확인하려면 다음 안내를 따르세요.

  1. 문제가 있는 노드의 anetd 포드에서 다음 명령어를 실행합니다.

    kubectl -n kube-system anetd-XXX -- hubble observe \
        --from-ip $IP --to-ip $IP -f
    

    다음 형식의 오류가 표시됩니다.

    No mapping for NAT masquerade DROPPED
    

이 문제를 해결하려면 트래픽을 다른 노드로 재분배하면 됩니다.

다음 단계

추가 지원이 필요하면 Cloud Customer Care에 문의하세요.