이 글에서는 Cilium을 사용하여 MinIO에 기본 네트워크 정책을 적용하는 방법을 실습 형태로 살펴보겠습니다. 네트워크 정책을 통해 MinIO 서버에 대한 접근을 효과적으로 제한하고 보안을 강화하는 방법을 단계별로 설명합니다.
📌 네트워크 정책 개요
✅ 네트워크 정책이란?
네트워크 정책은 쿠버네티스에서 Pod 간 통신을 제어하는 규칙 집합입니다. Cilium은 쿠버네티스 표준 NetworkPolicy를 지원할 뿐만 아니라, 확장된 기능을 제공하는 CiliumNetworkPolicy도 지원합니다.
▶️ 네트워크 정책의 주요 특징:
- Pod 간 통신을 명시적으로 허용/거부
- 기본적으로 화이트리스트 모델(명시적으로 허용한 트래픽만 허용)
- 인그레스(수신) 및 이그레스(송신) 트래픽 제어
- 라벨 선택자를 통한 세밀한 타겟팅
✅ 기본 정책 없는 상태의 네트워크 동작
기본적으로 쿠버네티스 클러스터에는 네트워크 정책이 적용되어 있지 않습니다. 이는 모든 Pod가 제한 없이 서로 통신할 수 있음을 의미합니다.
▶️ 정책 없는 상태의 특징:
- 모든 Pod 간 자유로운 통신 가능
- 네임스페이스 간 격리 없음
- 외부 네트워크에서의 접근 제한 없음
- 보안 측면에서 취약한 상태
# 테스트를 위한 임시 Pod 생성
apiVersion: v1 # 쿠버네티스 API 버전
kind: Pod # 리소스 종류
metadata:
name: network-test # Pod 이름
namespace: default # 네임스페이스
spec:
containers:
- name: network-test # 컨테이너 이름
image: nicolaka/netshoot # 네트워크 테스트용 이미지
command: ["sleep", "3600"] # 1시간 동안 실행
# 테스트 Pod에서 MinIO 접근 테스트 (정책 적용 전)
kubectl exec -it network-test -- curl http://minio.minio-system.svc.cluster.local:9000 -v
📌 MinIO 환경 설정
✅ 테스트 환경 구축
네트워크 정책을 테스트하기 위한 MinIO 환경을 설정합니다.
apiVersion: v1 # 쿠버네티스 API 버전
kind: Namespace # 리소스 종류
metadata:
name: minio-system # 네임스페이스 이름
labels:
name: minio-system # 네임스페이스 라벨
---
apiVersion: apps/v1 # 앱 API 그룹 버전
kind: Deployment # 리소스 종류
metadata:
name: minio # Deployment 이름
namespace: minio-system # 네임스페이스
spec:
selector:
matchLabels:
app: minio # Pod 선택자
replicas: 1 # 복제본 수
template:
metadata:
labels:
app: minio # Pod 라벨
spec:
containers:
- name: minio # 컨테이너 이름
image: minio/minio:RELEASE.2023-07-21T21-12-44Z # MinIO 이미지
args:
- server # 서버 모드
- /data # 데이터 경로
env:
- name: MINIO_ROOT_USER
value: "minioadmin" # 루트 사용자 (실제 환경에서는 Secret 사용 권장)
- name: MINIO_ROOT_PASSWORD
value: "minioadmin" # 루트 비밀번호 (실제 환경에서는 Secret 사용 권장)
ports:
- containerPort: 9000 # API 포트
name: api # 포트 이름
- containerPort: 9001 # 콘솔 포트
name: console # 포트 이름
volumeMounts:
- name: data # 볼륨 이름
mountPath: /data # 마운트 경로
volumes:
- name: data # 볼륨 정의
emptyDir: {} # 임시 볼륨 (테스트용)
---
apiVersion: v1 # 쿠버네티스 API 버전
kind: Service # 리소스 종류
metadata:
name: minio # Service 이름
namespace: minio-system # 네임스페이스
spec:
selector:
app: minio # 대상 Pod 선택자
ports:
- name: api # API 포트 이름
port: 9000 # Service 포트
targetPort: api # 대상 Pod 포트
- name: console # 콘솔 포트 이름
port: 9001 # Service 포트
targetPort: console # 대상 Pod 포트
type: ClusterIP # Service 유형
✅ 클라이언트 Pod 생성
다양한 접근 패턴을 테스트하기 위한 클라이언트 Pod를 생성합니다.
apiVersion: v1 # 쿠버네티스 API 버전
kind: Namespace # 리소스 종류
metadata:
name: client-allowed # 네임스페이스 이름
labels:
name: client-allowed # 네임스페이스 라벨
---
apiVersion: v1 # 쿠버네티스 API 버전
kind: Namespace # 리소스 종류
metadata:
name: client-denied # 네임스페이스 이름
labels:
name: client-denied # 네임스페이스 라벨
---
apiVersion: v1 # 쿠버네티스 API 버전
kind: Pod # 리소스 종류
metadata:
name: allowed-client # Pod 이름
namespace: client-allowed # 네임스페이스
labels:
app: minio-client # Pod 라벨
spec:
containers:
- name: client # 컨테이너 이름
image: nicolaka/netshoot # 네트워크 테스트용 이미지
command: ["sleep", "3600"] # 1시간 동안 실행
---
apiVersion: v1 # 쿠버네티스 API 버전
kind: Pod # 리소스 종류
metadata:
name: denied-client # Pod 이름
namespace: client-denied # 네임스페이스
labels:
app: general-client # Pod 라벨
spec:
containers:
- name: client # 컨테이너 이름
image: nicolaka/netshoot # 네트워크 테스트용 이미지
command: ["sleep", "3600"] # 1시간 동안 실행
📌 기본 네트워크 정책 적용
✅ 기본 인그레스 제한 정책
먼저 MinIO에 대한 모든 인그레스 트래픽을 제한하는 기본 정책을 적용해 봅시다.
apiVersion: "cilium.io/v2" # Cilium API 그룹 버전
kind: CiliumNetworkPolicy # Cilium 네트워크 정책 리소스
metadata:
name: "minio-deny-all" # 정책 이름
namespace: minio-system # 네임스페이스
spec:
endpointSelector: # 정책 적용 대상
matchLabels:
app: minio # MinIO Pod 선택
ingress: # 인바운드 규칙
- {} # 빈 규칙은 모든 인그레스 트래픽 차단
# 정책 적용
kubectl apply -f minio-deny-all-policy.yaml
# 정책 확인
kubectl get ciliumnetworkpolicies -n minio-system
▶️ 차단 정책 테스트:
# denied-client에서 MinIO 접근 테스트
kubectl exec -it -n client-denied denied-client -- curl http://minio.minio-system.svc.cluster.local:9000 -v --max-time 5
# 접근이 차단되어 타임아웃 발생
✅ 선택적 허용 정책
이제 특정 네임스페이스 및 라벨을 가진 Pod에서의 접근만 허용하는 정책을 적용해 봅시다.
apiVersion: "cilium.io/v2" # Cilium API 그룹 버전
kind: CiliumNetworkPolicy # Cilium 네트워크 정책 리소스
metadata:
name: "minio-selective-allow" # 정책 이름
namespace: minio-system # 네임스페이스
spec:
endpointSelector: # 정책 적용 대상
matchLabels:
app: minio # MinIO Pod 선택
ingress: # 인바운드 규칙
- fromEndpoints: # 소스 엔드포인트
- matchLabels: # 라벨 매칭
app: minio-client # minio-client 라벨을 가진 Pod
k8s:io.kubernetes.pod.namespace: client-allowed # client-allowed 네임스페이스
toPorts: # 대상 포트
- ports: # 포트 목록
- port: "9000" # MinIO API 포트
protocol: TCP # TCP 프로토콜
- port: "9001" # MinIO 콘솔 포트
protocol: TCP # TCP 프로토콜
# 이전 정책 삭제
kubectl delete ciliumnetworkpolicies minio-deny-all -n minio-system
# 새 정책 적용
kubectl apply -f minio-selective-allow-policy.yaml
# 정책 확인
kubectl get ciliumnetworkpolicies -n minio-system
▶️ 선택적 허용 정책 테스트:
# allowed-client에서 MinIO 접근 테스트 (허용됨)
kubectl exec -it -n client-allowed allowed-client -- curl http://minio.minio-system.svc.cluster.local:9000 -v
# denied-client에서 MinIO 접근 테스트 (차단됨)
kubectl exec -it -n client-denied denied-client -- curl http://minio.minio-system.svc.cluster.local:9000 -v --max-time 5
✅ L4 포트 기반 정책
포트 수준에서 더 세밀한 제어를 적용하는 네트워크 정책입니다.
apiVersion: "cilium.io/v2" # Cilium API 그룹 버전
kind: CiliumNetworkPolicy # Cilium 네트워크 정책 리소스
metadata:
name: "minio-l4-policy" # 정책 이름
namespace: minio-system # 네임스페이스
spec:
endpointSelector: # 정책 적용 대상
matchLabels:
app: minio # MinIO Pod 선택
ingress: # 인바운드 규칙
- fromEndpoints: # 소스 엔드포인트
- matchLabels: # 라벨 매칭
app: minio-client # minio-client 라벨을 가진 Pod
k8s:io.kubernetes.pod.namespace: client-allowed # client-allowed 네임스페이스
toPorts: # 대상 포트
- ports: # 포트 목록
- port: "9000" # MinIO API 포트만 허용
protocol: TCP # TCP 프로토콜
# 이전 정책 삭제
kubectl delete ciliumnetworkpolicies minio-selective-allow -n minio-system
# 새 정책 적용
kubectl apply -f minio-l4-policy.yaml
# 정책 확인
kubectl get ciliumnetworkpolicies -n minio-system
▶️ L4 정책 테스트:
# API 포트 접근 테스트 (허용됨)
kubectl exec -it -n client-allowed allowed-client -- curl http://minio.minio-system.svc.cluster.local:9000 -v
# 콘솔 포트 접근 테스트 (차단됨)
kubectl exec -it -n client-allowed allowed-client -- curl http://minio.minio-system.svc.cluster.local:9001 -v --max-time 5
📌 고급 Cilium 네트워크 정책
✅ HTTP 메서드 기반 L7 정책
Cilium의 강력한 기능인 L7 정책을 사용하여 HTTP 메서드 수준에서 접근을 제어해 봅시다.
apiVersion: "cilium.io/v2" # Cilium API 그룹 버전
kind: CiliumNetworkPolicy # Cilium 네트워크 정책 리소스
metadata:
name: "minio-l7-policy" # 정책 이름
namespace: minio-system # 네임스페이스
spec:
endpointSelector: # 정책 적용 대상
matchLabels:
app: minio # MinIO Pod 선택
ingress: # 인바운드 규칙
- fromEndpoints: # 소스 엔드포인트
- matchLabels: # 라벨 매칭
app: minio-client # minio-client 라벨을 가진 Pod
k8s:io.kubernetes.pod.namespace: client-allowed # client-allowed 네임스페이스
toPorts: # 대상 포트
- ports: # 포트 목록
- port: "9000" # MinIO API 포트
protocol: TCP # TCP 프로토콜
rules: # L7 규칙
http: # HTTP 프로토콜 규칙
- method: "GET" # HTTP GET 메서드만 허용
# 이전 정책 삭제
kubectl delete ciliumnetworkpolicies minio-l4-policy -n minio-system
# 새 정책 적용
kubectl apply -f minio-l7-policy.yaml
# 정책 확인
kubectl get ciliumnetworkpolicies -n minio-system
▶️ L7 정책 테스트:
# GET 요청 테스트 (허용됨)
kubectl exec -it -n client-allowed allowed-client -- curl http://minio.minio-system.svc.cluster.local:9000 -v
# PUT 요청 테스트 (차단됨)
kubectl exec -it -n client-allowed allowed-client -- curl -X PUT http://minio.minio-system.svc.cluster.local:9000/testbucket -v --max-time 5
✅ 특정 경로 기반 정책
MinIO의 특정 버킷이나 경로에 대한 접근을 제어하는 정책을 구성해 봅시다.
apiVersion: "cilium.io/v2" # Cilium API 그룹 버전
kind: CiliumNetworkPolicy # Cilium 네트워크 정책 리소스
metadata:
name: "minio-path-policy" # 정책 이름
namespace: minio-system # 네임스페이스
spec:
endpointSelector: # 정책 적용 대상
matchLabels:
app: minio # MinIO Pod 선택
ingress: # 인바운드 규칙
- fromEndpoints: # 소스 엔드포인트
- matchLabels: # 라벨 매칭
app: minio-client # minio-client 라벨을 가진 Pod
k8s:io.kubernetes.pod.namespace: client-allowed # client-allowed 네임스페이스
toPorts: # 대상 포트
- ports: # 포트 목록
- port: "9000" # MinIO API 포트
protocol: TCP # TCP 프로토콜
rules: # L7 규칙
http: # HTTP 프로토콜 규칙
- method: "GET" # HTTP GET 메서드
path: "/public/.*" # public 경로만 허용
# 이전 정책 삭제
kubectl delete ciliumnetworkpolicies minio-l7-policy -n minio-system
# 새 정책 적용
kubectl apply -f minio-path-policy.yaml
# 정책 확인
kubectl get ciliumnetworkpolicies -n minio-system
▶️ 경로 기반 정책 테스트:
# 허용된 경로 테스트
kubectl exec -it -n client-allowed allowed-client -- curl http://minio.minio-system.svc.cluster.local:9000/public/ -v
# 차단된 경로 테스트
kubectl exec -it -n client-allowed allowed-client -- curl http://minio.minio-system.svc.cluster.local:9000/private/ -v --max-time 5
📌 이그레스 정책 적용
✅ 기본 이그레스 제한 정책
MinIO Pod에서 외부로 나가는 트래픽을 제한하는 이그레스 정책을 적용해 봅시다.
apiVersion: "cilium.io/v2" # Cilium API 그룹 버전
kind: CiliumNetworkPolicy # Cilium 네트워크 정책 리소스
metadata:
name: "minio-egress-policy" # 정책 이름
namespace: minio-system # 네임스페이스
spec:
endpointSelector: # 정책 적용 대상
matchLabels:
app: minio # MinIO Pod 선택
egress: # 아웃바운드 규칙
- toEndpoints: # 목적지 엔드포인트
- matchLabels: # 라벨 매칭
k8s:io.kubernetes.pod.namespace: kube-system # kube-system 네임스페이스
k8s-app: kube-dns # DNS 서비스
toPorts: # 대상 포트
- ports: # 포트 목록
- port: "53" # DNS 포트
protocol: UDP # UDP 프로토콜
# 이그레스 정책 적용
kubectl apply -f minio-egress-policy.yaml
# 정책 확인
kubectl get ciliumnetworkpolicies -n minio-system
▶️ 이그레스 정책 테스트:
# MinIO Pod에 접속
kubectl exec -it $(kubectl get pods -n minio-system -l app=minio -o name) -n minio-system -- /bin/sh
# DNS 요청 테스트 (허용됨)
nslookup kubernetes.default.svc.cluster.local
# 외부 연결 테스트 (차단됨)
wget -O- --timeout=5 http://example.com
✅ 복합 인그레스/이그레스 정책
인그레스와 이그레스 정책을 결합하여 보다 포괄적인 보안을 구현합니다.
apiVersion: "cilium.io/v2" # Cilium API 그룹 버전
kind: CiliumNetworkPolicy # Cilium 네트워크 정책 리소스
metadata:
name: "minio-complete-policy" # 정책 이름
namespace: minio-system # 네임스페이스
spec:
endpointSelector: # 정책 적용 대상
matchLabels:
app: minio # MinIO Pod 선택
ingress: # 인바운드 규칙
- fromEndpoints: # 소스 엔드포인트
- matchLabels: # 라벨 매칭
app: minio-client # minio-client 라벨을 가진 Pod
toPorts: # 대상 포트
- ports: # 포트 목록
- port: "9000" # MinIO API 포트
protocol: TCP # TCP 프로토콜
# MinIO 인스턴스 간 통신 허용 (분산 설정용)
- fromEndpoints: # 소스 엔드포인트
- matchLabels: # 라벨 매칭
app: minio # 다른 MinIO Pod
toPorts: # 대상 포트
- ports: # 포트 목록
- port: "9000" # MinIO API 포트
protocol: TCP # TCP 프로토콜
egress: # 아웃바운드 규칙
- toEndpoints: # 목적지 엔드포인트
- matchLabels: # 라벨 매칭
k8s:io.kubernetes.pod.namespace: kube-system # kube-system 네임스페이스
k8s-app: kube-dns # DNS 서비스
toPorts: # 대상 포트
- ports: # 포트 목록
- port: "53" # DNS 포트
protocol: UDP # UDP 프로토콜
# 다른 MinIO 인스턴스와의 통신 허용
- toEndpoints: # 목적지 엔드포인트
- matchLabels: # 라벨 매칭
app: minio # 다른 MinIO Pod
toPorts: # 대상 포트
- ports: # 포트 목록
- port: "9000" # MinIO API 포트
protocol: TCP # TCP 프로토콜
# 이전 정책 삭제
kubectl delete ciliumnetworkpolicies -n minio-system --all
# 복합 정책 적용
kubectl apply -f minio-complete-policy.yaml
📌 Hubble을 통한 정책 모니터링
✅ Hubble 활성화
Cilium의 네트워크 가시성 도구인 Hubble을 활성화하여 정책 적용 결과를 모니터링합니다.
# Hubble 활성화
cilium hubble enable --ui
# Hubble UI 포트 포워딩
cilium hubble ui
✅ 네트워크 흐름 분석
Hubble UI 또는 CLI를 통해 네트워크 흐름을 분석합니다.
# Hubble CLI로 흐름 관찰
cilium hubble observe --namespace minio-system
# 드롭된 패킷 관찰
cilium hubble observe --verdict DROPPED
# 특정 MinIO Pod와 관련된 흐름 관찰
cilium hubble observe --pod minio-system/minio-5d6f9c8b96-xxx
# 허용된 트래픽 관찰
cilium hubble observe --verdict FORWARDED --namespace minio-system
📌 네트워크 정책 문제 해결
✅ 정책 검증 및 디버깅
네트워크 정책 적용 시 발생할 수 있는 문제를 해결하는 방법을 알아봅시다.
▶️ 일반적인 문제 해결 방법:
- Cilium 에이전트 상태 확인
- 정책 구문 유효성 검증
- Hubble을 통한 트래픽 흐름 분석
- 로그 확인
# Cilium 상태 확인
cilium status
# 엔드포인트 및 정책 상태 확인
cilium endpoint list
cilium policy get
# 특정 정책 확인
kubectl get ciliumnetworkpolicies minio-complete-policy -n minio-system -o yaml
# Cilium 에이전트 로그 확인
kubectl logs -n kube-system -l k8s-app=cilium -c cilium-agent
✅ 일반적인 실수 및 해결책
정책 구현 시 흔히 발생하는 실수와 그 해결책입니다.
- 잘못된 라벨 선택자:
- 문제: 정책이 적용되지 않음
- 해결: kubectl get pods --show-labels로 실제 라벨 확인
- DNS 해결 실패:
- 문제: Pod가 DNS를 통한 이름 해결 실패
- 해결: kube-dns에 대한 UDP/53 포트 이그레스 허용
- 정책 충돌:
- 문제: 여러 정책 간 충돌
- 해결: 모든 관련 정책 검토 및 통합
📌 운영 환경을 위한 권장사항
✅ 보안 강화를 위한 모범 사례
프로덕션 환경에서 MinIO 네트워크 보안을 강화하기 위한 권장사항입니다.
▶️ 주요 권장사항:
- 기본적으로 모든 트래픽 거부 정책으로 시작
- 필요한 트래픽만 명시적으로 허용
- 최소 권한 원칙 적용
- 정기적인 정책 검토 및 업데이트
- 서비스 계정 기반 정책 고려
# 모든 트래픽 기본 거부 정책
apiVersion: "cilium.io/v2" # Cilium API 그룹 버전
kind: CiliumNetworkPolicy # Cilium 네트워크 정책 리소스
metadata:
name: "minio-deny-all-base" # 정책 이름
namespace: minio-system # 네임스페이스
spec:
endpointSelector: # 정책 적용 대상
matchLabels:
app: minio # MinIO Pod 선택
✅ 자동화된 정책 관리
GitOps 방식으로 네트워크 정책을 관리하는 방법입니다.
▶️ 자동화 방법:
- 네트워크 정책을 Git 저장소에서 관리
- CI/CD 파이프라인으로 정책 배포
- 정책 변경 사항 테스트 자동화
- Helm 차트로 정책 템플릿화
# Helm을 사용한 정책 템플릿 예시 (values.yaml)
networkPolicies:
enabled: true
minioSelector:
app: minio
allowedClients:
- namespace: client-allowed
podSelector:
app: minio-client
allowedPorts:
- port: 9000
protocol: TCP
egressRules:
dnsEnabled: true
📌 Summary
- Cilium 네트워크 정책은 MinIO 접근을 효과적으로 제한하는 강력한 도구
- 기본적으로 모든 트래픽을 거부하고 필요한 트래픽만 허용하는 화이트리스트 모델 권장
- L3/L4 정책으로 포트 및 IP 기반 접근 제어 가능
- L7 정책을 통해 HTTP 메서드와 경로 기반의 세밀한 제어 구현
- 인그레스와 이그레스 정책을 함께 적용하여 완전한 네트워크 보안 구축
- Hubble로 네트워크 흐름을 시각화하여 정책 효과 검증 및 문제 해결 가능
- 라벨 선택자를 활용한 유연한 정책 타겟팅으로 다양한 환경에 적용 가능
- 최소 권한 원칙에 따른 정책 설계로 MinIO 데이터 보안 강화