튜닝 가이드
튜닝 가이드 (Tuning Guide)
이 가이드는 최적의 성능을 위해 Cilium 설치를 튜닝하는 방법을 안내해요. 기본 배포는 최적 성능보다 최대 호환성에 초점을 맞추므로, 성능에 민감한 사용자라면 권장 설정을 적용하세요.
출처: Tuning Guide
본문
이 가이드는 최적의 성능을 위해 Cilium 설치를 최적화하는 데 도움을 줍니다.
권장 사항 (Recommendation)
Cilium의 기본 배포는 가장 최적의 성능보다 최대 호환성에 초점을 맞춰요. 성능에 민감한 사용자라면, 설정을 최대한 활용하기 위한 권장 설정은 다음과 같습니다.
Note
기존 클러스터에서 구성 설정을 그냥 활성화하는 것만으로는 인플레이스 업그레이드가 불가능해요. 이런 튜닝은 기본 데이터패스의 근간을 바꾸므로 파드 또는 심지어 노드 재시작이 필요하기 때문입니다.
기존 클러스터에 적용하는 가장 좋은 방법은 클러스터에 합류하는 새 노드에서만 튜닝을 활성화하는 per-node 구성을 활용하는 것입니다. 자세한 내용은 Per-node 구성 페이지를 참고하세요.
권장 성능 프로필의 각 설정은 이 페이지와 KubeCon 발표에서 자세히 설명됩니다:
- netkit 디바이스 모드
- eBPF host-routing
- IPv4/IPv6용 BIG TCP
- Bandwidth Manager (선택, BBR 혼잡 제어용)
- Per-CPU 분산 LRU와 증가된 맵 크기 비율
- CT 맵에 jiffies를 사용하는 eBPF 클록 프로브
요구사항:
- Kernel >= 6.8
- BIG TCP 지원 NIC: mlx4, mlx5, ice
주요 설정을 활성화하려면:
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set routingMode=native \
--set bpf.datapathMode=netkit \
--set bpf.masquerade=true \
--set bpf.distributedLRU.enabled=true \
--set bpf.mapDynamicSizeRatio=0.08 \
--set ipv6.enabled=true \
--set enableIPv6BIGTCP=true \
--set ipv4.enabled=true \
--set enableIPv4BIGTCP=true \
--set kubeProxyReplacement=true \
--set bpfClockProbe=true
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set routingMode=native \
--set bpf.datapathMode=netkit \
--set bpf.masquerade=true \
--set bpf.distributedLRU.enabled=true \
--set bpf.mapDynamicSizeRatio=0.08 \
--set ipv6.enabled=true \
--set enableIPv6BIGTCP=true \
--set ipv4.enabled=true \
--set enableIPv4BIGTCP=true \
--set kubeProxyReplacement=true \
--set bpfClockProbe=true
추가로 BBR 혼잡 제어를 활성화하려면 위 Helm 설치에 다음 설정을 추가하는 것을 고려하세요:
--set bandwidthManager.enabled=true \
--set bandwidthManager.bbr=true
netkit 디바이스 모드
netkit 디바이스는 애플리케이션이 호스트 네임스페이스에 직접 상주한 것처럼 처리량과 지연을 개선하는 것을 목표로 파드에 연결성을 제공해요. 즉 네트워크 네임스페이스에 대한 데이터패스 오버헤드를 0으로 줄입니다. 커널의 netkit 드라이버는 Cilium의 요구에 맞게 특별히 설계되었으며 기존의 veth 디바이스 유형을 대체합니다. 자세한 내용은 netkit에 대한 KubeCon 발표도 참고하세요.
netkit 디바이스는 요구사항에 따라 Layer3 또는 Layer2 모드로 동작할 수 있어요. Layer3 모드는 Cilium이 ARP 패킷을 처리할 필요가 없어지므로 권장됩니다. 자세한 내용은 netkit 구성을 참고하세요.
Pod별 BPF 프로그램은 netkit 피어 디바이스 내부에 연결되며 호스트 네임스페이스에서만 Cilium을 통해 관리할 수 있어요. Cilium은 극히 드문 경우 BPF 프로그램이 연결되지 않았을 때 피어 디바이스가 트래픽을 블랙홀하도록 구성합니다.
netkit은 eBPF 기반 host-routing과 결합했을 때 오프노드 트래픽이 Pod로 들어오거나 Pod를 떠날 때 빠른 네트워크 네임스페이스 스위치를 달성합니다. netkit이 활성화되면 Cilium은 netkit이 아닌 디바이스에 대한 모든 연결에도 tcx를 활용합니다. 이는 더 높은 효율성과 모든 Cilium 연결에 BPF 링크 활용을 위해서입니다.
netkit은 커널 6.8부터 사용할 수 있으며 BIG TCP도 지원합니다. 기본 커널이 더 보편화되면 Cilium의 veth 디바이스 모드는 deprecated될 것입니다.
Warning
이 기능은 베타 기능입니다. 문제가 발생하면 피드백을 남기고 GitHub 이슈를 등록해 주세요. 이 기능의 알려진 문제는 여기에서 추적됩니다.
netkit 구성
netkit은 bpf.datapathMode를 다음 값 중 하나로 수정해 활성화할 수 있어요.
| 데이터패스 모드 값 | 설명 |
| veth (기본값) | Layer2로 동작하는 veth 디바이스 사용. |
| netkit | Layer3 모드로 netkit 사용. 지원되지 않으면 Cilium이 시작 시 오류를 냅니다. |
| netkit-l2 | Layer2 모드로 netkit 사용. 지원되지 않으면 Cilium이 시작 시 오류를 냅니다. |
| auto | 런타임에 자동 감지: 커널 지원이 있으면 netkit(Layer3)을 사용하고, 없으면 veth로 폴백. |
Note
CNI 플러그인은 Pod 생성 후 veth를 netkit으로 단순히 교체할 수 없으므로, 기존 클러스터에서 netkit만 활성화하는 것으로는 인플레이스 업그레이드가 불가능해요. 또한 두 플레이버를 병렬로 실행하는 것은 현재 지원되지 않습니다.
이 제한은 자동 감지에도 적용됩니다: veth를 사용하는 기존 Pod가 있는 상태에서
bpf.datapathMode=auto로 전환하고 재시작 시 netkit 지원이 감지되면 Cilium이 오류를 냅니다.기존 클러스터에 적용하는 가장 좋은 방법은 클러스터에 합류하는 새 노드에서만 netkit을 활성화하는 per-node 구성을 활용하는 것입니다. 또는 구성 수정 전에 기존 노드를 cordon·drain 하세요. 자세한 내용은 Per-node 구성 페이지를 참고하세요.
요구사항:
- Kernel >= 6.8
- eBPF host-routing
eBPF host-routing으로 netkit 디바이스 모드를 활성화하려면:
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set routingMode=native \
--set bpf.datapathMode=netkit \
--set bpf.masquerade=true \
--set kubeProxyReplacement=true
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set routingMode=native \
--set bpf.datapathMode=netkit \
--set bpf.masquerade=true \
--set kubeProxyReplacement=true
설치가 netkit으로 실행 중인지 검증하려면 아무 Cilium 파드에서 cilium status를 실행해 "Device Mode" 상태를 보고하는 줄을 확인하세요. 이는 현재 운영 데이터패스 모드를 나타냅니다. bpf.datapathMode=auto가 설정된 경우 구성된 모드도 확인할 수 있습니다.
netkit은 또한 eBPF host routing을 요구합니다. "Host Routing" 아래의 보고 상태가 "BPF"여야 합니다.
eBPF Host-Routing
네트워크 라우팅이 eBPF를 사용해 Cilium에 의해 수행되더라도, 기본적으로 네트워크 패킷은 여전히 노드의 일반 네트워크 스택 일부를 통과합니다. 이는 iptables 후크에 의존하는 경우 모든 패킷이 모든 iptables 후크를 통과하도록 보장합니다. 하지만 이는 상당한 오버헤드를 추가합니다. 테스트 환경의 정확한 수치는 TCP 처리량 (TCP_STREAM)을 참고해 "Cilium"과 "Cilium (legacy host-routing)"의 결과를 비교하세요.
우리는 Cilium 1.9에서 eBPF 기반 host-routing을 도입해 iptables와 상위 호스트 스택을 완전히 우회하고, 일반 veth 디바이스 동작보다 더 빠른 네트워크 네임스페이스 스위치를 달성했습니다. 이 옵션은 커널이 지원하면 자동으로 활성화됩니다. 설치가 eBPF host-routing으로 실행 중인지 검증하려면 아무 Cilium 파드에서 cilium status를 실행해 "Host Routing" 상태를 보고하는 줄을 확인하세요. "BPF"여야 합니다.
Note
BPF Host Routing은 Istio와 호환되지 않습니다 (자세한 내용은 GitHub 이슈 36022 참고).
Note
IPsec과 함께 BPF Host Routing을 사용할 때는 커널 버그픽스가 필요합니다. 연결 문제가 관찰되면, 이슈를 보고하기 전에 노드의 커널 패키지가 최근에 업그레이드되었는지 확인하세요.
요구사항:
- eBPF 기반 kube-proxy replacement
- eBPF 기반 masquerading
eBPF Host-Routing을 활성화하려면:
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set bpf.masquerade=true \
--set kubeProxyReplacement=true
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set bpf.masquerade=true \
--set kubeProxyReplacement=true
알려진 제한 사항:
eBPF host routing은 호스트 내부 패킷 라우팅을 최적화하며, 패킷이 더 이상 호스트 네임스페이스의 netfilter 테이블에 닿지 않습니다. 따라서 netfilter 후크에 의존하는 기능(예: GKE Workload Identities)과 호환되지 않습니다. bpf.hostLegacyRouting=true를 구성하거나 Local Redirect Policy를 활용해 이 제한을 우회하세요.
IPv6 BIG TCP
IPv6 BIG TCP는 네트워크 스택이 더 큰 GSO(전송) 및 GRO(수신) 패킷을 준비해 스택 통과 횟수를 줄임으로써 성능과 지연을 개선합니다. CPU 부하를 줄이고 더 높은 속도(100Gbit/s 이상)를 달성하는 데 도움이 됩니다.
이런 패킷을 스택에 통과시키기 위해 BIG TCP는 IPv6 헤더 뒤에 임시 Hop-By-Hop 헤더를 추가하며, 패킷을 선상으로 전송하기 전에 제거합니다.
BIG TCP는 DualStack 설정에서 동작할 수 있는데, IPv4 BIG TCP가 활성화되지 않으면 IPv4 패킷은 이전의 낮은 한도(64k)를 사용하고, IPv6 패킷은 새롭고 더 큰 한도(192k)를 사용합니다. IPv4 BIG TCP와 IPv6 BIG TCP를 모두 활성화해 둘 다 더 큰 한도(192k)를 사용하게 할 수 있어요.
Cilium은 GSO와 GRO 최대 크기의 기본 커널 값을 64k로 가정하고 필요한 경우에만 조정한다는 점을 기억하세요. 즉 BIG TCP가 활성화되고 현재 GSO/GRO 최대 크기가 192k 미만이면 늘리려 시도하고, BIG TCP가 비활성화되고 현재 최대 값이 64k보다 크면 줄이려 시도합니다.
BIG TCP는 네트워크 인터페이스 MTU 변경을 요구하지 않습니다.
Note
Cilium은 Pod가 생성된 후 그 안에 접근할 수 없으므로, 기존 클러스터에서 BIG TCP만 활성화하는 것만으로는 현재 인플레이스 업그레이드가 불가능해요.
기존 클러스터에 적용하는 가장 좋은 방법은 Pod를 재시작하거나 클러스터에 합류하는 새 노드에서 BIG TCP를 활성화하는 per-node 구성을 활용하는 것입니다. 자세한 내용은 Per-node 구성 페이지를 참고하세요.
요구사항:
- Kernel >= 5.19
- eBPF Host-Routing
- eBPF 기반 kube-proxy replacement
- eBPF 기반 masquerading
- Tunneling 및 암호화 비활성화
- 지원 NIC: mlx4, mlx5, ice
IPv6 BIG TCP를 활성화하려면:
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set routingMode=native \
--set bpf.masquerade=true \
--set ipv6.enabled=true \
--set enableIPv6BIGTCP=true \
--set kubeProxyReplacement=true
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set routingMode=native \
--set bpf.masquerade=true \
--set ipv6.enabled=true \
--set enableIPv6BIGTCP=true \
--set kubeProxyReplacement=true
IPv6 BIG TCP 옵션을 토글한 후에는 변경 사항이 적용되도록 Kubernetes 파드를 재시작해야 합니다.
설치가 IPv6 BIG TCP로 실행 중인지 검증하려면 아무 Cilium 파드에서 cilium status를 실행해 "IPv6 BIG TCP" 상태를 보고하는 줄을 확인하세요. "enabled"여야 합니다.
IPv4 BIG TCP
IPv6 BIG TCP와 유사하게, IPv4 BIG TCP는 네트워크 스택이 더 큰 GSO(전송) 및 GRO(수신) 패킷을 준비해 스택 통과 횟수를 줄임으로써 성능과 지연을 개선합니다. CPU 부하를 줄이고 더 높은 속도(100Gbit/s 이상)를 달성하는 데 도움이 됩니다.
그런 패킷을 스택에 통과시키기 위해 BIG TCP는 IPv4 tot_len을 0으로 설정하고 skb->len을 실제 IPv4 총 길이로 사용합니다. 올바른 IPv4 tot_len은 패킷을 선상으로 전송하기 전에 설정됩니다.
BIG TCP는 DualStack 설정에서 동작할 수 있는데, IPv6 BIG TCP가 활성화되지 않으면 IPv6 패킷은 이전의 낮은 한도(64k)를 사용하고, IPv4 패킷은 새롭고 더 큰 한도(192k)를 사용합니다. IPv4 BIG TCP와 IPv6 BIG TCP를 모두 활성화해 둘 다 더 큰 한도(192k)를 사용하게 할 수 있어요.
Cilium은 GSO와 GRO 최대 크기의 기본 커널 값을 64k로 가정하고 필요한 경우에만 조정한다는 점을 기억하세요. 즉 BIG TCP가 활성화되고 현재 GSO/GRO 최대 크기가 192k 미만이면 늘리려 시도하고, BIG TCP가 비활성화되고 현재 최대 값이 64k보다 크면 줄이려 시도합니다.
BIG TCP는 네트워크 인터페이스 MTU 변경을 요구하지 않습니다.
Note
Cilium은 Pod가 생성된 후 그 안에 접근할 수 없으므로, 기존 클러스터에서 BIG TCP만 활성화하는 것만으로는 현재 인플레이스 업그레이드가 불가능해요.
기존 클러스터에 적용하는 가장 좋은 방법은 Pod를 재시작하거나 클러스터에 합류하는 새 노드에서 BIG TCP를 활성화하는 per-node 구성을 활용하는 것입니다. 자세한 내용은 Per-node 구성 페이지를 참고하세요.
요구사항:
- Kernel >= 6.3
- eBPF Host-Routing
- eBPF 기반 kube-proxy replacement
- eBPF 기반 masquerading
- Tunneling 및 암호화 비활성화
- 지원 NIC: mlx4, mlx5, ice
IPv4 BIG TCP를 활성화하려면:
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set routingMode=native \
--set bpf.masquerade=true \
--set ipv4.enabled=true \
--set enableIPv4BIGTCP=true \
--set kubeProxyReplacement=true
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set routingMode=native \
--set bpf.masquerade=true \
--set ipv4.enabled=true \
--set enableIPv4BIGTCP=true \
--set kubeProxyReplacement=true
IPv4 BIG TCP 옵션을 토글한 후에는 변경 사항이 적용되도록 Kubernetes 파드를 재시작해야 합니다.
설치가 IPv4 BIG TCP로 실행 중인지 검증하려면 아무 Cilium 파드에서 cilium status를 실행해 "IPv4 BIG TCP" 상태를 보고하는 줄을 확인하세요. "enabled"여야 합니다.
iptables 연결 추적 우회
eBPF Host-Routing을 사용할 수 없어 네트워크 패킷이 여전히 호스트 네임스페이스의 일반 네트워크 스택을 통과해야 하는 경우, iptables가 상당한 비용을 추가할 수 있어요. 모든 Pod 트래픽에 대한 연결 추적 요구사항을 비활성화하여 iptables 연결 추적기를 우회하면 이 통과 비용을 최소화할 수 있습니다.
요구사항:
- 직접 라우팅(direct-routing) 구성
- eBPF 기반 kube-proxy replacement
- eBPF 기반 masquerading 또는 masquerading 없음
iptables 연결 추적 우회를 활성화하려면:
Cilium CLI
cilium install 1.20.2 \
--set installNoConntrackIptablesRules=true \
--set kubeProxyReplacement=true
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set installNoConntrackIptablesRules=true \
--set kubeProxyReplacement=true
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set installNoConntrackIptablesRules=true \
--set kubeProxyReplacement=true
Pod에 hostNetwork 플래그가 활성화되어 있다면 연결 추적을 건너뛸 포트는 network.cilium.io/no-track-host-ports 어노테이션을 사용해 명시적으로 나열해야 해요:
apiVersion: v1
kind: Pod
metadata:
annotations:
network.cilium.io/no-track-host-ports: "999/tcp,8123/tcp"
Note
작성 시점 기준으로
network.cilium.io/no-track-host-ports어노테이션은 UDP와 TCP 전송 프로토콜만 지원합니다.
Hubble
Hubble 관측성이 활성화된 상태로 실행하면 성능을 희생할 수 있어요. Hubble의 오버헤드는 네트워크 트래픽 패턴과 Hubble 집계 설정에 따라 1-15% 사이입니다.
네트워크 트래픽이 많은 클러스터에서 cilium-agent는 모니터링된 이벤트 처리에 상당한 CPU 시간을 쓸 수 있고, Hubble이 일부 이벤트를 잃을 수도 있습니다. 이를 피하기 위해 Hubble을 튜닝하는 여러 방법이 있습니다.
Hubble 이벤트 큐 크기 늘리기
Hubble 이벤트 큐는 이벤트가 데이터패스에서 방출된 후 Hubble 하위 시스템이 처리하기 전에 버퍼링합니다. 이 큐가 가득 차면(발생하는 이벤트 양을 Hubble이 따라가지 못해서) Cilium이 이벤트를 드랍하기 시작합니다. 이는 트래픽에는 영향을 주지 않지만, 이벤트가 Hubble에 의해 처리되지 않아 Hubble 흐름이나 메트릭에 나타나지 않습니다.
이런 일이 발생하면 다음과 유사한 로그 줄을 볼 수 있습니다.
level=info msg="hubble events queue is processing messages again: NN messages were lost" subsys=hubble
level=warning msg="hubble events queue is full: dropping messages; consider increasing the queue size (hubble-event-queue-size) or provisioning more CPU" subsys=hubble
기본적으로 Hubble 이벤트 큐 크기는 #CPU * 1024이며, 노드에 16개 이상의 CPU 코어가 있으면 16384입니다. 이벤트 폭주로 인해 이벤트 드랍이 발생하면 이 큐 크기를 늘리는 것이 도움이 될 수 있어요. 드랍이 사라질 때까지 큐 길이를 점진적으로 두 배로 늘리는 것을 권장합니다. 큐 길이를 128k로 늘린 후에도 개선이 보이지 않으면, 더 늘려도 도움이 되지 않을 가능성이 높습니다.
Hubble 이벤트 큐 크기를 늘리면 메모리 사용량이 증가한다는 점을 유의하세요. 트래픽 패턴에 따라 큐 크기를 10,000 늘리면 메모리 사용량이 최대 5MB까지 늘어날 수 있습니다.
Cilium CLI
cilium install 1.20.2 \
--set hubble.eventQueueSize=32768
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set hubble.eventQueueSize=32768
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set hubble.eventQueueSize=32768
일부 노드만 영향을 받는 경우 CiliumNodeConfig 오브젝트를 사용해 노드별로 큐 길이를 설정할 수도 있어요.
apiVersion: cilium.io/v2
kind: CiliumNodeConfig
metadata:
namespace: kube-system
name: set-hubble-event-queue
spec:
nodeSelector:
matchLabels:
# Update selector to match your nodes
io.cilium.update-hubble-event-queue: "true"
defaults:
hubble-event-queue-size: "32768"
Hubble 이벤트 큐 크기를 늘리는 것은 Cilium 데이터패스가 지속적으로 높은 비율로 이벤트를 방출하는 경우를 완화할 수 없으며 CPU 사용률을 줄이지도 않습니다. 이 경우 집계 간격을 늘리거나 이벤트를 rate limit 하는 것을 고려해야 합니다.
집계 간격 늘리기
기본적으로 Cilium은 구성된 monitor-aggregation 레벨에 따라 추적 이벤트를 생성합니다. 패킷 이벤트의 경우 Cilium은 새 연결마다, 패킷에 이전에 보지 못한 TCP 플래그가 포함된 경우, 평균적으로 monitor-aggregation-interval(기본값 5초)마다 한 번씩 전송 패킷에 대한 추적 이벤트를 생성합니다. 소켓 로드 밸런싱이 활성화되면 소켓 변환 이벤트(예: 사전/사후 역변환)에도 동일한 집계 레벨이 적용됩니다:
none: 모든 소켓 추적 이벤트 방출lowest/low: 역방향(recv) 소켓 추적 억제medium/maximum: connect 시스템 콜에 대해서만 소켓 추적 이벤트 방출
집계가 활성화되면(>= lowest), 소켓 추적 방출은 활성 흐름에 대해 간격당 약 하나의 추적이라는 엄격한 케이던스로 monitor-aggregation-interval에 정렬됩니다.
네트워크 트래픽 패턴에 따라 집계 간격당 추적 이벤트 재방출은 전체 이벤트의 큰 부분을 차지할 수 있어요. 집계 간격을 늘리면 CPU 사용률을 낮추고 이벤트 손실을 방지할 수 있습니다.
다음은 집계 간격을 10초로 설정합니다.
Cilium CLI
cilium install 1.20.2 \
--set bpf.events.monitorInterval="10s"
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set bpf.events.monitorInterval="10s"
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set bpf.events.monitorInterval="10s"
이벤트 Rate Limit
Hubble으로 인한 높은 CPU 사용률을 더 방지하려면 데이터패스 코드가 생성할 수 있는 이벤트 수에 한도를 설정할 수도 있습니다. 두 가지 한도를 구성할 수 있습니다:
- Rate limit - 평균적으로 생성할 수 있는 이벤트 수를 제한
- Burst limit - 1초 동안 생성할 수 있는 이벤트 수를 제한
두 한도 모두 0으로 설정하면 BPF 이벤트 rate limiting이 적용되지 않습니다.
Note
BPF 이벤트 맵 rate limiting에 대한 Helm 구성은 실험적이며 향후 릴리스에서 변경될 수 있습니다.
Warning
BPF 이벤트 맵 rate limiting이 활성화되면 이벤트 드랍으로 인해 Cilium monitor, Hubble 관측성, Hubble 메트릭 신뢰성, Hubble export 기능이 영향을 받을 수 있습니다.
rate limit 10,000과 burst limit 50,000으로 eBPF 이벤트 rate limiting을 활성화하려면:
Cilium CLI
cilium install 1.20.2 \
--set bpf.events.default.rateLimit=10000 \
--set bpf.events.default.burstLimit=50000
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set bpf.events.default.rateLimit=10000 \
--set bpf.events.default.burstLimit=50000
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set bpf.events.default.rateLimit=10000 \
--set bpf.events.default.burstLimit=50000
관심이 없는 이벤트 유형의 노출을 중단할 수도 있습니다. 예를 들어 드랍된 트래픽에 주로 관심이 있다면 "trace" 이벤트를 비활성화해 에이전트의 전체 CPU 소비를 줄일 수 있습니다.
Cilium CLI
cilium config set bpf-events-trace-enabled false
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set bpf.events.trace.enabled=false
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set bpf.events.trace.enabled=false
Warning
하나 이상의 이벤트 유형을 억제하면
cilium monitor와 Hubble 관측성 능력, 메트릭, export가 영향을 받습니다.
Hubble 비활성화
이 모든 것으로 부족하다면 최대 성능을 위해 Hubble을 비활성화할 수 있습니다:
Cilium CLI
cilium hubble disable
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set hubble.enabled=false
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set hubble.enabled=false
MTU
최대 전송 단위(MTU)는 구성의 네트워크 처리량에 상당한 영향을 줄 수 있어요. Cilium은 기본 네트워크 디바이스의 MTU를 자동으로 감지합니다. 따라서 시스템이 점보 프레임을 사용하도록 구성되어 있다면 Cilium이 자동으로 활용합니다.
이를 활용하려면 네트워크가 허용한다면 시스템이 점보 프레임을 사용하도록 구성되어 있는지 확인하세요.
패킷 레이어 PMTUD 비활성화
Cilium은 기본적으로 Pod 엔드포인트에 대해 Linux의 TCP 패킷화 레이어 경로 MTU 발견(PLPMTUD)을 활성화해요. 이는 RFC4821을 구현하는 커널 기능으로, 패킷 손실과 일반 ICMP 기반 PMTUD 메시지를 차단하는 방화벽에 강한 올바른 경로 MTU 크기를 동적으로 발견하는 방법을 제공합니다. 특히 잘못된 MTU 크기와 PMTUD 오류 메시지를 드랍하는 방화벽에서 발생하는 네트워크 블랙홀에 대한 견고한 MTU 발견 메커니즘을 제공합니다.
경로 MTU를 발견하는 더 견고한 방법을 제공하지만, 연결이 처음에 최적이 아닌 MSS를 사용해 네트워크 성능이 낮아질 수 있는 비용이 따릅니다. 올바른 MTU를 아는 경우 이 기능을 비활성화하면 TCP 연결에서 네트워크 처리량이 다소 개선될 수 있습니다.
이 기능은 helm 값 pmtuDiscovery.packetizationLayerPMTUDMode=disabled로 비활성화할 수 있습니다.
Bandwidth Manager
Cilium의 Bandwidth Manager는 전체 애플리케이션 지연과 처리량을 개선하는 목표로 네트워크 트래픽을 더 효율적으로 관리합니다.
Kubernetes Pod 대역폭 어노테이션을 네이티브로 지원하는 것 외에, Cilium 1.9에서 처음 도입된 Bandwidth Manager는 TCP 스택 페이싱(예: EDT/BBR)을 지원하기 위해 모든 외부 지향 네트워크 디바이스에 FQ(Fair Queue) 큐잉 규율을 설정하고, 네트워킹 스택에 최적의 서버급 sysctl 설정을 적용합니다.
요구사항:
- eBPF 기반 kube-proxy replacement
Bandwidth Manager를 활성화하려면:
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set bandwidthManager.enabled=true \
--set kubeProxyReplacement=true
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set bandwidthManager.enabled=true \
--set kubeProxyReplacement=true
설치가 Bandwidth Manager로 실행 중인지 검증하려면 아무 Cilium 파드에서 cilium status를 실행해 "BandwidthManager" 상태를 보고하는 줄을 확인하세요. "EDT with BPF"여야 합니다.
Pod용 BBR 혼잡 제어
Cilium의 Bandwidth Manager가 제공하는 MQ/FQ 설정의 기본 인프라는 Pod에 TCP BBR 혼잡 제어 사용을 허용합니다. BBR은 특히 Pod가 인터넷에서 외부 클라이언트를 마주하는 Kubernetes Services 뒤에 노출될 때 적합합니다. BBR은 인터넷 트래픽에 대해 더 높은 대역폭과 더 낮은 지연을 달성합니다. 예를 들어 BBR의 처리량이 현재 최고의 손실 기반 혼잡 제어보다 최대 2,700배 높고 큐잉 지연은 25배 낮을 수 있다고 보여졌습니다.
BBR이 Pod에서 안정적으로 동작하려면 5.18 이상 커널이 필요합니다. 우리의 Linux Plumbers 2021 발표에서 설명한 대로, 이전 커널은 Pod에서 호스트 네트워크 네임스페이스로 전환할 때 네트워크 패킷의 타임스탬프를 유지하지 않기 때문에 필요합니다. 그 결과 커널의 페이싱 인프라가 일반적으로(특정 Cilium에 국한되지 않음) 제대로 동작하지 않습니다. 우리는 최근 커널에서 이 문제가 타임스탬프를 유지하고 Pod용 BBR이 동작하도록 수정하는 데 기여했습니다.
BBR은 또한 패킷이 호스트 네임스페이스의 물리 디바이스에서 FQ 큐잉 규율에 닿을 때까지 네트워크 패킷의 소켓 연관을 유지하기 위해 eBPF Host-Routing이 필요합니다.
Note
Cilium은 기존 소켓을 BBR 혼잡 제어로 마이그레이션할 수 없으므로, 기존 클러스터에서 BBR만 활성화하는 것만으로는 인플레이스 업그레이드가 불가능해요.
이를 적용하는 가장 좋은 방법은 새로 구축한 클러스터에서만 활성화하거나, 기존 클러스터에서 Pod를 재시작하거나, 클러스터에 합류하는 새 노드에서 BBR을 활성화하는 per-node 구성을 활용하는 것입니다. 자세한 내용은 Per-node 구성 페이지를 참고하세요.
BBR 사용은 TCP 재전송이 더 많아지고 TCP CUBIC 연결에 더 공격적인 동작을 초래할 수 있다는 점을 참고하세요.
요구사항:
- Kernel >= 5.18
- Bandwidth Manager
- eBPF Host-Routing
Pod용 BBR로 Bandwidth Manager를 활성화하려면:
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set bandwidthManager.enabled=true \
--set bandwidthManager.bbr=true \
--set kubeProxyReplacement=true
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set bandwidthManager.enabled=true \
--set bandwidthManager.bbr=true \
--set kubeProxyReplacement=true
설치가 Pod용 BBR로 실행 중인지 검증하려면 아무 Cilium 파드에서 cilium status를 실행해 "BandwidthManager" 상태를 보고하는 줄을 확인하세요. EDT with BPF와 함께 [BBR]도 표시되어야 합니다.
XDP 가속
Cilium에는 백엔드가 원격 노드에 있을 때 도착한 요청을 노드 밖으로 다시 밀어내야 하는 경우 NodePort, LoadBalancer 서비스, externalIPs가 있는 서비스를 가속하는 내장 지원이 있습니다.
이 경우 네트워크 패킷을 상위 네트워킹 스택까지 모두 밀어 올릴 필요 없이, XDP의 도움으로 Cilium이 네트워크 드라이버 레이어에서 바로 이러한 요청을 처리할 수 있습니다. 이는 단일 노드의 포워딩 용량이 극적으로 증가하므로 지연을 줄이고 서비스의 스케일 아웃을 돕습니다. XDP 레이어의 kube-proxy replacement는 Cilium 1.8부터 사용 가능합니다.
요구사항:
- Kernel >= 4.19.57, >= 5.1.16, >= 5.2
- 네이티브 XDP 지원 드라이버, 드라이버 목록 확인
- eBPF 기반 kube-proxy replacement
XDP 가속을 활성화하려면 공용 클라우드 제공자 설정 지침이 포함된 시작하기 가이드를 확인하세요.
설치가 XDP 가속으로 실행 중인지 검증하려면 아무 Cilium 파드에서 cilium status를 실행해 "XDP Acceleration" 상태를 보고하는 줄을 확인하세요. "Native"여야 합니다.
eBPF 맵 백엔드 메모리
Cilium의 핵심 BPF 맵 메모리 구성을 노드 전체 LRU 메모리 풀에서 분산된 per-CPU 메모리 풀로 변경하면 스트레스 상황(많은 CT/NAT 요소 할당·해제 연산)에서 커널의 spinlock 경합을 피하는 데 도움이 됩니다.
per-CPU 풀은 더 이상 공유할 수 없으므로 트레이드오프는 더 높은 메모리 사용량입니다. 주어진 CPU 풀이 고갈되면 LRU 메커니즘으로 요소를 재활용해야 하기 때문입니다. 따라서 bpf.distributedLRU.enabled만 활성화하는 것이 아니라 bpf.mapDynamicSizeRatio로 맵 크기도 늘리는 것이 권장됩니다:
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set bpf.distributedLRU.enabled=true \
--set bpf.mapDynamicSizeRatio=0.08
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set bpf.distributedLRU.enabled=true \
--set bpf.mapDynamicSizeRatio=0.08
bpf.distributedLRU.enabled는 레거시 이유로 Cilium에서 기본적으로 꺼져 있는데, 이 설정을 즉시 활성화하면 BPF 맵을 재생성해야 하므로 진행 중인 트래픽에 지장을 주기 때문입니다.
per-node 구성을 사용해 클러스터에 합류하는 새 노드에 대해 이 설정을 점진적으로 도입하는 것이 권장됩니다. 또는 초기 클러스터 생성 시 활성화를 고려하는 것이 좋습니다.
또한 bpf.distributedLRU.enabled는 현재 정적으로 크기가 정해진 맵 구성이 아니라 bpf.mapDynamicSizeRatio와 함께 사용할 때만 지원됩니다.
eBPF 맵 크기 조정
모든 eBPF 맵은 상위 용량 한도로 생성됩니다. 한도를 초과해 삽입하면 실패하거나 데이터패스의 확장성을 제한할 수 있어요. Cilium은 총 시스템 메모리의 주어진 비율을 기반으로 자동 파생 기본값을 사용합니다.
하지만 Cilium 에이전트가 사용하는 상위 용량 한도는 고급 사용자가 덮어쓸 수 있습니다. eBPF 맵 가이드를 참고하세요.
eBPF 클록 프로브
Cilium은 기본 커널을 프로빙해 BPF가 ktime 대신 jiffies를 가져오는 것을 지원하는지 확인할 수 있어요. Cilium의 CT 맵은 높은 해상도를 요구하지 않으므로 jiffies가 더 효율적이고 선호되는 클록 소스입니다. 프로빙을 활성화하고 가능하면 jiffies를 사용하려면 bpfClockProbe=true를 설정할 수 있습니다:
Helm Repository
helm install cilium cilium/cilium --version 1.20.2 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set bpfClockProbe=true
OCI Registry
helm install cilium oci://quay.io/cilium/charts/cilium 1.20.2 \
--namespace kube-system \
--set kubeProxyReplacement=true \
--set bpfClockProbe=true
bpfClockProbe는 레거시 이유로 Cilium에서 기본적으로 꺼져 있는데, 이 설정을 즉시 활성화하면 이전에 ktime을 타임스탬프 클록 소스로 저장한 CT 맵 항목이 이제 jiffies로 해석되기 때문입니다.
따라서 per-node 구성을 사용해 클러스터에 합류하는 새 노드에 대해 이 설정을 점진적으로 도입하는 것이 권장됩니다. 또는 초기 클러스터 생성 시 활성화를 고려하는 것이 좋습니다.
이제 jiffies가 사용되는지 검증하려면 아무 Cilium 파드에서 cilium status --verbose를 실행하고 Clock Source for BPF 줄을 확인하세요.
Linux 커널
일반적으로 커널 커뮤니티 또는 선택한 다운스트림 배포판이 제공하는 가장 최근 LTS 안정 커널을 사용하는 것이 좋습니다. 커널이 최신일수록 다양한 데이터패스 최적화를 사용할 가능성이 높아집니다.
Cilium 릴리스 블로그에서 우리는 정기적으로 Cilium 데이터패스 성능을 암시적으로 돕는 eBPF 기반 커널 작업 중 일부(예: eBPF JIT에서 retpoline을 직접 점프로 대체)를 강조합니다.
또한 커널은 네트워크 성능을 극대화하는 데 도움이 될 여러 옵션을 구성할 수 있게 해줍니다.
CONFIG_PREEMPT_NONE
CONFIG_PREEMPT_NONE=y가 설정된 커널 버전을 실행하세요. 일부 Linux 배포판은 이 옵션이 설정된 커널 이미지를 제공하거나 Linux 커널을 다시 컴파일할 수 있습니다. CONFIG_PREEMPT_NONE=y는 서버 워크로드에 권장되는 설정입니다.
Kubernetes
스케줄링 모드 설정
기본적으로 cilium daemonset은 inter-pod anti-affinity 규칙으로 구성됩니다. inter-pod anti-affinity는 kube-scheduler의 스케줄링 처리량을 줄이므로 수백 노드보다 큰 클러스터에는 권장되지 않습니다.
cilium daemonset이 호스트 포트를 사용한다면(예: prometheus 메트릭이 활성화된 경우) kube-scheduler는 해당 포트/프로토콜의 단일 파드만 노드에 스케줄되도록 보장합니다. 이는 inter-pod anti-affinity 규칙이 제공하는 것과 효과적으로 동일한 보장을 제공합니다.
이를 활용하려면 cilium 설치·업그레이드 시 --set scheduling.mode=kube-scheduler를 사용하는 것을 고려하세요.
Note
호스트 포트 번호를 변경할 때는 주의하세요. 호스트 포트 번호를 변경하면
kube-scheduler보장이 사라집니다. 호스트 포트 번호를 변경해야 한다면 업그레이드를 거쳐 최소 하나의 호스트 포트 번호가 공유되도록 하거나,--set scheduling.mode=anti-affinity사용을 고려하세요.
추가 고려사항 (Further Considerations)
특정 워크로드에 맞게 시스템을 튜닝하고 지터를 줄이는 데 권장하는 다양한 추가 설정이 있습니다:
tuned network-* 프로필
tuned 프로젝트는 증가된 전력 소비를 대가로 결정론적 성능을 최적화하는 다양한 프로필을 제공합니다. 예를 들어 network-latency와 network-throughput가 있습니다. 전자를 활성화하려면:
tuned-adm profile network-latency
CPU governor를 performance로 설정
CPU 스케일링 업·다운은 지연 테스트에 영향을 주고 차선의 성능을 초래할 수 있어요. 최대의 일관된 성능을 달성하려면 CPU governor를 performance로 설정하세요:
for CPU in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
echo performance > $CPU
done
irqbalance 중지 및 NIC 인터럽트를 특정 CPU에 피닝
irqbalance를 실행 중이라면, NIC의 IRQ 처리를 CPU 사이에서 마이그레이션해 비결정적 성능을 초래할 수 있으므로 비활성화를 고려하세요:
killall irqbalance
최대 워크로드 격리를 위해 NIC 인터럽트를 특정 CPU에 피닝하는 것을 적극 권장합니다!
이를 달성하는 방법에 대한 자세한 내용과 초기 포인터는 이 스크립트를 참고하세요. 큐를 피닝하는 것은 드라이버에 따라 설정이 다를 수 있다는 점을 주의하세요.
Mellanox, Intel 등을 포함한 NIC 벤더의 다양한 문서와 성능 튜닝 가이드를 이 문제에 대해 확인하는 것도 일반적으로 권장합니다.