Network Policy
Ingress & Egress
각 애플리케이션(서버)를 기준으로 들어오는 트래픽을 Ingress라고 하고, 나가는 트래픽을 Egress라고 한다. 예를 들어 아래와 같은 구조로 애플리케이션이 통신한다고 가정해보자. Web server를 기준으로 사용자로부터 오는 트래픽은 Ingress이고, API Server로 나가는 트래픽은 Egress이다.
Network Security
아래 네트워크 솔루션에서는 노드들을 가로지르는 virtual private network에 의해 모든 파드들이 IP 또는 Pod name 또는 서비스들에 의해 기본적으로 서로 닿을 수 있다.
쿠버네티스에서 네트워킹을 위한 전제 조건 중 하나는 어떠한 솔루션을 구현하든 경로(routes)와 같은 추가 설정을 구성할 필요 없이 파드가 서로 통신할 수 있어야 한다는 것이다.
쿠버네티스는 기본적으로 클러스터내의 파드에서 다른 파드나 서비스로의 트래픽을 허용하는 ‘All Allow’ 규칙을 가진다.
이렇게 모든 파드들끼리 기본적으로 통신할 수 있는 환경을 ‘Ingress & Egress’ 섹션에서 보이는 이미지 구조(Web Server - API Server - DB 구조)에 적용한다고 가정해보자.
- 보안을 위해 웹 서버 - DB 간에는 직접 통신할 수 없게 해달라고 요청이 들어왔다고 가정해보자. 이런 경우에는 DB서버로는 API Server에서 오는 트래픽만 허용하는 네트워크 정책(Network Policy)을 구현해야 한다.
Network Policy object
`ingress[*].from[*]` 하위의 복수의 룰들은 OR 연산자와 같이 작동된다. (트래픽은 규칙들 중 하나라도 만족하면 통과한다.) 하지만 룰 내부에서의 여러 selector들은 AND 연산자와 같이 작동하여, 룰 내부의 모든 조건을 만족해야 해당 룰을 만족한다고 간주한다.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy # network policy name
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
name: api-pod # pod-labels
ports:
- protocol: TCP
port: 3306
Network Policy는 Name space 내에 존재하는 오브젝트로, 하나 혹은 그 이상의 파드와 연결할 수 있다.
Network Policy는 Whitelist 방식으로, 명시된 타겟만 허용되고, 나머지는 모두 차단된다.
- 허용한 트래픽(ingress)에 대한 응답(egress)는 자동으로 허용된다.
- 특정 파드 등에서 오는 ingress 트래픽을 받고자할 뿐만 아니라 외부로 새로운 egress 트래픽(call)을 보내고자 할 때는 둘에 대한 룰을 모두 작성
Network Policy 내부에는 규칙들(rules)을 정의할 수 있다. 예를 들어 위의 경우에는 DB 파드와 연결하되, API Server에서 3306 포트로 들어오는 트래픽을 허용하는 규칙을 생성하면, 다른 트래픽은 모두 거부된다.
파드와 연결하기 위해서 `Selectors` 를 사용한다.
- 파드의 `metadata.labels` 에서 사용한 라벨을 Network Policy manifest file의 `podSelector.matchLabels` 에 명시한다.
`policyTypes` 요소로 허용하는 타입의 트래픽을 명시한다. (`ingress` 와 `egress` 모두 또는 둘 중 하나)
- 다음의 경우 Ingress 타입만 해당 파드/통신프로토콜/포트에 한정되어 허용되고, Egress 타입 통신은 모두 허용된다.
policyTypes:
- Ingress
ingress:
- from:
- podSelectors:
matchLabels:
name: api-pod
ports:
- protocol: TCP
port: 3306
- Network Policy는 쿠버네티스에 구현된 네트워크 솔루션에 의해 시행되며, 모든 네트워크 솔루션이 지원하는 것은 아니다. (Network Policy를 지원하지 않는 Network Solution 을 사용하도록 구성된 클러스터 내에서는 Network Policy를 생성할 수는 있지만 시행되지 않는다.)
- Cf. 지원하는 Network Solution
지원하는 Network Solution | 지원하지 않는 Network Solution |
kube-router Calico Romana Weave-net |
Flannel |
클러스터내의 다른 Namespace에 같은 라벨(들)을 쓰는 Pod가 있는 경우
- 위의 `.yaml` 파일대로 생성할 경우 해당 Network Policy를 연결하는 Pod는 name: api-pod 라는 라벨과 매칭되는 모든 Namespace의 모든 Pod로 부터 오는 트래픽을 허용한다.
- 이를 해결하기 위해서는 `podSelector` 필드 외에도 `namespaceSeletor` 필드를 추가한다.
policyTypes:
- Ingress
ingress:
- from:
- podSeletor:
matchLabels:
name: api-pod
namespaceSelector:
matchLabels:
name: prod
ports:
protocol: TCP
port: 3306
특정 Namespace 내에 있는 모든 Pod들에 대한 ingress 트래픽을 허용할 경우
- `podSelector` 필드를 사용하지 않고, `namespaceSelector` 필드만 사용한다.
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
[key:value]
쿠버네티스 클러스터 밖에 백업 서버가 존재하는 경우(클러스터 내에 deploy되지 않은 경우)
- 이 경우에는 백업 서버가 클러스터 내에 존재하는 파드가 아니기 때문에 `podSelector`, `namespaceSelector` 필드가 적용되지 않는다. 특정 ip 범위를 가지고 룰을 생성하기 위해서는 `ipBlock` 필드를 사용할 수 있다.
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 192.168.5.10/32
만약 특정 파드(여기서는 DB Pod로 가정) 내에 에이전트가 있어, 이것이 클러스터 외부의 백업 서버로 백업 데이터를 전송한다고 가정해보자. 이 경우 egress rule이 필요하다.
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
name: api-pod
ports:
- protocol: TCP
port: 3306
egress:
- to:
- ipBlock:
cidr: 192.168.5.10/32
ports:
- protocol: TCP
port: 80
'Kubernetes' 카테고리의 다른 글
k8s) Storage - 2. Storage Class (0) | 2024.03.11 |
---|---|
k8s) Storage - 1. Volume : PV(Persistent Volume), PVC(Persistent Volume Claim) (0) | 2024.03.11 |
k8s) Security - 4. Image Security, Security Contexts, (0) | 2024.03.10 |
k8s) Security - 3. Authorization(RBAC, Cluster Role, Service Account) (0) | 2024.03.10 |
k8s) Security - 2. KubeConfig, API Groups (0) | 2024.03.10 |