실습 환경 구성

mkdir cilium-lab && cd cilium-lab
curl -O https://raw.githubusercontent.com/gasida/vagrant-lab/refs/heads/main/cilium-study/3w/Vagrantfile
vagrant up
- 기본 배포 가상 머신 : k8s-ctr, k8s-w1, router
- router : 사내망 10.10.0.0/16 대역 통신과 연결, k8s 에 join 되지 않은 서버, loop1/loop2 dump 인터페이스 배치
- Cilium CNI 설치 상태로 배포 완료됨
IP Address Management (IPAM)
IPAM은 네트워크상의 IP 주소를 체계적으로 계획, 추적, 관리하는 방법론과 도구를 말합니다. 단순히 IP 주소를 할당하는 것을 넘어서 전체 네트워크 인프라의 IP 주소 사용을 최적화하고 제어하는 포괄적인 관리 체계입니다. 특히 클라우드와 컨테이너 환경에서는 전통적인 수동 IP 관리로는 한계가 있기 때문에 현대적인 IPAM 도입을 통해 확장 가능하고 안정적인 네트워크 인프라 구축이 필요합니다.
| Feature | Kubernetes | Cluster Scope(default) | Multi-Pool(Beta) | CRD-backend | AWS ENI |
|---|---|---|---|---|---|
| Tunnel routing | ✅ | ✅ | ❌ | ❌ | ❌ |
| Direct routing | ✅ | ✅ | ✅ | ✅ | ✅ |
| CIDR Configuration | Kubernetes | Cilium | Cilium | External | External (AWS) |
| Multiple CIDRs per cluster | ❌ | ✅ | ✅ | N/A | N/A |
| Multiple CIDRs per node | ❌ | ❌ | ✅ | N/A | N/A |
| Dynamic CIDR/IP allocation | ❌ | ❌ | ✅ | ✅ | ✅ |
클러스터 운영 중에 IPAM 모드를 변경하면 연결 중단이 발생할 수 있기 때문에 운영 중에 변경은 안하는 것이 좋습니다.
1. Kubernetes Host Scope
가장 단순한 IPAM 모드로, Kubernetes Controller Manager가 각 노드에 Pod CIDR을 할당하고, Cilium이 해당 범위 내에서 Pod에 IP를 할당합니다.
주요 특징:
- Kubernetes의 기본 Node 리소스를 통해 PodCIDR 정보를 얻음
- spec.podCIDRs 또는 annotation을 통해 CIDR 정보 수집
- 클러스터 전체에서 단일 대형 접두사가 할당되고, Kubernetes가 각 노드에 서브넷을 분할
- 설정: ipam: kubernetes
2. Cluster Scope (Default)
Cilium의 기본 IPAM 모드로, Cilium Operator가 CiliumNode CRD를 통해 각 노드에 PodCIDR을 관리합니다.
주요 특징:
- Kubernetes Controller Manager에 의존하지 않고 독립적으로 동작
- v2.CiliumNode 리소스를 사용하여 노드별 PodCIDR 관리
- 기본적으로 10.0.0.0/8 CIDR을 사용하며, /24 서브넷으로 분할
- 클러스터에 여러 CIDR 할당 가능
- 중앙 집중식 IP 관리 제공
3. Multi-Pool (Beta)
가장 유연한 IPAM 모드로, Pod/Namespace의 어노테이션에 따라 여러 IP 풀에서 IP를 할당할 수 있습니다.
주요 특징:
- Pod 또는 Namespace의 ipam.cilium.io/ip-pool 어노테이션 기반으로 IP 할당
- 동일 노드의 Pod가 다양한 범위에서 IP 주소 수신 가능
- 필요에 따라 동적으로 PodCIDR을 노드에 추가
- CiliumPodIPPool CRD를 통한 IP 풀 관리
제한사항:
- 터널 모드에서 IPsec 미지원 (WireGuard는 지원)
- 중복 CIDR을 가진 IPAM 풀 미지원
4. CRD-backed
Kubernetes CRD를 통해 IPAM을 제어하는 확장 가능한 인터페이스를 제공합니다.
주요 특징:
- CiliumNode 커스텀 리소스를 통한 IP 관리
- spec.ipam.available 필드에 사용 가능한 IP 목록 정의
- 외부 오퍼레이터에게 IPAM 위임 가능
- 노드별로 사용자 구성 가능
5. AWS ENI
AWS 클라우드 환경에 특화된 IPAM 모드로, AWS Elastic Network Interface(ENI)를 기반으로 IP를 할당합니다.
주요 특징:
- AWS EC2 API와 통신하여 ENI 기반 IP 할당
- CRD-backed allocator 기반으로 구축
- 사전 할당 워터마크를 통해 IP 주소 풀 유지
- 서브넷 선택 및 보안 그룹 연결을 노드별로 제어 가능
샘플 애플리케이션으로 네트워크 동작 확인
# 샘플 애플리케이션 배포
cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: webpod
spec:
replicas: 2
selector:
matchLabels:
app: webpod
template:
metadata:
labels:
app: webpod
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- sample-app
topologyKey: "kubernetes.io/hostname"
containers:
- name: webpod
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: webpod
labels:
app: webpod
spec:
selector:
app: webpod
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
EOF
# k8s-ctr 노드에 curl-pod 파드 배포
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: curl-pod
labels:
app: curl
spec:
nodeName: k8s-ctr
containers:
- name: curl
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
샘플 애플리케이션을 실행한 후 아래 명령어로 지속적인 트래픽을 전달하면 Hubble을 통해 패킷 흐름을 확인할 수 있습니다.
# 통신 확인
kubectl exec -it curl-pod -- curl webpod | grep Hostname
kubectl exec -it curl-pod -- sh -c 'while true; do curl -s webpod | grep Hostname; sleep 1; done'
# hubble ui 웹 접속 주소 확인 : default 네임스페이스 확인
NODEIP=$(ip -4 addr show eth1 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
echo -e "http://$NODEIP:30003"
# hubble relay 포트 포워딩 실행
cilium hubble port-forward&
hubble status

이번에는 터미널에서 아래 hubble observe 명령으로 Flow 로그를 모니터링 해보도록 하겠습니다.
hubble observe -f --protocol tcp --pod curl-pod

위 화면에서 화살표는 패킷 흐름의 방향입니다. 예를들어 curl-pod -> webpod의 경우 화살표가 -> 이므로 curl-pod에서 webpod로 패킷을 보내고 있다는 의미입니다. 양방향(<>)으로 표기된 것은 주로 연결 설정 단계나 상태 정보를 나타낼 때 사용됩니다.
--to-pod와 --from-pod 옵션을 사용해서 특정 방향의 흐름만 캡처할 수도 있지만 보통 request가 있으면 reponse 패킷까지 확인하는 것이 일반적이기 때문에 전체 패킷을 보는 것이 효과적입니다.
FORWARDED : 패킷이나 연결이 다음 처리 단계로 성공적으로 전달된 상태를 의미합니다.
특징:
- 정상적인 패킷 흐름을 나타냄
- 패킷이 Cilium 데이터패스의 다음 처리 엔티티로 전달됨
- 네트워크 정책을 통과하여 허용된 트래픽
- 가장 일반적으로 볼 수 있는 정상 상태
TRANSLATED : 주소 변환(NAT, SNAT, DNAT 등)이 발생한 상태를 의미합니다.
특징:
- IP 주소나 포트 번호가 변환됨
- Service Load Balancing, NAT 처리 시 발생
- 소스 또는 목적지 주소 변환 작업이 수행됨
- Kubernetes Service의 ClusterIP 처리 등에서 자주 관찰
그외 Verdict 타입들:
- DROPPED : 정책 위반, 잘못된 패킷 등으로 드롭됨
- REDIRECTED : 프록시로 리다이렉트됨
- AUDIT : 정책 감사 모드에서 드롭되었을 트래픽
- ERROR : 처리 중 오류 발생
네트워크 패킷 분석을 위해서는 tcpdump를 사용해야할 수도 있는데 이 때는 termshark를 통해서 패킷 흐름을 확인할 수도 있습니다. Wireshark의 경우 pcap 파일을 복사해서 Wireshark를 사용할 수 있는 환경으로 옮겨서 봐야하는데 termshark는 즉시 확인할 수 있어서 편리합니다.
tcpdump -i eth1 tcp port 80 -w /tmp/http.pcap
termshark -r /tmp/http.pcap


Routing
라우팅에는 크게 두가지 방식이 존재합니다.
Encapsulation 라우팅 (터널링) : VXLAN (기본)과 Geneve 프로토콜을 지원하고, 설정이 단순하며 네트워크 인프라에 독립적이라는 장점이 있는 반면 패킷 오버헤드가 존재하고 캡슐화/역캡슐화에 CPU 리소스를 필요로 합니다. 패킷이 캡슐화 되기 때문에 트러블슈팅의 복잡성이 증가한다는 단점이 있습니다.
- Cilium 기본 네트워킹 인프라에서 요구 사항이 가장 적은 모드이기 때문에 Encapsulation 모드에서 자동으로 실행됩니다.
- 이 모드에서는 모든 클러스터 노드가 UDP 기반 캡슐화 프로토콜 VXLAN 또는 Geneve를 사용하여 터널의 메시를 형성합니다.
- Cilium 노드 간의 모든 트래픽이 캡슐화됩니다.
- 캡슐화는 일반 노드 간 연결에 의존합니다. 이는 Cilium 노드가 이미 서로 연결될 수 있다면 모든 라우팅 요구 사항이 이미 충족된다는 것을 의미합니다.
- 기본 네트워크는 IPv4를 지원해야 합니다. 기본 네트워크와 방화벽은 캡슐화된 패킷을 허용해야 합니다:
- VXLAN (default) : UDP 8472
- Geneve : UDP 6081
- 장점
- 단순성 Simplicity
클러스터 노드를 연결하는 네트워크는 PodCIDR을 인식할 필요가 없습니다.
-
-
- 클러스터 노드는 여러 라우팅 또는 링크 계층 도메인을 생성할 수 있습니다.
- 클러스터 노드가 IP/UDP를 사용하여 서로 연결할 수 있는 한 기본 네트워크의 토폴로지는 중요하지 않습니다.
- 정체성 맥락 Identity context
- 캡슐화 프로토콜은 네트워크 패킷과 함께 메타데이터를 전송할 수 있게 해줍니다.
- Cilium은 소스 보안 ID와 같은 메타데이터를 전송하는 이 기능을 활용합니다.
- The identity transfer is an optimization designed to avoid one identity lookup on the remote node.
-
- 단점
- MTU Overhead
- 캡슐화 헤더를 추가하면 페이로드에 사용할 수 있는 유효 MTU가 네이티브 라우팅(VXLAN의 경우 네트워크 패킷당 50바이트)보다 낮아집니다.
- 이로 인해 특정 네트워크 연결에 대한 최대 처리량이 낮아집니다.
- 이는 점보 프레임(1500바이트당 오버헤드 50바이트 대 9000바이트당 오버헤드 50바이트)을 활성화함으로써 크게 완화될 수 있습니다.
- MTU Overhead
- 설정
- tunnel-protocol: Set the encapsulation protocol to vxlan or geneve, defaults to vxlan.
- tunnel-port: Set the port for the encapsulation protocol. Defaults to 8472 for vxlan and 6081 for geneve.
Native 라우팅 (Direct 라우팅) : 패킷이 노드에서 직접 라우팅되기 때문에 오버레이가 없고 Linux 커널 라우팅 테이블을 사용합니다.

- 네이티브 라우팅 데이터 경로는 라우팅 모드에서 네이티브로 활성화되며 네이티브 패킷 전달 모드를 활성화합니다.
- 네이티브 패킷 전달 모드는 캡슐화를 수행하는 대신 Cilium이 실행되는 네트워크의 라우팅 기능을 활용합니다.
- 네이티브 라우팅 모드에서는 Cilium이 다른 로컬 엔드포인트로 주소 지정되지 않은 모든 패킷을 Linux 커널의 라우팅 하위 시스템에 위임합니다.
- 이는 패킷이 로컬 프로세스가 패킷을 방출한 것처럼 라우팅된다는 것을 의미합니다.
- 따라서 클러스터 노드를 연결하는 네트워크는 PodCIDR을 라우팅할 수 있어야 합니다.
- PodCIDR 라우팅 방안 1
- 각 개별 노드는 다른 모든 노드의 모든 포드 IP를 인식하고 이를 표현하기 위해 Linux 커널 라우팅 테이블에 삽입됩니다.
- 모든 노드가 단일 L2 네트워크를 공유하는 경우 auto-direct-node-routes: true하여 이 문제를 해결할 수 있습니다.
- 그렇지 않으면 BGP 데몬과 같은 추가 시스템 구성 요소를 실행하여 경로를 배포해야 합니다.
- PodCIDR 라우팅 방안 2
- 노드 자체는 모든 포드 IP를 라우팅하는 방법을 모르지만 다른 모든 포드에 도달하는 방법을 아는 라우터가 네트워크에 존재합니다.
- 이 시나리오에서는 Linux 노드가 이러한 라우터를 가리키는 기본 경로를 포함하도록 구성됩니다.
- 이 모델은 클라우드 제공자 네트워크 통합에 사용됩니다. 자세한 내용은 Google Cloud, AWS ENI 및 Azure IPAM을 참조하세요.
- 설정
- routing-mode: native: Enable native routing mode.
- ipv4-native-routing-cidr: x.x.x.x/y: Set the CIDR in which native routing can be performed.
- auto-direct-node-routes: true : 동일 L2 네트워크 공유 시, 걱 노드의 PodCIDR에 대한 Linux 커널 라우팅 테이블에 삽입.
라우팅 확인 실습
현재 curl-pod와 webpod가 존재하며 curl-pod에서 webpod로 ICMP 요청 및 curl 요청을 하고 있습니다.


여기서 현재 Cilium 설정은 Native-Routing을 사용하고 있기 때문에 앞서 Native-Routing에 대한 동작을 정리했던 것처럼, 오버레이 네트워크를 사용하지 않고 Pod IP를 Pod 간 통신에 사용하기 때문에 NAT 없이 Pod IP가 Source IP로 지정됩니다.
tcpdump -i eth1 icmp -w /tmp/icmp.pcap
termshark -r /tmp/icmp.pcap


tcpdump로 캡처한 패킷을 termshark로 확인해보면 ICMP 패킷의 Source와 Dest IP가 모두 Pod의 IP로 그대로 기록된 것을 확인할 수 있습니다.
Masquerading
마스커레이딩은 클러스터를 벗어나는 모든 트래픽의 소스 IP를 노드 IP로 변경하는 NAT 기술을 의미합니다. 포드에 사용되는 IPv4 주소는 일반적으로 RFC1918 개인 주소 블록에서 할당되므로 공개적으로 라우팅할 수 없습니다. Cilium은 노드의 IP 주소가 이미 네트워크에서 라우팅 가능하기 때문에 클러스터를 떠나는 모든 트래픽의 소스 IP 주소를 자동으로 masquerade 합니다. (SNAT)

마스커레이딩은 크게 eBPF-based, iptables-based 두가지 방식으로 구현합니다. iptables 방식은 레거시이고 eBPF를 사용하는 방식을 권장합니다. 아래 명령으로 확인해볼 수 있습니다.
kubectl exec -it -n kube-system ds/cilium -c cilium-agent -- cilium status | grep Masquerading

현재 실습환경에서는 위와 같이 eBPF로 설정되어 있는 것을 확인할 수 있습니다. 별도로 지정되지 않은 경우, 프로그램은 BPF NodePort 장치 감지 메커니즘에 의해 선택된 장치에 자동으로 연결됩니다.
Pod에서 다른 노드로 패킷을 보낼 때 어떻게 동작하는지도 확인해보겠습니다.


위 tcpdump 기록에서 Pod의 IP인 10.244.0.175가 다른 Node의 IP인 192.168.10.101로 ICMP 패킷을 보낼 때도 Pod가 속한 노드의 IP로 SNAT가 발생하지 않고, Pod의 IP가 그대로 사용되는 것을 확인할 수 있습니다.
기본적으로 ipv4-native-routing-cidr 범위를 벗어난 IP 주소로 향하는 포드의 모든 패킷은 Masquerading되지만, 다른 (클러스터) 노드(Node IP)로 향하는 패킷은 제외됩니다. eBPF 마스커딩이 활성화되면 포드에서 클러스터 노드의 External IP로의 트래픽도 마스커딩되지 않습니다.
이번에는 Pod에서 쿠버네티스 클러스터에 속해있지 않은 다른 서버에 접근할 때는 어떻게 패킷이 흘러가는지 확인해보겠습니다. 네트워크 구성은 아래와 같습니다.

k8s-w1 노드에 속한 Pod가 클러스터 밖의 router라는 서버에 접근할 때 어떻게 동작하는지 tcpdump로 확인해보겠습니다.

먼저 클러스터 내 워커노드(192.168.10.101)로 ICMP를 보낼 때는 기존과 동일하게 Pod의 IP(10.244.0.175)가 그대로 남는 것을 확인할 수 있습니다. 그 다음으로 클러스터 밖의 router 서버(192.168.10.200)로 ICMP를 보낼 때는 Pod의 IP가 SNAT되어 노드의 IP(192.168.10.100)가 기록된 것을 확인할 수 있습니다.
(참고) CNI 체이닝의 개념과 필요성
CNI 체이닝은 두 개 이상의 CNI 플러그인을 함께 사용하여 각각의 강점을 활용하는 기술입니다. AWS EKS 환경에서 Cilium과 AWS VPC CNI의 조합이 보편적으로 사용되는 이유는 각 CNI가 담당하는 역할이 명확히 분리되어 있기 때문입니다.

AWS VPC CNI의 역할:
- 네트워크 디바이스 및 플럼빙 관리
- ENI를 통한 IP 주소 관리(IPAM)
- 기본 라우팅 설정
- Pod에 VPC IP 주소 직접 할당
Cilium CNI의 역할:
- 로드 밸런싱
- 네트워크 정책 적용
- 가시성 및 모니터링
- 멀티 클러스터 지원
체이닝 모드의 구현 방식
AWS EKS에서 Cilium CNI 체이닝을 구현할 때는 AWS VPC CNI를 먼저 설치한 후 Cilium을 추가로 설치하게 됩니다. 설정 과정에서 다음과 같은 Helm 옵션을 사용합니다.
cni:
chainingMode: aws-cni
exclusive: false
enableIPv4Masquerade: false
routingMode: native
이 설정은 터널링을 비활성화하고 매스커레이딩을 제거하여 ENI IP 주소가 VPC에서 직접 라우팅될 수 있도록 합니다.
Cilium IP 매스커레이딩 에이전트 기능
Cilium의 eBPF 기반 IP 매스커레이딩은 전통적인 iptables 방식보다 효율적인 구현을 제공합니다. 이 기능을 활성화하려면 bpf.masquerade=true 옵션을 사용하며, 이는 BPF Host-Routing 모드도 자동으로 활성화합니다.
지원 프로토콜:
- TCP
- UDP
- ICMP (Echo request, Echo reply, Destination unreachable 등 제한적 지원)
기본적으로 모든 Pod에서 ipv4-native-routing-cidr 범위 밖의 IP 주소로 향하는 패킷은 매스커레이딩 됩니다. 더 세밀한 제어를 위해 Cilium은 eBPF에서 ip-masq-agent를 구현하여 ipMasqAgent.enabled=true 옵션으로 활성화할 수 있습니다.
기본 비매스커레이딩 CIDR 목록:
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
100.64.0.0/10
192.0.0.0/24
192.0.2.0/24
192.88.99.0/24
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
240.0.0.0/4
ConfigMap을 통해 사용자 정의 비매스커레이딩 CIDR을 설정할 수 있습니다.
apiVersion: v1
kind: ConfigMap
metadata:
name: ip-masq-agent
namespace: kube-system
data:
config: |
nonMasqueradeCIDRs:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
masqLinkLocal: true
이 설정을 통해 사내망과 같은 특정 대역과의 통신에서 NAT 없이 직접 통신이 가능합니다. 이 때 클러스터 외부 서버에서 라우팅 테이블에 Pod의 IP 대역과 통신을 위한 설정이 되어 있지 않으면 통신이 불가능하기 때문에 Static routing 설정이 필요할 수 있습니다.
이 때는 노드가 추가되거나 변경될 때마다 라우팅 테이블 수정이 필요하기 때문에 Static Routing 은 사실상 Node가 많아 질 수록 운영 상 불가능합니다. 이런 경우 BGP 를 사용하여 동적으로 라우팅 설정이 가능합니다.
CoreDNS와 NodeLocalDNS
Kubernetes에서 CoreDNS는 클러스터 DNS 서버 역할을 수행하며, kube-dns 서비스명을 유지하여 이전 버전과의 호환성을 보장합니다. CoreDNS는 Corefile 설정 파일을 통해 다양한 플러그인을 체인 형태로 구성할 수 있습니다.
주요 플러그인들(참고):
kubernetes: 클러스터 서비스와 Pod DNS 처리forward: 업스트림 DNS 서버로 요청 전달cache: DNS 응답 캐싱 (기본 30초)prometheus: 메트릭 수집health: 상태 확인 엔드포인트
3.2 CoreDNS 설정 예시
kubectl describe cm -n kube-system coredns
...
Corefile:
----
.:53 { # 모든 도메인 요청을 53포트에서 수신
errors # DNS 응답 중 에러가 발생할 경우 로그 출력
health { # health 엔드포인트를 제공하여 상태 확인 가능
lameduck 5s # 종료 시 5초간 lameduck 모드로 트래픽을 점차 줄이며 종료
}
ready # ready 엔드포인트 제공, 8181 포트의 HTTP 엔드포인트가, 모든 플러그인이 준비되었다는 신호를 보내면 200 OK 를 반환
kubernetes cluster.local in-addr.arpa ip6.arpa { # Kubernetes DNS 플러그인 설정(클러스터 내부 도메인 처리), cluster.local: 클러스터 도메인
pods insecure # 파드 IP로 DNS 조회 허용 (보안 없음)
fallthrough in-addr.arpa ip6.arpa # 해당 도메인에서 결과 없으면 다음 플러그인으로 전달
ttl 30 # 캐시 타임 (30초)
}
prometheus :9153 # Prometheus metrics 수집 가능
forward . /etc/resolv.conf { # CoreDNS가 모르는 도메인은 지정된 업스트림(보통 외부 DNS)으로 전달, .: 모든 쿼리
max_concurrent 1000 # 병렬 포워딩 최대 1000개
}
cache 30 { # DNS 응답 캐시 기능, 기본 캐시 TTL 30초
disable success cluster.local # 성공 응답 캐시 안 함 (cluster.local 도메인)
disable denial cluster.local # NXDOMAIN 응답도 캐시 안 함
}
loop # 간단한 전달 루프(loop)를 감지하고, 루프가 발견되면 CoreDNS 프로세스를 중단(halt).
reload # Corefile 이 변경되었을 때 자동으로 재적용, 컨피그맵 설정을 변경한 후에 변경 사항이 적용되기 위하여 약 2분정도 소요.
loadbalance # 응답에 대하여 A, AAAA, MX 레코드의 순서를 무작위로 선정하는 라운드-로빈 DNS 로드밸런서.
}
Pod에서 CoreDNS를 통해 DNS 질의를 하는 과정을 확인해보겠습니다.
# 모니터링1
cilium hubble port-forward&
hubble observe -f --port 53
# 모니터링2
tcpdump -i any udp port 53 -nn
# 도메인 질의
kubectl exec -it curl-pod -- nslookup webpod

NodeLocal DNS Cache의 필요성과 효과
NodeLocal DNS Cache는 클러스터 노드에서 DaemonSet으로 DNS 캐싱 에이전트를 실행하여 DNS 성능을 향상시킵니다. 기존 아키텍처에서는 Pod가 kube-proxy를 통해 CoreDNS 서비스에 연결해야 했지만, NodeLocal DNS Cache를 사용하면 동일 노드의 DNS 캐시 에이전트로 직접 요청할 수 있습니다.
성능 향상 효과:
- DNS 쿼리 지연 시간 감소
- iptables DNAT 규칙 회피
- conntrack 경합 상태 방지
- UDP에서 TCP로의 연결 업그레이드를 통한 안정성 향상
NodeLocal DNS Cache는 다음과 같은 방식으로 동작합니다.
- 모든 노드에 DaemonSet으로 배포
- 링크 로컬 주소 범위(169.254.0.0/16) 사용
- 클러스터 도메인 쿼리는 CoreDNS로 전달
- 외부 도메인 쿼리는 업스트림 DNS 서버로 전달
NodeLocal DNS Cache는 다음과 같은 성능 특성을 가집니다.
- 약 10,000개의 엔트리를 캐시로 저장 가능
- 쿼리 처리 시 약 30MB의 메모리 사용
- TTL 기반 캐시 관리 (기본 30초)
- NXDOMAIN 응답의 경우 5초 캐시
Cilium 환경에서의 NodeLocal DNS 문제점
Cilium의 eBPF 기반 네트워킹을 사용할 때, 기존의 iptables 기반 NodeLocal DNS Cache가 동작하지 않는 문제가 발생합니다. 이는 Cilium이 iptables 규칙을 우회하여 eBPF 프로그램으로 트래픽을 처리하기 때문입니다.
Cilium Local Redirect Policy(LRP)는 특정 IP 주소와 포트/프로토콜 조합 또는 Kubernetes 서비스로 향하는 Pod 트래픽을 노드 내의 백엔드 Pod로 로컬 리디렉션할 수 있는 기능입니다.
LRP 구성 예시:
apiVersion: "cilium.io/v2"
kind: CiliumLocalRedirectPolicy
metadata:
name: "lrp-nodelocaldns"
spec:
redirectFrontend:
serviceMatcher:
serviceName: kube-dns
namespace: kube-system
toPorts:
- port: "53"
protocol: TCP
- port: "53"
protocol: UDP
redirectBackend:
localEndpointSelector:
matchLabels:
k8s-app: node-local-dns
toPorts:
- port: "53"
protocol: TCP
- port: "53"
protocol: UDP
CNI 체이닝 모드를 사용할 때 아래와 같이 일부 Cilium의 고급 기능이 제한될 수 있습니다.
- 특정 네트워크 정책 기능의 제한
- 일부 보안 기능의 호환성 문제
- VLAN 트래픽 처리 시 추가 설정 필요
eBPF 기반 매스커레이딩 사용 시 다음과 같은 제한사항이 있습니다.
- Linux 커널 4.19 이상 필요
- BPF NodePort 기능에 대한 의존성
- 클러스터 노드의 External IP로 향하는 트래픽은 매스커레이딩되지 않음
NodeLocal DNS Cache 운영 시 다음 사항들을 고려해야 합니다.
- 각 노드에서 추가 컴퓨팅 리소스 사용
- Windows Server 노드에서 지원되지 않음
- 포트 53, 9253, 9353, 8080에서 리슨하므로 충돌 방지 필요
'Work > 개발 노트' 카테고리의 다른 글
| [Cilium study] 5주차 - BGP Control Plane (0) | 2025.08.15 |
|---|---|
| [Cilium study] 4주차 - Networking - 노드에 파드들간 통신 및 외부 노출 (2) | 2025.08.09 |
| [Cilium study] 2주차 - Observability (3) | 2025.07.26 |
| [Cilium study] 1주차 - Cilium 구축 환경 이해하기 (0) | 2025.07.18 |
| [Istio 스터디] 9주차 - Ambient Mesh (4) | 2025.06.08 |
댓글