eBPF Maps

eBPF Maps (BPF 맵)

Cilium의 데이터 경로는 여러 eBPF 맵을 사용하며, 각 맵에는 상한 용량 제한이 있어요. 이 글에서는 맵별 기본 한도 값과 명령줄 옵션으로 한도를 조정하는 방법, 동적 크기 조정에 대해 설명해요.

출처: eBPF Maps

본문

모든 BPF 맵은 상한 용량 제한과 함께 생성돼요. 이 한도를 넘어 삽입하려 하면 실패하고, 그 결과 데이터 경로의 확장성이 제한돼요. 아래 표는 맵의 기본값을 보여줘요. 각 한도는 소스 코드에서 늘릴 수 있고, 필요가 생기면 요청에 따라 설정 옵션이 추가되기도 해요.

Map Name Scope Default Limit Scale Implications
Auth node 512k Max 512k authenticated relations per node
Connection Tracking node 512k TCP/256k UDP Max 512k concurrent TCP connections, max 256k expected UDP answers
NAT node 512k Max 512k NAT entries
Neighbor Table node 512k Max 512k neighbor entries
Endpoints node 64k Max 64k local endpoints + host IPs per node
IP cache node 512k Max 256k endpoints (IPv4+IPv6), max 512k endpoints (IPv4 or IPv6) across all clusters
Service Load Balancer node 64k Max ~3k clusterIP/nodePort Services across all clusters (see: service map sizing section for details).
Service Backends node 64k Max 64k cumulative unique backends across all services across all clusters
Service Source Ranges node 64k Max 64k cumulative LB source ranges across all services
Service Session Affinity node 64k Max 64k affinities from different clients
Policy endpoint 16k Max 16k allowed identity + port + protocol pairs for specific endpoint
IPv4 Fragmentation node 8k Max 8k fragmented datagrams in flight simultaneously on the node
IPv6 Fragmentation node 8k Max 8k fragmented datagrams in flight simultaneously on the node
IPv4 Masq node 16k Max 16k IPv4 cidrs used by BPF-based ip-masq-agent
IPv6 Masq node 16k Max 16k IPv6 cidrs used by BPF-based ip-masq-agent
Egress Policy node 16k Max 16k endpoints across all destination CIDRs across all clusters
Node node 16k Max 16k distinct node IPs (IPv4 & IPv6) across all clusters.

일부 BPF 맵은 cilium-agent의 명령줄 옵션으로 상한 용량을 재정의할 수 있어요. 특정 용량은 --bpf-auth-map-max, --bpf-ct-global-tcp-max, --bpf-ct-global-any-max, --bpf-nat-global-max, --bpf-neigh-global-max, --bpf-policy-map-max, --bpf-fragments-map-max, --bpf-lb-map-max 옵션으로 설정할 수 있어요.

Note --bpf-ct-global-tcp-max 또는 --bpf-ct-global-any-max를 지정한 경우, NAT 테이블 크기(--bpf-nat-global-max)는 결합된 CT 테이블 크기(TCP + UDP)의 2/3을 초과하면 안 돼요. 이 값은 --bpf-nat-global-max를 명시적으로 설정하지 않았거나 동적 BPF 맵 크기 조정을 사용할 때 자동으로 설정돼요 (아래 참고).

--bpf-map-dynamic-size-ratio 플래그를 사용하면 여러 큰 BPF 맵의 상한 용량이 에이전트 시작 시 전체 시스템 메모리의 주어진 비율을 기준으로 결정돼요. 예를 들어 비율 0.0025를 주면 전체 시스템 메모리의 0.25%를 이 맵들에 사용하게 돼요.

이 플래그는 시스템에서 메모리를 가장 많이 사용하는 다음 BPF 맵에 영향을 줘요: cilium_ct_{4,6}_global, cilium_ct_{4,6}_any, cilium_nodeport_neigh{4,6}, cilium_snat_v{4,6}_external, cilium_lb{4,6}_reverse_sk.

kube-proxy는 머신의 코어 수를 기준으로 리눅스 커넥션 트래킹 테이블의 최대 항목 수를 설정해요. kube-proxy는 코어당 최대 32768개 항목을 기본값으로 하고, 코어 수와 무관하게 최소 131072개 항목을 보장해요.

Cilium은 자체 커넥션 트래킹 테이블을 BPF 맵으로 갖고 있으며, 이 맵의 항목 수는 노드의 총 메모리 양을 기준으로 계산돼요. 머신의 메모리 양과 무관하게 최소 131072개 항목을 보장해요.

Cilium을 --bpf-map-dynamic-size-ratio: 0.0025로 설정했을 때 kube-proxy와 Cilium이 각자의 커넥션 트래킹 테이블에 설정하는 값을 아래 표에서 보여줘요.

vCPU Memory (GiB) Kube-proxy CT entries Cilium CT entries
1 3.75 131072 131072
2 7.5 131072 131072
4 15 131072 131072
8 30 262144 284560
16 60 524288 569120
32 120 1048576 1138240
64 240 2097152 2276480
96 360 3145728 4552960

Service LB Map Sizing

Cilium은 cilium_lb{4,6}_services_v2라는 이름의 LB 서비스 맵을 사용해서 clusterIP 및 nodePort 서비스 타입의 Service 로드 밸런서 항목을 보관해요. 이 맵들은 --bpf-lb-map-max 플래그로 설정되며 기본값은 64k예요. 이 맵이 가득 차면 Cilium이 Service 업데이트를 동기화하지 못할 수 있고, 이는 서비스 IP 연결성에 영향을 주거나 새 서비스를 만들지 못하게 할 수 있어요.

서비스 LB 맵의 필요 크기는 여러 요인에 따라 달라져요. 각 clusterIP/nodePort 서비스는 해당 Service가 선택한 Pod 백엔드 수에 서비스 spec의 포트/프로토콜 항목 수를 곱한 만큼의 항목을 생성해요.

(\text{LB map entries per Service} = (\text{number of endpoints per service}) * (\text{number of port/protocols per service}))

이를 이용해 필요한 맵 크기를 대략 이렇게 구할 수 있어요:

(\text{LB map entries} \approx (\text{number of LB services}) * (\text{avg number of endpoints per service}) * (\text{avg number of port/protocols per service}))

Note 이 휴리스틱은 서비스별 선택된 Pod 수와 포트/프로토콜 항목 수가 대략 정규분포를 따른다고 가정해요. 사용 사례에 큰 이상치가 있다면 (예: 매우 많은 Pod 백엔드를 선택하는 서비스), 더 정밀한 추정이 필요할 수 있어요.

Cilium이 노드의 서비스 LB 맵을 생성한 후(즉, 노드에서 Cilium 에이전트를 처음 실행했을 때) 맵 크기 파라미터를 바꾸고 Cilium을 재시작하면, 새 맵이 기존 서비스 항목으로 다시 채워지면서 커넥션 중단이 발생해요. 따라서 이런 중단이 우려된다면 Cilium을 설치하기 전에 맵 요구 사항을 신중히 검토하는 것이 중요해요.

더 알아보기 (Learn more)