[MacOS 환경 #23] 쿠버네티스 네트워크 정책(NetworkPolicy)

도람·2025년 11월 26일
post-thumbnail

네트워크 정책(NetworkPolicy)이란?

쿠버네티스를 처음 쓰면, 파드끼리 서로 다 통신 가능하다.
default 네임스페이스든, 다른 네임스페이스든, 아무 제약 없이 서로 TCP/UDP 통신이 된다.

공식 문서에서는 NetworkPolicy를

“파드가 서로, 그리고 다른 네트워크 엔드포인트와 어떻게 통신할 수 있는지 정의하는 스펙”

이라고 설명한다.

즉, NetworkPolicy는 “어떤 파드가 누구랑 통신해도 되는지”를 선언적으로 적어놓는 정책이다.

  • 리소스 타입: NetworkPolicy (네임스페이스 단위)
  • 주요 요소
    • podSelector : 어떤 파드들에 이 정책을 적용할 건지 선택
    • policyTypes : Ingress, Egress (들어오는/나가는 트래픽 중 무엇을 다룰지)
    • ingress, egress : 실제 허용 규칙들 (from, to, ports …)

중요한 포인트는:

  • 아무 NetworkPolicy도 없으면
    → 모든 트래픽 허용
  • 하나라도 매칭되는 NetworkPolicy가 있으면
    →해당 방향(ingress/egress)은 명시적으로 허용한 것만 통신 가능

이라고 정리할 수 있다.

그리고 또한 그리고 클러스터 CNI 플러그인이 NetworkPolicy를 지원해야 한다.


실습

1. 테스트 파드 생성

파일명: 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. podSelector – 특정 파드끼리만 허용

이번에는 특정 라벨을 가진 파드끼리만 서로 통신 허용하고, 나머지는 모두 막는 실습을 할 것이다.

진행예정 내용

  • role: internal 라벨을 가진 파드가 있다고 가정
  • 이 파드는 app=chk-info 라벨을 가진 파드와만 통신 가능하게 만든다.
  • ingress.from.podSelector, egress.to.podSelector 를 같이 쓰면 된다.

NetworkPolicy-podSelector.yaml

파일명: 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 파드에
접근이 안되는 것을 확인할 수 있다.


3. ipBlock / ipBlock-except – IP 대역 기준 제어

podSelector 는 “라벨을 기준으로 파드끼리” 통신을 제어하는 방식이었다.
이번에는 라벨이 아니라, IP 대역(CIDR) 을 기준으로 제어하는 방법이다.

쿠버네티스 공식 문서에서는 ipBlock 을 이렇게 설명한다.

ipBlock은 CIDR 형식의 IP 블록을 기준으로
인그레스/이그레스 트래픽을 허용(또는 except 로 제외)할 수 있게 해주는 필드이다.

쉽게 말하면,

  • cidr: 이 IP 대역은 허용
  • except: 그 중에서 예외로 차단할 IP 대역

을 의미한다.

예를 들어,

  • cidr: 10.244.0.0/16
  • except: 10.244.3.7/32

라고 쓰면,

10.244.0.0/16 대역은 다 허용하는데
그 중 10.244.3.7 IP 하나만 딱 빼고 차단

하는 식으로 동작한다고 보면 된다.


### NetworkPolicy-ipblock.yaml 생성 파일명: 3-1-NetworkPolicy-ipblock.yaml

이번에는 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 규칙을 타게 된다.


테스트 1 – 차단된 IP(netpol-client)에서 접근 시도

먼저, 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 단계에서 차단되기 때문이다.


테스트 2 – 허용된 다른 Pod IP에서 접근 시도

반대로, 동일 네임스페이스 안에 있는 다른 Pod (예: mypod-run = 10.244.3.4) 에서
curl 을 시도하면 이 트래픽은 허용된다.

실습 정리

cidr: 10.244.0.0/16 → 클러스터 Pod 전체 허용
except: 10.244.3.6/32 → 그 중 netpol-client 하나만 콕 집어서 차단한 것이다.


4. 실습 전체 정리

단계적용 대상 / 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단계 – podSelector2-2-NetworkPolicy-podSelector.yamlIngress + Egressrole=internal 파드는 app=chk-info 라벨을 가진 파드와만 송·수신 가능
그 외 라벨/네임스페이스에서 오는·가는 트래픽은 차단
netpol-client(role=internal, app=chk-info)netpol-server(role=sensitive) : 차단
role=sensitive 파드에서 netpol-client 로 접근도 차단
3단계 – ipBlock + except3-1-NetworkPolicy-ipblock.yamlIngressrole=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/

profile
정도를 걷는 엔지니어

0개의 댓글