1. Network Policy 개념
- Network Policy를 통해 클러스터 내부에서 파드 간에 트래픽 룰을 규정할 수 있다.
- Network Policy를 사용하지 않을 경우 클러스터 내부의 모든 파드는 서로 통신이 가능하다.
- Network Policy의 용도
- 기본적으로 모든 파드 간 통신은 차단하고 특정 파드 간 통신만 허용하는 화이트리스트 방식을 사용할 수 있다.
- 네임스페이스별로 트래픽을 전송하지 못하게 할 수 있다.
2. Network Policy 활성화 방법
1) 온프레미스 환경
- Network Policy 정책을 지원하는 네트워크 플러그인(CNI 플러그인)을 사용하여 클러스터가 구축되어야 한다.
- CNI 플러그인으로 Flannel, Calico, Weavenet, NSX 등 다양한 종류가 있다.
2) AKS(Azure Kubernetes Service) 환경
- AKS 생성 시 하기 Network Policy 옵션을 선택하면 Azure Network Policy 또는 Calico가 배포되어 있는 클러스터가 생성되어 Network Policy를 사용할 수 있다.
- Azure Network Policy Manager (Azure 자체 구현 서비스)
- Calico
3. Network Policy 생성
- Network Policy는 Ingress와 Egress로 구성되어 있다.
- Ingress는 인바운드 트래픽 룰을 설정하고, Egress는 아웃버운드 트래픽 룰을 설정한다.
- Network Policy 설정 범위를 podSelector로 지정한다.
- Network Policy는 네임스페이스별로 생성해야 한다.
- ingress from/egress to에 지정할 수 있는 Selector 종류: podSelector, namespaceSelector, namespaceSelector and podSelector, ipBlock
- 클러스터 내부 네트워크 제어는 podSelector, namespaceSelector를 사용하는 것 좋다.
- 클러스터 외부 네트워크 제어는 ipBlock를 사용하는 것 좋다.
4. Network Policy 예제
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector: # 설정할 대상 pod를 기입, 레이블 셀렉터이므로 여러 파드를 대상을 할 수 있음
matchLabels:
role: db
policyTypes:
- Ingress # ingress 룰을 생성할 경우 명시
- Egress # engress 룰을 생성할 경우 명시
ingress:
- from: # ingress 룰을 기입(podSelector, namespaceSelector,ipBlock 사용)
- podSelector:
matchLabels:
role: frontend
- namespaceSelector:
matchLabels:
project: myproject
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
ports: # 이 ingress 룰로 허가할 수신 포트 번호와 프로토콜 기입
- protocol: TCP
port: 6379
egress:
- to: # engress 룰을 기입(podSelector, namespaceSelector,ipBlock 사용)
- ipBlock:
cidr: 10.0.0.0/24
ports: # 이 egress 룰로 허가할 목적지 포트 번호와 프로토콜 기입
- protocol: TCP
port: 5978
5. Network Policy 테스트
※ 실습 환경은 AKS를 사용하였으며 Network Policy는 Calico를 사용하였다.
5-1. 테스트01 - Network Policy 활성화 후, 룰 설정은 하지 않은 상태에서 pod 간 트래픽 테스트
1) default 네임스페이스에 pod 2개 생성, nptest 네임스페이스에 pod 2개 생성
# pods.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: sample-pod-np1
namespace: default
labels:
app: np1
spec:
containers:
- name: nginx-container
image: amsy810/echo-nginx:v2.0
---
apiVersion: v1
kind: Pod
metadata:
name: sample-pod-np2
namespace: default
labels:
app: np2
spec:
containers:
- name: nginx-container
image: amsy810/echo-nginx:v2.0
---
apiVersion: v1
kind: Namespace
metadata:
name: nptest
---
apiVersion: v1
kind: Pod
metadata:
name: sample-pod-np3
namespace: nptest
labels:
app: np3
spec:
containers:
- name: nginx-container
image: amsy810/echo-nginx:v2.0
---
apiVersion: v1
kind: Pod
metadata:
name: sample-pod-np4
namespace: nptest
labels:
app: np4
spec:
containers:
- name: nginx-container
image: amsy810/echo-nginx:v2.0
kubectl apply -f pods.yaml
2) 생성한 pod의 IP 주소 및 label 확인
3) default 네임스페이스에 레이블 지정
kubectl label namespace default ns=default
4) pod 간 통신 테스트
- 내부 네임스페이스 간의 (sample-pod-np1 -> sample-pod-np2) 통신 테스트
- Network Policy을 구성하지 않아 내부 네임스페이스 간의 통신이 가능하다.
- 외부 네임스페이스 간의 (sample-pod-np1 -> sample-pod-np3) 통신 테스트
- Network Policy을 구성하지 않아 외부 네임스페이스 간의 통신이 가능하다.
5-2. 테스트02 - 인바운드는 전체 차단, 아운바운드는 전체 허용
1) 인바운드는 전체 차단, 아운바운드는 전체 허용하는 Network Policy 생성
# networkpolicy-denyinbound.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: cloud-networkpolicy
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Ingress
- Egress
kubectl apply -f networkpolicy-denyinbound.yaml
2) pod 간 통신 테스트
- 내부 네임스페이스 간의 (sample-pod-np1 -> sample-pod-np2) 통신 테스트
- 인바운드가 차단되어 내부 네임스페이스 간의 통신이 불가능하다.
- 외부 네임스페이스 간의 (sample-pod-np1 -> sample-pod-np3) 통신 테스트
- Network Policy는 네임스페이스별로 생성해야 한다.
- 현재 default 네임스페이스에만 Network Policy를 생성하였기 때문에 nptest 네임스페이스에는 정책이 적용되지 않아 외부 네임스페이스 간의 통신이 가능하다.
4) nptest 네임스페이스에도 Network Policy 배포
kubectl apply -n nptest -f networkpolicy.yaml
5-3. 테스트03 - podSelector 사용: 특정 레이블을 가진 pod에서 들어오는 통신을 허용
1) sample-pod-np2에 app:np1 레이블을 가진 파드에서 들어오는 인바운드 오픈
# networkpolicy-podselector.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: sample-podselector-ingress-networkpolicy
spec:
podSelector:
matchLabels:
app: np2
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: np1
ports:
- protocol: TCP
port: 80
kubectl apply -f networkpolicy-podselector.yaml
2) sample-pod-np1 -> sample-pod-np2 통신 테스트
- sample-pod-np2에 app:np1 레이블을 가진 파드에서 들어오는 인바운드를 오픈하여 정상적으로 통신이 된다.
5-4. 테스트04 - namespaceSelector 사용: 특정 레이블을 가진 네임스페이스에서 들어오는 통신을 허용
1) sample-pod-np3에 ns: default 레이블을 가진 네임스페이스에서 들어오는 인바운드 오픈
# networkpolicy-namespaceselector.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: sample-namespaceselector-ingress-networkpolicy
namespace: nptest
spec:
podSelector:
matchLabels:
app: np3
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
ns: default
ports:
- protocol: TCP
port: 80
kubectl apply -f networkpolicy-namespaceselector.yaml
2) sample-pod-np1 -> sample-pod-np3 통신 테스트
- sample-pod-np3에 ns: default 레이블을 가진 네임스페이스에서 들어오는 인바운드를 오픈하여 정상적으로 통신이 된다.
5-5. 테스트05 - ipBlock 사용: 특정 IP 블록에서 들어오는 통신을 허용
1) sample-pod-np1 파드의 IP 주소에서 들어오는 인바운드 오픈
# networkpolicy-ipblock.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: sample-ipblock-ingress-networkpolicy
namespace: nptest
spec:
podSelector:
matchLabels:
app: np4
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 10.224.0.177/32 # sample-pod-np1의 파드 IP 주소
ports:
- protocol: TCP
port: 80
kubectl apply -f networkpolicy-ipblock.yaml
2) sample-pod-np1 -> sample-pod-np4 통신 테스트
- sample-pod-np1 파드의 IP 주소에서 들어오는 인바운드를 오픈하여 정상적으로 통신이 된다.
※ 번외
LoadBalancer 타입으로 노출시킨 pod는 외부에서 LB IP로 접속하려 해도 pod로 들어오는 인바운드 트래픽이 막혀있기 때문에 접속이 불가능하다. 이를 위해 ipBlock 을 사용하여 node의 IP를 허용해 줘야 한다.
참고
'Container > Kubernetes' 카테고리의 다른 글
[Kubernetes] AKS 클러스터 노드 접속 방법 (0) | 2024.03.07 |
---|---|
[AKS] Azure Key Vault Provider for Secrets Store CSI Driver 테스트 (0) | 2024.01.22 |
[Kubernetes] Docker 및 Container 개념 정리 (1) | 2024.01.04 |
[Kubernetes] Helm을 사용하여 Nginx Ingress 설치 (0) | 2024.01.02 |
[Kubernetes] 서로 다른 Namespace에 있는 서비스로 Nginx Ingress 설정 (0) | 2024.01.02 |