Skip to content

필사 모드: 컨테이너 & 쿠버네티스 네트워크 디버깅 완전 가이드

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

1. Docker 네트워킹 모델

컨테이너 네트워크 디버깅의 기초는 Docker가 제공하는 네트워킹 모델을 정확히 이해하는 것에서 시작합니다.

1.1 Bridge 네트워크

Docker의 기본 네트워크 드라이버입니다. 각 컨테이너는 `docker0` 브릿지에 연결된 가상 이더넷(veth) 인터페이스를 할당받습니다.

브릿지 네트워크 상세 확인

docker network inspect bridge

컨테이너의 네트워크 네임스페이스 확인

docker inspect --format '{{.NetworkSettings.IPAddress}}' <container_id>

veth 페어 확인

ip link show type veth

브릿지에 연결된 인터페이스 확인

brctl show docker0

브릿지 네트워크에서 흔히 발생하는 문제는 다음과 같습니다.

- 컨테이너 간 통신 불가: 동일 브릿지에 연결되어 있는지 확인

- 외부 통신 불가: iptables NAT 규칙과 IP 포워딩 설정 확인

- 포트 충돌: 호스트 포트 바인딩 중복 확인

iptables NAT 규칙 확인

sudo iptables -t nat -L -n -v

IP 포워딩 상태 확인

cat /proc/sys/net/ipv4/ip_forward

포트 바인딩 확인

docker port <container_id>

1.2 Host 네트워크

컨테이너가 호스트의 네트워크 스택을 직접 사용합니다. 네트워크 격리가 없으므로 성능은 좋지만 포트 충돌 위험이 있습니다.

host 모드로 컨테이너 실행

docker run --network host nginx

컨테이너 내부에서 네트워크 인터페이스 확인

docker exec <container_id> ip addr show

호스트와 동일한 네트워크 스택을 사용하는지 확인

docker exec <container_id> ss -tlnp

1.3 Overlay 네트워크

여러 Docker 호스트에 걸쳐 컨테이너 간 통신을 가능하게 합니다. Docker Swarm이나 외부 키-값 저장소가 필요합니다.

overlay 네트워크 생성

docker network create --driver overlay my-overlay

VXLAN 터널 상태 확인

ip -d link show type vxlan

overlay 네트워크의 피어 정보 확인

docker network inspect my-overlay --format '{{json .Peers}}'

overlay 네트워크 디버깅 시 주의할 점은 다음과 같습니다.

- VXLAN 포트(UDP 4789)가 방화벽에서 허용되어 있는지 확인

- MTU 설정이 올바른지 확인 (VXLAN 오버헤드 50바이트 고려)

- 노드 간 시간 동기화 상태 확인

2. Kubernetes 네트워킹 모델과 CNI

2.1 Kubernetes 네트워킹의 기본 원칙

Kubernetes 네트워킹 모델은 세 가지 핵심 원칙을 따릅니다.

1. 모든 Pod는 NAT 없이 다른 모든 Pod와 통신할 수 있어야 한다

2. 모든 노드는 NAT 없이 모든 Pod와 통신할 수 있어야 한다

3. Pod가 자신의 IP로 인식하는 주소가 다른 Pod가 보는 주소와 동일해야 한다

클러스터 네트워크 CIDR 확인

kubectl cluster-info dump | grep -m 1 cluster-cidr

노드의 Pod CIDR 확인

kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}'

현재 사용 중인 CNI 플러그인 확인

ls /etc/cni/net.d/

cat /etc/cni/net.d/*.conflist

2.2 CNI 플러그인 이해

CNI(Container Network Interface)는 컨테이너의 네트워크 인터페이스를 구성하는 표준입니다.

CNI 바이너리 위치 확인

ls /opt/cni/bin/

CNI 설정 파일 확인

cat /etc/cni/net.d/10-calico.conflist

kubelet의 CNI 관련 로그 확인

journalctl -u kubelet | grep -i cni

주요 CNI 플러그인별 특징은 다음과 같습니다.

| CNI 플러그인 | 데이터 플레인 | Network Policy | 특징 |

| ------------ | ------------- | -------------- | -------------------- |

| Calico | iptables/eBPF | 지원 | BGP 기반 라우팅 |

| Cilium | eBPF | 지원 | L7 정책, Hubble 관측 |

| Flannel | VXLAN/host-gw | 미지원 | 간단한 설정 |

| Weave | VXLAN | 지원 | 자동 메시 네트워크 |

3. Pod-to-Pod 통신 디버깅

3.1 같은 노드 내 Pod 간 통신

Pod IP 확인

kubectl get pods -o wide

Pod에서 다른 Pod로 ping 테스트

kubectl exec -it <pod-a> -- ping <pod-b-ip>

같은 노드의 Pod 간 경로 확인

kubectl exec -it <pod-a> -- traceroute <pod-b-ip>

노드에서 veth 인터페이스 확인

kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- ip link show

3.2 다른 노드의 Pod 간 통신

노드 간 라우팅 테이블 확인

kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- route -n

VXLAN이나 IPIP 터널 상태 확인

kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- ip tunnel show

tcpdump로 패킷 캡처

kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- \

tcpdump -i any -nn host <target-pod-ip>

MTU 문제 확인 (Path MTU Discovery)

kubectl exec -it <pod> -- ping -M do -s 1400 <target-pod-ip>

노드 간 통신 문제의 주요 원인은 다음과 같습니다.

- 클라우드 보안 그룹에서 Pod CIDR 트래픽 차단

- MTU 불일치로 인한 패킷 단편화

- 노드 간 라우팅 테이블 불일치

- IPIP/VXLAN 터널 인터페이스 다운

4. Pod-to-Service 통신 디버깅

4.1 Service 기본 동작 확인

Service의 ClusterIP와 Endpoints 확인

kubectl get svc <service-name> -o wide

kubectl get endpoints <service-name>

Service에 연결된 Pod 확인

kubectl get endpoints <service-name> -o yaml

Service로 접근 테스트

kubectl exec -it <test-pod> -- curl -v http://<service-name>:<port>

Service의 selector와 매칭되는 Pod 확인

kubectl get pods -l <label-selector>

4.2 kube-proxy와 iptables/IPVS 규칙

kube-proxy는 Service의 가상 IP를 실제 Pod IP로 변환하는 역할을 합니다.

kube-proxy 모드 확인

kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode

iptables 모드: Service 관련 iptables 규칙 확인

sudo iptables -t nat -L KUBE-SERVICES -n

sudo iptables -t nat -L KUBE-SVC-<hash> -n

sudo iptables -t nat -L KUBE-SEP-<hash> -n

IPVS 모드: 가상 서버 목록 확인

sudo ipvsadm -Ln

sudo ipvsadm -Ln -t <cluster-ip>:<port>

kube-proxy 로그 확인

kubectl logs -n kube-system -l k8s-app=kube-proxy --tail=100

iptables 규칙 분석 시 체인의 흐름을 이해해야 합니다.

PREROUTING -> KUBE-SERVICES -> KUBE-SVC-xxx -> KUBE-SEP-xxx (DNAT)

특정 Service의 전체 iptables 체인 추적

SERVICE_IP=$(kubectl get svc <service-name> -o jsonpath='{.spec.clusterIP}')

sudo iptables -t nat -L KUBE-SERVICES -n | grep $SERVICE_IP

conntrack 테이블에서 Service 연결 추적

sudo conntrack -L -d $SERVICE_IP

5. Service DNS 해석 문제

5.1 CoreDNS 동작 확인

Kubernetes 클러스터 내부 DNS는 CoreDNS가 담당합니다.

CoreDNS Pod 상태 확인

kubectl get pods -n kube-system -l k8s-app=kube-dns

CoreDNS 설정 확인

kubectl get configmap coredns -n kube-system -o yaml

DNS 해석 테스트

kubectl exec -it <test-pod> -- nslookup <service-name>

kubectl exec -it <test-pod> -- nslookup <service-name>.<namespace>.svc.cluster.local

DNS 응답 시간 측정

kubectl exec -it <test-pod> -- dig <service-name>.default.svc.cluster.local +stats

5.2 DNS 문제 진단

Pod의 DNS 설정 확인

kubectl exec -it <pod> -- cat /etc/resolv.conf

CoreDNS 로그에서 에러 확인

kubectl logs -n kube-system -l k8s-app=kube-dns --tail=200

DNS 디버깅용 Pod 배포

kubectl run dnsutils --image=gcr.io/kubernetes-e2e-test-images/dnsutils:1.3 \

--restart=Never -- sleep 3600

외부 도메인 해석 테스트

kubectl exec -it dnsutils -- nslookup google.com

kubectl exec -it dnsutils -- nslookup kubernetes.default

흔히 발생하는 DNS 문제와 해결 방법은 다음과 같습니다.

- **ndots 설정**: `resolv.conf`의 ndots:5 설정 때문에 짧은 이름에 대해 여러 번 DNS 쿼리가 발생합니다. FQDN(마지막에 `.` 포함)을 사용하면 해결됩니다.

- **CoreDNS CrashLoopBackOff**: 로그를 확인하고, 업스트림 DNS 서버 연결 상태를 점검합니다.

- **DNS 캐시 문제**: CoreDNS의 cache 플러그인 설정을 확인합니다.

ndots 문제 확인: 쿼리 횟수 비교

kubectl exec -it <pod> -- dig myservice.default.svc.cluster.local +search +showsearch

kubectl exec -it <pod> -- dig myservice.default.svc.cluster.local. +search +showsearch

6. 외부 통신 디버깅

6.1 Ingress / LoadBalancer 문제

Ingress 리소스 상태 확인

kubectl get ingress -A

kubectl describe ingress <ingress-name>

Ingress Controller 로그 확인

kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=100

LoadBalancer Service의 External IP 확인

kubectl get svc -l type=LoadBalancer

NodePort를 통한 외부 접근 테스트

curl -v http://<node-ip>:<node-port>

6.2 Egress 트래픽 디버깅

Pod에서 외부로 나가는 트래픽 확인

kubectl exec -it <pod> -- curl -v https://httpbin.org/ip

NAT 게이트웨이 및 라우팅 확인

kubectl exec -it <pod> -- traceroute 8.8.8.8

SNAT 규칙 확인

sudo iptables -t nat -L POSTROUTING -n -v

7. Network Policy 디버깅

7.1 Network Policy 기본 진단

적용된 Network Policy 확인

kubectl get networkpolicy -A

kubectl describe networkpolicy <policy-name> -n <namespace>

Pod에 적용되는 Network Policy 확인

kubectl get networkpolicy -n <namespace> -o json | \

jq '.items[] | select(.spec.podSelector.matchLabels | to_entries[] |

.key == "app" and .value == "myapp")'

Network Policy 적용 전후 연결 테스트

kubectl exec -it <source-pod> -- nc -zv <target-pod-ip> <port>

7.2 Network Policy 트러블슈팅 패턴

모든 트래픽을 차단하는 기본 정책

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

name: default-deny-all

spec:

podSelector: {}

policyTypes:

- Ingress

- Egress

정책 적용 후 통신 테스트

kubectl exec -it <pod> -- wget -qO- --timeout=2 http://<target-service>

CNI별 Network Policy 로그 확인

Calico

kubectl logs -n calico-system -l k8s-app=calico-node --tail=100

Cilium

kubectl exec -n kube-system <cilium-pod> -- cilium policy get

kubectl exec -n kube-system <cilium-pod> -- cilium endpoint list

8. Calico 트러블슈팅

8.1 Calico 상태 확인

Calico 노드 상태 확인

kubectl get pods -n calico-system

calicoctl node status

BGP 피어 상태 확인

calicoctl get bgpPeer

calicoctl node status | grep -A 5 "BGP"

IP Pool 확인

calicoctl get ippool -o wide

Calico 네트워크 정책 확인 (Kubernetes + Calico 전용)

calicoctl get networkpolicy -A

calicoctl get globalnetworkpolicy

8.2 Calico 디버깅

Felix 로그 레벨 변경 (디버깅 시)

calicoctl patch felixconfiguration default \

--patch '{"spec":{"logSeverityScreen":"Debug"}}'

BIRD 라우팅 데몬 상태 확인

kubectl exec -n calico-system <calico-node-pod> -- birdcl show route

IP-in-IP 터널 상태

kubectl exec -n calico-system <calico-node-pod> -- ip tunnel show

Calico가 프로그래밍한 iptables 규칙 확인

sudo iptables -L -n | grep cali

9. Cilium 트러블슈팅

9.1 Cilium 상태 확인

Cilium 에이전트 상태 확인

kubectl exec -n kube-system <cilium-pod> -- cilium status --verbose

Cilium 엔드포인트 목록

kubectl exec -n kube-system <cilium-pod> -- cilium endpoint list

BPF 맵 상태 확인

kubectl exec -n kube-system <cilium-pod> -- cilium bpf lb list

kubectl exec -n kube-system <cilium-pod> -- cilium bpf ct list global

Hubble로 네트워크 플로우 관찰

hubble observe --namespace <namespace>

hubble observe --pod <pod-name> --protocol TCP

9.2 Cilium 디버깅

Cilium 연결성 테스트

kubectl exec -n kube-system <cilium-pod> -- cilium connectivity test

eBPF 프로그램 상태 확인

kubectl exec -n kube-system <cilium-pod> -- cilium bpf prog list

Cilium 정책 트레이싱

kubectl exec -n kube-system <cilium-pod> -- cilium policy trace \

--src-k8s-pod <namespace>:<src-pod> \

--dst-k8s-pod <namespace>:<dst-pod> \

--dport <port>

Cilium 모니터로 실시간 이벤트 관찰

kubectl exec -n kube-system <cilium-pod> -- cilium monitor --type drop

kubectl exec -n kube-system <cilium-pod> -- cilium monitor --type policy-verdict

10. Debug 컨테이너와 Ephemeral 컨테이너

10.1 kubectl debug 활용

실행 중인 Pod에 디버그 컨테이너 연결

kubectl debug -it <pod-name> --image=nicolaka/netshoot --target=<container-name>

노드 수준 디버깅

kubectl debug node/<node-name> -it --image=ubuntu

Pod 복사본 생성하여 디버깅 (원본에 영향 없음)

kubectl debug <pod-name> -it --copy-to=debug-pod --image=nicolaka/netshoot

프로세스 네임스페이스를 공유하는 디버그 컨테이너

kubectl debug -it <pod-name> --image=busybox --share-processes

10.2 netshoot을 활용한 네트워크 디버깅

netshoot 컨테이너 배포

kubectl run netshoot --image=nicolaka/netshoot --restart=Never -- sleep 3600

종합 네트워크 진단

kubectl exec -it netshoot -- bash

내부에서 실행할 명령어들

TCP 연결 테스트

nc -zv <service-ip> <port>

HTTP 요청 테스트

curl -v http://<service-name>.<namespace>.svc.cluster.local:<port>/health

DNS 조회

dig +short <service-name>.<namespace>.svc.cluster.local

패킷 캡처

tcpdump -i eth0 -nn port 80

네트워크 경로 추적

mtr <target-ip>

SSL/TLS 연결 확인

openssl s_client -connect <service-ip>:443

11. 실전 디버깅 시나리오

시나리오 1: Pod가 Service에 접근할 수 없는 경우

1단계: Service와 Endpoints 확인

kubectl get svc <service-name> -o yaml

kubectl get endpoints <service-name>

2단계: Endpoints가 비어있다면 -> selector 확인

kubectl get pods -l <label-selector> --show-labels

3단계: Pod가 Ready 상태인지 확인

kubectl get pods -l <label-selector> -o wide

kubectl describe pod <target-pod> | grep -A 5 "Conditions"

4단계: kube-proxy 규칙 확인

sudo iptables -t nat -L KUBE-SERVICES -n | grep <cluster-ip>

5단계: 직접 Pod IP로 접근 테스트

kubectl exec -it <source-pod> -- curl -v http://<pod-ip>:<target-port>

시나리오 2: 간헐적인 타임아웃 발생

1단계: conntrack 테이블 포화 확인

sudo sysctl net.netfilter.nf_conntrack_count

sudo sysctl net.netfilter.nf_conntrack_max

2단계: 패킷 드롭 확인

kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- \

netstat -s | grep -i drop

3단계: 네트워크 인터페이스 오류 확인

kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- \

ip -s link show

4단계: TCP 재전송 확인

kubectl debug node/<node-name> -it --image=nicolaka/netshoot -- \

netstat -s | grep -i retrans

시나리오 3: DNS 해석이 느린 경우

1단계: DNS 응답 시간 측정

kubectl exec -it <pod> -- dig <service-name>.default.svc.cluster.local +stats | grep "Query time"

2단계: CoreDNS Pod 리소스 사용량 확인

kubectl top pods -n kube-system -l k8s-app=kube-dns

3단계: ndots 최적화 적용

Pod spec에 다음 추가:

dnsConfig:

options:

- name: ndots

value: "2"

4단계: CoreDNS 캐시 히트율 확인

kubectl exec -n kube-system <coredns-pod> -- \

wget -qO- http://localhost:9153/metrics | grep coredns_cache

12. 디버깅 체크리스트

네트워크 문제를 체계적으로 접근하기 위한 체크리스트입니다.

[ ] Pod 상태 확인 (Running, Ready)

[ ] Service Endpoints 확인 (비어있지 않은지)

[ ] DNS 해석 확인 (nslookup/dig)

[ ] 직접 Pod IP로 연결 테스트

[ ] kube-proxy 규칙 확인 (iptables/IPVS)

[ ] Network Policy 확인 (Ingress/Egress 규칙)

[ ] CNI 플러그인 상태 확인

[ ] 노드 간 네트워크 연결 확인

[ ] MTU 설정 확인

[ ] 방화벽/보안그룹 규칙 확인

[ ] conntrack 테이블 상태 확인

[ ] CoreDNS 상태 및 로그 확인

네트워크 디버깅은 계층적으로 접근하는 것이 효과적입니다. L2(이더넷) -> L3(IP/라우팅) -> L4(TCP/UDP) -> L7(HTTP/DNS) 순서로 각 계층에서 문제가 없는지 확인하면, 복잡한 네트워크 문제도 체계적으로 해결할 수 있습니다.

현재 단락 (1/192)

컨테이너 네트워크 디버깅의 기초는 Docker가 제공하는 네트워킹 모델을 정확히 이해하는 것에서 시작합니다.

작성 글자: 0원문 글자: 10,262작성 단락: 0/192