- Authors

- Name
- Youngju Kim
- @fjvbn20031
Cilium 아키텍처 내부 분석: eBPF 기반 네트워킹의 핵심
개요
Cilium은 eBPF(extended Berkeley Packet Filter)를 활용하여 쿠버네티스 환경에서 고성능 네트워킹, 보안, 관찰성을 제공하는 CNI 플러그인입니다. 이 글에서는 Cilium의 내부 아키텍처를 구성하는 핵심 컴포넌트들을 깊이 분석합니다.
1. Cilium Agent: 노드 수준의 핵심 엔진
1.1 Agent 개요
Cilium Agent는 각 쿠버네티스 노드에서 DaemonSet으로 실행되는 핵심 컴포넌트입니다. 주요 역할은 다음과 같습니다.
- 엔드포인트 관리: Pod 생성/삭제 시 네트워크 인터페이스 설정
- 정책 컴파일: CiliumNetworkPolicy를 eBPF 프로그램으로 변환
- eBPF 프로그램 로딩: 컴파일된 BPF 프로그램을 커널에 로드
- Identity 관리: 보안 레이블 기반 Identity 할당 및 추적
- IPAM: 노드 수준 IP 주소 관리
- 상태 동기화: KVStore 또는 CRD와 상태 동기화
1.2 Agent 내부 구조
Cilium Agent는 여러 서브시스템으로 구성됩니다.
// Cilium Agent의 주요 서브시스템 (개념적 구조)
type Daemon struct {
// 엔드포인트 관리
endpointManager *endpoint.EndpointManager
// 정책 리포지토리
policy *policy.Repository
// Identity 할당기
identityAllocator *cache.CachingIdentityAllocator
// IPAM
ipam *ipam.IPAM
// 데이터패스 관리
datapath datapath.Datapath
// KVStore 클라이언트
kvStore kvstore.BackendOperations
// 모니터링
monitorAgent monitorAgent.Agent
}
1.3 Agent 시작 프로세스
Agent가 시작될 때 다음 순서로 초기화가 진행됩니다.
- 설정 로드: ConfigMap 또는 명령줄 인자에서 설정 읽기
- KVStore 연결: etcd 또는 CRD 기반 KVStore 연결
- IPAM 초기화: IP 주소 풀 설정
- BPF 맵 초기화: 필요한 BPF 맵 생성 또는 복원
- 기존 엔드포인트 복원: 재시작 시 기존 엔드포인트 상태 복원
- 정책 로드: 기존 네트워크 정책 로드 및 적용
- 이벤트 감시 시작: 쿠버네티스 API 서버 이벤트 감시
# Agent 상태 확인
cilium status --verbose
# Agent 설정 확인
cilium config
1.4 엔드포인트 관리 상세
Cilium Agent는 Pod 생성 시 CNI 인터페이스를 통해 호출됩니다.
# Pod 생성 시 Cilium CNI 호출 흐름
# 1. kubelet이 CRI를 통해 컨테이너 런타임에 Pod 생성 요청
# 2. 컨테이너 런타임이 CNI 플러그인(Cilium) 호출
# 3. Cilium CNI가 Agent에 API 호출
# 4. Agent가 veth pair 생성, IP 할당, BPF 프로그램 로드
# 엔드포인트 목록 확인
cilium endpoint list
# 특정 엔드포인트 상세 정보
cilium endpoint get 12345
2. Cilium Operator: 클러스터 수준 관리
2.1 Operator 역할
Cilium Operator는 클러스터 수준에서 실행되는 컴포넌트로, 단일 인스턴스(또는 HA를 위한 리더 선출 기반 다중 인스턴스)로 배포됩니다.
주요 역할:
- IPAM 관리: 클러스터 범위 IP 풀 관리 (Cluster Scope IPAM, AWS ENI 등)
- CRD 관리: CiliumNode, CiliumIdentity 등 CRD 가비지 컬렉션
- 노드 디스커버리: 새 노드 등록 및 메타데이터 관리
- Ingress/Gateway 관리: Ingress 및 Gateway API 리소스 처리
2.2 Operator와 Agent의 역할 분리
+------------------+ +-------------------+
| Cilium Operator | | Cilium Agent |
| (클러스터 범위) | | (노드 범위) |
+------------------+ +-------------------+
| - Cluster IPAM | | - 엔드포인트 관리 |
| - CRD GC | | - BPF 프로그램 로드 |
| - 노드 디스커버리 | | - 정책 적용 |
| - Ingress 처리 | | - conntrack 관리 |
| - Identity GC | | - Identity 할당 |
+------------------+ +-------------------+
2.3 Operator 설정 예시
apiVersion: apps/v1
kind: Deployment
metadata:
name: cilium-operator
namespace: kube-system
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
spec:
containers:
- name: cilium-operator
image: quay.io/cilium/operator-generic:v1.16.0
args:
- --config-dir=/tmp/cilium/config-map
- --cluster-pool-ipv4-cidr=10.0.0.0/8
- --cluster-pool-ipv4-mask-size=24
3. eBPF 데이터패스: 커널 수준의 네트워크 처리
3.1 eBPF 프로그램 훅 포인트
Cilium은 리눅스 커널의 여러 훅 포인트에 eBPF 프로그램을 부착합니다.
tc (Traffic Control) 훅
가장 주요한 훅 포인트로, 각 네트워크 인터페이스의 ingress/egress에 부착됩니다.
패킷 수신 흐름:
NIC -> [XDP] -> 드라이버 -> [tc ingress] -> 네트워크 스택 -> [tc egress] -> NIC
Cilium BPF 프로그램 부착 위치:
- lxc* (veth): from-container, to-container
- cilium_host: to-host, from-host
- cilium_net: from-host (오버레이)
- eth0 (물리): from-netdev, to-netdev
XDP (eXpress Data Path)
네트워크 드라이버 수준에서 동작하는 가장 빠른 패킷 처리 경로입니다.
# XDP 프로그램 확인
ip link show dev eth0
# eth0: ... xdp/id:42 ...
# BPF 프로그램 목록 확인
bpftool prog list
Socket 수준 훅
소켓 시스템 콜을 가로채어 서비스 로드 밸런싱을 수행합니다.
connect() -> [BPF sock_ops] -> 서비스 IP를 백엔드 IP로 변환
sendmsg() -> [BPF sk_msg] -> 소켓 간 메시지 리디렉션
3.2 BPF 프로그램 컴파일 파이프라인
C 소스 코드 (bpf/*.c)
|
v
LLVM/Clang (BPF 백엔드)
|
v
BPF ELF 오브젝트 파일 (.o)
|
v
BPF 로더 (bpf 시스템 콜)
|
v
커널 BPF 검증기
|
v
JIT 컴파일 -> 네이티브 기계어
|
v
커널에서 실행
3.3 주요 BPF 프로그램 파일
bpf/
bpf_lxc.c # Pod(엔드포인트) 데이터패스
bpf_host.c # 호스트 네트워크 데이터패스
bpf_overlay.c # 오버레이(VXLAN/Geneve) 데이터패스
bpf_network.c # 물리 네트워크 인터페이스
bpf_xdp.c # XDP 프로그램
bpf_sock.c # 소켓 수준 프로그램
lib/
common.h # 공통 헤더 및 매크로
maps.h # BPF 맵 정의
policy.h # 정책 관련 함수
conntrack.h # 커넥션 트래킹
nat.h # NAT 엔진
lb.h # 로드 밸런서
4. BPF 맵: 데이터패스의 상태 저장소
4.1 주요 BPF 맵 타입
Cilium은 다양한 BPF 맵 타입을 사용합니다.
| 맵 이름 | 타입 | 용도 |
|---|---|---|
| cilium_ipcache | LPM Trie | IP에서 Identity/터널 정보 매핑 |
| cilium_policy | Hash | Identity 기반 정책 룩업 |
| cilium_ct4_global | Hash (LRU) | IPv4 커넥션 트래킹 |
| cilium_ct6_global | Hash (LRU) | IPv6 커넥션 트래킹 |
| cilium_lb4_services | Hash | IPv4 서비스 로드 밸런서 |
| cilium_lb4_backends | Hash | IPv4 백엔드 정보 |
| cilium_snat_v4_external | Hash (LRU) | IPv4 SNAT 매핑 |
| cilium_tunnel_map | Hash | 터널 엔드포인트 매핑 |
| cilium_lxc | Hash | 엔드포인트 정보 |
| cilium_signals | Perf Event Array | 이벤트 시그널링 |
4.2 BPF 맵 확인 명령
# 모든 BPF 맵 목록 확인
bpftool map list
# 특정 맵 내용 확인 (ipcache)
cilium bpf ipcache list
# 커넥션 트래킹 테이블
cilium bpf ct list global
# 서비스 로드 밸런서 테이블
cilium bpf lb list
# 정책 맵 확인
cilium bpf policy get 12345
# 터널 맵 확인
cilium bpf tunnel list
4.3 LPM Trie: CIDR 정책의 핵심
LPM(Longest Prefix Match) Trie는 CIDR 기반 정책 매칭에 사용됩니다.
IP Cache 구조:
10.0.0.0/8 -> Identity: 1 (world)
10.244.0.0/16 -> Identity: 100 (cluster)
10.244.1.0/24 -> Identity: 200 (특정 네임스페이스)
10.244.1.5/32 -> Identity: 300 (특정 Pod)
룩업: 10.244.1.5 -> Identity 300 (가장 구체적인 매칭)
4.4 LRU Hash: 커넥션 트래킹
LRU(Least Recently Used) Hash 맵은 커넥션 트래킹에 사용됩니다. 맵이 가득 차면 가장 오래된 항목이 자동으로 제거됩니다.
# conntrack 항목 예시
cilium bpf ct list global
# SRC: 10.244.1.5:34567 DST: 10.96.0.1:443
# Flags: rx+tx closing
# Lifetime: 120s
# RxPackets: 42 RxBytes: 3456
# TxPackets: 38 TxBytes: 2890
5. Identity 할당: 레이블 기반 보안 모델
5.1 Identity 할당 메커니즘
Cilium의 보안 모델은 레이블 기반 Identity에 기초합니다.
Pod 레이블:
app: frontend
env: production
team: web
|
v (보안 관련 레이블 추출)
보안 관련 레이블:
k8s:app=frontend
k8s:io.kubernetes.pod.namespace=default
|
v (해시 계산)
Identity: 48291 (수치 식별자)
5.2 보안 관련 레이블 결정
모든 레이블이 Identity에 사용되는 것은 아닙니다. 기본적으로 다음이 보안 관련 레이블로 간주됩니다.
# Identity 목록 확인
cilium identity list
# 특정 Identity 상세 정보
cilium identity get 48291
# Identity에 포함되는 레이블 예시:
# - k8s:app=...
# - k8s:io.kubernetes.pod.namespace=...
# - k8s:io.cilium.k8s.policy.cluster=...
# Identity에서 제외되는 레이블 예시:
# - k8s:controller-revision-hash=...
# - k8s:pod-template-hash=...
# - k8s:pod-template-generation=...
5.3 Identity 동기화
Identity는 KVStore를 통해 클러스터 전체에서 동기화됩니다.
노드 A: Pod 생성 -> 레이블 기반 Identity 요청
|
v
KVStore (CRD 또는 etcd)
|
v (Identity 할당/조회)
CiliumIdentity CRD:
metadata:
name: "48291"
security-labels:
k8s:app: frontend
k8s:io.kubernetes.pod.namespace: default
|
v
노드 B: ipcache에 IP-to-Identity 매핑 업데이트
5.4 예약된 Identity
Cilium은 특수 목적의 예약된 Identity를 정의합니다.
| Identity | 수치값 | 의미 |
|---|---|---|
| unknown | 0 | 알 수 없는 소스 |
| host | 1 | 로컬 호스트 |
| world | 2 | 클러스터 외부 |
| unmanaged | 3 | Cilium이 관리하지 않는 엔드포인트 |
| health | 4 | 헬스 체크 엔드포인트 |
| init | 5 | 초기화 중인 엔드포인트 |
| remote-node | 6 | 원격 노드 |
| kube-apiserver | 7 | 쿠버네티스 API 서버 |
| ingress | 8 | Ingress |
6. 엔드포인트 라이프사이클
6.1 엔드포인트 생성
1. Pod 생성 이벤트 수신
|
v
2. CNI ADD 호출 -> veth pair 생성
|
v
3. IP 주소 할당 (IPAM)
|
v
4. Identity 할당
|
v
5. 정책 계산 (Identity 기반)
|
v
6. BPF 프로그램 컴파일
(정책 + Identity + 설정 -> 맞춤형 BPF 코드)
|
v
7. BPF 프로그램 로드 (tc ingress/egress)
|
v
8. BPF 맵 업데이트
(ipcache, endpoint map, policy map)
|
v
9. 엔드포인트 상태: Ready
6.2 엔드포인트 재생성 (Regeneration)
정책 변경 시 영향받는 엔드포인트의 BPF 프로그램을 재컴파일합니다.
# 엔드포인트 재생성 트리거 이유
# - 네트워크 정책 변경
# - Identity 변경
# - Cilium 설정 변경
# - 정책에서 참조하는 FQDN의 IP 변경
# 재생성 상태 모니터링
cilium endpoint list
# ID IDENTITY POLICY ENDPOINT STATUS
# 1234 48291 OK ready
# 1235 48292 OK regenerating <-- 재생성 중
6.3 엔드포인트 삭제
1. Pod 삭제 이벤트 수신
|
v
2. CNI DEL 호출
|
v
3. BPF 프로그램 분리 및 제거
|
v
4. BPF 맵에서 관련 항목 제거
|
v
5. veth pair 삭제
|
v
6. IP 주소 반환 (IPAM)
|
v
7. 엔드포인트 메타데이터 정리
6.4 엔드포인트 상태 확인
# 상세 엔드포인트 정보
cilium endpoint get 1234
# 엔드포인트 헬스 확인
cilium endpoint health 1234
# 엔드포인트별 BPF 프로그램 확인
cilium bpf prog list
# 엔드포인트 로그 확인
cilium endpoint log 1234
7. 상태 관리 및 복원
7.1 KVStore 백엔드
Cilium은 두 가지 KVStore 백엔드를 지원합니다.
# CRD 기반 (기본값)
# - CiliumIdentity, CiliumEndpoint, CiliumNode 등의 CRD 사용
# - etcd 의존성 제거
# - 쿠버네티스 API 서버를 통한 상태 관리
# etcd 기반
# - 별도의 etcd 클러스터 필요
# - 대규모 클러스터에서 성능 우위
# - ClusterMesh 시 필수 (clustermesh-apiserver)
7.2 Agent 재시작 시 상태 복원
Agent 재시작
|
v
BPF 맵 복원 (맵은 커널에 유지)
|
v
기존 엔드포인트 검색 (veth 인터페이스 스캔)
|
v
엔드포인트 상태 복원 (CRD에서 로드)
|
v
Identity 캐시 워밍
|
v
정책 재계산 및 적용
|
v
정상 운영 재개
Agent가 재시작되더라도 BPF 맵과 프로그램은 커널에 유지되므로 데이터패스는 중단 없이 동작합니다. 이를 통해 Agent 업그레이드 시에도 네트워크 연결이 유지됩니다.
8. 아키텍처 디버깅 도구
8.1 핵심 디버깅 명령
# 전체 상태 확인
cilium status --verbose
# BPF 프로그래밍 상태
cilium bpf prog list
# 데이터패스 설정 확인
cilium debuginfo
# 모니터링 (실시간 패킷 이벤트)
cilium monitor --type trace
cilium monitor --type drop
cilium monitor --type policy-verdict
# 메트릭 확인
cilium metrics list
8.2 트러블슈팅 체크리스트
cilium status로 Agent/Operator 상태 확인cilium endpoint list로 엔드포인트 상태 확인 (ready/not-ready/regenerating)cilium bpf ipcache list로 IP-to-Identity 매핑 확인cilium monitor --type drop으로 드롭된 패킷 원인 분석cilium policy get으로 적용된 정책 확인cilium bpf ct list global로 커넥션 트래킹 상태 확인
정리
Cilium의 아키텍처는 다음과 같은 핵심 설계 원칙에 기반합니다.
- 커널 수준 처리: eBPF를 통해 네트워크 패킷을 커널에서 직접 처리하여 고성능 달성
- Identity 기반 보안: IP 주소 대신 레이블 기반 Identity로 정책을 적용하여 동적 환경에 적합
- 선언적 관리: 쿠버네티스 CRD를 통한 선언적 상태 관리
- 무중단 업데이트: BPF 프로그램과 맵이 커널에 유지되어 Agent 재시작 시에도 데이터패스 유지
- 역할 분리: Agent(노드 수준)와 Operator(클러스터 수준)의 명확한 역할 분리