쿠버네티스가 기본적으로 제공하는 네트워크 정책 구성 요소들로만으로는 실무 환경에서 발생하는 다양한 네트워크 정책을 구현하기 쉽지 않다.
이를 보완해주는게 바로 CNI 플러그인이다.
쿠버네티스 네트워크 정책은 L3(IP), L4(Port) 계층의 트래픽만 제어 가능하고, L7 트래픽을 제어할 순 없다.

FQDN(Fully Qualifed Domain Name) 기반 제어 지원 XHTTP Path, method, Kafka 등 L7 프로토콜 등의 세부적인 정책 미지원ServiceMesh나 Ingres Controller 의 보조 필요클러스터 내 모든 노드, 네임스페이스, 파드에 적용 후 유지할 수 있는 정책이 별도 존재 X로깅 기능 지원 X 🔹 Calico에서 제공하는 확장 네트워크 정책으로, 네임스페이스에 국한되지 않고 클러스터 전체에 적용할 수 있게 해준다.
🔹 명시적 차단 기능(action:Deny), DNS 기반 제어, 정책 우선 순위(tier, order) 등 다양한 확장 기능 지원
🔹 log: true 설정을 통한 정책과 매칭되는 로그를 수집할 수 있는 로깅 기능도 지원함
명시적 Deny
apiVersion: protectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: deny-ssh
spec:
selector: all()
ingress:
- action: Deny # 명시적 차단!
destination:
ports: [22]
types:
- Ingress
특정 도메인 허용
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: allow-egress-to-domains
spec:
selector: all()
types:
- Egress
egress:
- action: Allow
protocol: UDP
destination:
ports:
- 53
- action: Allow
destination: # 특정 도메인 허용 기능!(유료 기능)
domains:
- api.example.com
- '*.example.org'
🚨 DNS 기반 제어 기능은 Calico의 유료 버전만 지원한다
🔹 Calico에서 제공하는 정책 시뮬레이션 및 단계적 적용을 위한 확장 리소스
🔹 실수로 모든 트래픽을 차단하는 문제 방지, 정책 충돌 원인 파악에 유용
🔹 적용 전, 적용 후로 나누어 세밀한 트래픽 제어 가능
모든 Ingress 트래픽을 기록(Log)만 수행
# only logging ingress traffic without block
apiVersion: projectcalico.org/v3
kind: StagedNetworkPolicy
metadata:
name: log-all-ingress
spec:
selector: app == "web"
ingress:
preRules:
- action: Log
source:
nets:
- 0.0.0.0/0
모든 Ingress 트래픽을 기록하고, 그중 SSH(22번 포트)만 차단
# logging all ingress & only block 22 port
apiVersion: projectcalico.org/v3
kind: StagedNetworkPolicy
metadata:
name: deny-ssh-after-log
spec:
selector: all()
ingress:
preRules:
- action: Log
postRules:
- action: Deny
destination:
ports: [22]
🧠
StagedNetworkPolicy는 Calico의 "미리 시뮬레이션" 기능으로,
🔹 실제로 트래픽을 차단하지 않고, 어떤 정책이 어떤 트래픽에 적용될지 사전 테스트 가능
🔹 운영 중인 시스템에 영향을 최소화하며 정책을 실험할 수 있는 안전한 방법
🔹 Cilium에서 제공하는 확장 네트워크 리소스로, 다양한 L7 트래픽 세밀 제어 지원
🔹 Hubble UI를 통한 정책 적용 결과 확인 가능
🔸 트래픽 추적 지원 등의 정책 적용 후 가시성 지원
🔹 IP, FQDN 외에도 파드의 Security Identity를 기반으로 하는 Identity 정책 적용 지원
allow-get-healthz.yaml
# only allow GET /healthz req
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-get-healthz
spec:
endpointSelector:
matchLabels:
app: my-api
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "80"
protocol: TCP
rules:
http:
- method: GET
path: "/healthz"
allow-egress-to-openai.yaml
# only allow specific domain (openai)
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-egress-to-openai
spec:
endpointSelector:
matchLabels: {}
egress:
- toFQDNs:
- matchName: "api.openai.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
🔹 GlobalNetworkPolicy 같이 클러스터 전체 워크로드에 적용 목적으로 지원하는 리소스
🔹 CiliumNetworkPolicy의 전역 일괄 적용이 필요한 경우 CiliumCluster*wide*NetworkPolicy를 활용
allow-openai-egress.yaml
# only openai domain across the cluster
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: allow-openai-egress
spec:
endpointSelector:
matchLabels: {}
egress:
- toFQDNs:
- matchName: "api.openai.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
allow-get-status.yaml
# only allow /status req in all namespaces
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: allow-get-status
spec:
endpointSelector:
matchLabels:
role: api
ingress:
- fromEndpoints:
- matchLabels:
role: client
toPorts:
- ports:
- port: "80"
rules:
http:
- method: GET
path: "/status"

🔹Calico는 GlobalNetworkPolicy의 egress 규칙에서 destination.domains 필드를 사용해 지원 가능
🔹내부적으로는 DNS를 주기적으로 조회해 IP를 계산하는 DNS IP 캐싱 기반으로 동작
🔸dnsPolicy가 적용된 kube-dns , CoreDNS를 통해 FQDN->IP 변환 후 해당 IP 에 대한 egress 규칙을 적용
🔹단, 해당 도메인으로 나가는 트래픽만 정책이 적용되며, DNS 쿼리 패턴 매칭 등의 고급 기능은 지원 X
# DNS policy example
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: allow-egress-to-domains
spec:
selector: all()
types:
- Egress
egress:
- action: Allow
protocol: UDP
destination:
ports:
- 53
- action: Allow
destination:
domains:
- api.example.com
- '*.example.org'
🔹Cilium은 CiliumNetworkPolicy에서 toFQDN 필드를 사용해 도메인 기반 제어 지원
🔹또한, toPorts의 rules.dns.matchPattern을 통해서도 패턴 매칭 기반의 도메인 기반 제어 지원
🔹Cilium은 eBPF 기반 DNS request 가로채기를 수행하며, 식별된 IP에 대해 커널 레벨에서 제어 수행
🔸eBPF DNS Tracker를 사용한 DNS 요청 및 응답 실시간 트래킹 수행 -> DNS 쿼리 필터링 등의 강력한 기능 지원
🔸도메인과 매칭되는 IP가 변경될 경우, 자동으로 정책 동기화
# FQDN policy + DNS pattern matching
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
name: "fqdn"
spec:
endpointSelector:
matchLabels:
org: empire
class: mediabot
egress:
- toFQDNs:
- matchPattern: "*.github.com"
toPorts:
- ports:
- port: "443"
protocol: TCP
- toEndpoints:
- matchLabels:
"k8s:io.kubernetes.pod.namespace": kube-system
"k8s:k8s-app": kube-dns
toPorts:
- ports:
- port: "53"
protocol: ANY
rules:
dns:
- matchPattern: "*"
🔹 Calico는 기본적으로 HTTP 메소드, URL 경로 등의 세부적인 트래픽 정책을 지원하지 않음
🔸L7 필터링 지원을 위해서는 서비스 메시와의 연동, 혹은 애플리케이션 레벨 필터링 리소스 연동 필요
🔹 ApplicationLayer과 같은 custom resource를 통해 제한된 기능을 GlobalNetworkPolicy에 적용 가능
🔸Ingress 규칙, 클러스터 레벨에만 적용 가능한 제한 사항이 존재함
🔸 프로토콜 또한 HTTP, HTTPS, gRPC 등의 한정된 프로토콜만 지원
# ApplicationLayer Custom Resource
apiVersion: operator.tigera.io/v1
kind: ApplicationLayer
metadata:
name: tigera-secure
spec:
applicationLayerPolicy: Enabled
---
# Application Layer policy example
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: customer
spec:
selector: app == 'tradingapp'
ingress:
- action: Allow
http:
methods: ["GET"]
paths:
- exact: "/projects/calico"
- prefix: "/users"
egress:
- action: Allow
🔹Cilium은 포트 기반 toPorts 규칙 아래 L7 필터링 정책을 정의하여 제어 가능
🔸 rules.http.method, rules.http.path 필드를 통해 HTTP 메소드, 경로에 대한 요청 차단 및 허용 가능
🔹또한, Kafka topic이나 gRPC method 등의 프로토콜에 대한 topic 및 method 필터링 지원이 가능함
🔸rules.kafka, rules.grpc 등의 필드를 통해 지원
🔹Cilium 내 내장된 eBPF + Envoy Proxy를 통해, 커널에서 L3/L4 처리 및 사용자 공간에서 L7 프록시 처리
# CiliumNetworkPolicy L7 policy
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-healthz
spec:
endpointSelector:
matchLabels:
app: backend
ingress:
- fromEndpoints:
- matchLabels:
app: frontend
toPorts:
- ports:
- port: "80"
protocol: TCP
rules:
http:
- method: GET
path: "/healthz"