Skip to content

KR_K8s_Networking

somaz edited this page Jul 13, 2026 · 6 revisions

Kubernetes 네트워킹

서비스 타입 & 네트워크 심화 (Q6, Q11-Q21)

Q6. Kubernetes Service Type & ExternalTrafficPolicy

Kubernetes Service Type

Kubernetes에서 서비스는 논리적 Pod 세트와 이에 액세스하는 정책을 정의한다. 서비스 유형은 서비스가 네트워크에 노출되는 방식을 지정한다.

주요 서비스 유형은 다음과 같다.

  • ClusterIP: 클러스터 내에서만 접속 가능한 서비스를 제공하는 기본 서비스 유형이다.
  • NodePort: 정적 포트에서 각 노드의 IP에 대한 서비스를 노출한다. <NodeIP>:<NodePort>를 요청하여 클러스터 외부에서 NodePort 서비스에 연결할 수 있다.
  • LoadBalancer: 현재 클라우드에 외부 로드 밸런서를 생성하고(지원되는 경우) 고정 외부 IP를 서비스에 할당한다.
  • ExternalName: 해당 값과 함께 CNAME 레코드를 반환하여 externalName 필드(예: foo.bar.example.com)의 콘텐츠에 서비스를 매핑한다.

ExternalTrafficPolicy

externalTrafficPolicy는 수신 트래픽이 라우팅되는 방식을 제어하는 ​​LoadBalancer 또는 NodePort 유형의 서비스 옵션이다. Cluster 또는 Local이라는 두 가지 값을 가질 수 있다.

  • Cluster: 트래픽은 임의의 노드로 라우팅되며, 해당 노드에 서비스용 Pod가 없으면 트래픽은 있는 노드로 전달된다. 이로 인해 추가 홉이 발생하고 소스 IP 주소가 모호해질 수 있다.
  • Local: 트래픽은 서비스용 Pod가 있는 노드로만 라우팅된다. 트래픽이 파드 없이 노드에 도달하면 전달되지 않고 삭제된다. 이렇게 하면 원래 소스 IP 주소가 유지되지만 파드 전체에 트래픽이 고르지 않게 분산될 수 있다.


Q11. 같은 노드 내 Pod 통신에서 ARP Proxy의 동작 원리는?

  • Pod의 veth pair는 호스트의 caliXXX 인터페이스와 연결되는데, caliXXX는 IP 없이 MAC 주소만 가진다.
  • Pod가 목적지 Pod의 MAC 주소를 알기 위해 ARP 요청을 보내면, 호스트 커널의 ARP Proxy가 자신의 MAC 주소로 응답한다.
  • Pod는 호스트 MAC으로 패킷을 보내고, 호스트의 라우팅 테이블이 목적지 Pod의 veth 인터페이스로 패킷을 전달한다. 이를 통해 L2 브리지 없이도 효율적인 Pod 간 통신이 가능하다.

Q12. Overlay Network의 VXLAN 캡슐화 과정과 성능 영향은?

VXLAN은 L2 over L3 터널링으로 동작한다.

  • ① Pod의 원본 패킷(Inner Ethernet + IP) →
  • ② VXLAN 헤더 추가(VNID 포함) →
  • ③ 외부 UDP 헤더(포트 4789) 추가 →
  • ④ 외부 IP 헤더(노드 IP) 추가 →
  • ⑤ 외부 Ethernet 헤더.

MTU는 1500에서 50바이트 감소하여 1450이 되며, CPU 오버헤드(캡슐화/역캡슐화)와 대역폭 오버헤드(약 3%)가 발생한다. AWS VPC CNI는 이를 해결하기 위해 Pod가 VPC IP를 직접 사용한다.


Q13. iptables vs IPVS 모드의 성능 차이와 선택 기준은?

  • iptables는 순차 검색으로 O(n) 복잡도를 가지며, 1000개 이상 Service에서 성능 저하가 발생한다. Rule 업데이트 시 전체 재작성이 필요하다.
  • IPVS는 해시 테이블로 O(1) 복잡도를 가지며, 대규모 클러스터에 적합하다. rr(라운드 로빈), lc(최소 연결), sh(소스 해싱) 등 다양한 로드밸런싱 알고리즘을 지원한다.
  • 100개 이하 Service는 iptables, 그 이상은 IPVS를 권장한다. IPVS는 ipvsadm으로 실시간 연결 상태를 확인할 수 있다.

Q14. kube-proxy의 iptables 체인 구조와 DNAT/SNAT 과정은?

Service 생성 시 kube-proxy가 iptables 규칙을 생성한다.

  • PREROUTING → KUBE-SERVICES → KUBE-SVC-XXX → KUBE-SEP-XXX (각 Pod Endpoint). ClusterIP 트래픽: DNAT로 Pod IP로 변환.
  • NodePort 트래픽: KUBE-MARK-MASQ로 마킹 후 SNAT로 노드 IP로 변환(externalTrafficPolicy: Cluster), Local 설정 시 SNAT 생략.
  • conntrack으로 연결 추적하여 응답 패킷도 올바르게 라우팅한다. iptables-save로 전체 규칙을 확인하고, KUBE-SERVICES 체인부터 추적한다.

Q15. CoreDNS의 캐싱 전략과 ndots 설정의 영향은?

  • CoreDNS는 /etc/resolv.conf 의 ndots(기본값 5) 설정에 따라 DNS 쿼리를 처리한다.
  • FQDN이 아닌 경우 search 도메인을 순차적으로 붙여 조회하므로, my-service 조회 시 최대 6번의 쿼리가 발생할 수 있다.
  • ndots를 낮추거나 FQDN(my-service.namespace.svc.cluster.local)을 사용하여 쿼리 수를 줄인다.
  • CoreDNS는 cache plugin으로 TTL 기반 캐싱을 하며, 응답 시간을 ms 단위로 단축한다. autopath plugin은 search 순서를 최적화한다.

Q16. Calico의 BGP 라우팅과 Route Reflector의 역할은?

  • Calico는 BGP로 Pod CIDR 정보를 노드 간 광고한다.
  • Full-mesh 모드는 모든 노드가 서로 피어링하여 N(N-1)/2 개의 연결이 생성되므로, 100개 이상 노드에서는 확장성 문제가 발생한다.
  • Route Reflector 모드는 중앙 RR 노드가 라우팅 정보를 집중 관리하여 N개의 연결만 필요하다.
  • RR은 SPOF 방지를 위해 다중화하며, Kubernetes Node를 RR로 설정하거나 전용 RR을 구성한다. calicoctl node status로 BGP 피어 상태를 확인한다.

Q17. Service Mesh 없이 Pod 간 mTLS 구현 방법은?

  • ① Cert-Manager로 CA 인증서 생성 →
  • ② 각 Pod에 TLS Secret 마운트 →
  • ③ 애플리케이션에서 TLS 핸드셰이크 구현.

NetworkPolicy로 특정 Label Pod만 통신 허용하고, PSP(Pod Security Policy) 또는 PSA(Pod Security Admission)로 권한 제한한다.

Linkerd/Istio 같은 Service Mesh는 이를 자동화하여 애플리케이션 코드 수정 없이 mTLS를 제공하며, 트래픽 암호화, 인증, 인가, Observability를 통합 관리한다.


Q18. Ingress Controller의 동작 원리와 NGINX vs Traefik vs Istio Gateway 비교는?

  • Ingress Controller는 Ingress 리소스를 감시하여 리버스 프록시 설정을 자동 생성한다. NGINX Ingress: 가장 성숙하고 안정적, annotation 기반 설정, ConfigMap으로 글로벌 설정.
  • Traefik: 동적 설정, 자동 SSL(Let's Encrypt), 미들웨어 체인, Kubernetes CRD 지원.
  • Istio Gateway: Service Mesh 통합, L7 라우팅, 트래픽 분할(Canary), mTLS, Observability 내장.
  • 단순한 L7 라우팅은 NGINX, 동적 환경은 Traefik, 마이크로서비스 고급 기능은 Istio를 선택한다.

Q19. AWS LoadBalancer Controller vs Legacy Cloud Provider의 차이는?

Legacy (in-tree) AWS LoadBalancer Controller (out-of-tree)
업데이트 주기 느림 (K8s 코어에 종속) 독립적, 빠름
LB 지원 Classic LB만 ALB + NLB 네이티브
기능 기본 IP 모드, TargetGroupBinding, WAF 통합, Subnet Discovery(태그 기반), NLB Client IP 보존

Ingress로 ALB 생성 시 annotation으로 세밀한 제어가 가능하며, Service로 NLB 생성 시 Instance/IP 타입을 선택할 수 있다. IP 타입은 Pod IP를 직접 등록하여 노드 홉을 제거한다.


Q20. 외부 클라이언트 Source IP 확인 방법과 X-Forwarded-For vs Proxy Protocol 차이는?

  • AWS: externalTrafficPolicy: Local + NLB(Proxy Protocol v2)로 클라이언트 IP 유지. ALB는 X-Forwarded-For 헤더 사용.
  • On-Premise: externalTrafficPolicy: Local + MetalLB(Layer2/BGP 모드).
X-Forwarded-For Proxy Protocol
계층 L7 (HTTP 헤더) L4 (TCP 연결)
동작 애플리케이션이 직접 파싱, 다중 프록시 시 체인 형성 연결 시작 시 바이너리 헤더 전송
지원 모든 HTTP 프록시 NGINX, HAProxy, NLB
성능 약간의 오버헤드 오버헤드 거의 없음

externalTrafficPolicy: Local 은 불균형 문제가 있으므로 Pod가 모든 노드에 고르게 분산되도록 Anti-Affinity 설정이 필요하다.

💡 용어 설명:

  • 네트워크 심화 질문들(Q11-Q20)에서 사용된 용어들(ARP Proxy, Overlay Network, VXLAN, IPIP, iptables, IPVS, CNI, Calico, BGP, CoreDNS, Ingress Controller, X-Forwarded-For, Proxy Protocol 등)에 대한
  • 상세한 설명은 문서 상단의 주요 용어 통합 정리 > 네트워킹 섹션을 참고하세요.

Q21. 외부에서 Pod까지 전체 패킷 흐름을 단계별로 설명하세요.

  • External Traffic → Ingress Controller/LoadBalancer(AWS ELB, NLB, ALB) 진입 →
  • Service ClusterIP(Virtual IP, Endpoints 관리) →
  • kube-proxy(iptables KUBE-SERVICES 체인, DNAT로 Pod IP 변환, IPVS 모드는 해시 테이블 사용) →
  • CNI Network(Calico/Flannel이 라우팅, 같은 노드는 veth pair + ARP Proxy) →
  • Overlay Network(다른 노드는 VXLAN/IPIP 캡슐화, 터널링 인터페이스) →
  • Pod Container Port 도착. 디버깅: kubectl logs, tcpdump, iptables-save, Endpoints 확인, NetworkPolicy 검증.

💡 용어 설명:

  • 위 답변에 사용된 네트워크 관련 용어들(ClusterIP, Endpoints, DNAT, IPVS, CNI, veth pair, ARP Proxy, Overlay Network, VXLAN, IPIP, 캡슐화, NetworkPolicy 등)에 대한
  • 상세한 설명은 문서 상단의 주요 용어 통합 정리 > 네트워킹 섹션을 참고하세요.

Q21-1. CNI Plugin이 Pod 네트워크를 설정하는 전체 과정과 IPAM의 역할은?

CNI(Container Network Interface)는 kubelet과 네트워크 플러그인 간의 표준 인터페이스다.

Pod 네트워크 설정 흐름:

  • ① kubelet이 CRI(Container Runtime Interface)를 통해 컨테이너 생성 요청 →
  • ② CRI가 네트워크 네임스페이스 생성 →
  • ③ kubelet이 CNI Plugin 호출(ADD 커맨드) →
  • IPAM(IP Address Management) Plugin이 사용 가능한 IP 주소 할당 →
  • ⑤ CNI Plugin이 veth pair 생성(한쪽은 Pod 네임스페이스, 다른쪽은 호스트) →
  • ⑥ Pod쪽 인터페이스에 IP 설정 및 기본 라우트 추가 →
  • ⑦ 호스트쪽 인터페이스를 브리지 또는 라우팅 테이블에 연결 →
  • ⑧ CNI가 결과(IP, Gateway, DNS)를 kubelet에 반환.

IPAM 역할:

  • host-local: 로컬 파일에 IP 할당 정보 저장, 간단하지만 노드 간 동기화 없음.
  • Calico IPAM: etcd 기반 분산 IP 관리, IP Pool 개념으로 효율적 할당.
  • Whereabouts: etcd/Kubernetes API로 멀티 네트워크 IP 관리.

디버깅:

# CNI 로그
ls /var/log/pods/
ls /opt/cni/bin/

# IP 할당 상태 (Calico)
calicoctl ipam show

# 네트워크 네임스페이스 확인
ip netns list
nsenter -t <pid> -n ip addr

Q21-2. Service Mesh에서 Sidecar Proxy가 트래픽을 가로채는 iptables 규칙 원리는?

Istio/Linkerd 같은 Service Mesh는 Envoy/Linkerd-proxy를 sidecar로 주입하여 모든 트래픽을 가로챈다.

Sidecar Injection 과정:

  • ① Mutating Admission Webhook이 Pod Spec 수정 →
  • ② Init Container(istio-init)가 iptables 규칙 설정 →
  • ③ Sidecar Proxy 컨테이너 추가 →
  • ④ 애플리케이션 컨테이너와 함께 실행.

iptables 규칙 구조:

# Outbound 트래픽 가로채기
-A OUTPUT -p tcp -j ISTIO_OUTPUT
-A ISTIO_OUTPUT ! -d 127.0.0.1/32 -j ISTIO_REDIRECT
-A ISTIO_REDIRECT -p tcp -j REDIRECT --to-ports 15001

# Inbound 트래픽 가로채기
-A PREROUTING -p tcp -j ISTIO_INBOUND
-A ISTIO_INBOUND -p tcp --dport 80 -j REDIRECT --to-ports 15006

동작 원리:

  • Outbound: 애플리케이션이 외부로 보내는 트래픽을 Envoy의 15001 포트로 리다이렉트
  • Inbound: Pod로 들어오는 트래픽을 Envoy의 15006 포트로 리다이렉트
  • Envoy가 mTLS, 라우팅, 로드밸런싱, Retry, Circuit Breaker 적용 후 실제 목적지로 전달

예외 처리:

  • Envoy 자신의 트래픽은 무한 루프 방지를 위해 제외
  • Prometheus 메트릭 수집 포트(15090) 제외
  • traffic.sidecar.istio.io/excludeOutboundPorts annotation으로 특정 포트 제외

Q21-3. Kubernetes에서 MTU 불일치로 인한 패킷 단편화 문제와 해결 방법은?

MTU(Maximum Transmission Unit)는 한 번에 전송 가능한 최대 패킷 크기다.

문제 상황:

  • 일반 Ethernet MTU: 1500 bytes
  • VXLAN Overlay 오버헤드: 50 bytes (VXLAN header 8 + Outer IP 20 + Outer UDP 8 + Outer Ethernet 14)
  • Pod의 실제 사용 가능 MTU: 1450 bytes
  • 애플리케이션이 1500 byte 패킷 전송 시 단편화(fragmentation) 발생

증상:

  • 대용량 데이터 전송 시 성능 저하
  • TCP 연결이 중간에 끊김
  • PMTUD (Path MTU Discovery) 실패 시 통신 불가

해결 방법:

1. Pod MTU 자동 설정:

# Calico CNI 설정
apiVersion: projectcalico.org/v3
kind: FelixConfiguration
metadata:
  name: default
spec:
  mtuIfacePattern: "^((en|wl|ww|sl|ib)[opsx].*|(eth|wlan|wwan).*)"
  vxlanMTU: 1450  # VXLAN 사용 시

2. CNI에서 자동 감지:

  • Calico: FELIX_IPINIPMTU, FELIX_VXLANMTU 환경변수
  • Cilium: tunnel-protocol 설정에 따라 자동 계산
  • AWS VPC CNI: ENI MTU 기반 자동 설정 (Jumbo Frame 지원 시 9001)

3. TCP MSS Clamping:

# iptables로 MSS 조정
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

4. 물리 인터페이스 Jumbo Frame 활성화:

# 호스트 네트워크에서 MTU 증가
ip link set dev eth0 mtu 9000

확인 방법:

# Pod 내부 MTU 확인
kubectl exec -it <pod> -- ip link show eth0

# PMTUD 테스트 (Don't Fragment 플래그로 ping)
ping -M do -s 1472 <destination>  # 성공하면 MTU 1500 OK
ping -M do -s 1422 <destination>  # VXLAN 환경에서 테스트

Q21-4. NodePort Service의 SNAT 동작과 Session Affinity 문제를 설명하세요.

NodePort Service는 모든 노드의 특정 포트로 외부 접근을 허용한다.

기본 동작 (externalTrafficPolicy: Cluster):

  • ① 외부 클라이언트가 Node1:30080으로 요청 →
  • ② Node1의 kube-proxy가 랜덤하게 Node2의 Pod B 선택 →
  • SNAT(Source NAT) 발생: 클라이언트 IP → Node1 IP로 변경 →
  • ④ Pod B는 Node1을 클라이언트로 인식 (원본 IP 손실) →
  • ⑤ 응답 패킷도 Node1을 거쳐 돌아감 (추가 홉)

SNAT 발생 이유:

  • Node2의 Pod B가 클라이언트 IP로 직접 응답하면, 클라이언트는 Node1으로 요청했는데 Node2에서 응답이 와서 연결이 끊김 (비대칭 라우팅)
  • SNAT로 Node1 IP를 유지하여 응답 경로 보장

Session Affinity 문제:

apiVersion: v1
kind: Service
spec:
  sessionAffinity: ClientIP  # 같은 클라이언트 IP는 같은 Pod로
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800  # 3시간

문제점:

  • SNAT로 인해 모든 요청이 Node IP에서 오는 것처럼 보임
  • 여러 클라이언트가 같은 Node를 통하면 모두 같은 Pod로 라우팅 (불균형)

해결 방법:

1. externalTrafficPolicy: Local 사용:

spec:
  type: NodePort
  externalTrafficPolicy: Local  # SNAT 제거, 원본 IP 유지
  • 장점: 클라이언트 IP 유지, Session Affinity 정상 동작, 홉 감소
  • 단점: Pod 없는 노드로 요청 시 실패, 불균형 가능성

2. LoadBalancer + Proxy Protocol:

service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"

3. Ingress Controller 사용:

  • L7에서 X-Forwarded-For 헤더로 원본 IP 전달
  • Ingress가 Session Affinity 관리 (Cookie 기반)

디버깅:

# conntrack 테이블 확인
conntrack -L | grep <service-ip>

# iptables SNAT 규칙 확인
iptables -t nat -L KUBE-POSTROUTING -n -v

# Session Affinity 동작 확인
kubectl get endpoints <service> --watch

Q21-5. Dual-Stack (IPv4/IPv6) Kubernetes 클러스터 구성과 고려사항은?

Dual-Stack은 IPv4와 IPv6를 동시에 지원하는 네트워크 구성이다 (K8s 1.23+ GA).

클러스터 설정:

# kube-apiserver 플래그
--service-cluster-ip-range=10.96.0.0/12,fd00:1234::/112
--feature-gates=IPv6DualStack=true

# kube-controller-manager 플래그
--cluster-cidr=10.244.0.0/16,fd00:5678::/104
--service-cluster-ip-range=10.96.0.0/12,fd00:1234::/112
--node-cidr-mask-size-ipv4=24
--node-cidr-mask-size-ipv6=120

Pod 네트워크:

apiVersion: v1
kind: Pod
metadata:
  name: dual-stack-pod
spec:
  containers:
  - name: app
    image: nginx
status:
  podIPs:
  - ip: 10.244.1.5      # IPv4
  - ip: fd00:5678::5    # IPv6

Service 구성:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ipFamilyPolicy: PreferDualStack  # SingleStack | PreferDualStack | RequireDualStack
  ipFamilies:
  - IPv4
  - IPv6
  clusterIPs:
  - 10.96.100.200      # Primary (IPv4)
  - fd00:1234::200     # Secondary (IPv6)

CNI 지원:

  • Calico: Dual-Stack 완전 지원, IPv6 BGP 피어링
  • Cilium: Native IPv6 지원, eBPF 기반 고성능
  • Flannel: 제한적 지원 (VXLAN 모드만)

고려사항:

1. DNS 해석:

# CoreDNS가 AAAA 레코드 자동 생성
my-service.default.svc.cluster.local.  # A + AAAA 반환

2. 애플리케이션 호환성:

  • 0.0.0.0:8080::/0:8080 또는 [::]:8080 (IPv6 바인딩)
  • Go: net.Listen("tcp", ":8080") 자동 Dual-Stack
  • Python: socket.AF_INET6 + IPV6_V6ONLY=0

3. NetworkPolicy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
spec:
  ingress:
  - from:
    - ipBlock:
        cidr: 10.0.0.0/8      # IPv4
    - ipBlock:
        cidr: fd00::/8        # IPv6

4. Cloud Provider 제약:

  • AWS: VPC IPv6 CIDR 필요, ELB는 Dual-Stack NLB만 지원
  • GCP: Dual-Stack GKE 베타, 추가 설정 필요
  • Azure: AKS Dual-Stack 프리뷰

마이그레이션 전략:

  • ① IPv4 Single-Stack 클러스터 구성
  • ipFamilyPolicy: PreferDualStack으로 점진적 IPv6 추가
  • ③ 애플리케이션별 IPv6 호환성 검증
  • ipFamilyPolicy: RequireDualStack으로 강제
  • ⑤ Primary IP Family를 IPv6로 전환 (ipFamilies 순서 변경)

디버깅:

# Pod IPv6 주소 확인
kubectl get pod <pod> -o jsonpath='{.status.podIPs}'

# IPv6 연결 테스트
kubectl exec -it <pod> -- curl -6 http://[fd00:1234::200]:80

# CNI IPv6 라우팅 확인
ip -6 route show


네트워크 패킷 흐름 (외부 → 클러스터)

19. Kubernetes Network Packet Flow (외부 → 클러스터)

Kubernetes 클러스터로 외부 트래픽이 전달되는 과정을 이해하면 네트워킹 문제를 효과적으로 디버깅할 수 있다. 패킷이 외부에서 Pod까지 전달되는 전체 흐름을 단계별로 살펴보자.

패킷 흐름 단계

graph LR
    A[External Traffic] --> B[Ingress Controller / LoadBalancer]
    B --> C[Service ClusterIP]
    C --> D[kube-proxy iptables/IPVS]
    D --> E[CNI Network]
    E --> F[Pod Container Port]
    
    D -.DNAT.-> E
    E -.Overlay Network.-> F
Loading

1. 외부 트래픽 진입점

외부 트래픽은 먼저 Ingress Controller 또는 LoadBalancer를 통해 클러스터로 진입한다.

  • Ingress Controller: HTTP/HTTPS 트래픽을 처리하며, 도메인 기반 라우팅을 제공한다.
    • 예: NGINX Ingress, Traefik, HAProxy
  • LoadBalancer: 클라우드 환경에서 제공하는 외부 로드 밸런서
    • 예: AWS ELB, GCP Load Balancer, Azure Load Balancer
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: my-app

2. Service 객체로 전달

트래픽은 Service 객체의 ClusterIP로 전달된다.

  • ClusterIP는 실제 물리적 IP가 아닌 **가상 IP(Virtual IP)**이다.
  • 이 가상 IP는 클러스터 내부에서만 유효하며, 실제 네트워크 인터페이스에 할당되지 않는다.
  • Service는 Selector를 통해 매칭되는 Pod들을 찾고, 이들의 IP를 Endpoints 객체로 관리한다.
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP

3. kube-proxy에 의한 패킷 라우팅

kube-proxy가 각 노드에서 iptables 또는 IPVS 규칙을 관리하며, Service IP로 오는 패킷을 실제 Pod IP로 변환한다.

kube-proxy 동작 모드
  • iptables 모드 (기본값):

    • Service IP를 Pod IP로 DNAT(Destination NAT) 변환
    • 랜덤 방식으로 Pod 선택
    • 대규모 클러스터에서는 성능 저하 가능성
  • IPVS 모드:

    • Linux 커널의 IPVS(IP Virtual Server) 활용
    • 더 효율적인 로드 밸런싱 알고리즘 제공
    • 대규모 클러스터에 적합
# kube-proxy 모드 확인
kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode

# iptables 규칙 확인 (노드에서 실행)
sudo iptables -t nat -L -n | grep my-service

4. CNI를 통한 Pod 네트워크 전달

CNI(Container Network Interface) 가 구성한 네트워크를 통해 해당 Pod의 Container 포트로 패킷이 전달된다.

CNI 역할
  • Pod에 IP 주소 할당
  • Pod 간 네트워크 연결 구성
  • 네트워크 정책(NetworkPolicy) 적용
주요 CNI 플러그인
  • Calico: NetworkPolicy 지원, 확장성 우수
  • Flannel: 간단한 오버레이 네트워크
  • Weave Net: 암호화 지원
  • Cilium: eBPF 기반, 고성능
# NetworkPolicy 예제
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-frontend
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

5. 노드 간 통신 (Overlay Network)

Pod가 다른 노드에 있는 경우, Overlay 네트워크를 통해 노드 간 통신이 이루어진다.

Overlay Network 기술
  • VXLAN: 가장 일반적으로 사용되는 오버레이 프로토콜
  • IPIP: IP-in-IP 터널링
  • WireGuard: 암호화된 터널링
# VXLAN 인터페이스 확인
ip -d link show type vxlan

# CNI 설정 확인
cat /etc/cni/net.d/10-calico.conflist

일반적인 네트워킹 문제와 디버깅

1. Service Endpoints 문제

Service가 Selector와 매칭되는 Pod가 없으면 Endpoints가 생성되지 않아 503 에러 발생

# Endpoints 확인
kubectl get endpoints my-service

# Service와 Pod Selector 매칭 확인
kubectl get pods -l app=my-app
2. NetworkPolicy로 인한 통신 차단

NetworkPolicy 설정으로 Pod 간 트래픽이 차단될 수 있다.

# NetworkPolicy 확인
kubectl get networkpolicies

# NetworkPolicy 상세 확인
kubectl describe networkpolicy allow-from-frontend
3. CNI 문제

CNI 장애 시 노드 간 통신이 불가능하다.

# CNI Pod 상태 확인 (Calico 예시)
kubectl get pods -n kube-system | grep calico

# CNI 로그 확인
kubectl logs -n kube-system calico-node-xxxxx
4. kube-proxy 장애

kube-proxy 장애 시 Service 라우팅이 불가능하다.

# kube-proxy Pod 상태 확인
kubectl get pods -n kube-system | grep kube-proxy

# kube-proxy 로그 확인
kubectl logs -n kube-system kube-proxy-xxxxx

패킷 흐름 디버깅 도구

# 1. Pod 연결 테스트
kubectl exec -it my-pod -- curl http://my-service:80

# 2. DNS 확인
kubectl exec -it my-pod -- nslookup my-service

# 3. 네트워크 추적 (tcpdump)
kubectl exec -it my-pod -- tcpdump -i any -n port 8080

# 4. Service 상세 정보
kubectl describe service my-service

# 5. Pod 네트워크 인터페이스 확인
kubectl exec -it my-pod -- ip addr show

전체 패킷 흐름 요약

  1. External Traffic → Ingress/LoadBalancer로 진입
  2. Ingress/LoadBalancer → Service ClusterIP로 라우팅
  3. Service (Virtual IP) → kube-proxy가 인식
  4. kube-proxy → iptables/IPVS 규칙으로 Pod IP로 DNAT 변환
  5. CNI Network → Pod가 있는 노드로 패킷 전달 (필요시 Overlay Network)
  6. Pod Container Port → 최종 목적지 도착

이 흐름을 이해하면 Kubernetes 네트워킹 문제를 체계적으로 디버깅할 수 있으며, 각 단계에서 발생할 수 있는 문제를 빠르게 파악할 수 있다.

Reference


참고

Clone this wiki locally