7. 쿠버네티스 네트워크 정책

MAYFIFTH·2025년 6월 6일

K8S

목록 보기
7/10

✅네트워크 정책이란?

파드 및 엔드포인트 간 트래픽 흐름(Ingress/Egress)을 제어하기 위한 리소스

  • 기본적으로 쿠버네티스 클러스터는 네트워크 모델 특성 상 모든 파드가 서로 통신 가능

보안이나 서비스 격리를 위해 특정 파드, 네임스페이스 간 통신을 차단하거나 허용하는 정책

  • 단, NetworkPolicy 리소스를 지원하는 CNI가 설치되어 있어야 실제 동작
    • Flannel은 지원 X

비유하면 인터넷 방화벽과 유사한 기능을 한다.

  • 다만 방화벽은 외부에서 들어오는 트래픽을 제어하고,
  • 쿠버네티스 네트워크 정책은 파드 간 트래픽도 제어한다는 범위와 대상 관점의 차이가 존재

✅네트워크 정책의 필요성

  • 기본적으로 쿠버네티스의 보안 모델은 All Allow
    • 클러스터 내부 모든 파드 간 통신은 자유로우며, L3/L4 네트워크가 개방되어 있음
  • 취약한 파드를 통한 공격자의 접근, 개발/운영 환경의 네트워크 분리
    • 제로 트러스트 모델을 적용하기 위한 접근제어 적용

✅네트워크 정책 핵심 구성 요소책 핵심 구성 요소

1️⃣ podSelector

  • NetworkPolicy가 어떤 파드에 적용될 지 결정하는 필드

  • label기반 선택자 사용(e.g app=nginx)

  • app=nginx 라벨이 적용된 파드에 대한 ingress 제한 예시

deny-all-to-nginx.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-to-nginx
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: nginx
  policyTypes:
    - Ingress
  ingress:
    - {} # Deny All Ingress
kubectl run nginx --image=nginx --labels="app=nginx" --port=80
kubectl run client --image=busybox:1.28 --restart=Never -it --rm --sh
# curl http://nginx -> 성공


kubectl apply -f deny-all-to-nginx.yaml
kubectl run client --image=busybox:1.28 --restart=Never -it --rm --sh
# curl http://nginx -> 실패

kubectl delete networkpolicy --all

🤔 쿠버네티스 네트워크 보안 모델의 기본 트래픽 방침은 All Allow라고 했는데, ingress 설정이 의미가 있을까?

기본적으로 모든 인바운드/아웃바운드를 허용하지만, ingress 설정을 지정하면 해당 설정이 적용되고 All Deny 설정으로 변경된다.

2️⃣ namespaceSelector

  • 다른 네임스페이스의 Pod로부터의 접근 허용/제한
  • matchLabels를 통해 네임스페이스 필터링
  • ex) 테스트 클라이언트가 운영 API 호출하는 것을 방지

allow-from-frontend-ns.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-frontend-ns
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: nginx
  policyTypes:
    - Ingress
  ingress:
    - from:
      - namespaceSelector:
        matchLabels:
          team: frontend
kubectl create ns frontend # frontend라는 이름의 네임스페이스 생성
kubectl create ns dev # dev라는 이름의 네임스페이스 생성
kubectl run nginx --image=nginx --labels="app=nginx" --port=80 --expose -n deafult # nginx라는 이름의 컨테이너를 생성 -> default 네임스페이스
kubectl run client --image=busybox:1.28 --restart=Never -it --labels="team=frontend" -n frontend --sh # client 라는 이름의 컨테이너 실행 -> team=frontend 라벨을 갖고 네임스페이스는 frontend

kubectl label ns frontend team=frontend # frontend라는 네임스페이스에 team=frontend라는 라벨 추가

kubectl apply -f allow-from-frontend-ns.yaml

kubectl run cliend --image=busybox:1.28 --restart=Never -it --rm -n frontend --sh # curl http://nginx -> 성공

kubectl run client --image=busybox:1.28 --restart=Never -it -n dev --sh # curl http://nginx -> 실패

kubectl delete networkpolicy --all

podSelector에서 네트워크 정책을 적용할 pod label을 선택한 뒤에, namespaceSelector로 선택한 네임 스페이스로부터의 요청만 허용하는 설정

3️⃣ egress

  • 어떤 트래픽이 파드 밖으로 나갈 수 있는지 아웃바운드 트래픽 규칙 정의
  • To, ports 필드를 통해 목적지와 포트 지정 가능
  • ex) 백엔드 서비스가 의도치 않은 외부에 연결되는 것을 차단

allow-egress-to-nginx.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-egress-to-nginx
spec:
  podSelector:
    matchLabels:
      run: client
  policyTypes:
    - Egress
  egress:
    - to:
      - podSelector:
          matchLabels:
            app:nginx
      ports:
      - protocol: TCP
        port: 80
kubectl run nginx --image=nginx --labels="app=nginx" --port=80
kubectl run client --image=busybox:1.28 --restart=Never -it --rm -- sh

# curl http://nginx -> 성공

kubectl apply -f allow-egress-to-nginx.yaml
kubectl run client --image=busybox:1.28 --restart=Never -it --labels="run=client" --rm – sh

# curl http://nginx -> 성공 ingress 제한 없음

# ping 8.8.8.8 # 실패 egress 정책 적용

# wget http://google.com # 실패

kubectl delete networkpolicy --all

4️⃣ ipBlock

  • 클러스터 외부 IP 또는 특정 IP 대역에 대한 허용/제한
  • except 필드를 이용한 예외 설정 가능
  • ex) 인트라넷 서비스의 외부 접근 제한, 특정 IP 블랙리스트

allow-cidr-access.yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-cidr-access
spec:
  podSelector:
   matchLabels:
     app: nginx
  policyTypes:
    - Ingress
  ingress:
    - from:
      - ipBlock:
        cidr: 192.168.xx.xx/8
        except:
        - 192.168.xx.xx/32
kubectl run nginx --image=nginx --labels="app=nginx" --port=80

kubectl apply -f allow-cidr-access.yaml

kubectl run client --image=busybox:1.28 --restart=Never -it --rm --sh 

#curl http://nginx

kubectl get pod client -o wide # 파드 IP 확인

kubectl delete networkpolicy --all

📄 네트워크 정책 핵심 구성요소 요약 정리

1. Selector -> 정책이 적용될 대상

2. ingress/egress -> 허용 트래픽 방향

3. from/to -> 어디서 오는지/ 가는지 지정

4. ports -> 허용할 프로토콜/ 포트 지정

profile
HARVEY

0개의 댓글