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

네트워크 셋(network set) 이해하기

원문 보기 위키 갱신

Kubernetes 클러스터 밖의 서드파티 API나 SaaS 서비스와 연동하는 앱이라면, egress·ingress 트래픽의 IP 범위를 제한해야 할 때가 있어요. 그때 쓰는 Calico Cloud 리소스가 바로 **network set(네트워크 셋)**입니다. 네트워크 셋이 무엇인지, 왜 강력한지, 정책에서 어떻게 활용하는지 차례로 살펴봐요.

출처: 문서

본문

클러스터로 오가는 트래픽 시각화하기

요즘 애플리케이션은 Kubernetes 클러스터 밖에 있는 서드파티 API와 SaaS 서비스를 자주 연동해요. 이런 연동을 안전하게 허용하려면 워크로드의 egress·ingress 트래픽에 대해 IP 범위를 제한할 수 있어야 하죠. IP 목록이나 범위를 제한하는 일은 악의적인 행위자(bad actors)나 제재 대상 국가를 거부 목록(deny-list)에 넣을 때도 쓰입니다. IP 범위를 제한하려면 Calico Cloud의 network sets 리소스를 사용해야 해요.

네트워크 셋이란 무엇인가?

**Network sets(네트워크 셋)**은 Kubernetes 또는 Calico Cloud 네트워크 정책의 표준 라벨 셀렉터로 매칭할 수 있는, 임의의 IP 서브넷/CIDR이나 도메인 집합을 만들 수 있게 해주는 그룹핑 메커니즘이에요. 파드의 IP 풀(IP pools)처럼, 정책 안에서 IP 주소 집합을 재사용하고 확장할 수 있게 해줍니다.

네트워크 셋은 Kubernetes 또는 Calico Cloud 네트워크 정책과 함께 쓸 수 있는 네임스페이스 리소스이고, 글로벌 네트워크 셋은 Calico Cloud 네트워크 정책에서 사용할 수 있는 클러스터 전체 리소스예요.

네트워크 정책과 마찬가지로, 네트워크 셋에 대한 사용자 접근 권한도 표준 Kubernetes RBAC으로 관리합니다.

네트워크 셋은 왜 강력한가?

웹 콘솔의 Service Graph를 사용해 봤다면, 클러스터 안의 pod-to-pod 트래픽을 눈으로 볼 수 있다는 가치를 이미 알고 있을 거예요. 그런데 클러스터 바깥의 트래픽은 어떨까요?

Calico Cloud는 표준 IETF "public network"와 "private network" 구분에 해당하는 파드·노드 IP를 자동으로 탐지해서 Service Graph에 아이콘으로 표시해 줘요. 그래서 네트워크 셋을 전혀 쓰지 않아도 외부 트래픽에 대한 어느 정도 가시성은 확보할 수 있습니다.

public-private-networks

하지만 네트워크 셋을 직접 만들면, 퍼블릭 네트워크로 나가는 트래픽을 훨씬 더 세밀하게 볼 수 있어요. 그룹핑과 이름 붙이기, 라벨링을 여러분이 직접 통제하기 때문에, 조직에 맞춘 가시성을 만들 수 있죠. 네트워크 셋이 강력한 이유가 바로 이 점입니다.

네트워크 셋의 활용 예시는 다음과 같아요:

  • Egress 접근 제어

    네트워크 셋은 egress 접근 제어를 정의하는 핵심 리소스예요. 예를 들어 마이크로서비스/앱으로의 ingress를 보호하거나, 클러스터 밖 워크로드의 egress를 통제하는 데 쓰입니다.

  • 문제 해결(troubleshooting)

    네트워크 셋은 플로우 로그, Flow Visualizer, Service Graph에 추가 메타데이터로 표시돼요.

  • 효율성과 확장

    배포를 확장할 때 네트워크 셋이 결정적인 역할을 해요. 처음에는 CIDR이 몇 개뿐일 수 있지만, 규모가 커지면 네트워크 정책을 하나하나 고치는 것보다 소수의 네트워크 셋만 업데이트하는 편이 훨씬 수월합니다. 또 Kubernetes 배포에서는 CIDR이든 포트든 정책 규칙이든, 뭐든 대량으로 정책 안에 직접 넣으면 트래픽 처리(iptables/eBPF)의 비효율을 초래해요.

  • 마이크로세그멘테이션과 shift left

    네트워크 셋은 네트워크 정책과 같은 마이크로세그멘테이션 제어를 제공해요. 예를 들어 정책(네트워크 셋을 참조하는) 생성은 특정 사용자에게 허용하되, 네트워크 셋 자체를 관리하는 권한은 일부 사용자에게만 줄 수 있죠.

  • 위협 방어

    악성 IP를 정책으로 신속하게 차단해서 위협을 관리하려면 네트워크 셋이 핵심이에요. 차단해야 할 악성 IP를 발견할 때마다 개별 정책을 일일이 수정해야 한다고 상상해 보세요. 아예 컨트롤러에 권한을 줘서, 악성 IP가 발견되면 네트워크 셋의 CIDR을 자동으로 업데이트하게 할 수도 있습니다.

네트워크 셋 생성 후 정책에서 사용하기

이 절에서는 웹 콘솔에서 네임스페이스 네트워크 셋을 만드는 과정을 진행해 봐요. 여러분의 클러스터든 tigera-labs 클러스터든 따라 할 수 있습니다.

이 예시에서는 google이라는 이름의 네트워크 셋을 만들어요. 이 네트워크 셋은 hipstershop이라는 마이크로서비스가 접근할 신뢰할 수 있는 google 엔드포인트 목록을 담습니다. 서비스 소유자 입장에서는 마이크로서비스에서 나가는 트래픽을 Service Graph에서 보고 싶겠죠. 엔드포인트를 IP 주소로 매칭하는 대신 도메인 이름을 사용할 거예요.

  1. 왼쪽 내비게이션 바에서 Network Sets를 클릭하세요.

  2. Add Network Set을 클릭하고 다음 값을 입력합니다.

    • Name: google
    • Scope: Namespace를 선택하고 hipstershop을 고르세요.
  3. Labels에서 Add label을 클릭합니다.

    • Select key 필드에 destinations를 입력하고 초록색 막대를 클릭해 이 새 항목을 추가하세요.
    • Value 필드에 google을 입력하고 초록색 막대로 항목을 추가한 뒤 저장합니다.
  4. Domains에서 +Add Domain을 클릭하고 다음 URL들을 입력하세요: clouddebugger.googleapis.com, cloudtrace.googleapis.com, metadata.google.internal, monitoring.googleapis.com.

  5. Create Network Set을 클릭합니다.

첫 번째 네트워크 셋을 만들었어요.

add-networkset-google

YAML은 다음과 같이 생겼습니다:

kind: NetworkSet
apiVersion: projectcalico.org/v3
metadata:
  name: google
  labels:
    destinations: google
  namespace: hipstershop
spec:
  nets: []
  allowedEgressDomains:
    - clouddebugger.googleapis.com
    - cloudtrace.googleapis.com
    - metadata.google.internal
    - monitoring.googleapis.com

다음은 hipstershop에서 신뢰할 수 있는 google 사이트들로 나가는 egress 트래픽을 허용하는 DNS 정책을 작성해요. 아래 네트워크 정책은 google 라벨이 붙은 모든 목적지 셀렉터에 대해 egress 접근을 허용합니다. 도메인을 네트워크 셋에 넣고 정책에서 그 네트워크 셋을 참조하는 것이 베스트 프랙티스라는 점 기억해 주세요. 또 selector: all()은 네임스페이스의 모든 파드가 네트워크 셋의 모든 도메인에 접근할 수 있을 때만 써야 하고, 그렇지 않다면 정책을 나눠서 만들어야 해요.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: application.allow-egress-domain
  namespace: hipstershop
spec:
  tier: application
  order: 0
  selector: all()
  serviceAccountSelector: ''
  egress:
    - action: Allow
      source: {}
      destination:
        selector: destinations == "google"
  types:
    - Egress

Service Graph에서 네트워크 셋 보기

hipstershop 예시를 이어서, Service Graph로 가면 hipstershop이 표시돼요(노란색으로 하이라이트됨).

hipstershop

hipstershop을 더블클릭해서 들여다보면 이제 google 네트워크 셋 아이콘이 보여요(노란색으로 하이라이트됨). 이제 google 사이트에서 hipstershop으로 오가는 외부 트래픽 가시성을 확보한 것입니다. (tigera-labs 클러스터를 사용 중이라면, 네트워크 셋은 아래 그림처럼 표시되지 않는다는 점에 유의하세요.)

google-networkset

Service Graph는 서비스들이 어떻게 연결되어 있는지 이해하기 쉬운 뷰로 보여주고, 플로우 로그에도 쉽게 접근할 수 있게 해줘요. Flow Visualizer에서는 네트워크 셋과 관련된 트래픽을 볼륨 기반 표시로 함께 볼 수 있습니다.

튜토리얼 (Tutorial)

다음 예시에서는 마이크로서비스와 애플리케이션에서 사용할 수 있는, 신뢰할 수 있는 로드밸런서용 글로벌 네트워크 셋 리소스를 만들어요. trusted-ep: load-balancer 라벨이 이 글로벌 네트워크 셋을 정책에서 참조하는 방법입니다.

apiVersion: projectcalico.org/v3
kind: GlobalNetworkSet
metadata:
  name: load-balancer
  labels:
    trusted-ep: "load-balancer"
spec:
  nets:
 # 환경의 로드밸런서 IP 주소로 바꾸세요
    - 10.0.0.1/32
    - 10.0.0.2/32

다음 네트워크 정책은 selector: trusted-ep == "load-balancer"로 위 GlobalNetworkSet을 참조해요. app2-ns 네임스페이스에서 app2와 svc1에 매칭되는 모든 애플리케이션이, 신뢰할 수 있는 로드밸런서에서 포트 1001로 들어오는 ingress 트래픽을 허용합니다.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: application.app2-svc1
  namespace: app2-ns
spec:
  tier: application
  order: 500
  selector: (app == "app2"&&svc == "svc1")
  ingress:
    - action: Allow
      protocol: TCP
      source:
        selector: trusted-ep == "load-balancer"
      destination:
        ports:
          - '10001'
  types:
    - Ingress

네트워크 셋을 활용한 고급 정책 규칙

Calico Cloud 정책 규칙과 네트워크 셋을 조합하면 정책을 정교하게 다듬을 수 있는 강력한 방법이 생겨요. 다음 예시는 글로벌 네트워크 정책 안의 특정 규칙과 네트워크 셋을 결합해 접근을 더 빠르게 거부하는 사례입니다. 먼저 거부할 CIDR 범위 목록인 192.0.2.55/32와 203.0.113.0/24를 지정하는 Calico Cloud GlobalNetworkSet을 만들어요.

apiVersion: projectcalico.org/v3
kind: GlobalNetworkSet
metadata:
  name: ip-protect
  labels:
    ip-deny-list: 'true'
spec:
  nets:
    - 192.0.2.55/32
    - 203.0.113.0/24

다음으로 Calico Cloud GlobalNetworkPolicy 리소스 두 개를 만듭니다. 첫 번째는 높은 "order" 정책으로, 두 번째 정책에 매칭되지 않는 트래픽을 기본으로 허용해요. 두 번째는 낮은 "order" 정책으로, GlobalNetworkSet 라벨(IP-deny-list, 앞 단계에서 만든 것)을 셀렉터로 사용해 ingress 트래픽을 거부합니다. 라벨 셀렉터에는 !has(projectcalico.org/namespace)라는 항도 포함했어요. 이 항은 이 정책이 같은 라벨을 가진 파드나 NetworkSet에 매칭되는 것을 막아줍니다. 호스트로 포워딩되는 트래픽의 거부를 패킷 수준에서 더 빠르게 적용하려면 doNotTrack과 applyOnForward 옵션을 사용하세요.

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: forward-default-allow
spec:
  selector: apply-ip-protect == 'true'
  order: 1000
  doNotTrack: true
  applyOnForward: true
  types:
    - Ingress
  ingress:
    - action: Allow
---
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: ip-protect
spec:
  selector: apply-ip-protect == 'true'
  order: 0
  doNotTrack: true
  applyOnForward: true
  types:
    - Ingress
  ingress:
    - action: Deny
      source:
        selector: ip-deny-list == 'true' && !has(projectcalico.org/namespace)

네트워크 셋 사용 베스트 프랙티스

  • 시작하자마자 최대한 빨리 네트워크 셋을 만드세요

    플로우 로그에서 커스텀 메타데이터를 보고, Service Graph와 Flow Visualizer에서 트래픽을 시각화하는 이점을 빠르게 누릴 수 있게 됩니다.

  • 네트워크 셋의 라벨·이름 스키마를 정하세요

    "Service Graph나 Flow Visualizer에서 봤을 때 어떤 이름이 의미 있고 이해하기 쉬울까?", "네트워크 정책에서 사용할 때 어떤 라벨이 이해하기 쉬울까?"를 먼저 생각해 두면 좋아요. 특히 네트워크 셋을 관리하는 사용자와 정책에서 소비하는 사용자를 분리하는 경우 더욱 그렇습니다.

  • 대량의 CIDR·도메인 집합을 정책에 직접 넣지 마세요

    네트워크 셋은 CIDR과/또는 도메인을 지정할 수 있게 해줘요. 정책 안에 CIDR과 도메인을 직접 넣을 수도 있지만, 확장되지 않습니다.

  • 수천 개의 규칙을 하나의 정책에, 각기 다른 CIDR로 넣지 마세요

    /32 집합이 보안을 해치지 않으면서 몇 개의 더 넓은 CIDR로 쉽게 통합될 수 있다면, 그렇게 하는 게 좋아요. 그 CIDR을 규칙에 넣든 네트워크 셋을 쓰든 마찬가지입니다.

  • 수천 개의 엔드포인트를 매칭하고 싶다면, 규칙 한두 개를 작성하고 셀렉터로 엔드포인트를 매칭하세요

    포트마다, 호스트마다 규칙을 하나씩 만드는 건 비효율적이에요. 각 규칙이 IP set을 제대로 활용하지 못하고 iptables/eBPF 규칙으로 각각 렌더링되기 때문입니다.

  • networkset/globalnetworkset 정의에서 겹치는 IP 주소/서브넷은 피하세요

다음 표는 네트워크 셋을 효율적으로 쓰기 위한 가이드를 제공합니다.

Policy Network set Results
source: selector: foo="bar" 소수의 넓은 CIDR 몇 개 효율적(Efficient) - iptables/eBPF 규칙 1개 - 소수의 CIDR을 담은 IP set 1개
source: nets: [ ... handful ...] 사용하지 않음 효율적(Efficient) - iptables/eBPF 규칙 소수 - IP set 0개
source: selector: foo="bar" 2000개 x /32를 담은 네트워크 셋 하나 상당히 효율적(Fairly efficient) - iptables/eBPF 규칙 1개 - 2000 항목의 IP set 1개
각 1000개 x /32를 담은 네트워크 셋 둘 효율적(Efficient) - iptables/eBPF 규칙 2개 - 1000 항목의 IP set 2개
source: nets: [... 2000 /32s ...] - source: nets: [1 x /32] - source: nets: [1 x /32] - ... x 2000 사용하지 않음 비효율적(Inefficient) iptables/eBPF 규칙 2k개 프로그래밍 결과 - iptables/eBPF 규칙 2000+개 - IP set 0개

네트워크 셋과 정책을 함께 쓰는 예시가 더 필요하면 다음을 참고하세요:

더 알아보기 (Learn more)