본문 바로가기
WIKI 기술 지식 베이스

Cilium

원문 보기 위키 갱신

Cilium은 클라우드 네이티브 환경의 네트워킹, 보안, 가시성 솔루션이에요. CloudNativePG PostgreSQL 인스턴스를 Cilium 네트워크 정책으로 보호하는 방법을 YAML 예시와 함께 살펴볼게요.

출처: 문서

본문

소개

Cilium은 2021년 Incubating 프로젝트로 승인되고 2023년에 Graduated가 된 CNCF Graduated 프로젝트예요. 원래 Isovalent이 만들었어요. eBPF 기술 위에 구축된 클라우드 네이티브 환경을 위한 고급 네트워킹, 보안, 가시성 솔루션이에요. Cilium은 eBPF 프로그램을 Linux 커널에 동적으로 주입해 Kubernetes 클러스터의 네트워크 트래픽을 관리하며, 낮은 지연 시간, 고성능 통신을 가능하게 하고 세밀한 보안 정책을 강제해요.

Cilium의 주요 기능:

  • 세밀한 네트워크 트래픽 제어를 위한 고급 L3-L7 보안 정책
  • eBPF를 통한 효율적인 커널 레벨 트래픽 관리
  • Service Mesh 통합 (Cilium Service Mesh)
  • Kubernetes NetworkPolicy와 CiliumNetworkPolicy 모두 지원
  • Hubble을 통한 내장 가시성 및 모니터링

환경에 Cilium을 설치하려면 문서의 지침을 따르세요: https://docs.cilium.io/en/stable/gettingstarted/k8s-install-default/

CloudNativePG와 Cilium을 이용한 파드 간 네트워크 보안

Kubernetes의 기본 동작은 클러스터 네트워크에서 임의의 두 파드 간 트래픽을 허용하는 것이에요. Cilium은 CiliumNetworkPolicy 리소스로 고급 L3/L4 네트워크 보안을 제공해요. 이를 통해 Kubernetes 클러스터 내 파드 간 네트워크 트래픽을 세밀하게 제어할 수 있어요. 특히 애플리케이션 워크로드와 백엔드 서비스 간 통신을 보호하는 데 유용해요.

다음 예시에서는 Cilium을 사용해 인그레스 트래픽을 인가된 파드로만 제한해 CloudNativePG PostgreSQL 인스턴스를 보호하는 방법을 보여줄게요.

:::info[Important] 진행하기 전에 cluster-example Postgres 클러스터가 환경에서 실행 중인지 확인해 주세요. :::

Cilium의 기본 거부(Default Deny) 동작

기본적으로 Cilium은 명시적으로 구성하지 않는 한 모든 트래픽을 거부하지 않아요. 네임스페이스에 정책이 존재하면 기본 거부 모델을 사용하는 Kubernetes NetworkPolicy와 달리, Cilium은 기본 거부 동작에 대해 더 유연한 제어를 제공해요.

Cilium으로 기본 거부 자세(default deny posture)를 강제하려면, 명시적으로 허용하지 않는 한 파드 집합에 대한 모든 트래픽을 거부하는 정책을 만들어야 해요. 이는 일반적으로 endpointSelector와 함께 빈 ingress 섹션을 사용하거나, 더 넓은 범위의 강제를 위해 Cilium 에이전트 레벨에서 **--enable-default-deny**를 활성화해 달성해요.

기본 거부 정책의 최소 예시:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: default-deny
  namespace: default
spec:
  description: "Default deny all ingress traffic to all Pods in this namespace"
  endpointSelector: {}
  ingress: []

Cilium 네트워크 정책을 CloudNativePG 오퍼레이터와 함께 동작시키기

네트워크 정책(Cilium이든 아니든)으로 작업할 때 첫 번째 단계는 오퍼레이터가 대상 네임스페이스의 파드에 도달할 수 있는지 확인하는 것이에요. 오퍼레이터가 파드에 대한 검사와 동작을 수행할 수 있어야 하기 때문이에요. 그중 한 동작은 파드의 포트 8000에 접근해 내부에서 실행 중인 PostgreSQL 인스턴스의 현재 상태를 가져오는 것이에요.

다음 CiliumNetworkPolicy는 오퍼레이터가 대상 default 네임스페이스의 파드에 접근할 수 있게 해줘요:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: cnpg-operator-access
  namespace: default
spec:
  description: "Allow CloudNativePG operator access to any pod in the target namespace"
  endpointSelector: {}
  ingress:
    - fromEndpoints:
        - matchLabels:
            io.kubernetes.pod.namespace: cnpg-system
      toPorts:
        - ports:
            - port: "8000"
              protocol: TCP

:::info[Important] YAML 매니페스트를 사용할 때 cnpg-system 네임스페이스는 오퍼레이터의 기본 네임스페이스예요. 오퍼레이터를 다른 프로세스(Helm, OLM 등)로 설치했다면 네임스페이스가 다를 수 있어요. 네임스페이스를 적절히 조정해야 해요. :::

클러스터 파드 간 접근 허용하기

기본 정책이 "모두 거부"이므로, 같은 네임스페이스의 클러스터 파드 간 접근을 명시적으로 허용해야 해요. 이전 정책에 필요한 인그레스 규칙을 추가해 개선할게요:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: cnpg-cluster-internal-access
  namespace: default
spec:
  description: "Allow CloudNativePG operator access and connection between pods in the same namespace"
  endpointSelector: {}
  ingress:
    - fromEndpoints:
        - matchLabels:
            io.kubernetes.pod.namespace: cnpg-system
        - matchLabels:
            io.kubernetes.pod.namespace: default
            cnpg.io/cluster: cluster-example
      toPorts:
        - ports:
            - port: "8000"
              protocol: TCP
            - port: "5432"
              protocol: TCP

이 정책은 cnpg-system 파드와 cluster-example에도 속하는 default 네임스페이스 파드의 접근을 허용해요. matchLabels 셀렉터는 파드가 나열된 레이블의 전체 집합을 가져야 요구해요. 레이블 하나라도 없으면 파드는 매칭되지 않아요.

Cilium으로 PostgreSQL 접근 제한하기

이 예시에서는 default 네임스페이스에서 role=backend 레이블이 있는 파드만 cluster-example이라는 PostgreSQL 클러스터에 연결할 수 있게 하는 CiliumNetworkPolicy를 정의해요. 다른 모든 인그레스 트래픽은 기본적으로 차단돼요.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: postgres-access-backend-label
  namespace: default
spec:
  description: "Allow PostgreSQL access on port 5432 from Pods with role=backend"
  endpointSelector:
    matchLabels:
      cnpg.io/cluster: cluster-example
  ingress:
    - fromEndpoints:
       - matchLabels:
            role: backend
      toPorts:
        - ports:
          - port: "5432"
            protocol: TCP

이 CiliumNetworkPolicy는 default 네임스페이스에서 role=backend 레이블이 있는 파드만 CloudNativePG가 관리하는 PostgreSQL 인스턴스에 포트 5432로 접근할 수 있게 보장해요.

다음 정책에서는 임의의 네임스페이스에서 role=backend 레이블이 있는 파드에서만 cluster-example이라는 PostgreSQL 클러스터의 포트 5432로 인그레스 트래픽을 허용하는 방법을 보여줄게요.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: postgres-access-backend-any-ns
  namespace: default
spec:
  description: "Allow PostgreSQL access on port 5432 from Pods with role=backend in any namespace"
  endpointSelector:
    matchLabels:
      cnpg.io/cluster: cluster-example
  ingress:
    - fromEndpoints:
        - labelSelector:
            matchLabels:
              role: backend
            matchExpressions:
              - key: io.kubernetes.pod.namespace
                operator: Exists
      toPorts:
        - ports:
          - port: "5432"
            protocol: TCP

다음 예시는 backend 네임스페이스의 임의의 파드에서 default 네임스페이스에 있는 cluster-example 클러스터의 포트 5432로 인그레스 트래픽을 허용해요.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: postgres-access-backend-namespace
  namespace: default
spec:
  description: "Allow PostgreSQL access on port 5432 from any Pods in the backend namespace"
  endpointSelector:
    matchLabels:
      cnpg.io/cluster: cluster-example
  ingress:
    - fromEndpoints:
        - matchLabels:
            io.kubernetes.pod.namespace: backend
      toPorts:
        - ports:
            - port: "5432"
              protocol: TCP

Cilium의 L3/L4 정책 모델을 사용해, backend 네임스페이스의 애플리케이션 파드에서만 클러스터 파드로 인그레스 트래픽을 명시적으로 허용하는 CiliumNetworkPolicy를 정의했어요. 다른 모든 트래픽은 추가 정책으로 명시적으로 허용되지 않는 한 암시적으로 거부돼요.

다음 예시는 Kubernetes 클러스터 내 임의의 소스에서 default 네임스페이스에 있는 cluster-example 클러스터의 포트 5432로 인그레스 트래픽을 허용해요.

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: postgres-access-cluster-wide
  namespace: default
spec:
  description: "Allow ingress traffic to port 5432 of the cluster-example from any pods within the Kubernetes cluster"
  endpointSelector:
    matchLabels:
      cnpg.io/cluster: cluster-example
  ingress:
    - fromEntities:
        - cluster
      toPorts:
        - ports:
            - port: "5432"
              protocol: TCP

editor.networkpolicy.io를 고려해 볼 수 있어요. Cilium 네트워크 정책의 생성과 검증을 단순화하는 시각적이고 상호작용적인 도구예요. 잘못된 구성을 피하고 트래픽 규칙을 시각적으로 이해하는 데 특히 도움이 돼요.

이 정책들로 PostgreSQL에 대한 기본 접근 제어를 수립했어요. Cilium의 정책 언어로 추가 egress 또는 감사 규칙을 계층화하거나 Envoy로 L7 강제로 확장할 수 있어요.

더 알아보기 (Learn more)