Data Engineering/s3 minio

EP16 [ MinIO S3 + Cilium 기초 과정 ] 네트워크 기초 #4 | 기본 네트워크 정책 적용하기 - MinIO 접근 제한 실습

ygtoken 2025. 3. 29. 16:32
728x90

 

이 글에서는 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

✅ 일반적인 실수 및 해결책

정책 구현 시 흔히 발생하는 실수와 그 해결책입니다.

  1. 잘못된 라벨 선택자:
    • 문제: 정책이 적용되지 않음
    • 해결: kubectl get pods --show-labels로 실제 라벨 확인
  2. DNS 해결 실패:
    • 문제: Pod가 DNS를 통한 이름 해결 실패
    • 해결: kube-dns에 대한 UDP/53 포트 이그레스 허용
  3. 정책 충돌:
    • 문제: 여러 정책 간 충돌
    • 해결: 모든 관련 정책 검토 및 통합

📌 운영 환경을 위한 권장사항

✅ 보안 강화를 위한 모범 사례

프로덕션 환경에서 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 데이터 보안 강화
728x90