1. 개요

Cilium 은 리눅스 커널의 eBPF 로 Pod 네트워크를 처리하는 CNI 플러그인이다. Pod 에 IP 를 붙이는 기본 역할에 더해 네트워크 정책, 서비스 로드 밸런싱(kube-proxy 대체), 통신 관측(Hubble), 외부 요청 분배(Gateway API)를 한 컴포넌트에서 제공한다.

정책은 IP 가 아니라 신원(identity) 으로 판단한다. Pod 의 라벨 묶음마다 숫자 신원을 붙이고, 패킷이 Pod 출입구를 지날 때 그 신원으로 허용·차단을 정한다. Pod IP 가 바뀌어도 정책을 다시 쓸 필요가 없다.

Pod ──veth── [eBPF: 정책·NAT·로드 밸런싱] ── 노드 네트워크
                       │
                       └─ Hubble: 흐름 기록 (허용 / 차단 / DNS)

2. 구성 요소

구성 요소형태하는 일
cilium-agentDaemonSet (노드마다)eBPF 프로그램을 커널에 올리고 정책을 집행한다
cilium-operatorDeployment클러스터 단위 작업. IP 주소 관리(IPAM), 남은 자원 정리
cilium-envoyDaemonSetL7 정책·Gateway 의 HTTP 처리
Hubbleagent 안 + Relay흐름 기록 수집과 조회

3. IP 주소 관리 모드

모드Pod IP 의 출처쓰는 곳
cluster-poolCilium 이 나눠 주는 대역일반 클러스터
kubernetes노드의 podCIDRkubeadm·kind 등
eniAWS ENI 의 보조 IP (VPC 주소)EKS. vpc-cni 를 대신할 때

ENI 모드에서는 operator 가 노드에 ENI 를 붙이고 IP 를 받아 온다. 그래서 operator 에 EC2 네트워크 인터페이스 권한(IRSA)이 필요하다. 같은 AWS 계정에 다른 클러스터가 있으면, operator 가 ENI 를 정리(GC)하고 인스턴스를 찾는 범위를 태그로 묶어 둔다.

eni:
  gcTags:                       # 이 태그가 있는 ENI 만 정리
    io.cilium/cilium-managed: "true"
    Environment: hosting
  instanceTagsFilter:           # 이 태그가 있는 인스턴스만 탐색
    - Environment=hosting

4. 네트워크 정책

표준 NetworkPolicy 를 그대로 집행하고, Cilium 전용 CiliumNetworkPolicy 로 더 넓은 규칙을 쓴다.

기능표준 NetworkPolicyCiliumNetworkPolicy
Pod·Namespace·IP 대역 기준 허용됨됨
도메인 이름 기준 외부 허용 (toFQDNs)없음됨
특수 대상 (world, host, ingress 등 entity)없음됨
거부 규칙 (egressDeny) — 허용보다 우선없음됨
L7 (HTTP 경로·메서드)없음됨
클러스터 전체 정책없음CiliumClusterwideNetworkPolicy

Cilium Gateway 로 들어온 요청은 일반 Pod 가 아니라 ingress 라는 특수 신원으로 들어온다. 표준 NetworkPolicy 로 Namespace 를 막아 두면 Gateway 요청도 막히므로, 따로 허용한다.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata: {name: allow-cilium-gateway, namespace: team-a}
spec:
  endpointSelector: {}
  ingress:
  - fromEntities: [ingress]

5. kube-proxy 대체와 소켓 LB

kubeProxyReplacement: true 이면 Service 주소를 Pod 주소로 바꾸는 일을 kube-proxy 의 iptables 대신 eBPF 가 한다. 변환은 두 단계에서 일어날 수 있다.

단계방식
소켓 단계 (socket LB)앱이 connect() 할 때 호스트 커널 소켓에서 주소를 바꾼다. 패킷이 생기기 전이라 빠르다
패킷 단계Pod 를 나가는 패킷의 주소를 바꾼다

gVisor Pod 의 앱은 호스트 커널 소켓을 쓰지 않으므로 소켓 단계 변환을 받지 못한다. 그러면 Service 주소가 그대로 나가 정책에 막힐 수 있다. socketLB.hostNamespaceOnly: true 로 소켓 단계를 호스트에만 적용하면, Pod 트래픽은 패킷 단계에서 변환된다.

kube-proxy 를 빼면 Cilium 이 API 서버에 닿을 다른 길이 없으므로 k8sServiceHost·k8sServicePort 에 API 서버 주소를 직접 적는다. 이 값이 틀리면 agent 가 시작하지 못하고 노드 네트워크가 끊긴다.

6. Hubble

Hubble 은 Cilium 이 처리한 흐름을 기록한다.

기록내용
흐름출발·도착 신원, 포트, 판정(FORWARDED / DROPPED), 차단 이유
DNSDNS 규칙을 건 Namespace 의 조회 도메인
지표차단 수, 포트별 연결, SYN 수 등을 Namespace 라벨과 함께 Prometheus 로

응답이 없을 때 “대상이 없어서” 인지 “정책 때문에” 인지를 기록으로 구분할 수 있다. 채굴 풀 조회, 일정 간격의 원격 조종 신호, 포트 스캔 같은 악용의 흔적도 흐름과 지표에 남는다.

hubble observe --namespace team-a --verdict DROPPED
hubble observe --namespace team-a --protocol dns

DNS 지표에 query 라벨을 붙이면 도메인마다 지표가 생겨 수가 폭발한다. 도메인은 흐름 기록으로 본다.

7. EKS 기본 CNI 와 비교

vpc-cni (EKS 기본)Cilium (ENI 모드)
Pod IPVPC 주소VPC 주소
표준 NetworkPolicy지원 (eBPF 에이전트)지원
도메인·거부·L7 정책없음있음
통신 관측없음Hubble
Gateway별도 설치내장
운영AWS 관리형 add-on직접 설치·업그레이드

8. 확인 명령

kubectl -n kube-system get ds cilium                       # 노드마다 agent 가 떠 있는지
kubectl -n kube-system exec ds/cilium -- cilium status     # agent 상태 요약
kubectl -n kube-system exec ds/cilium -- cilium-dbg config | grep -i sock   # 소켓 LB 설정

9. 관련 문서

  • CNI — Cilium 이 따르는 규격
  • gVisor — 함께 쓸 때의 소켓 LB 주의점
  • Service — kube-proxy 대체가 처리하는 주소 변환
  • conntrack — kube-proxy(iptables) 방식의 연결 추적
  • IMDS — 정책으로 막아 두는 메타데이터 주소
  • eBPF (예정) — Cilium 의 패킷 처리 방식
  • NetworkPolicy (예정) — 표준 Pod 방화벽

10. 출처