cilium에서도 istio처럼 Mutual Authentication이 가능한지 테스트해보려고 합니다.
환경 구성하기
cilium 설치하기
먼저 mutual spire를 활성화 합니다. 이렇게 설치하면 자동으로 cilium-spire에 spire도 설치되게 됩니다.
helm install cilium cilium/cilium --namespace kube-system \
--set k8sServiceHost=auto --set ipam.mode="cluster-pool" \
--set k8s.requireIPv4PodCIDR=true --set ipv4NativeRoutingCIDR=10.244.0.0/16 \
--set routingMode=native --set autoDirectNodeRoutes=true --set endpointRoutes.enabled=true \
--set kubeProxyReplacement=true --set bpf.masquerade=true --set installNoConntrackIptablesRules=true \
--set endpointHealthChecking.enabled=false --set healthChecking=false \
--set hubble.enabled=true --set hubble.relay.enabled=true --set hubble.ui.enabled=true \
--set hubble.ui.service.type=NodePort --set hubble.ui.service.nodePort=30003 \
--set prometheus.enabled=true --set operator.prometheus.enabled=true --set hubble.metrics.enableOpenMetrics=true \
--set hubble.metrics.enabled="{dns,drop,tcp,flow,port-distribution,icmp,httpV2:exemplars=true;labelsContext=source_ip\,source_namespace\,source_workload\,destination_ip\,destination_namespace\,destination_workload\,traffic_direction}" \
--set localRedirectPolicy=true --set l2announcements.enabled=true \
--set gatewayAPI.enabled=true \
--set operator.replicas=1 --set debug.enabled=true --set bpf.tproxy=true \
--set authentication.mutual.spire.enabled=true
샘플 애플리케이션 배포
테스트는 m-auth 네임스페이스에서 진행합니다.
kubectl create ns m-auth
kubectl config set-context --current --namespace m-auth
테스트를 위한 샘플 애플리케이션을 배포합니다.
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
labels:
app: echo
name: echo
spec:
ports:
- port: 3000
name: high
protocol: TCP
targetPort: 3000
selector:
app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: echo
name: echo
spec:
replicas: 1
selector:
matchLabels:
app: echo
template:
metadata:
labels:
app: echo
spec:
containers:
- image: gcr.io/k8s-staging-ingressconformance/echoserver:v20221109-7ee2f3e
name: echo
ports:
- containerPort: 3000
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod-worker
name: pod-worker
spec:
containers:
- name: netshoot
image: nicolaka/netshoot:latest
command: ["sleep", "infinite"]
EOF
이제 네트워크 정책도 배포해줍니다. 이 네트워크 정책으로는 /headers로의 요청은 정상이지만 그 외의 경우에는 통신이 되지 않게 합니다.
cat << EOF | kubectl apply -f -
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: no-mutual-auth-echo
spec:
endpointSelector:
matchLabels:
app: echo
ingress:
- fromEndpoints:
- matchLabels:
app: pod-worker
toPorts:
- ports:
- port: "3000"
protocol: TCP
rules:
http:
- method: "GET"
path: "/headers"
EOF
테스트를 해보면 잘 적용된 것을 확인할 수 있습니다.
spire 설치확인하기
cilium을 설치하면서 spire도 설치되는데 정상적으로 설치가 되었는지 확인해보겠습니다.
아래와 같이 에러가 발생하면
Server crashed" error="listen unix /tmp/spire-server/private/api.sock: bind: permission denied
spire-server 파드가 떠있는 서버에 들어가서 권한을 설정해줍니다.
chown 1000 -R /var/run/spire-server/sockets
이제 헬스체크를 확인해보겠습니다.
kubectl exec -n cilium-spire spire-server-0 -c spire-server -- /opt/spire/bin/spire-server healthcheck
인증된 목록을 확인해봅니다.
SPIRE 서버는 Kubernetes Projected Service Account Token(PSAT) 을 사용해 Kubernetes 클러스터에서 실행 중인 SPIRE 에이전트의 ID를 검증합니다. PSAT는 기존의 Service Account Token보다 보안성이 높으며, 클러스터가 지원한다면 권장되는 인증 방식입니다.
kubectl exec -n cilium-spire spire-server-0 -c spire-server -- /opt/spire/bin/spire-server agent list
SPIFFE 아이덴티티 확인
SPIRE 서비스가 정상임을 확인했으니, Cilium과 SPIRE 통합이 제대로 되었는지 확인합니다.
- Cilium 에이전트와 오퍼레이터는 SPIRE 서버에 등록된 대리(delegate) 아이덴티티를 가져야 합니다.
- Cilium 오퍼레이터는 워크로드(쿠버네티스 파드) 를 대신해 SPIRE 서버에 아이덴티티를 등록해야 합니다.
Cilium 에이전트와 오퍼레이터가 SPIRE 서버에 아이덴티티를 가지고 있는지 확인
kubectl exec -n cilium-spire spire-server-0 -c spire-server -- /opt/spire/bin/spire-server entry show -parentID spiffe://spiffe.cilium/ns/cilium-spire/sa/spire-agent
여기서부터 안되는데... 뭔가 통신이 안되는것 같당.. 확인 중
상호 인증 강제(Enforce)
기존(또는 새) CiliumNetworkPolicy 의 egress/ingress 규칙에 아래 블록을 추가하면 상호 인증을 적용할 수 있습니다.
kubectl get ciliumnetworkpolicy no-mutual-auth-echo -o json \
| jq '.spec.ingress = (.spec.ingress // [])
| .spec.ingress |= map(. + {authentication:{mode:"required"}})
| .spec.egress = (.spec.egress // [])
| .spec.egress |= map(. + {authentication:{mode:"required"}})' \
| kubectl apply -f -
다시한번 테스트로 호출해보겠습니다. 상호 인증을 하기 전과 동일한 결과가 나와야합니다.
'K8S > 🔥 network study🔥' 카테고리의 다른 글
[cilium] gateway API로 트래픽 분할하기 (0) | 2025.08.22 |
---|---|
[cilium] TProxy 이해해보기 (0) | 2025.08.22 |
[cilium] L7 Traffic Shifting 테스트 (2) | 2025.08.22 |
[cilium] Service Mesh 구성하기 (shared 모드) (0) | 2025.08.22 |
[cilium] containerlab으로 lb ippool 테스트 해보기 (6) | 2025.08.17 |