
쿠버네티스를 처음 쓰면, 파드끼리 서로 다 통신 가능하다.
default 네임스페이스든, 다른 네임스페이스든, 아무 제약 없이 서로 TCP/UDP 통신이 된다.
공식 문서에서는 NetworkPolicy를
“파드가 서로, 그리고 다른 네트워크 엔드포인트와 어떻게 통신할 수 있는지 정의하는 스펙”
이라고 설명한다.
즉, NetworkPolicy는 “어떤 파드가 누구랑 통신해도 되는지”를 선언적으로 적어놓는 정책이다.
중요한 포인트는:
- 아무 NetworkPolicy도 없으면
→ 모든 트래픽 허용- 하나라도 매칭되는 NetworkPolicy가 있으면
→해당 방향(ingress/egress)은 명시적으로 허용한 것만 통신 가능
이라고 정리할 수 있다.
그리고 또한 그리고 클러스터 CNI 플러그인이 NetworkPolicy를 지원해야 한다.
파일명: netpol-test-pods.yaml
apiVersion: v1
kind: Pod
metadata:
name: netpol-client
labels:
role: internal
app: chk-info
spec:
containers:
- name: curl
image: curlimages/curl
command: ["sleep", "3600"]
---
apiVersion: v1
kind: Pod
metadata:
name: netpol-server
labels:
role: sensitive
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
위 파일은 네트워크 정책이 없는 간단한 파드 2개를 생성하는 yaml 파일이다.

파드가 Running 상태로 잘 배포가 된 것을 확인할 수 있다.
이 상태에서 client 파드 안에서 curl 명령어로 server 파드를 접속해보면
# 쉘 접속
kubectl exec -it netpol-client -- sh
# 파드 안에서
curl -m 3 http://<서버 파드 IP>:80
# 예시: curl -m 3 http://10.244.3.7:80

접속이 잘 되는 것을 확인할 수 있다.
이 테스트는 아직 어떤 NetworkPolicy 도 적용하지 않은 상태에서
기본적으로 Pod 간 통신이 허용된다는 것을 확인하기 위한 베이스 테스트다.
이후 NetworkPolicy 를 하나씩 적용하면서, 동일한 curl 테스트가 어떻게 달라지는지 비교해볼 예정이다.
이번에는 특정 라벨을 가진 파드끼리만 서로 통신 허용하고, 나머지는 모두 막는 실습을 할 것이다.
파일명: 2-2-NetworkPolicy-podSelector.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: networkpolicy-podselector
namespace: default
spec:
podSelector:
matchLabels:
role: internal # 대상 파드
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector: # 여기에서만 들어오는 트래픽 허용
matchLabels:
app: chk-info
egress:
- to:
- podSelector: # 여기로만 나가는 트래픽 허용
matchLabels:
app: chk-info
kubectl apply -f 2-2-NetworkPolicy-podSelector.yaml
kubectl describe networkpolicy networkpolicy-podselector

이제 네트워크 정책이 적용되었다.
role=internal, app=chk-info 파드 → 서로 통신 OK
role=internal 이지만 app 라벨이 다른 파드 → 차단
다른 네임스페이스/라벨의 파드에서 role=internal 파드로 접근 → 차단
되는 네트워크 정책이다.

따라서 role=internal, app=chk-info인 client 파드가
role=sensitive 및 app 라벨이 다른 파드에 통신을 하려고 하니 실패하는 것을 확인할 수 있다.

또한 role=sensitive인 client 파드가 role=internal, app=chk-info인 client 파드에
접근이 안되는 것을 확인할 수 있다.
podSelector 는 “라벨을 기준으로 파드끼리” 통신을 제어하는 방식이었다.
이번에는 라벨이 아니라, IP 대역(CIDR) 을 기준으로 제어하는 방법이다.
쿠버네티스 공식 문서에서는 ipBlock 을 이렇게 설명한다.
ipBlock은 CIDR 형식의 IP 블록을 기준으로
인그레스/이그레스 트래픽을 허용(또는 except 로 제외)할 수 있게 해주는 필드이다.
쉽게 말하면,
을 의미한다.
예를 들어,
라고 쓰면,
10.244.0.0/16 대역은 다 허용하는데
그 중 10.244.3.7 IP 하나만 딱 빼고 차단
하는 식으로 동작한다고 보면 된다.
이번에는 netpol-server 파드에 대해,
특정 IP 대역에서 들어오는 트래픽만 허용하고, 그 외는 모두 막는 예시를 만들었다.
# 파일명: 3-1-NetworkPolicy-ipblock.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: networkpolicy-ipblock
namespace: default
spec:
podSelector:
matchLabels:
role: sensitive # netpol-server 에 붙어있던 라벨이라고 가정
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 10.244.0.0/16 # 이 대역에서 오는 요청은 기본적으로 허용
except:
- 10.244.3.6/32 # 이 IP(= netpol-client 파드 IP)만 예외로 차단
ports:
- protocol: TCP
port: 80
여기서 중요한 포인트는:
podSelector.role: sensitive
→ 이 정책은 role=sensitive 라벨을 가진 netpol-server 파드에 적용된다.
policyTypes: Ingress
→ 들어오는 트래픽(ingress)만 제어한다.
ipBlock.cidr: 10.244.0.0/16
→ 이 IP 구간(보통 클러스터 Pod CIDR)에서 오는 트래픽은 허용한다.
except: 10.244.3.6/32
→ 하지만 그 중 10.244.3.6(= netpol-client 파드 IP) 에서 오는 트래픽만 예외로 차단한다.
즉, 이 정책은
“10.244.0.0/16 대역 Pod 들은 모두 netpol-server 로 접근 가능하지만,
딱 한개(netpol-client = 10.244.3.6)만 골라서 막고 싶은 상황”
이라고 보면 된다.
# 네트워크 정책 적용
kubectl apply -f 3-1-NetworkPolicy-ipblock.yaml
# 상태 확인
kubectl describe networkpolicy networkpolicy-ipblock

이렇게 적용이 잘 된 것을 확인할 수 있다.
이제부터는 role=sensitive 라벨을 가진 netpol-server 파드에 대해,
Ingress 트래픽이 ipBlock 규칙을 타게 된다.
먼저, except 에 명시한 IP(10.244.3.6)를 가진 netpol-client 파드에서
netpol-server 로 curl 을 시도해본다.
# netpol-client 파드 안으로 접속
kubectl exec -it netpol-client -- sh
# 파드 안에서 (서버 IP는 실제 netpol-server IP 사용)
curl -m 3 http://10.244.3.7:80

이렇게 실패를 했다.
이 요청은 타임아웃 또는 connection refused 로 실패해야 정상이다.
netpol-client(10.244.3.6) → netpol-server(10.244.3.7) 로 들어가는 트래픽이
ipBlock.except 에 의해 Ingress 단계에서 차단되기 때문이다.
반대로, 동일 네임스페이스 안에 있는 다른 Pod (예: mypod-run = 10.244.3.4) 에서
curl 을 시도하면 이 트래픽은 허용된다.

cidr: 10.244.0.0/16 → 클러스터 Pod 전체 허용
except: 10.244.3.6/32 → 그 중 netpol-client 하나만 콕 집어서 차단한 것이다.
| 단계 | 적용 대상 / YAML | 규칙 타입 | 허용 / 차단 내용 | curl 결과 정리 |
|---|---|---|---|---|
| 1단계 – 기본 통신 확인 | netpol-test-pods.yaml(netpol-client, netpol-server) | (정책 없음) | NetworkPolicy가 하나도 없으므로, 기본적으로 모든 Pod ↔ Pod 통신 허용 | netpol-client 파드 안에서curl http://<netpol-server IP>:80→ 정상 응답 (200 OK) |
| 2단계 – podSelector | 2-2-NetworkPolicy-podSelector.yaml | Ingress + Egress | role=internal 파드는 app=chk-info 라벨을 가진 파드와만 송·수신 가능그 외 라벨/네임스페이스에서 오는·가는 트래픽은 차단 | netpol-client(role=internal, app=chk-info) → netpol-server(role=sensitive) : 차단role=sensitive 파드에서 netpol-client 로 접근도 차단 |
| 3단계 – ipBlock + except | 3-1-NetworkPolicy-ipblock.yaml | Ingress | role=sensitive 파드로 들어오는 트래픽 중cidr: 10.244.0.0/16 대역은 허용그 중 10.244.3.6/32(= netpol-client)만 예외로 차단 | netpol-client(10.244.3.6) → netpol-server(10.244.3.7) : 타임아웃/실패mypod-run(10.244.3.4) → netpol-server(10.244.3.7) : 정상 응답 |
참고자료:
[쿠버네티스 공식 홈페이지 - Network Policies]
https://kubernetes.io/docs/concepts/services-networking/network-policies/
[쿠버네티스 공식 홈페이지 - Declare Network Policy]
https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy/