Kubernetes

Network Policy

라온클 2023. 3. 10. 00:55

<목차>

1. Network Policy 요약

2. Network Policy 의 manifest파일 이해하기

2-1. 그림으로 한 눈에 보는 Network Policy

2-2. to 및 from 셀럭터의 동작
2-2-1. and
2-2-2. or

2-3. 포트 범위 지정

2-4. Network Policy 기본 정책
2-4-1. (기본값)모든 Ingress와 모든 Egress 트래픽 허용
2-4-2. 모든 Ingress와 모든 Egress 트래픽 거부
2-4-3. 모든 Ingress 트래픽 거부
2-4-4. 모든 Egress 트래픽 거부
2-4-5. 모든 Ingress 트래픽 허용
2-4-6. 모든 Egress 트래픽 허용


3. 참고 링크


1. Network Policy 요약

<한줄 요약>
쿠버네티스의 네트워크를 레이블, IP주소, 포트 수준에서 제어할 수 있는 네임스페이스 단위의 리소스
 
 
<세줄 요약>
쿠버네티스의 네트워크를 레이블, IP주소, 포트 수준에서 제어할 수 있다.
 
Network Policy를 적용할 Pod를 식별하는 방법으로 Pod, 네임스페이스, IP주소를 조합하여 만들 수 있다.
 
특정 Network Policy를 적용한 Pod는 해당 Network Policy를 제외한 트래픽은 모두 deny한다.

  • Network Policy가 없다면, 네임스페이스의 모든 트래픽이 열려있다.(default-allow)
  • Network Policy가 있다면, 해당 Network Policy의 영향을 받는 Pod는 해당 Network Policy 를 제외하고 나머지 트래픽은 전부 막힌다.(default-deny)

 
<특징>

  • Network Policy는 Pod에만 적용된다.
  • 쿠버네티스 클러스터에는 Network Policy가 설정되어 있지 않은 것이 기본값이다.

 
 
 

 

2. Network Policy 의 manifest파일 이해하기

<Network Policy의 spec 구성요소>

policyTypes

  • Network Policy의 트래픽 종류를 지정한다.

 
 podSelector

  • Network Policy가 적용될 Pod를 지정한다.

 
 egress:

  • 아웃바운드 트래픽 허용 정책을 정의한다.
  • egress 항목이 {}과 같이 비어있으면 모두 허용이다.

 
ingress:

  • 인바운드 트래픽 허용 정책을 정의한다.
  • ingress 항목이 {}과 같이 비어있으면 모두 허용이다.





<Network Policy 세가지 식별자(identifier) 종류>

podSelector

  • 특정 레이블을 가진 Pod에서 들어오는/나가는 통신 허용

 
namespaceSelector

  • 특정 네임스페이스에 있는 Pod에서 들어오는/나가는 통신 허용
  • 특정 레이블을 가진 네임스페이스의 모든 Pod들을 대상으로 적용한다.

 
ipBlock

  • 특정 CIDR에서 들어오는/나가는 통신 허용

 
 
[🍯참고] ipBlock식별자에 대해 알아두면 좋은 점

  • ipBlock식별자는 주로 쿠버네티스 클러스터 '외부' 네트워크의 트래픽을 제어하는 방법으로 사용된다. Pod의 IP는 임시적이고 예측할 수 없기 때문이다
  • ingress와 egress의 CIDR는 동일하지 않아도 된다.(애초에 별도 정책입니다. 헷갈리지 맙시다!)




[🍯참고] namespace에 레이블 붙이는 방법

# 코드
kubectl label namespace <namespace_name> <label_key>=<label_value>

# 예시
kubectl label namespace my-namespace env=production

# 특정 namespace의 레이블 보는 방법
kubectl describe namespace my-namespace

 
 
 
 
 

2-1. 그림으로 한 눈에 보는 Network Policy 

 
 
manifest파일의 세부 설명을 그림으로 표현하면 다음과 같다.

 
 
 
코드

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  policyTypes:
    - Ingress
    - Egress
  podSelector:
    matchLabels:
      role: db
  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

 
 
 
 
 
 

2-2. to 및 from 셀렉터의 동작

from(혹은 to) 하위 항목들에 "-가 여러개 붙느냐, 한개 붙느냐"에 따라서 조건을 표현하는 or 와 and가 달라진다.
 

2-2-1. and

from(혹은 to) 하위 항목들에 -가 한개 붙으면 and다.
다음은 and에 해당되는 예시다.
아래 두 조건을 모두 충족하는 ingress 통신을 허용한다.

  • namespaceSelector: 이름이 'dev-2'인 네임스페이스에 속한 Pod
  • podSelector: 'role: frontend'레이블을 가진 Pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: and-networkpolicy
  namespace: dev-1
spec:
  policyTypes:
    - Ingress
  podSelector:
    matchLabels:
      role: db
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: dev-2
          podSelector:
            matchLabels:
              role: frontend
      ports:
        - protocol: TCP
          port: 6379

 

 

and 조건을 그림으로 표현하면 다음과 같다.

'-'로 묶어서 and조건을 만들 수 있다.


 

2-2-2. or

from(혹은 to) 하위 항목들에 -가 여러개 붙으면 or 이다.
다음은 or에 해당되는 예시다.

아래 두 조건 중 1개라도 충족하면 ingress 통신을 허용한다.

  • namespaceSelector: 이름이 'dev-2'인 네임스페이스에 속한 Pod
  • podSelector: 'role: frontend'레이블을 가진 Pod
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: or-networkpolicy
  namespace: dev-1
spec:
  policyTypes:
    - Ingress
  podSelector:
    matchLabels:
      role: db
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: dev-2
        - podSelector:
            matchLabels:
              role: frontend
      ports:
        - protocol: TCP
          port: 6379

 
or 조건을 그림으로 표현하면 다음과 같다.

각 규칙마다 '-'를 붙여서 or조건을 만들 수 있다.


 

2-3. 포트 범위 지정

Network Policy에 특정 포트 번호 1개가 아닌, 포트 범위를 전제조건으로 지정할 수 있다.
 
다음은 "대상 포트가 32000에서 32768 사이에 있는 경우, 네임스페이스 default 에 레이블이 role=db 인 모든 파드가 TCP를 통해 10.0.0.0/24 범위 내의 모든 IP와 통신하도록 허용한다." 를 나타내는 Network Policy예시다.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: multi-port-egress
  namespace: dev
spec:
  policyTypes:
  - Egress
  podSelector:
    matchLabels:
      role: db
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 32000
      endPort: 32768

 
 
이를 그림으로 나타내면 다음과 같다.(초록색을 봐주세욥!)

 
 
 
 
 
 

2-4. Network Policy 기본 정책

2-4-1. (기본값) 모든 Ingress와 모든 Egress 트래픽 허용

"podSelector: {}" 라는 것은 모든 Pod에 적용된다는 뜻이다.

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

 
 
 

2-4-2. 모든 Ingress와 모든 Egress 트래픽 거부

policyTypes은 Ingress, Egress지만,
허용하는 조건을 명시하는 ingress와 egress 항목 모두 없으므로, 허용되는 트래픽이 인바운드, 아웃바운드 모두 없다.

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

 
 
 

2-4-3. 모든 Ingress 트래픽 거부

policyTypes은 Ingress지만, 
허용하는 조건을 명시하는 ingress항목이 없으므로, 허용되는 인바운드 트래픽이 없음을  알 수 있다.

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

 
 
 
 

2-4-4. 모든 Egress 트래픽 거부

policyTypes은 Egress지만, 
허용하는 조건을 명시하는 egress항목이 없으므로, 허용되는 아웃바운드 트래픽이 없음을  알 수 있다.

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

 
 
 

2-4-5. 모든 Ingress 트래픽 허용

policyTypes가 Ingress이고, 
허용하는 조건을 명시하는 ingress항목이 {}으로 특정한 조건이 없다고 나와있으므로(=모든 조건 OK) 
모든 Ingress 트래픽을 허용함을 알 수 있다.

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

 
 
 

2-4-6. 모든 Egress 트래픽 허용

policyTypes가 Egress이고, 
허용하는 조건을 명시하는 egress항목이 {}으로 특정한 조건이 없다고 나와있으므로(=모든 조건 OK) 
모든 Ingress 트래픽을 허용함을 알 수 있다.

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

 
 
 
 

3. 참고 링크

공식 문서 <Network Policy>
https://kubernetes.io/ko/docs/concepts/services-networking/network-policies/ 
 
공식 문서 <네트워크 폴리시(Network Policy) 선언하기>
https://kubernetes.io/ko/docs/tasks/administer-cluster/declare-network-policy/ 
 
GitHub <Network Policies 샘플 YAML file 레시피>
https://github.com/ahmetb/kubernetes-network-policy-recipes 
 
책 <핵심만 콕! 쿠버네티스>
https://www.yes24.com/Product/Goods/92426926 
 
GitHub <핵심만 콕! 쿠버네티스>
https://github.com/bjpublic/core_kubernetes/tree/master/chapters/13 
 
강의 <그림으로 배우는 쿠버네티스>
https://www.inflearn.com/course/lecture?courseSlug=%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4&unitId=85699 
 
GitHub <그림으로 배우는 쿠버네티스>
https://github.com/sysnet4admin/_Lecture_k8s_learning.kit/tree/main/ch8/8.6