본문 바로가기
IT/k8s

[k8s] Calico 네트워크 정책 베스트 프랙티스: 프로덕션 환경 보안 강화 체크리스트

by 수누다 2026. 6. 1.

Calico 네트워크 정책 베스트 프랙티스: 프로덕션 환경 보안 강화 체크리스트

안녕하세요, 13년차 서버실 지킴이입니다. 오늘은 Kubernetes(쿠버네티스) 환경에서 네트워크 보안을 단단하게 다지는 핵심 요소인 Calico 네트워크 정책(Network Policy)에 대해 이야기해보려고 합니다. 프로덕션 환경에서 보안은 아무리 강조해도 지나치지 않거든요. 특히 마이크로서비스 아키텍처(MSA)가 보편화되면서 수많은 Pod(파드)들이 서로 통신하게 되는데, 이때 제대로 된 네트워크 격리(Network Isolation)가 이루어지지 않으면 작은 취약점이 전체 시스템으로 퍼질 수 있는 무서운 상황이 발생합니다. 저도 처음엔 '에이, 그냥 Pod끼리 통신 잘 되면 됐지 뭐' 하고 안일하게 생각했었는데, 한 번 크게 데이고 나서는 Calico 네트워크 정책의 중요성을 뼈저리게 느꼈습니다. 오늘은 제가 직접 삽질하면서 터득한 Calico 네트워크 정책 베스트 프랙티스와 함께, 프로덕션 환경 보안 강화를 위한 체크리스트를 공유해보겠습니다. Pod 간 불필요한 통신으로 고민이 많으셨다면, 이 글이 좋은 가이드가 될 거예요!

Kubernetes 클러스터에서 Calico 네트워크 정책이 적용되어 Pod 간 통신을 제어하는 개념도

1. Calico 네트워크 정책, 쉽게 말해 뭘까요? 💡

Calico는 Kubernetes 클러스터의 CNI(Container Network Interface, 컨테이너 네트워크 인터페이스) 솔루션 중 하나입니다. Calico 네트워크 정책은 바로 이 Calico가 제공하는 Pod 간 통신 규칙을 정의하는 도구거든요. 쉽게 말해, '어떤 Pod가 어떤 Pod와 통신할 수 있고, 어떤 포트로 통신할 수 있는지'를 명확하게 지정해주는 방화벽(Firewall) 역할을 Kubernetes 레벨에서 해주는 거라고 생각하시면 돼요.

Kubernetes 자체적으로도 NetworkPolicy 리소스가 있긴 한데, Calico는 이를 확장해서 더 강력하고 유연한 기능을 제공합니다. 예를 들어, Namespace(네임스페이스)를 넘어선 통제나, Host(호스트) 레벨의 정책, 그리고 GlobalNetworkPolicy(글로벌 네트워크 정책) 같은 기능들이 대표적이에요. 저도 처음엔 Kubernetes NetworkPolicy만으로 충분하다고 생각했었는데, 실제 운영 환경에서는 Calico의 확장 기능이 훨씬 유용하더라고요. 특히 클러스터 전체에 걸쳐 일관된 보안 정책을 적용해야 할 때 GlobalNetworkPolicy가 정말 빛을 발합니다.

2. 프로덕션 환경을 위한 Calico 네트워크 정책 베스트 프랙티스 체크리스트 ✅

자, 이제 본론으로 들어가서 프로덕션 환경에서 제가 추천하는 Calico 네트워크 정책 베스트 프랙티스들을 하나씩 살펴보겠습니다. 이 체크리스트만 잘 따라 하셔도 보안 레벨을 한 단계 업그레이드할 수 있을 거예요.

2.1. 기본은 'Deny All' (모든 트래픽 차단)부터 시작하기

가장 중요한 원칙 중 하나입니다. 처음부터 모든 통신을 허용하고 필요한 것만 차단하는 방식(Permissive Policy)은 보안에 구멍이 생기기 쉬워요. 기본적으로 모든 Ingress(인그레스, 외부에서 들어오는 트래픽)와 Egress(이그레스, 내부에서 나가는 트래픽)를 차단한 다음, 허용해야 할 통신만 명시적으로 열어주는 방식(Restrictive Policy)을 채택해야 합니다. 이게 바로 Zero Trust(제로 트러스트) 보안 모델의 핵심이기도 하죠. 처음엔 좀 귀찮을 수 있지만, 장기적으로 보면 훨씬 안전합니다.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: default
spec:
  selector: {}
  types:
  - Ingress
  - Egress
  ingress:
  - {}
  egress:
  - {}

위 정책은 default 네임스페이스의 모든 Pod에 대해 Ingress와 Egress를 차단하는 정책입니다. selector: {}는 모든 Pod를 의미하고, ingress: - {}egress: - {}는 아무런 규칙도 없으므로 기본적으로 모든 트래픽을 차단해요. ⚠️ 주의: 이 정책을 적용하면 해당 네임스페이스의 Pod들이 통신을 전혀 할 수 없게 되니, 바로 이어서 필요한 허용 정책을 적용해야 합니다.

2.2. 필요한 통신만 최소한으로 허용하기

default-deny-all 정책을 적용했다면, 이제 애플리케이션이 정상적으로 동작하는 데 필요한 통신만 정확히 허용해야 합니다. 예를 들어, 프론트엔드(Frontend) Pod는 백엔드(Backend) Pod의 특정 포트로만 접근할 수 있게 하고, 백엔드 Pod는 데이터베이스(Database) Pod의 특정 포트로만 접근할 수 있게 하는 식이죠.

apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: default
spec:
  selector: app == 'backend'
  types:
  - Ingress
  ingress:
  - from:
    - selector: app == 'frontend'
    ports:
    - protocol: TCP
      port: 8080 # 백엔드 서비스 포트

이 정책은 app: backend 레이블을 가진 Pod에게, app: frontend 레이블을 가진 Pod로부터 8080 포트로 들어오는 TCP 트래픽만 허용합니다. Pod Selector(파드 셀렉터)와 Port(포트)를 명확히 지정하는 게 정말 중요해요.

2.3. 레이블 기반 정책 활용하기

Pod의 레이블(Label)은 네트워크 정책을 관리하는 데 있어 강력한 도구입니다. app: myapp, tier: frontend, env: production 같은 레이블을 잘 활용하면, 수십, 수백 개의 Pod가 생겨나더라도 정책을 쉽게 적용하고 관리할 수 있어요. 저도 처음엔 IP 기반으로 정책을 만들까 고민했었는데, Kubernetes 환경에서는 Pod IP가 동적으로 할당되니 레이블 기반이 훨씬 효율적이고 유지보수하기 좋더라고요.

Calico 네트워크 정책이 레이블 셀렉터를 이용해 다양한 Pod 그룹 간 통신을 제어하는 다이어그램

Calico 네트워크 정책이 레이블 셀렉터를 이용해 다양한 Pod 그룹 간 통신을 제어하는 다이어그램

2.4. GlobalNetworkPolicy 활용하여 클러스터 전역 정책 적용하기

특정 네임스페이스에 국한되지 않고 클러스터 전체에 적용해야 하는 정책들이 있습니다. 예를 들어, 모든 Pod가 DNS 서버에 접근할 수 있도록 허용하거나, 특정 관리용 Pod만 Kubernetes API 서버에 접근할 수 있도록 하는 정책 같은 거죠. 이럴 때 GlobalNetworkPolicy를 사용합니다.

apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-dns-egress
spec:
  selector: {}
  order: 100 # 우선순위, 숫자가 낮을수록 높음
  types:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
    ports:
    - protocol: UDP
      port: 53 # DNS (UDP)
    - protocol: TCP
      port: 53 # DNS (TCP)

위 정책은 모든 Pod가 53번 포트로 DNS 쿼리를 날릴 수 있도록 허용하는 GlobalNetworkPolicy입니다. order 필드는 정책의 우선순위를 결정하는데, 숫자가 낮을수록 우선순위가 높아요. 여러 정책이 겹칠 때 어떤 정책이 먼저 적용될지 잘 고려해야 합니다.

2.5. Egress 정책도 Ingress만큼 중요하게 다루기

보통 네트워크 정책을 만들 때 Ingress(들어오는 트래픽)에만 집중하는 경향이 있는데, Egress(나가는 트래픽) 정책도 보안에 아주 중요해요. 악성 Pod가 외부로 데이터를 유출하거나 C2(Command & Control) 서버와 통신하는 것을 막으려면 Egress 정책을 꼼꼼하게 설정해야 합니다. 예를 들어, 개발 Pod들은 특정 개발용 리포지토리(Repository)에만 접근할 수 있게 하고, 운영 Pod들은 외부에 전혀 접근하지 못하게 할 수도 있어요.

2.6. 테스트 환경에서 충분히 검증하기 ⚠️

네트워크 정책은 잘못 설정하면 서비스 장애로 직결될 수 있습니다. 그래서 프로덕션에 적용하기 전에 반드시 개발/스테이징 환경에서 충분히 테스트해야 해요. 저도 한 번은 너무 엄격하게 정책을 설정해서 핵심 서비스의 DB 연결이 끊긴 적이 있었거든요. 결국 밤샘 삽질 끝에 겨우 복구했었죠. calicoctl 명령어나 kubectl describe networkpolicy 등으로 정책이 제대로 적용되었는지 확인하고, curl이나 ping 명령어로 통신 테스트를 꼼꼼히 해보는 게 좋습니다.

3. Calico 네트워크 정책 검증/결과 🎉

정책을 적용하고 나면, 예상대로 통신이 차단되거나 허용되는지 확인해야 합니다. kubectl exec 명령으로 Pod에 접속해서 curl 등의 도구를 사용하거나, calicoctl 명령으로 정책 상태를 확인할 수 있어요.

# 특정 Pod에서 다른 Pod로 통신 테스트
kubectl exec -it <my-app-pod> -- curl <target-service-ip>:<port>

# Calico 네트워크 정책 목록 확인
calicoctl get networkpolicy -o wide
calicoctl get globalnetworkpolicy -o wide

# 특정 Pod에 적용된 정책 확인 (이건 Calico Enterprise 기능일 수 있으니 확인 필요)
# calicoctl get activepolicy --namespace <namespace> --workload <pod-name>

만약 통신이 안 된다면, calicoctllog 명령어를 활용해서 어떤 정책에 의해 트래픽이 차단되었는지 확인할 수 있어요. 저도 이 로그를 보면서 '아, 이 정책 때문에 막혔구나!' 하고 무릎을 탁 친 적이 한두 번이 아닙니다. 😅

Calico 네트워크 정책 적용 후 Pod 간 통신 흐름이 시각적으로 차단되거나 허용되는 대시보드 화면 캡처

Calico 네트워크 정책 적용 후 Pod 간 통신 흐름이 시각적으로 차단되거나 허용되는 대시보드 화면 캡처

4. 삽질 경험 공유 및 트러블슈팅 ⚠️

제가 Calico 네트워크 정책을 운영하면서 겪었던 흔한 삽질과 해결책을 공유해볼게요.

  1. 정책 순서(Order) 문제: GlobalNetworkPolicyNetworkPolicy, 그리고 여러 정책이 동시에 적용될 때 order 필드를 제대로 설정하지 않아 예상과 다르게 동작하는 경우가 많아요. Calico는 우선순위가 높은 정책(order 값이 낮은 정책)이 먼저 적용됩니다. 기본적으로 NetworkPolicyGlobalNetworkPolicy보다 우선순위가 낮게(order 값이 높게) 적용되니, 충돌을 피하려면 order 값을 잘 조정해야 해요.
  2. kube-system 네임스페이스 정책 누락: kube-system 네임스페이스의 Pod들은 Kubernetes 클러스터 운영에 필수적인 역할을 하거든요. 여기에 default-deny-all 같은 강력한 정책을 적용했다가 클러스터 자체가 마비되는 참사를 겪을 수 있습니다. kube-system이나 calico-system 같은 핵심 네임스페이스에는 웬만하면 정책을 적용하지 않거나, 적용하더라도 매우 신중하게 필수 통신만 허용해야 해요.
  3. Prometheus/Grafana 같은 모니터링 툴 통신 문제: 모니터링 툴들은 다른 Pod의 메트릭(Metric)을 수집해야 하는데, 네트워크 정책으로 인해 이 통신이 막히는 경우가 잦습니다. 모니터링 스택(Stack)을 배포할 때는 반드시 해당 Pod들이 메트릭을 수집할 대상 Pod에 접근할 수 있도록 Ingress 정책을 허용해줘야 해요.
Calico 네트워크 정책의 Ingress/Egress, Selector, Order 필드 등 주요 개념을 요약한 인포그래픽

Calico 네트워크 정책의 Ingress/Egress, Selector, Order 필드 등 주요 개념을 요약한 인포그래픽

5. 마무리하며: 꾸준한 관리와 검토가 중요합니다.

오늘은 Calico 네트워크 정책을 활용해서 Kubernetes 프로덕션 환경의 보안을 강화하는 베스트 프랙티스들을 소개해드렸습니다. 기본적으로 모든 트래픽을 차단하고 필요한 통신만 명시적으로 허용하는 방식, 레이블 기반의 유연한 정책 관리, 그리고 GlobalNetworkPolicy를 활용한 클러스터 전역 정책 적용 등이 핵심이었습니다. 처음에는 다소 복잡하고 어렵게 느껴질 수 있지만, 몇 번 해보면 금방 익숙해져요. 오히려 이렇게 단단하게 네트워크 보안을 구축해두면 나중에 훨씬 마음이 편하거든요.

네트워크 정책은 한 번 설정했다고 끝이 아닙니다. 애플리케이션이 변경되거나 새로운 서비스가 추가될 때마다 정책을 검토하고 업데이트해야 해요. 지속적인 관리와 검토만이 강력한 보안을 유지하는 길입니다. 저도 아직 배워야 할 게 많지만, 앞으로도 이렇게 삽질하며 얻은 경험들을 아낌없이 공유해드리겠습니다. 다음번에는 Calico 네트워크 정책을 GitOps 방식으로 관리하는 방법에 대해 다뤄볼까 합니다. 기대해주세요! 궁금한 점이 있다면 언제든지 댓글로 남겨주세요. 😊