Pod간 접근제어, NetworkPolicy 이해하기

728x90

NetworkPolicy란

NetworkPolicy는 Kubernetes에서 Pod 간 네트워크 트래픽을 제어하는 리소스입니다.
이는 마치 AWS의 보안 그룹(Security Group)과 비슷한 개념으로, Ingress(수신)Egress(송신) 트래픽을 제한할 수 있습니다.

 

NetworkPolicy 기본규칙

1. NetworkPolicy가 없을 경우 ➝ 모든 트래픽 허용
2. 하나 이상의 NetworkPolicy가 적용되면 ➝ 명시된 Pod, 네임스페이스, IP 블록에서의 트래픽만 허용 (화이트리스트 방식)

 

NetworkPolicy의 구조

NetworkPolicy는 Label Selector를 통해 적용 대상 Pod를 지정하고,

spec 하위에 Ingress 또는 Egress 정책을 정의하여 허용할 트래픽 범위를 설정합니다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978
  • spec.podSelector: 해당 정책을 적용할 대상 Pod 지정
  • policyTypes: 적용할 트래픽 방향 (Ingress, Egress)
  • ingress.from.podSelector: 특정 라벨의 Pod에서 오는 요청만 허용
  • ingress.from.namespaceSelector: 특정 라벨의 네임스페이스에서 오는 요청만 허용

 

실습: 파드에 NetworkPolicy 적용해 보기

두 개의 네임스페이스(test-a, test-b)를 생성한 뒤, 각 네임스페이스에 web 서비스용 Pod를 배치하고, test-a에 curl Pod를 하나 추가하여 통신 테스트를 진행합니다.

 

그림으로 나타내면 다음과 같습니다

 

현재상태에서 test-a 파드에서 test-b 파드로 curl 명령어를 실행해 봅니다.

kubectl exec -n test-a curl -- curl http://web.test-b.svc.cluster.local

 

이 상태에서는 NetworkPolicy가 없기 때문에 통신이 정상적으로 이루어집니다.
이를 통해 Kubernetes는 기본적으로 모든 트래픽을 허용한다는 것을 확인할 수 있습니다.

 

(참고) 위 명령어 입력 시 아래 그림과 같이 test-b 네임스페이스의 web 파드에 접근합니다.

 

이번에는 아래 networkpolicy를 적용해서 curl 명령어를 수행 시, 어떻게 동작하는지 확인해 보겠습니다.

해당 리소스는 test-b 네임스페이스인 ingress만 허용하도록 하는 정책이 설정되어 있습니다.

# deny-from-other-namespaces.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-from-other-namespaces
  namespace: test-b
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: test-b

 

 

이전과 다르게 접속이 실패하는 것을 알 수 있습니다. 왜냐하면 networkpolicy에서 test-b 네임스페이스에서 들어오는 트래픽만 허용하는 Ingress 정책을 사용했기 때문입니다.

 

통신과정을 그림으로 그려보면 그림과 같습니다.

 

이번에는 test-a에서 들어오는(Ingress) 트래픽을 허용하는 Networkpolicy를 추가로 생성하면 어떻게 되는지 확인해 보겠습니다.

# allow-from-test-a.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-test-a
  namespace: test-b
spec:
  podSelector:
    matchLabels:
      app: web
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: test-a

 

이번에는 통신이 허용한 것을 알 수 있습니다.

 

통신과정을 그림으로 그려보면 그림과 같습니다.

 

2개의 networkpolicy가 test-b 네임스페이스의 web 파드의 붙어있는 것을 알 수 있습니다.

 

위 실습을 통해 알 수 있듯이, 하나의 Pod에는 여러 NetworkPolicy가 동시에 적용될 수 있으며,
여러 정책 중 하나라도 해당 트래픽을 허용하면 통신은 허용됩니다.
즉, NetworkPolicy는 AND 조건이 아닌 OR 조건으로 평가됩니다.

728x90