Kubernetes 네트워킹 문제 디버깅: 필수 기술

파드 연결, 서비스, DNS, 네트워크 정책, 인그레스 라우팅 전반에 걸친 Kubernetes 네트워킹 문제를 디버깅합니다.

Kubernetes 네트워킹 문제 디버깅: 필수 기술

Kubernetes 네트워킹 문제는 일반적으로 타임아웃, Connection refused, DNS 오류, 빈 Service 엔드포인트, 또는 잘못된 Ingress 응답처럼 나타납니다. 빠르게 해결하려면 경로를 추적하세요: 소스 파드, 대상 파드, Service, DNS, NetworkPolicy, 그리고 Ingress 또는 로드 밸런서 순서입니다.

이 가이드는 트래픽이 중단되는 위치를 드러내는 실용적인 점검 순서와 kubectl 명령어를 제공합니다.

Kubernetes 네트워킹 기본 이해

디버깅에 들어가기 전에 Kubernetes의 핵심 네트워킹 개념을 이해하는 것이 중요합니다:

  • 파드 네트워킹: 각 파드는 고유한 IP 주소를 받습니다. 같은 노드 내의 파드는 직접 통신할 수 있습니다. 다른 노드의 파드는 가상 네트워크(CNI 플러그인)를 통해 통신합니다.
  • 서비스: 서비스는 파드 집합에 안정적인 IP 주소와 DNS 이름을 제공합니다. 추상화 계층 역할을 하여 다른 파드나 외부 클라이언트가 개별 파드 IP를 알 필요 없이 애플리케이션 백엔드에 접근할 수 있게 합니다.
  • DNS: Kubernetes DNS(보통 CoreDNS)는 서비스 이름을 클러스터 IP로 변환하여 서비스 검색을 가능하게 합니다.
  • 네트워크 정책: 이 리소스는 CNI 플러그인이 적용할 때 파드 트래픽을 제어합니다. NetworkPolicy 지원이 없는 클러스터는 객체를 수락하지만 규칙을 적용하지 않을 수 있습니다.
  • 인그레스: Ingress 컨트롤러는 일반적으로 HTTP 및 HTTPS를 통해 클러스터 내 서비스에 대한 외부 접근을 관리합니다. 라우팅, 로드 밸런싱, SSL 종료를 제공합니다.

일반적인 네트워킹 문제 및 디버깅 전략

1. 파드 간 통신 실패

파드가 서로 통신할 수 없을 때, 같은 네임스페이스 내에서도 네트워킹 문제의 주요 지표입니다.

증상:

  • 연결 타임아웃 또는 거부를 나타내는 애플리케이션 오류.
  • 한 파드에서 다른 파드로의 curl 또는 ping 명령 실패.

디버깅 단계:

  1. 파드 IP 확인: 소스 및 대상 파드 모두 유효한 IP 주소를 가지고 있는지 확인합니다. kubectl exec <pod-name> -- ip addr을 사용하세요.
  2. 네트워크 연결 확인(파드 내): 소스 파드에서 대상 파드의 IP 주소로 ping을 시도합니다. 실패하면 CNI 플러그인 또는 노드 네트워킹에 문제가 있을 수 있습니다.
    kubectl exec <source-pod-name> -- ping <destination-pod-ip>
    
  3. 네트워크 정책 검사: NetworkPolicy는 일반적인 원인입니다. 정책이 실수로 파드 간 트래픽을 차단하고 있는지 확인합니다.
    kubectl get networkpolicies -n <namespace>
    
    podSelectoringress/egress 규칙을 검토하여 허용되거나 거부되는 트래픽을 이해합니다. 파드가 인그레스 정책에 의해 선택되면 명시적으로 허용된 인그레스 트래픽만 허용됩니다.
  4. CNI 플러그인 상태: CNI(Container Network Interface) 플러그인(예: Calico, Flannel, Cilium)이 모든 노드에서 올바르게 실행되고 있는지 확인합니다. CNI 데몬셋 파드의 로그를 확인합니다.
    kubectl get pods -n kube-system -l k8s-app=<cni-plugin-label>
    kubectl logs <cni-plugin-pod-name> -n kube-system
    

2. 서비스 검색 문제

파드가 DNS 이름이나 클러스터 IP로 다른 서비스에 도달할 수 없을 때, Kubernetes DNS 또는 Service 객체 구성에 문제가 있음을 나타냅니다.

증상:

  • Name or service not known과 같은 애플리케이션 오류.
  • 파드 내 nslookup 또는 dig 명령이 서비스 이름을 확인하지 못함.

디버깅 단계:

  1. DNS 확인 확인: 파드에서 알려진 서비스에 대한 DNS 확인을 테스트합니다.
    kubectl exec <pod-name> -- nslookup <service-name>.<namespace>.svc.cluster.local
    
    실패하면 CoreDNS 파드에서 오류를 확인합니다.
    kubectl get pods -n kube-system -l k8s-app=kube-dns
    kubectl logs <coredns-pod-name> -n kube-system
    
  2. Service 객체 확인: Service 객체가 올바르게 구성되었고 정상 파드를 가리키는 엔드포인트가 있는지 확인합니다.
    kubectl get service <service-name> -n <namespace> -o yaml
    kubectl get endpoints <service-name> -n <namespace>
    
    endpoints 출력에는 서비스를 지원하는 파드의 IP 주소가 나열되어야 합니다.
  3. 파드 준비 상태 프로브: 파드가 준비 상태 프로브를 통과하지 못하면 Service의 엔드포인트에 추가되지 않습니다. 준비 상태 프로브 구성 및 파드 로그에서 문제를 확인합니다.

3. Ingress 컨트롤러 문제

서비스에 대한 외부 접근은 Ingress 리소스와 Ingress 컨트롤러에 의해 관리됩니다. 여기서 문제가 발생하면 클러스터 외부에서 애플리케이션에 접근할 수 없게 될 수 있습니다.

증상:

  • 외부 URL을 통해 애플리케이션에 접근할 때 502 Bad Gateway, 404 Not Found, 또는 503 Service Unavailable 오류.
  • Ingress 컨트롤러 로그에 백엔드 서비스 관련 오류 표시.

디버깅 단계:

  1. Ingress 컨트롤러 파드 확인: Ingress 컨트롤러 파드(예: Nginx Ingress, Traefik)가 실행 중이고 정상인지 확인합니다.
    kubectl get pods -l app.kubernetes.io/component=controller # 인그레스 컨트롤러에 따라 레이블 조정
    kubectl logs <ingress-controller-pod-name> -n <ingress-namespace>
    
  2. Ingress 리소스 확인: Ingress 리소스의 구성을 확인합니다.
    kubectl get ingress <ingress-name> -n <namespace> -o yaml
    
    rules 섹션이 호스트 이름과 경로를 적절한 service.nameservice.port에 올바르게 매핑하는지 확인합니다.
  3. Service 및 엔드포인트 확인: 서비스 검색과 마찬가지로 Ingress가 가리키는 백엔드 서비스가 올바르게 구성되었고 정상 엔드포인트가 있는지 확인합니다.
    kubectl get service <backend-service-name> -n <namespace>
    kubectl get endpoints <backend-service-name> -n <namespace>
    
  4. 방화벽 및 로드 밸런서: 클러스터 외부에서 접근하는 경우 외부 방화벽이나 클라우드 제공자 로드 밸런서가 Ingress 컨트롤러의 서비스(보통 LoadBalancer 유형 서비스)로 트래픽을 전달하도록 올바르게 구성되었는지 확인합니다.

4. 네트워크 정책 적용

NetworkPolicy는 강력할 수 있지만 잘못 구성되면 연결 문제의 원인이 될 수 있습니다. 최소 권한 원칙에 따라 작동합니다. 정책이 명시적으로 트래픽을 허용하지 않으면 거부됩니다.

디버깅 단계:

  1. 적용된 정책 식별: 문제의 파드에 영향을 미치는 NetworkPolicy를 확인합니다.
    kubectl get networkpolicy -n <namespace>
    
  2. 정책 선택자 검사: 각 관련 NetworkPolicy의 podSelector를 주의 깊게 검토합니다. 이 선택자는 정책이 적용되는 파드를 결정합니다. 파드가 여러 정책에 의해 선택되면 허용된 트래픽은 해당 정책 규칙의 합집합이며, 가장 제한적인 단일 규칙이 아닙니다.
  3. Ingress/Egress 규칙 검토: NetworkPolicy의 ingressegress 섹션을 분석합니다. 파드 A에서 파드 B로 연결을 설정하려는 경우 다음을 확인해야 합니다:
    • 파드 B에 적용된 NetworkPolicy가 파드 A(또는 파드 A를 포함하는 더 넓은 레이블 선택자)의 인그레스 트래픽을 허용합니다.
    • 파드 A에 적용된 NetworkPolicy가 파드 B(또는 파드 B를 포함하는 더 넓은 레이블 선택자)로의 이그레스 트래픽을 허용합니다.
  4. 광범위 허용 정책으로 테스트: 임시 문제 해결 단계로 특정 파드나 네임스페이스에 대한 모든 트래픽을 허용하는 NetworkPolicy를 생성하여 연결이 복원되는지 확인할 수 있습니다. 이는 문제가 실제로 NetworkPolicy와 관련된 것인지 격리하는 데 도움이 됩니다.
    # 예시: 레이블 app=my-app을 가진 파드에 대한 모든 인그레스 및 이그레스 허용
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-all-for-my-app
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: my-app
      policyTypes:
      - Ingress
      - Egress
      ingress:
        - {}
      egress:
        - {}
    
    경고:allow-all 정책은 임시 디버깅용으로만 사용해야 합니다. 테스트를 마친 후 즉시 제거하세요.

필수 도구 및 명령어

  • kubectl exec: 파드 내에서 명령 실행(예: ping, curl, nslookup).
  • kubectl logs: 파드 로그 보기, 특히 컨트롤 플레인 구성 요소 및 네트워크 플러그인.
  • kubectl describe: 파드, 서비스, 인그레스, 네트워크 정책에 대한 상세 정보를 얻으며, 종종 상태와 이벤트를 드러냅니다.
  • kubectl get: 리소스 및 기본 상태 나열.
  • tcpdump: 강력한 명령줄 패킷 분석기. 파드 내부나 노드에서 실행하여 네트워크 트래픽을 캡처할 수 있습니다.
    # 예시: 파드 내 eth0 인터페이스에서 포트 80 트래픽 캡처
    kubectl exec <pod-name> -- tcpdump -i eth0 -nn port 80
    

핵심 요점

Kubernetes 네트워킹을 내부에서 외부로 디버깅하세요. 먼저 파드 IP 연결을 증명한 다음 Service 엔드포인트, DNS, NetworkPolicy, 마지막으로 Ingress 또는 외부 로드 밸런서 동작을 확인하세요. 이 순서는 Service에 준비된 엔드포인트가 없는데 Ingress 증상을 쫓는 것을 방지합니다.