작년 AWS에서 VPC CNI에서도 별도 설치 없이 NetworkPolicy를 지원한다고 발표했습니다. 발표 시기와 비슷하게 하나의 클러스터에 서로 다른 팀이 접근하는 프로젝트를 진행하면서 NetworkPolicy를 도입하게 됐습니다. 서로 다른 팀을 목적에 따라 Namespace로 구분하고, 각 환경에서 통신이 필요한 구간만 허용하고, 불필요한 통신을 차단하고자 했습니다. 실제 적용하기 전 진행했던 PoC 내용을 공유하여, EKS 환경에 Network Policy 도입 검토에 도움이 됐으면 합니다.

요약
NetworkPolicy는 Kubernetes에서 기본적으로 제공하는 오브젝트로써 Pod의 네트워크를 트래픽(InBound, OutBound)을 제어를 통해 애플리케이션을 보호하는데 사용됩니다.
그 동안, EKS 환경에서 NetworkPolicy를 사용하기 위해서는 반드시 Calico CNI + Tigera Operator를 별도로 설치해서 운영해야 했지만, 2023년 8월 29일 AWS에서 VPC CNI에서도 별도 설치 없이 NetworkPolicy를 지원한다고 발표했습니다. (클러스터 버전은 1.25 이상, VPC CNI 버전은 1.14 이상, 노드의 Linux 커널 버전 5.10 이상이어야 합니다.)
별도 서드파티가 아닌 VPC CNI를 통해 NetworkPolicy를 사용함으로써 얻을 수 있는 장점은 추가로 설치해야 했던 리소스(Calico CNI, Tigera Operator)를 설치할 필요가 없기 때문에 노드 리소스(CPU, Memeory, IP 등)를 추가로 확보할 수 있고, 운영해야 하는 리소스가 감소하니 오버헤드도 감소합니다.
사용 방법
NetworkPolicy 사용 시 명시해야 하는 Fields는 아래와 같습니다. (NetworkPolicy는 Stateful하며, Whitelist 방식으로 동작합니다.)
- podSelector : NetworkPolicy가 적용되는 기준
- policyTypes : NetworkPolicy를 통해 제어하고자 하는 트래픽의 방향 (InBound, OutBound)
- ingress : NetworkPolicy를 통해 InBound 트래픽을 제어할 규칙
- egress: NetworkPolicy를 통해 OutBound 트래픽을 제어할 규칙

아래 예시를 살펴보면, spec.podSelector.matchLabels를 통해 app=nginx이라는 Pod에 access-nginx라는 NetworkPolicy를 적용한 것을 알 수 있습니다. 해당 NetworkPolicy는 Ingress 트래픽을 제어하며, 해당 Pod로 Ingress 트래픽이 가능한 서비스를 podSelector를 통해 선언했습니다. (access=true Label이 설정된 Pod만 통신 가능)

트래픽을 정의하는 규칙 선언에는 namespaceSelector 뿐만 아니라, podSelector, ipBlock을 사용할 수 있고, 여러가지 조합(AND, OR 조건)으로 사용할 수도 있습니다.
Ingress, Egress 공통
- podSelector만 사용하는 경우

- namespaceSelector만 사용하는 경우

- podSelector, namespaceSelector를 함께 사용하는 경우 (AND 조건)

- podSelector, namespaceSelector를 각각 사용하는 경우 (OR 조건)

- ipBlock을 사용하는 경우

- ipBlock과 except를 함께 사용하는 경우 (except에서 정의한 CIDR를 제외하나 ipBlock에 대해 허용 처리)

확인 작업
Network Policy를 지원하는 EKS 버전인지 확인합니다.

Network Policy를 지원하는 VPC CNI 버전인지 확인합니다.

Network Policy를 지원하는 노드의 Linux 커널 버전인지 확인합니다.

VPC CNI를 활용해 NetworkPolicy를 사용할 경우, VPC CNI의 ConfigMap설정을 변경해야 합니다. (기본값은 false이며, true 변경해야 합니다.)

EKS 대시보드에서 수동 변경하는 방법은 아래와 같습니다. (Addon의 VPC CNI 설정)

Terraform을 통해 변경하는 방법은 아래와 같습니다.

작업 요구사항 정리 (Usecase)
- 하나의 클러스터에 서로 다른 팀이 Namespace 단위로 관리되기 때문에 통신이 필요한 Namespace를 제외하고 나머지 Namespace는 모두 차단 (클러스터에 a~f Namespace가 존재할 때, A팀이 a,b,c Namespace만 담당한다면 d,e,f Namespace에는 접근할 필요가 없습니다.)
- 인터넷 통신 가능

확인 방법
- PolicyEndPoint
- NetworkPolicy를 배포하면, PolicyEndpoint라는 오브젝트가 생성됩니다. (마치 Service를 배포한 후, Selector가 지정되면 Control Plane이 자동으로 EndpointSlice를 생성하는 것과 같습니다.) 해당 오브젝트를 통해 egress, ingress에 적용되는 IP를 확인할 수 있습니다.

- Tracing Log
- NetworkPolicy는 VPC CNI를 통해 동작하기 때문에 각 노드에서 로그를 확인할 수 있습니다.
- 로그 위치 : /var/log/aws-routed-eni/network-policy-agent.log
- NetworkPolicy는 VPC CNI를 통해 동작하기 때문에 각 노드에서 로그를 확인할 수 있습니다.

발생한 문제
Case 1) - Except 처리에도 통신이 되는 건
테스트 진행 시 ipBlock의 except를 통해 특정 CIDR의 통신을 차단하려고 했으나, 테스트가 원활히 진행되지 않았고, 확인 결과, VPC CNI 버전(v1.15.0-eksbuild.2)에서 발생한 버그였습니다. (해당 버그는 v1.15.1-eksbuild.1에서 수정되었습니다.)
흥미로운 부분은 cidr를 /0에서 /1로 변경하고 생성하면, except를 사용할 수 있다고 설명합니다. 그런데, except에 169.264.169.254/32 IP만 넣으면 에러가 발생합니다.

에러없이 정상적으로 생성되는 코드입니다.

(버그로 인해) 에러가 발생하는 코드입니다.

버그를 조치하기 위해 VPC CNI 버전을 업그레이드 후 확인합니다.

에러가 발생했던 코드가 정상 적용됩니다.

Network Policy Agent 특정 버전에서 지연이 발생하는 케이스가 존재합니다. GitHub Issue에 여러 버전에서 지연이 발생하는 글이 올라오고 있고, 도입을 고려해야 하는 주된 이유입니다. (트러블슈팅에서 지연을 발견하고, 조치하기 까지 많은 시간이 소요될 수 밖에 없습니다.)
참고사항
- PodSelector에서 {}는 모든 Pod를 의미합니다.
- 장애 포인트가 될 수 있으므로 도입을 고려해야 합니다.
- EKS에서 NetworkPolicy와 유사한 Security Group for Pod가 있습니다. 공통점으로는 네트워크를 트래픽을 제어한다는 부분이며, 차이점으로는 트래픽을 제어하는 수준(방식)의 차이라고 생각합니다.
NetworkPolicy는 클러스터 내부에서 podSelector, namespaceSelector를 통해 Security Group 보다 디테일한 제어가 가능합니다. EKS 환경에선 Pod의 IP를 고정할 수가 없기 때문에 Security Group을 통해 제어할 경우 /32 단위로 제어가 불가능(Pod는 언제든지 재성성 될 수 있기 때문에)하지만, NetworkPolicy는 podSelector를 통해 쉽게 제어가 가능합니다. 실제로 AWS EKS팀의 Github Code를 보면 NetworkPolicy를 Advanced로 별도로 관리하고 있는 것으로 봐서 비슷한 생각을 하는 것 같습니다.
참고문서
https://kubernetes.io/docs/concepts/services-networking/network-policies/
Network Policies
If you want to control traffic flow at the IP address or port level (OSI layer 3 or 4), NetworkPolicies allow you to specify rules for traffic flow within your cluster, and also between Pods and the outside world. Your cluster must use a network plugin tha
kubernetes.io
Amazon VPC CNI, 이제 Kubernetes NetworkPolicy 시행 지원
이제 Amazon VPC Container Networking Interface(CNI) 플러그인에서 Kubernetes NetworkPolicy 리소스를 지원합니다. 고객은 동일한 오픈 소스 Amazon VPC CNI를 사용해 포드 네트워킹과 네트워크 정책을 모두 구현하여
aws.amazon.com
https://docs.aws.amazon.com/eks/latest/userguide/cni-network-policy.html
Limit pod traffic with Kubernetes network policies - Amazon EKS
Help improve this page Want to contribute to this user guide? Scroll to the bottom of this page and select Edit this page on GitHub. Your contributions will help make our user guide better for everyone. Limit pod traffic with Kubernetes network policies By
docs.aws.amazon.com
https://kubernetes.io/docs/reference/kubernetes-api/policy-resources/network-policy-v1/
NetworkPolicy
NetworkPolicy describes what network traffic is allowed for a set of Pods.
kubernetes.io
https://github.com/kubernetes-sigs/network-policy-api
GitHub - kubernetes-sigs/network-policy-api: This repo addresses further work involving Kubernetes network security beyond the i
This repo addresses further work involving Kubernetes network security beyond the initial NetworkPolicy resource - kubernetes-sigs/network-policy-api
github.com
https://github.com/networkpolicy/tutorial
GitHub - networkpolicy/tutorial: Kubernetes Network Policy Tutorial
Kubernetes Network Policy Tutorial. Contribute to networkpolicy/tutorial development by creating an account on GitHub.
github.com