Kubernetes 환경에서 nf_conntrack 고갈로 발생하는 패킷 드롭 — Ubuntu 기준 실전 가이드

Kubernetes 환경에서 NodePort, 외부 API 호출, 내부 서비스 간 통신이 간헐적으로 타임아웃 나는 경우가 있다.
Pod도 정상이고, 노드 리소스도 여유 있고, 로그도 깨끗한데 특정 트래픽만 불규칙하게 drop되는 패턴이다.

Ubuntu 기반 Kubernetes 노드에서 이런 현상이 반복될 때 가장 먼저 확인해야 하는 부분이 있다.

노드의 nf_conntrack 테이블이 한계에 도달했는지 여부다.

Ubuntu는 기본적으로 적당한 conntrack 값을 제공하지만,
Kubernetes 환경처럼 NAT이 집중되는 구조에서는 기본값이 모자라는 경우가 많다.

이 글은 Ubuntu 기반 Kubernetes 노드에서
conntrack이 어떤 역할을 하고,
왜 고갈되며,
어떻게 튜닝해야 안정화되는지를 실전 기준으로 정리한다.


1. Ubuntu + Kubernetes에서 NAT이 왜 과도하게 발생하는가

Kubernetes는 결국 리눅스 커널 위에서 돌아간다.
그리고 NAT이 발생하는 순간 conntrack 테이블에 세션이 저장된다.

Ubuntu든 CentOS든 상관없이 이 메커니즘은 동일하다.

Ubuntu에서 NAT이 가장 많이 발생하는 지점은 아래 네 가지다.

1) Pod → 외부 API (SNAT)

외부 SaaS, 외부 DB, 외부 REST 호출이 많은 서비스는
해당 노드의 NAT 세션이 빠르게 증가한다.

2) NodePort

NodePort는 구조적으로 DNAT/SNAT을 연속으로 사용한다.
트래픽이 몰리면 conntrack이 눈에 띄게 빨리 찬다.

3) ClusterIP (kube-proxy iptables 모드)

Ubuntu에서 kubeadm으로 구성한 Kubernetes는 기본적으로 iptables 기반 kube-proxy를 사용한다.

iptables 기반 로드밸런싱은
트래픽 경로에 따라 NAT이 1~2회 발생할 수 있다.

4) readinessProbe / livenessProbe 폭주

probe 자체도 TCP/HTTP 세션이다.
노드 하나에 probe가 몰리면 conntrack count가 의미 있게 증가한다.


2. conntrack 고갈 시 나타나는 Ubuntu 기반 Kubernetes 장애 패턴

conntrack table이 가득 차면
커널은 경고를 남기고 패킷을 그냥 버린다.

nf_conntrack: table full, dropping packet.

Ubuntu 노드에서 실질적으로 나타나는 현상은 다음과 같다.

  • NodePort 간헐적 timeout
  • 외부 API 호출 일부 실패
  • Ingress 503 (특정 노드만)
  • Pod → Pod 통신 중 Sporadic drop
  • HTTP 502/503 증가
  • 특정 Node만 트래픽 처리 불안정

특징은 랜덤처럼 보이지만 특정 노드에서만 반복된다는 점이다.


3. CNI 종류와 conntrack — 핵심은 “Calico냐 아니냐”가 아니다

많이 오해하는 부분이지만, conntrack은 CNI와 직접적인 관계가 없다.
CNI는 Pod ↔ Pod 라우팅을 담당하고,
conntrack은 NAT 시 상태 추적을 담당한다.

즉, Ubuntu + Kubernetes에서 NAT이 발생하면
CNI가 뭐든 conntrack은 사용된다.

CNIconntrack 의존도이유
CalicoOkube-proxy NAT 그대로 사용
FlannelOSNAT/DNAT 동일
WeaveOkube-proxy NAT 동일
Cilium (kube-proxy ON)ONAT 경로 동일
Cilium (kube-proxy replacement/eBPF)△ (줄어듦)내부 LB는 eBPF가 처리하지만 외부 SNAT은 여전히 Ubuntu 커널 위에서 처리됨

결론:
Kubernetes에서 NAT이 발생하는 모든 구조는 conntrack을 소비한다.
CNI 종류와 거의 무관하다.


4. Ubuntu에서 conntrack 실제 기본값을 어떻게 이해해야 하나?

중요한 부분.

Ubuntu 20.04 / 22.04 / 24.04 기준으로
아래 값을 “절대적 기본값”이라고 단정하는 것은 틀리다.

Ubuntu는 conntrack 값을 다음 요인으로 결정한다.

  • 커널 버전
  • 메모리 크기
  • nf_conntrack_buckets 자동 계산
  • /usr/lib/sysctl.d/ 내부 distro 기본 설정
  • 클라우드 이미지(EKS, GKE, AKS 등)의 prebaked sysctl 값
  • kubeadm 구성 여부

즉,

“Ubuntu 기본값 = 65536”
라는 식의 표현은 잘못이다.

다만 현실적으로 Ubuntu 노드에서 종종 관찰되는 낮은값이
65536 ~ 131072 범위라서
튜닝 필요성을 설명할 때 예시로 자주 등장하는 것이다.

그래서 실무에서는 실제 노드 값을 확인하는 것이 정답이다.

실제 값 확인

cat /proc/sys/net/netfilter/nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count

5. Ubuntu + Kubernetes에서 권장하는 conntrack 튜닝 값

트래픽 볼륨이 있는 Kubernetes라면
Ubuntu 기본 세팅 그대로는 부족한 경우가 많다.

Ubuntu에서 실전 튜닝 값은 다음과 같다.

기본 권장 (중형 클러스터 이상)

nf_conntrack_max = 262144
nf_conntrack_buckets = 65536

트래픽이 많은 환경

nf_conntrack_max = 524288  ~ 1048576
nf_conntrack_buckets = nf_conntrack_max / 4

메모리 16GB 이상 노드라면 이 값은 부담이 거의 없다.


6. Ubuntu에서 실제 튜닝 방법

/etc/sysctl.d/99-nf-conntrack.conf 생성:

net.netfilter.nf_conntrack_max=262144
net.netfilter.nf_conntrack_buckets=65536

적용:

sysctl --system

확인:

cat /proc/sys/net/netfilter/nf_conntrack_max
cat /sys/module/nf_conntrack/parameters/hashsize

hashsize가 변경되지 않는다면 Ubuntu에서는
모듈이 이미 로드된 상태라 재부팅이 필요할 수 있다.


7. Cilium eBPF 환경에서 conntrack이 줄어드는 이유 (Ubuntu 기준)

Cilium에서 kube-proxy replacement를 활성화하면
내부 ClusterIP LB나 NodePort LB 동작을
Ubuntu iptables가 아닌 eBPF가 처리한다.

그래서 내부 트래픽 NAT이 줄어들고
conntrack 소비량이 감소한다.

하지만 아래는 여전히 Ubuntu 커널 NAT을 사용한다.

  • Pod → 외부 인터넷 (SNAT 강제)
  • ExternalTrafficPolicy=Local
  • HostNetwork Pod
  • Services with externalTrafficPolicy=Cluster (부분 NAT)

즉,

NAT이 완전히 사라지는 게 아니라
“일부 구간에서 eBPF가 NAT을 우회한다”
정도로 이해하면 정확하다.


8. Ubuntu Kubernetes 환경에서 conntrack 고갈이 발생하는 실제 사례

  • NodePort가 붙은 API에 트래픽 집중
  • 단일 노드에 외부 outbound 트래픽 몰림
  • livenessProbe/readinessProbe가 초당 수십 번 발생
  • sidecar 구조로 트래픽 multiplicative 증가
  • StatefulSet Pod들이 같은 외부 DB로 집중 호출
  • Ingress 트래픽이 특정 노드에만 치우침

특히 Ubuntu 노드에서 기본값이 낮게 잡혀 있을 경우
(예: 65536~131072)
이 패턴이면 거의 100% 고갈된다.


결론

Ubuntu 기반 Kubernetes 노드에서 NAT 트래픽이 많은 경우
간헐적 타임아웃, NodePort 503, Pod ↔ Pod sporadic drop 등
원인을 찾기 어려운 장애가 반복된다.

이 현상의 핵심 원인은 대부분 다음이다.

Ubuntu 노드의 nf_conntrack 테이블이 기본값으로 너무 작게 잡혀 있음.

  • 기본값은 고정값이 아니고 환경별로 다르다.
  • CNI는 conntrack과 거의 무관하다.
  • kube-proxy iptables 모드인 이상 NAT은 Ubuntu 커널에서 발생한다.
  • Pod → 외부 트래픽, NodePort, ClusterIP LB가 모두 conntrack을 소비한다.
  • Ubuntu Kubernetes 환경에서는 nf_conntrack_max 증가가 필수다.

Ubuntu 기준 Kubernetes 환경에서
nf_conntrack_max = 262144 이상은 사실상 기본 운영선이고,
트래픽이 많은 시스템은 그 이상으로 설정해야 한다.

🛠 마지막 수정일: 2025.11.19

ⓒ 2025 엉뚱한 녀석의 블로그 [quirky guy's Blog]. 본문 및 이미지를 무단 복제·배포할 수 없습니다. 공유 시 반드시 원문 링크를 명시해 주세요.
ⓒ 2025 엉뚱한 녀석의 블로그 [quirky guy's Blog]. All rights reserved. Unauthorized copying or redistribution of the text and images is prohibited. When sharing, please include the original source link.

💡 도움이 필요하신가요?
Zabbix, Kubernetes, 그리고 다양한 오픈소스 인프라 환경에 대한 구축, 운영, 최적화, 장애 분석이 필요하다면 언제든 편하게 연락 주세요.

📧 Contact: jikimy75@gmail.com
💼 Service: 구축 대행 | 성능 튜닝 | 장애 분석 컨설팅


💡 Need Professional Support?
If you need deployment, optimization, or troubleshooting support for Zabbix, Kubernetes, or any other open-source infrastructure in your production environment, feel free to contact me anytime.

📧 Email: jikimy75@gmail.com
💼 Services: Deployment Support | Performance Tuning | Incident Analysis Consulting