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은 사용된다.
| CNI | conntrack 의존도 | 이유 |
|---|---|---|
| Calico | O | kube-proxy NAT 그대로 사용 |
| Flannel | O | SNAT/DNAT 동일 |
| Weave | O | kube-proxy NAT 동일 |
| Cilium (kube-proxy ON) | O | NAT 경로 동일 |
| 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]. 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
답글 남기기
댓글을 달기 위해서는 로그인해야합니다.