5 분 소요

📦 망분리 이후의 금융보안 5부작 — 금융권이 왜 망을 끊었고 지금은 왜 푸는지(1편), 그 자리를 메우는 제로트러스트 설계(2편), 내부를 잘게 쪼개는 마이크로세그멘테이션 실전(3편), 흐름을 관찰하고 정책을 자동화하는 운영(4편), 그리고 이 모델을 여러 클라우드로 넓히기(5편)까지 이어집니다. 전체 5편.
  1. 금융권 망분리, 내부망과 외부망 — 왜 갈랐고 지금은 왜 푸는가
  2. 제로트러스트 설계 — 망분리 다음의 금융보안을 구성요소로 뜯어보기
  3. 마이크로세그멘테이션 실전 — 트래픽 흐름 위에 default-deny 그리기
  4. 가시성·정책 자동화 — 흐름을 관찰하고 정책을 코드로 굴리기지금 글
  5. 멀티 클라우드로 넓히기 — 클라우드가 여럿일 때 깨지는 것들

Summary

지난 글에서 NetworkPolicy 를 손으로 깔아봤어요. 그런데 세그먼트가 셋이 아니라 수백 개가 되면? 어떤 흐름이 오가는지 눈으로 못 좇고, 정책을 kubectl apply 로 하나씩 미는 것도 한계가 옵니다.

그래서 제로트러스트가 6대 요소를 가로지르는 두 가지 교차기능으로 꼽은 게 가시성·분석자동화·오케스트레이션 이었어요. 이번 글은 그 둘을 실전으로 내려봅니다. 흐름을 관찰하고(가시성) → 정책을 코드로 굴리는(자동화) 운영 모델이에요.

💡 이 글에서 다루는 것

  • 왜 가시성이 정책보다 먼저인가
  • eBPF 흐름 관찰 — Hubble 로 허용·차단·드롭까지 보기
  • 관찰한 흐름을 정책 초안으로 — allowlist 자동화
  • policy-as-code — 정책을 Git 에 코드로 두는 이유
  • GitOps + 가드레일(Kyverno) — 자동 배포·기본정책 생성·drift 되돌리기
  • 운영에서 빠지기 쉬운 함정



1. 왜 가시성이 먼저인가

마이크로세그멘테이션 글에서 “도구부터 사지 말고 흐름부터 그려라” 했죠. 그 “흐름 그리기”가 곧 가시성이에요. 그리고 가시성은 정책을 깔기 전 에만 필요한 게 아닙니다.

  • 정책을 짜기 전 — 무엇이 무엇과 통신하는지 알아야 allowlist 를 그림.
  • 정책을 켜는 중 — 무엇이 끊길지 미리 봐야 장애 없이 시행으로 넘어감.
  • 정책을 켠 후 — 차단·드롭이 실제로 일어나는지, 이상 흐름은 없는지 계속 관측.

🚨 안 보이면 지킬 수 없어요. 흐름이 안 보이는 상태에서 정책부터 조이면 멀쩡한 업무가 끊기고, 반대로 관측만 하고 자동화가 없으면 사람이 수백 개 정책을 못 따라갑니다. 가시성과 자동화는 한 쌍이에요.



2. 실전 가시성 — eBPF 흐름 관찰

쿠버네티스에서 흐름 가시성의 현실적인 답 하나가 Cilium 의 Hubble 이에요. 커널의 eBPF 훅에서 흐름을 직접 떠서, 출발·도착 파드와 네임스페이스·신원까지 붙여 보여줍니다. 별도 에이전트 없이 정책 집행과 같은 경로에서 관측해서 부담도 적고요.

hubble observe 로 흐름을 그대로 들여다볼 수 있어요.

hubble observe --namespace core-banking --follow
Jun 24 05:21:03.114  core-banking/web-7d  -> core-banking/api-5b   to-endpoint  FORWARDED  TCP 8080 SYN
Jun 24 05:21:03.221  core-banking/api-5b  -> core-banking/db-0     to-endpoint  FORWARDED  TCP 5432 SYN
Jun 24 05:21:07.880  core-banking/web-7d  -> core-banking/db-0     to-endpoint  DROPPED    TCP 5432 SYN

마지막 줄이 핵심이에요. web 이 db 에 직접 손을 뻗었고, 정책에 막혀 DROPPED 됐다는 게 그대로 찍힙니다. 지난 글에서 깐 default-deny 가 실제로 일하는 걸 눈으로 확인하는 거예요.

차단된 흐름만 따로 모아서 “지금 무엇이 막히고 있나” 를 볼 수도 있어요.

hubble observe --namespace core-banking --verdict DROPPED --last 20

Hubble 은 CLI 외에 서비스 의존성 맵(UI) 도 제공해서, 어떤 서비스가 어떤 서비스에 의존하는지 그래프로 보여줘요. 이게 1번에서 말한 “흐름 그리기”를 사람이 손으로 안 그려도 되게 해줍니다.



3. 관찰을 정책으로 — allowlist 자동화

관찰의 진짜 값어치는 정책 초안으로 바로 이어진다는 데 있어요. 며칠~몇 주 흐름을 모으면, “실제로 일어난 정상 흐름” 의 목록이 쌓입니다. 그 목록이 곧 allowlist 예요.

관찰된 흐름                         →  생성될 정책(짝)
web → api : 8080                    →  api ingress(from web) + web egress(to api)
api → db  : 5432                    →  db ingress(from api)  + api egress(to db)
*   → kube-dns : 53                 →  allow-dns egress

머릿속 다이어그램이 아니라 실측 트래픽에서 뽑으니, 빠지기 쉬운 흐름(배치 잡·모니터링·DNS)이 자동으로 잡혀요. 도구에 따라 이 추천 정책을 YAML 로 바로 뽑아주기도 합니다. 사람은 검토하고 다듬는 역할만 하면 돼요.

✅ 포인트는 “사람이 정책을 발명하지 않는다” 예요. 흐름을 관찰해 초안을 기계가 만들고, 사람은 “이 흐름이 정상 업무가 맞나” 만 판단합니다. 정책 작성의 부담이 확 줄어요.



4. policy-as-code — 정책을 코드로

여기서 운영 방식을 한 번 더 바꿔야 해요. 추천받은 정책을 kubectl apply 로 손수 미는 건 세그먼트 몇 개일 때 얘기고, 규모가 커지면 정책을 코드처럼 다뤄야 합니다. 이걸 policy-as-code 라고 해요.

정책 YAML 을 Git 저장소에 두면, 소프트웨어 개발의 검증된 습관이 그대로 따라옵니다.

손으로 kubectl apply policy-as-code (Git)
누가 언제 바꿨는지 모름 변경 이력 · 책임 추적
리뷰 없이 즉시 반영 PR 리뷰 · 승인 후 반영
테스트 없이 운영 직행 CI 에서 사전 검증
클러스터마다 제각각 한 소스로 전 클러스터 동기화
되돌리기 어려움 git revert 로 롤백

금융권 맥락에선 마지막 두 줄이 특히 커요. “누가 이 방화벽 규칙을 왜 바꿨나” 가 감사에서 늘 나오는 질문인데, 정책이 Git 에 있으면 커밋 하나가 곧 그 답이 됩니다.



5. GitOps + 가드레일

policy-as-code 를 실제로 굴리는 엔진이 GitOps 예요. Git 을 단일 진실 공급원(single source of truth) 으로 두고, 도구가 클러스터 상태를 자동으로 Git 과 맞춥니다.

흐름은 이래요.

정책 변경 → PR → CI 검증·리뷰 → 머지
   → GitOps 도구가 자동 reconcile → 클러스터 반영
   → 누가 손으로 바꿔도(drift) Git 상태로 되돌림

여기에 가드레일을 한 겹 더 얹어요. 사람이 새 네임스페이스를 만들 때 default-deny 를 깜빡하면 그 구간은 무방비가 됩니다. Kyverno 같은 정책 엔진으로 “네임스페이스가 생기면 기본 차단 정책을 자동 생성” 하게 강제할 수 있어요.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-default-deny
spec:
  rules:
    - name: default-deny-on-new-ns
      match:
        any:
          - resources:
              kinds:
                - Namespace
      generate:                       # 매칭되면 아래 리소스를 자동 생성
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        name: default-deny-all
        namespace: "{{request.object.metadata.name}}"
        synchronize: true             # 누가 지워도 다시 만들어 둠
        data:
          spec:
            podSelector: {}
            policyTypes:
              - Ingress
              - Egress

이러면 새 구간은 태어날 때부터 기본 차단이에요. 사람의 실수에 기대지 않는 거죠. Kyverno 는 쿠버네티스 API 에 admission controller 로 붙어서 검증(validate)·변형(mutate)·생성(generate)을 다 해줘요. 더 복잡한 정책 로직이 필요하면 OPA/Gatekeeper(Rego) 를 쓰기도 하고요.



6. drift 탐지와 대응

정책을 한 번 깔았다고 끝이 아니에요. 운영 중엔 늘 이탈(drift) 이 생깁니다. 정책 적용 전부터 있던 리소스, admission 을 우회한 직접 변경 같은 것들요.

  • Kyverno background scan / Gatekeeper audit — 이미 떠 있는 리소스 중 정책 위반을 사후 에 훑어서 리포트. 정책보다 먼저 있던 위반을 잡아요.
  • GitOps reconcile — 클러스터가 Git 과 어긋나면 자동으로 되돌림. “누가 콘솔에서 손댄” 변경이 슬그머니 살아남지 못해요.
  • 대응 자동화 — 이상 흐름이 관측되면 알림에서 끝내지 않고, 세그먼트 격리·정책 강화 같은 후속 동작까지 자동으로 묶을 수 있어요(오케스트레이션).

💡 가시성(2장)이 “무엇이 어긋났나” 를 보여주고, 자동화(4~6장)가 “어긋난 걸 되돌린다” 는 한 바퀴예요. 이 루프가 돌아가야 수백 개 세그먼트도 사람 몇 명으로 운영됩니다.



7. 빠지기 쉬운 함정

  • 가시성 데이터 폭증 — 흐름 로그는 양이 엄청나요. 다 저장하면 비용·성능이 무너지니, 표본·보존기간·집계 전략을 먼저 정해야 합니다.
  • 자동화의 오작동 — 잘못된 정책이 자동으로 전 클러스터에 퍼지면 사고도 자동으로 커져요. 그래서 CI 검증과 사람 승인 단계는 남겨둬야 합니다. 자동화 = 무인이 아니에요.
  • 추천 정책 맹신 — 관찰 기간에 안 돌던 흐름(월말 배치)은 추천에서 빠져요. 한 주기 이상 관찰하고, 추천은 초안 으로만.
  • 도구 종속 — eBPF·CNI·정책 엔진에 깊게 묶이면 이전이 어려워요. 정책은 가능하면 표준(NetworkPolicy)에 가깝게, 확장은 신중히.



마치며

네 편에 걸쳐 여기까지 왔어요. 끊기(망분리) → 검증하기(제로트러스트) → 쪼개기(마이크로세그멘테이션) → 그리고 오늘 보고 되돌리기(가시성·자동화).

큰 그림은 하나로 모여요. 경계를 믿는 대신 모든 흐름을 보이게 하고, 정상만 코드로 허용하고, 어긋나면 자동으로 되돌린다. 망분리가 비웠던 자리를, 더 정교하고 지속 가능한 운영으로 메우는 일이었습니다.

손으로 NetworkPolicy 한 짝을 깔던 데서 시작해, 그걸 Git 으로 굴리고 기계가 추천·검증·복구하는 데까지 — 한 클러스터·한 환경 안에서 할 이야기는 거의 다 한 셈이에요.

일단 오늘은 여기까지…..
다음 글에서는 이 운영 모델을 여러 클라우드로 넓힐 때 깨지는 것들을 정리해볼게요.



← 이전 글: (3/5) 마이크로세그멘테이션 실전 — 트래픽 흐름 위에 default-deny 그리기다음 글 →: (5/5) 멀티 클라우드로 넓히기 — 클라우드가 여럿일 때 깨지는 것들


참고: Hubble — Network & Security Observability (Cilium) · Kyverno 공식 문서