티스토리 뷰

728x90
반응형

개요

Kubernetes는 Pod 간 또는 다른 네트워크와 통신할 수 있도록 네트워크 Policy를 정의할 수 있다.
Kubernetes는 네티워크 정책을 지정하기 위해 NetworkPolicy 리소스를 사용하며, Label을 사용하여 Pod를 지정하고 해당 Pod로 유입되는 모든 네트워크 트래픽을 구성한다.
네트워크 정책은 네트워크 플러그인으로 구현된다. Kuberentes 는 CNI와 Kubenet 네트워크 플러그인을 지원한다.

Kubernete를 통해 구현되는 Pod는 기본으로 네트워크가 격리되지 않는다. 즉 Pod는 모든 네트워크에서 들어오는 유입을 허용한다.

이와 같이 유입을 모두 허용하는 Pod는 불 특정 요청에 노출되고 외부로 부터 침입 당할 수 있는 상태가 되어 보안에 유협받을 수 있다. 따라서 Pod를 구성할 경우 정책에 따라 NetworkPolicy를 정의하고 관리해야 한다. 네임스페이스에 특정 Pod를 선택하는 NetworkPolicy가 있으면 해당 Pod는 NetworkPolicy에서 허용하지 않는 모든 연결을 차단한다.

NetworkPolicy

NetworkPolicy 리소스는 다음과 같이 구성된다.

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

NetworkPolicy를 구성하는 spec을 통해 해당 네임스페이스 내의 특정 네트워크 정책을 정의할 수 있다.


- podSelector : NetworkPolicy 에는 정책이 적용되는 Pod 그룹을 선택하는 podSelector 가 포함된다. 위 예시와 같이 "role=db" 레이블이 있는 Pod를 선택한다. podSelector가 비어있을 경우 네임스페이스의 모든 파드를 선택한다.

- policyTypes : 각 NetworkPolicy 에는 Ingress, Egress 또는 두 가지 모두를 포함할 수 있는 policyTypes 목록이 포함된다. policyTypes 필드는 podSelector에 의해 선택된 Pod에 대한 Ingress 트래픽 정책, 선택한 Pod에 대한 Egress 트래픽 정책 또는 두 가지 모두에 지정된 정책의 적용 여부를 나타낸다.

- ingress : 각 NetworkPolicy 에는 화이트리스트 ingress 규칙 목록이 포함될 수 있다. 각 규칙은 from과 ports 부분과 모두 일치하는 트래픽을 허용한다.

[from]
ipBlock은 CIDR 대역을 지정하며, 특정 IP대역에서만 트래픽이 유입되도록 제한한다.
podSelector와 namespaceSelector는 특정 Label을 포함하는 Object에서 요청되는 트래픽만 유입하는 방법이다. podSelector는 해당 label을 포함하는 pod의 요청만 허용하며, namespaceSelector는 해당 namespace에서 유입되는 요청만 허용한다. 이를 기반으로 개발, 검증, 운영 환경을 구분하여 설계하거나, 배포방식의 다변화를 가져갈 수 있다.
[ports]
protocol : 허용되는 프로토콜의 종류
port : 유입이 허용되는 포트

위를 기반으로 subnet 환경을 구성하듯 유입되는 네트워크 트래픽 규칙을 유연하게 관리할 수 있다.

- egress : 각 NetworkPolicy 에는 화이트리스트 egress 규칙이 포함될 수 있다. 각 규칙은 to 와 ports 부분과 모두 일치하는 트래픽을 허용한다.

[to]
ipBlock은 CIDR 대역을 지정하며, 특정 IP 대역으로만 트래픽을 반환하도록 제한한다.
[ports]
protocol : 반환되는 프로토콜의 종류
port : 반환이 허용되는 포트

위를 기반으로 반환되는 네트워크 트래픽 규칙을 유연하게 관리할 수 있다.


즉, "myproject라는 label을 갖고 있는 namespace의 frontend라는 label을 갖고 있는 Pod 그룹은 default namespace의 role=db라는 label을 갖고 있는 pod로 접근할 수 있다."고 해석할 수 있다.

NetworkPolicy 동작방식

예시의 NetworkPolicy는 다음과 같이 동작한다고 볼 수 있다.
1) ingress는 "role=db" label을 사용하는 "default" 네임스페이스의 모든 pod에 대해서 TCP 포트 6397로의 연결을 허용한다. 유입을 허용 할 대상은 다음과 같다.


- "role=frontend" label을 갖는 "default" namespace에 배치된 모든 pod 
- "project=myproject" label을 갖는 namespace에 배치된 모든 pod 
- 172.17.0.0 ~ 172.17.0.255 와 172.17.2.0 ~ 172.17.255.255의 범위를 가지는 IP 주소
(예: 172.17.0.0/16 전체에서 172.17.1.0/24 를 제외한 ip address)


2) egress는 "role=db" 레이블이 있는 "default" 네임스페이스의 모든 파드에서 TCP 포트 5978의 CIDR 10.0.0.0/24 로의 연결을 허용한다.
이를 기반으로 다음과 같은 동작 방식을 예상할 수 있다.

1) Default Namespace의 role=frontend label을 갖고 있는 service #1의 요청은 정상적으로 유입되지만, 같은 Namespace 내 role=backend label을 갖고 있는 service #2의 요청은 차단된다.
2) Network Namespace의 project=myproject label을 갖고 있는 service의 요청은 모두 정상적으로 유입된다.
물론 위의 예시는 Service to Service의 관계도를 설명하지만, External Client의 경우도 동일하게 처리된다. 이를 통해 클라이언트의 IP 대역을 제한하고, Egress를 통해 Outbound 트래픽을 관리할 수 있다.

NetworkPolicy 제어방식

다음으로 NetworkPolicy를 통해 관리할 수 있는 다양한 트래픽 제어 방식에 대해 살펴보자.

1) 모든 Ingress 트래픽 거부

모든 파드를 대상으로 하지만 해당 파드에 대한 Ingress 트래픽은 허용하지 않는 NetworkPolicy를 생성해서 네임스페이스에 대한 차단 정책을 생성한다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}
  policyTypes:
  - Ingress

2) 모든 Ingress 트래픽 허용
네임스페이스의 모든 파드에 대한 모든 트래픽을 허용하려는 경우 해당 네임스페이스의 모든 트래픽을 명시적으로 허용하는 정책을 만들어야 한다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-ingress
spec:
  podSelector: {}
  ingress:
  - {}
  policyTypes:
  - Ingress

3) 모든 egress 트래픽 거부
모든 파드를 선택하지만, 해당 파드의 이그레스 트래픽을 허용하지 않는 NetworkPolicy를 생성해서 네임스페이스에 대한 egress 격리 정책을 생성할 수 있다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress

4) 모든 egress 트래픽 허용
네임스페이스의 모든 파드의 모든 트래픽을 허용하려면 해당 네임스페이스에서 모든 이그레스 트래픽을 명시적으로 허용하는 정책을 생성할 수 있다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-egress
spec:
  podSelector: {}
  egress:
  - {}
  policyTypes:
  - Egress

5) 모든 인그레스와 모든 이그레스 트래픽 거부
해당 네임스페이스에 아래의 NetworkPolicy를 만들어 모든 ingress와 egress 트래픽을 방지하는 네임스페이스에 대한 정책을 만들 수 있다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

결론

이와 같이 Kubernetes는 NetworkPolicy를 활용하여 Pod로의 유입과 반환에 대한 트래픽을 관리할 수 있다. NetworkPolicy를 활용하여 환경을 구분하여 설계하거나, 배포 전략을 새우는등 다양한 적용 방안을 고려하면서 보안 역시 강화할 수 있는 방안을 고려해야 할 것이다.

728x90
반응형