[CKA] NetworkPolicy
NetworkPolicy의 핵심 개념과 구성 방법, 실습 풀이를 정리합니다.
Network Policy
- Ingress는 입구이자 수신하는 것이며 인바운드이다.
- Egress는 출구이자 송신하는 것이며 아웃바운드이다.
Kubernetes network security
파드와 서비스 세트를 호스팅하는 노드 집합의 클러스터가 있으며 노드마다 IP 주소가 있고 파드마다 서비스도 존재합니다.
또한 쿠버네티스 네트워킹의 전제조건은 다음과 같습니다.
1. 어떤 솔루션을 구현하든 파드가 서로 통신할 수 있어야 한다.
이 네트워크 솔루션에서 모든 파드가 가상 사설 네트워크에 있고 IP나 파드 이름 또는 서비스 이름을 통해
쿠버네티스 클러스터 내 노드를 가로질러 기본값으로 상호간 통신이 가능합니다.
쿠버네티스는 기본값으로 모든 허용 규칙과 함께 구성됩니다.
따라서 클러스터 내의 어떤 파드나 서비스가 서로에게 접근할 수 있습니다.
우리는 파드를 통해 앱의 각 구성요소(프론트엔드 웹 서버, 백엔드 API 서버, DB)를 배포합니다.
또한 이전부터 확인해본 바로, 쿠버네티스 클러스터 내에서 세 개의 파드는 서로 통신할 수 있습니다.
하지만 이때 보안을 위해 프론트엔드 웹 서버가 데이터베이스 서버와 직접적으로 통신이 되면 안되는 케이스에서는 Network Policy를 설정해야합니다.
Network Policy은 쿠버네티스 네임스페이스에 있는 또 다른 객체로 파드, 레플리카 셋이나 서비스 처럼 하나 이상의 파드에 네트워크 정책을 연결할 수 있습니다.
아래 이미지의 경우에는 5000번 포트의 API 파드에서만 Ingress 트래픽을 허용합니다.
NetworkPolicy가 특정 Pod를 선택하면 policyTypes에 지정된 방향의 트래픽이 격리되고, 해당 방향에서는 정책이 허용한 연결만 통과합니다.
혹은 replicaset이나 service를 파드와 matchlabels, labels를 통해 링크하는 동일한 방식을 사용할 수 있습니다.
일반적인 Network Policy의 정의 파일은 다음과 같습니다.
Ingress만 지정한 정책은 수신 트래픽만 격리하며 Egress는 그대로 유지됩니다. 송신 트래픽도 제한하려면 policyTypes와 egress 규칙을 함께 구성합니다.
**또한 네트워크 정책은 네트워크 솔루션에 의해 실행된다. 모든 네트워크 솔루션이 네트워크 정책을 지원하는 것은 아니며 **네트워크 정책을 지원하는지 확인하기 위해 공식 문서를 항상 참조해보길 권장합니다.
네트워크 정책을 지원하지 않는 솔루션으로 구성된 클러스터에서도 정책을 만들 순 있지만 강요되는 것은 아니다.
Developing network policies
백엔드 API 파드를 제외한 다른 소스로부터 데이터베이스 파드로의 트래픽을 허용해서는 안됩니다.
만약 들어오는 트래픽을 허용하면 그 트래픽에 대한 응답이나 회신이 자동으로 허용되는 흔한 클라이언트-서버 구조이므로 응답, 회신에 대한 것은 따로 규정하지 않아도 됩니다.
위 이미지처럼 ingress에 조건과 받는 포트를 명시합니다.
네트워크 정책은 기본으로 metadata에 지정된 namespace에 있는 파드(지정된 파드와 동일한 네임스페이스에 있는 파드)만 지정할 수 있지만, 다른 네임스페이스의 파드에 도달하고 싶다면 namespaceSelector 영역에 네임스페이스를 지정해야합니다.
아래와 같습니다.
podSelector 없이 namespaceSelector만 지정할 수도 있습니다. 이러한 경우 지정한 네임스페이스 내의 모든 파드만 데이터베이스 파드에 도달할 수 있습니다.
따라서 정리하면 특정한 파드, 네임스페이스, ip 주소를 지정하기 위해 podSelector, namespaceSelector, ipBlock 영역을 사용하면 된다.
이러한 것들은 개별적인 규칙으로 통과될 수도 있고 하나의 규칙의 일부로 함께 통과될 수도 있습니다.
2개의 조건을 하나의 규칙으로 설정될 수 있으며, 두 개의 규칙을 추가할 수 있습니다.
반대로 DB 파드에서 백업 서버로 푸쉬해야 한다면 데이터베이스 파드에서 외부 백업 서버로 네트워크를 허용해야 합니다. policyTypes에 Egress를 추가하고 데이터베이스 파드에서 외부 백업 서버로 통신을 허용하는 egress 규칙을 추가해야 한다.
kubectl get networkpolicies
- name=payroll인 파드에게 internal 파드에서 오는 8080 트래픽만 허용한다는 의미입니다.
k describe networkpolicies.networking.k8s.io payroll-policy
Name: payroll-policy
Namespace: default
Created on: 2024-10-24 13:15:02 +0000 UTC
Labels: <none>
Annotations: <none>
Spec:
PodSelector: name=payroll
Allowing ingress traffic:
To Port: 8080/TCP
From:
PodSelector: name=internal
Not affecting egress traffic
Policy Types: Ingress
파드간 통신은 서비스명으로 통신합니다.
k get svc
들여쓰기 매우 헷갈리니 주의하자.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: internal-policy
namespace: default
spec:
podSelector:
matchLabels:
name: internal
policyTypes:
- Egress
- Ingress
ingress:
- {}
egress:
- to:
- podSelector:
matchLabels:
name: mysql
ports:
- protocol: TCP
port: 3306
- to:
- podSelector:
matchLabels:
name: payroll
ports:
- protocol: TCP
port: 8080
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP