네트워크 정책이란 무엇인가요?
네트워크 정책은 Kubernetes 네트워크를 보호하는 기본 도구예요. 이 교육 자료에서는 네트워크 정책이 왜 중요한지, Kubernetes 정책과 Calico Cloud 정책이 어떻게 다른지, 실전에서 어떤 모범 사례를 쓰는지 차례로 살펴봐요.
출처: 문서
본문
SECONDARY: 이 가이드는 Calico Cloud에 국한되지 않는 교육용 자료를 제공해요.
Kubernetes와 Calico Cloud는 워크로드를 보호하는 데 도움이 되는 네트워크 정책 API를 제공해요.
이 가이드에서 배울 내용은 다음과 같아요:
- 네트워크 정책이 무엇이고 왜 중요한지.
- Kubernetes 네트워크 정책과 Calico Cloud 네트워크 정책의 차이, 그리고 각각을 언제 쓰면 좋은지.
- 네트워크 정책을 사용할 때의 몇 가지 모범 사례.
네트워크 정책이란 무엇인가요?
네트워크 정책은 Kubernetes 네트워크를 보호하는 기본 도구예요. 클러스터 안의 네트워크 트래픽을 쉽게 제한해서, 원하는 트래픽만 흐르도록 허용할 수 있게 해 줘요.
네트워크 정책의 의미를 제대로 이해하려면, 네트워크 정책 이전에 네트워크 보안이 보통 어떻게 달성되었는지 잠깐 살펴볼게요. 과거 엔터프라이즈 네트워크에서 네트워크 보안은 네트워크 장치(스위치, 라우터, 방화벽)와 그 설정으로 물리적 토폴로지를 설계하는 방식으로 제공됐어요. 물리적 토폴로지가 네트워크의 보안 경계를 정의했죠. 가상화의 첫 단계에서는 같은 네트워크와 네트워크 장치 구조가 클라우드에서 가상화되었고, (가상) 네트워크 장치로 특정 네트워크 토폴로지를 만드는 같은 기법이 네트워크 보안에 쓰였어요. 새 애플리케이션이나 서비스를 추가하려면 원하는 보안을 제공하도록 네트워크 토폴로지와 네트워크 장치 설정을 업데이트하는 추가 네트워크 설계가 자주 필요했어요.
반면 Kubernetes 네트워크 모델은 모든 파드가 파드 IP 주소로 클러스터의 다른 모든 파드와 통신할 수 있는 "평평한(flat)" 네트워크를 정의해요. 이 접근은 네트워크 설계를 크게 단순화하고, 새 워크로드가 네트워크 설계에 대한 의존 없이 클러스터 어디에서든 동적으로 스케줄될 수 있게 해 줘요.
이 모델에서는 네트워크 보안이 네트워크 토폴로지 경계로 정의되는 게 아니라, 토폴로지와 독립적인 네트워크 정책으로 정의돼요. 네트워크 정책은 IP 주소나 IP 주소 범위 대신 레이블 셀렉터를 주된 수단으로 사용해서 "어떤 워크로드가 어떤 워크로드와 통신할 수 있는지"를 정의하기 때문에, 네트워크에서 한층 더 추상화되어 있어요.
네트워크 정책이 왜 중요한가요?
공격자들이 점점 더 정교해지는 시대에, 방어선으로서의 네트워크 보안은 그 어느 때보다 중요해요.
방화벽을 사용해 네트워크 경계의 트래픽을 제한할 수 있고(흔히 남북(north-south) 트래픽이라고 불러요), 그래야 하기도 해요. 하지만 방화벽이 Kubernetes 트래픽을 단속하는 능력은 파드 스케줄링과 파드 IP 주소가 동적인 탓에, 특정 파드 그룹이 아니라 클러스터 전체 단위의 입도(granularity)로 제한되기 쉬워요. 게다가 대부분의 공격자가 경계 안에 작은 발판을 얻은 뒤에는 측면으로 이동(흔히 동서(east-west)라고 불러요)해서 더 가치 있는 표적을 노리는데, 경계 기반 방화벽은 이런 이동을 단속할 수 없어요.
반면 네트워크 정책은 IP 주소가 아니라 레이블 셀렉터로 파드 그룹을 정의하는 표준 Kubernetes 패러다임을 따름으로써 Kubernetes의 동적인 성격에 맞게 설계되어 있어요. 그리고 네트워크 정책이 클러스터 내부 자체에서 시행되기 때문에 남북 트래픽과 동서 트래픽 모두를 단속할 수 있어요.
네트워크 정책은 네트워크 보안의 중요한 진화예요. 현대 마이크로서비스의 동적인 성격을 다루는 것만이 아니라, dev와 DevOps 엔지니어가 저수준 네트워킹 세부 사항을 배우거나 방화벽을 관리하는 별도 팀에 티켓을 올리지 않고도 스스로 네트워크 보안을 쉽게 정의할 수 있게 해 주기 때문이에요. 네트워크 정책은 "이 마이크로서비스만 데이터베이스에 접속할 수 있다" 같은 의도(intent)를 쉽게 정의하고, 그 의도를 코드로 작성하고(보통 YAML 파일로요), 네트워크 정책 작성을 git 워크플로와 CI/CD 프로세스에 통합하기 쉽게 해 줘요.
SECONDARY: 참고: Calico Cloud는 경계 방화벽이 Kubernetes와 더 긴밀하게 통합되도록 돕는 기능을 제공해요. 다만 이것이 클러스터 내부의 네트워크 정책 필요성과 가치를 없애 주지는 않아요.)
Kubernetes 네트워크 정책
Kubernetes 네트워크 정책은 Kubernetes NetworkPolicy 리소스로 정의해요.
Kubernetes 네트워크 정책의 주요 특징은 다음과 같아요:
- 정책은 네임스페이스 스코프예요(즉 파드처럼 특정 네임스페이스 컨텍스트 안에서 만들어요)
- 정책은 레이블 셀렉터로 파드에 적용돼요
- 정책 규칙은 다른 파드, 네임스페이스, CIDR로부터/로의 허용 트래픽을 지정할 수 있어요
- 정책 규칙은 프로토콜(TCP, UDP, SCTP), 이름 붙은 포트, 포트 번호를 지정할 수 있어요
Kubernetes 자체는 네트워크 정책을 시행하지 않고, 그 시행을 네트워크 플러그인에 위임해요. 대부분의 네트워크 플러그인이 Kubernetes 네트워크 정책의 주요 요소를 구현하지만, 스펙의 모든 기능을 구현하는 것은 아니에요. (Calico Cloud는 모든 기능을 구현하고, Kubernetes 네트워크 정책의 최초 레퍼런스 구현체였어요.)
Calico Cloud 네트워크 정책
Kubernetes 네트워크 정책을 시행하는 것에 더해, Calico Cloud는 네임스페이스가 있는 자체 NetworkPolicy와 네임스페이스가 없는 GlobalNetworkPolicy 리소스를 지원해요. 이 리소스들은 Kubernetes 네트워크 정책이 지원하는 것 이상의 추가 기능을 제공해요. 다음을 지원하죠:
- 정책 순서/우선순위
- 규칙에서의 deny와 log 액션
- 정책 적용과 정책 규칙에서 더 유연한 매치 기준. Kubernetes ServiceAccount 매칭, (Istio와 Envoy를 쓴다면) 암호학적 정체성, HTTP와 gRPC URL 같은 레이어 5-7 매치 기준도 포함돼요.
- 정책에서 Kubernetes가 아닌 워크로드를 참조하는 능력. 정책 규칙에서 NetworkSet 매칭을 포함해요.
Kubernetes 네트워크 정책은 파드에만 적용되지만, Calico Cloud 네트워크 정책은 파드, VM, 호스트 인터페이스를 포함한 여러 유형의 엔드포인트에 적용될 수 있어요.
Calico Cloud 네트워크 정책에 대해 더 알고 싶다면 Calico Cloud 네트워크 정책 시작하기 가이드를 읽어보세요.
네트워크 정책에 Calico Cloud를 사용하는 이점
전체 Kubernetes 네트워크 정책 지원
다른 네트워크 정책 구현체와 달리, Calico Cloud는 Kubernetes 네트워크 정책 기능 전체를 구현해요.
더 풍부한 네트워크 정책
필요하다면 Calico Cloud 네트워크 정책은 Kubernetes 네트워크 정책보다 한층 풍부한 트래픽 제어를 가능하게 해요. 또한 Calico Cloud 네트워크 정책은 GlobalNetworkPolicy 리소스를 사용해 여러 네임스페이스에 걸쳐 적용되는 정책을 만들 수 있게 해 줘요.
Kubernetes와 Calico Cloud 네트워크 정책 혼합
Kubernetes 네트워크 정책과 Calico Cloud 네트워크 정책은 매끄럽게 섞을 수 있어요. 흔한 활용 사례는 보안/클러스터 운영팀과 개발자/서비스팀 사이의 책임 분리예요. 예컨대 보안/클러스터 운영팀에게 Calico Cloud 정책을 정의할 RBAC 권한을 주고, 개발자/서비스팀에게는 자기 네임스페이스에서 Kubernetes 네트워크 정책을 정의할 RBAC 권한을 주는 식이에요. Calico Cloud 정책 규칙은 Kubernetes 네트워크 정책보다 앞서거나 뒤에서 시행되도록 순서를 정할 수 있고, deny와 log 같은 액션을 포함할 수 있기 때문에, 보안/클러스터 운영팀은 기본적이고 범용적인 상위 규칙을 정의하고, 개발자/서비스팀은 자기가 책임지는 앱과 서비스에 자기만의 세밀한 제약을 정의하게 할 수 있어요.
두 개 이상의 팀 사이에서 더 유연한 제어와 책임 위임을 하려면, Calico Cloud가 이 모델을 확장해 계층적 정책(hierarchical policy)을 제공해요.
Calico Cloud로 확장
Calico Cloud는 계층적 정책을 지정하는 능력, 각 팀이 자기만의 신뢰 경계를 갖게 하는 능력, 정책 규칙에서 FQDN/도메인 이름으로 특정 외부 서비스 접근을 제한하는 능력까지 더해 한층 풍부한 네트워크 정책 기능을 제공해요.
네트워크 정책 모범 사례
Ingress와 egress
최소한으로, 모든 파드가 네트워크 정책 ingress 규칙으로 보호받도록 권해요. 어떤 것을 파드에 연결할 수 있고 어느 포트로 할 수 있는지 제한하는 규칙이요. 모범 사례는 파드 자체가 허용하는 나가는 연결을 제한하는 네트워크 정책 egress 규칙까지 정의하는 거예요. Ingress 규칙은 파드 바깥에서 오는 공격으로부터 파드를 보호해요. Egress 규칙은 파드가 침해되었을 때 파드 바깥의 모든 것을 보호하는 데 도움이 돼요. 측면 이동(동서)을 어렵게 하거나, 공격자가 침해된 데이터를 클러스터에서 빼내는 것(남북)을 막아 공격 표면을 줄여 주죠.
정책 스키마
네트워크 정책과 레이블링이 유연하다 보니, 같은 목표를 달성하는 방법이 여러 가지일 때가 많아요. 가장 흔한 접근 중 하나는 모든 파드에 적용되는 소수의 글로벌 정책을 두고, 그다음 파드별 정책 하나에 그 파드에 특유한 모든 ingress와 egress 규칙을 정의하는 거예요.
예를 들면 다음과 같아요:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: front-end
namespace: staging
spec:
podSelector:
matchLabels:
app: back-end
ingress:
- from:
- podSelector:
matchLabels:
app: front-end
ports:
- protocol: TCP
port: 443
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 27017
기본 거부
이 모범 사례가 지켜지는지 확인하는 한 가지 방법은 기본 거부(default deny) 네트워크 정책을 정의하는 거예요. 이 정책들은 파드로부터/로의 트래픽을 명시적으로 허용하는 다른 정책이 없으면 트래픽이 거부되도록 보장해요. 그 결과 어떤 팀이 새 파드를 배포할 때마다 그 파드의 네트워크 정책도 함께 정의하게 돼요. (새 네임스페이스를 만들 때마다 정책을 정의해야 하는 대신) Calico Cloud GlobalNetworkPolicy를 이 용도로 쓰고, 기본 거부에 예외를 몇 가지 포함하는 것(예: 파드가 DNS에 접근할 수 있게 하기)이 유용할 수 있어요.
예컨대 다음 정책을 사용하면 kube-dns/core-dns로 가는 DNS 질의를 제외한 모든 (비시스템) 파드 트래픽을 기본 거부할 수 있어요.
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: default-app-policy
spec:
namespaceSelector: has(projectcalico.org/name) && projectcalico.org/name not in {"kube-system", "calico-system"}
types:
- Ingress
- Egress
egress:
- action: Allow
protocol: UDP
destination:
selector: k8s-app == "kube-dns"
ports:
- 53
계층적 정책
Calico Cloud는 정책 티어(tier)를 사용하는 계층적 네트워크 정책을 지원해요. 각 티어의 RBAC을 정의해 누가 각 티어와 상호작용할 수 있는지 제한할 수 있어요. 이를 통해 여러 팀 사이에 신뢰를 위임할 수 있어요.