이 글은 Kubernetes에서 NetworkPolicy(네트워크 정책) 를 설계/적용하기 위해 필요한 흐름을 “기본 개념 → 최소 요구사항 정의 → 정책 작성(deny-by-default + allowlist) → 네임스페이스/IP 확장 → egress 확장 → 규칙 조합(AND/OR) 주의점 → 적용/검증” 순서로 정리합니다.
1) Ingress / Egress: “요청 방향”만 보면 된다
3티어 예시로 시작합니다.
- 사용자 → Web 서버(80)
- Web 서버 → API 서버(5000)
- API 서버 → DB 서버(3306)
여기서 Ingress/Egress는 ‘해당 컴포넌트 기준으로 요청이 들어오고 나가는 방향’ 입니다.
- Web 서버 관점
- 사용자 → Web(80) : Ingress
- Web → API(5000) : Egress
- API 서버 관점
- Web → API(5000) : Ingress
- API → DB(3306) : Egress
- DB 서버 관점
- API → DB(3306) : Ingress
중요한 포인트:
- 정책 설계 시에는 “요청이 시작되는 방향(실선)”을 기준으로 생각합니다.
- 응답 트래픽(점선)은 보통 별도로 신경 쓰지 않습니다. (대부분의 CNI 구현에서 연결 추적 기반으로 응답은 자동 허용되는 형태로 동작)
2) Kubernetes 기본 네트워킹 전제: Pod 간 통신은 기본 허용(allow-all)
Kubernetes는 일반적으로 클러스터 내부 Pod/Service 간 통신이 기본적으로 가능한 네트워크 모델을 전제로 합니다.
그래서 정책을 만들지 않으면 보통:
- Web Pod → DB Pod 직접 통신도 가능
- “원래 막고 싶었던” 경로가 열려있는 상태가 됩니다.
3) NetworkPolicy가 필요한 상황: “DB는 API만 허용” 같은 요구사항
이제 심화 요구사항을 명확히 잡아봅니다.
요구사항(정확히)
- 목표: DB Pod 보호
- DB Pod의 3306 포트는 API Pod에서 오는 트래픽만 허용
- 그 외(Web Pod 포함) 어떤 Pod도 DB:3306에 접근 못 하게 차단
범위 정리(중요)
- Web Pod나 API Pod의 다른 포트, 외부 트래픽 등은 “이번 요구사항에서는 신경 쓰지 않는다”라고 가정
- 즉, 핵심은 DB Pod 인그레스(3306)만 통제입니다.
4) 첫 단계: “DB Pod에 대한 기본 차단”부터 만든다
NetworkPolicy는 “방화벽처럼” 동작시키려면 보통 deny-by-default 를 먼저 만들고, 그 다음 allowlist를 추가합니다.
4.1 DB Pod에 레이블 부여
DB Pod가 role=db 라벨을 갖도록 합니다.
kubectl label pod db-pod role=db
API Pod에도 라벨을 붙입니다.
kubectl label pod api-pod role=api
4.2 DB Pod에 대해 Ingress 기본 차단(deny) 만들기
policyTypes: [Ingress]를 선언하고, ingress: []로 비워두면 “인그레스 전부 차단” 효과를 만들 수 있습니다.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy-deny-ingress
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress: []
이 시점에 DB Pod는:
- 어디서든 들어오는 연결이 차단됩니다(= DB 접근이 전부 막힘)
- ingress: [] 는 비어있으므로 전부 차단이며 아래는 허용을 해주는 하나의 정책이 있는것이라 전부 허용을 의미
ingress:
- {}
5) 두 번째 단계: “API Pod만 DB:3306 인그레스 허용” 규칙 추가
이제 요구사항을 만족시키기 위한 allow 규칙을 넣습니다.
핵심은 DB Pod 관점:
- API Pod에서 DB로 들어오는 트래픽(Ingress) 만 열면 됩니다.
- 응답 트래픽을 위해 별도의 룰은 보통 필요 없습니다.
5.1 최종 형태(deny-by-default + allow API on 3306)
아래 정책 하나로도 “선택된 DB Pod의 인그레스는 allowlist만 허용”이 됩니다.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: api
ports:
- protocol: TCP
port: 3306
이제 DB Pod는:
role=api라벨을 가진 Pod에서 오는 TCP/3306만 허용- Web Pod(예: role=web)에서 DB로 직접 붙는 트래픽은 차단
6) 네임스페이스가 여러 개면? namespaceSelector로 “특정 네임스페이스의 API만 허용”
문제 상황:
- dev/test/prod 네임스페이스가 있고
- 각 네임스페이스에
role=apiPod가 존재 - 지금 정책은 “같은 네임스페이스(default) 내 role=api”만 매칭하지만, 설계에 따라 “네임스페이스 경계도 포함해서” 명확히 하고 싶을 수 있습니다.
요구사항 예:
- prod 네임스페이스의 API Pod만 DB에 접근 허용
6.1 먼저 네임스페이스에 라벨을 붙인다
예: prod 네임스페이스에 env=prod
kubectl label namespace prod env=prod
6.2 podSelector + namespaceSelector를 함께 사용(AND)
같은 from 항목 안에 podSelector와 namespaceSelector를 같이 넣으면 둘 다 만족해야(AND) 허용됩니다.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy-prod-api-only
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes: ["Ingress"]
ingress:
- from:
- podSelector:
matchLabels:
role: api
namespaceSelector:
matchLabels:
env: prod
ports:
- protocol: TCP
port: 3306
이 의미는:
env=prod네임스페이스 안에 있으면서role=api라벨인 Pod만- DB:3306 인그레스 허용
6.3 namespaceSelector만 있고 podSelector가 없으면?
from에 namespaceSelector만 두면:
- 해당 네임스페이스의 모든 Pod가 DB로 접근 가능해집니다.
7) 클러스터 외부(백업 서버 등)에서 DB 접근을 허용하려면? ipBlock 사용
상황:
- 쿠버네티스 클러스터 외부에 백업 서버가 있고
- 이 서버가 DB Pod에 접근해야 함
- 이 서버는 Pod가 아니므로
podSelector/namespaceSelector로 표현 불가
이때는 ipBlock을 사용합니다.
예: 백업 서버 IP가 192.168.5.1 이면:
ingress:
- from:
- ipBlock:
cidr: 192.168.5.1/32
ports:
- protocol: TCP
port: 3306
ipBlock.cidr는 범위를 지정할 수 있고, 필요하면 except로 일부 IP를 제외할 수도 있습니다.
8) 규칙 조합에서 가장 많이 실수하는 부분: AND / OR, 그리고 “대시(-)” 위치
NetworkPolicy는 “YAML 리스트 구조” 때문에 작은 차이가 의미를 크게 바꿉니다.
8.1 OR 동작(여러 from 항목)
from 아래에 -가 여러 개면 OR 입니다.
from:
- podSelector: { ... } # 조건 A
- ipBlock: { ... } # 조건 B
→ A 또는 B면 허용
8.2 AND 동작(한 항목 안에 selector를 같이 넣는 경우)
한 - 항목 안에 podSelector와 namespaceSelector를 같이 넣으면 AND 입니다.
from:
- podSelector: { ... }
namespaceSelector: { ... }
→ podSelector도 맞고 namespaceSelector도 맞아야 허용
8.3 “대시(-)를 하나 더 쳤을 뿐인데” 정책이 완전히 달라지는 예
아래처럼 분리하면 두 개가 별도 규칙(OR)이 됩니다.
from:
- podSelector:
matchLabels:
role: api
- namespaceSelector:
matchLabels:
env: prod
이 경우 의미는:
- role=api 인 Pod(네임스페이스 무관)도 허용될 수 있고
- env=prod 네임스페이스의 모든 Pod도 허용될 수 있음
요구사항이 “prod의 api만”이었다면 완전히 다른 결과가 됩니다.
9) Egress까지 필요해지는 순간: “DB가 외부 백업 서버로 Push”해야 한다면
지금까지는 DB Pod로 “들어오는 것(ingress)”만 다뤘습니다.
하지만 DB Pod가 외부로 나가는 트래픽이 필요한 경우가 있습니다.
예:
- DB Pod 안에 백업 에이전트가 있어서
- 백업 서버로 데이터를 푸시(egress) 한다
이때는 Egress 정책이 필요합니다.
9.1 egress를 정책 타입에 추가하고 egress 규칙 정의
예: DB Pod가 192.168.5.1 백업 서버의 80 포트로 나가는 것을 허용
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy-with-egress
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes: ["Ingress", "Egress"]
ingress:
- from:
- podSelector:
matchLabels:
role: api
ports:
- protocol: TCP
port: 3306
egress:
- to:
- ipBlock:
cidr: 192.168.5.1/32
ports:
- protocol: TCP
port: 80
주의:
policyTypes에Egress를 넣는 순간, 해당 Pod는 egress도 “allowlist 기반”으로 바뀌는 형태가 될 수 있습니다.- 실무에서는 DNS(53) 같은 기본 통신이 막혀 장애가 나기도 하므로, egress 차단을 시작할 땐 “필수 목적지(DNS 등)”도 같이 열어줘야 합니다.
10) 적용/확인 커맨드
정책 적용:
kubectl apply -f db-policy.yaml
kubectl get netpol -n default
kubectl describe netpol db-policy -n default
접속 테스트(예시):
- Web Pod에서 DB로 접속 시도 → 실패해야 정상
- API Pod에서 DB로 접속 시도 → 성공해야 정상
(테스트 도구는 환경에 따라 nc, curl, mysql 클라이언트 등 사용)
11) 마지막으로 꼭 기억할 것: “CNI가 NetworkPolicy를 집행해야 실제로 막힌다”
NetworkPolicy 오브젝트는 Kubernetes API에 “생성”할 수 있지만,
실제 패킷 차단/허용(enforcement)은 CNI 플러그인 구현이 지원해야 동작합니다.
- 정책을 만들었는데도 전혀 막히지 않으면: CNI가 NetworkPolicy를 지원하는지 먼저 확인합니다.
요약
- Ingress/Egress는 “요청 방향” 관점으로 이해하면 설계가 쉬워진다.
- Kubernetes 기본은 allow-all에 가까워서, DB 같은 핵심 컴포넌트는 NetworkPolicy로 보호해야 한다.
- 추천 접근:
- DB Pod를 selector로 고른다
- Ingress/Egress를 deny-by-default로 만든다(필요한 방향만)
- API Pod만 3306 허용 같은 allowlist 규칙을 추가한다
podSelector,namespaceSelector,ipBlock을 조합할 때 AND/OR와 “대시(-) 위치”가 의미를 크게 바꾼다.- Egress가 필요하면
policyTypes에 Egress를 추가하고egress.to규칙을 설계한다. - CNI가 NetworkPolicy enforcement를 지원해야 실제로 적용된다.
Practice Test: https://uklabs.kodekloud.com/topic/practice-test-network-policies-2/
'CKA' 카테고리의 다른 글
| Security - Custom Resource Definition (0) | 2026.01.02 |
|---|---|
| Security - Context & 네임스페이스 전환을 빠르게 하는 도구 (0) | 2026.01.02 |
| Security - 도커 보안 기초 + 쿠버네티스의 Security Context (0) | 2026.01.02 |
| Security - Secret of Docker Registry (0) | 2026.01.02 |
| Security - Service Account (0) | 2026.01.02 |