본문 바로가기
클라우드/Cilium

🚨쿠버네티스 보안 비상! Label만 알면 우리 서비스는 안전할까? (Cilium Network Policy 파헤치기)

by gasbugs 2025. 12. 5.

안녕하세요! 오늘은 복잡한 쿠버네티스 환경에서 우리 서비스를 안전하게 지키는 강력한 도구, Cilium의 네트워크 정책(Network Policy)에 대해 깊이 알아보려고 합니다.

쿠버네티스를 사용하다 보면 수많은 파드(Pod)들이 서로 통신하게 되는데요. "어떤 파드가 누구와 통신할 수 있는지" 명확하게 제어하지 않으면, 마치 모든 문이 열려있는 아파트처럼 보안에 취약해질 수 있습니다. 😟

이때 등장하는 것이 바로 네트워크 정책! 그리고 그중에서도 eBPF 기술로 강력한 성능과 기능을 자랑하는 Cilium의 네트워크 정책은 어떻게 동작할까요? 핵심은 바로 'Label''Selector'에 있습니다.


🌍 전체적인 그림: 네트워크 정책은 왜 필요할까?

먼저 큰 그림부터 살펴봅시다. 쿠버네티스에서 네트워크 정책은 파드 그룹 간의 트래픽을 제어하는 방화벽 규칙이라고 생각하면 쉽습니다.

기본적으로 쿠버네티스 클러스터 내에서는 모든 파드가 서로 자유롭게 통신할 수 있습니다. 하지만 실제 서비스를 운영할 때는 이런 구성은 매우 위험합니다. 💣

예를 들어, 결제-API 파드는 주문-서비스 파드와는 통신해야 하지만, 전혀 관련 없는 로그인-UI 파드와 통신할 필요는 없죠. 만약 로그인-UI 파드가 해킹당했을 때, 네트워크 정책이 없다면 공격자는 쉽게 내부망을 통해 결제-API까지 접근할 수 있게 됩니다.

 

Cilium 네트워크 정책은 바로 이런 상황을 막기 위해 어떤 파드(Endpoint)에, 어떤 트래픽(Ingress/Egress)을 허용할지를 매우 세밀하게 정의할 수 있게 해줍니다.


🎯 핵심 원리: '누구'를 선택할 것인가? Label & Namespace Selectors

Cilium 네트워크 정책의 핵심은 "어떤 파드에 이 정책을 적용할 것인가?" 그리고 "어떤 파드/네임스페이스로부터 오는 트래픽을 허용할 것인가?"를 결정하는 'Selector(선택자)' 메커니즘에 있습니다.

Cilium은 이를 위해 두 가지 주요 선택자를 사용합니다.

1. endpointSelector: 정책을 적용할 대상을 콕 집어내기

endpointSelector는 이 네트워크 정책 규칙이 적용될 파드(Cilium에서는 엔드포인트라고 부릅니다)를 선택합니다. 마치 "이 방화벽 규칙은 'class: backend' 딱지가 붙은 서버들에게만 적용해!"라고 명령하는 것과 같습니다.

여기서 바로 'Label Selector'가 사용됩니다. 파드에 붙어있는 Label을 기준으로 정책 대상을 정확하게 골라낼 수 있습니다.

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: backend-api-policy
spec:
  endpointSelector:
    matchLabels:
      app: backend
      tier: api
  # ... 이제 이 파드들에 대한 규칙을 정의합니다.

위 예시에서는 app=backend와 tier=api라는 레이블을 모두 가진 파드들이 이 정책의 적용 대상이 됩니다.

2. namespaceSelector: 통신을 허용할 동네(Namespace) 정하기

정책을 적용할 파드를 골랐다면, 이제 어떤 트래픽을 허용할지 정해야겠죠? 이때 특정 네임스페이스 전체에서 오는 트래픽을 허용하고 싶을 때 'Namespace Selector'를 사용합니다.

ingress(수신) 또는 egress(송신) 규칙 안에서 사용되며, "나는 'team: monitoring' 레이블이 붙은 네임스페이스에서 오는 모든 트래픽은 믿고 받을래!" 와 같은 규칙을 만들 수 있습니다.

# ... (endpointSelector 이후)
  ingress:
  - fromEndpoints:
    - matchLabels:
        # 같은 네임스페이스 내의 특정 파드를 선택
        app: frontend
  - fromCIDR:
    - "10.0.0.0/8"
  - toPorts:
    - ports:
      - port: "8080"
        protocol: TCP

위 코드는 ingress 규칙의 일부입니다. fromEndpoints를 사용해서 같은 네임스페이스 내의 app=frontend 레이블을 가진 파드로부터의 트래픽을 허용하고 있습니다.

만약 다른 네임스페이스를 선택하고 싶다면 어떨까요? 바로 이럴 때 namespaceSelector가 등장합니다.

# ... (endpointSelector 이후)
  ingress:
  - fromEndpoints:
    # 'monitoring' 네임스페이스에 있는 모든 파드로부터의 트래픽 허용
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: monitoring

이 규칙은 kubernetes.io/metadata.name=monitoring 레이블을 가진 네임스페이스, 즉 'monitoring' 네임스페이스에 있는 모든 파드로부터의 트래픽을 허용합니다.


🛠️ 실제 코드 예제로 전체 흐름 이해하기

자, 이제 두 가지 Selector를 모두 활용한 전체 정책 예시를 통해 흐름을 완벽하게 이해해 봅시다.

시나리오: default 네임스페이스에 있는 app=backend-db 파드는 오직 app=api-server 레이블을 가진 파드로부터의 6379/TCP 포트 트래픽만 허용하고 싶습니다.

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: db-access-policy
  namespace: default
spec:
  # 1. 정책 적용 대상 선택 (Label Selector)
  # 'app=backend-db' 레이블이 붙은 파드에 이 정책을 적용합니다.
  endpointSelector:
    matchLabels:
      app: backend-db

  # 2. 수신(Ingress) 규칙 정의
  ingress:
  - fromEndpoints:
      # 3. 통신 허용 소스 선택 (Label Selector)
      # 'app=api-server' 레이블을 가진 파드로부터 오는 트래픽만 허용합니다.
      - matchLabels:
          app: api-server
    # 4. 허용할 포트 및 프로토콜 정의
    toPorts:
    - ports:
      - port: "6379"
        protocol: TCP

이 YAML 파일 하나로 우리는 매우 명확하고 선언적인 방법으로 파드 간의 통신을 제어할 수 있게 됩니다.


🤔 잠깐, 다른 방법은 왜 안될까요?

"왜 굳이 복잡하게 Label을 쓰나요? 그냥 파드 이름이나 IP로 지정하면 안 되나요?"

좋은 질문입니다! 하지만 쿠버네티스의 동적인 환경을 생각해보면 왜 Label을 사용해야 하는지 명확해집니다.

  • 파드 이름(Pod Name) 👎: 파드는 언제든지 죽고 다시 생성될 수 있습니다. (e.g., 배포, 스케일링, 노드 장애) 이때마다 파드 이름은 backend-db-xxxx-yyyy 처럼 매번 바뀌게 됩니다. 바뀔 때마다 정책을 수정하는 것은 거의 불가능에 가깝습니다.
  • IP 주소(IP Address) 👎: 파드의 IP 역시 고정되어 있지 않습니다. 파드가 재시작되면 새로운 IP를 할당받는 경우가 대부분입니다. IP 기반으로 정책을 관리하는 것은 안정적이지 않으며, 쿠버네티스의 유연성을 해치는 방식입니다.

결론적으로 Label과 Selector는 변하지 않는 '역할'과 '속성'을 기반으로 대상을 식별하기 때문에, 파드가 동적으로 생성되고 사라지는 클라우드 네이티브 환경에 가장 적합한 방식입니다. ✨

Cilium 네트워크 정책의 핵심은 바로 이 Label SelectorNamespace Selector를 자유자재로 활용하여, 유연하고 강력한 보안 정책을 수립하는 데 있습니다. 이제 여러분의 쿠버네티스 클러스터 보안, 한 단계 더 업그레이드할 준비가 되셨나요?