[Kubernetes] NetworkPolicy 적용

안녕하세요? 정리하는 개발자 워니즈입니다. 오랜만에 블로그 포스팅을 합니다. 최근에 Blog Domain이 변경되면서 여러가지 고초를 겪었습니다. 이부분은 다른 포스팅에서 기록하도록 하겠습니다.

이번 포스팅은 Kubernets Networkpolicy에 대해서 정리를 해보려고합니다. 필자가 속한 프로젝트에서는 보안 네트워크(독립망)을 사용하고있어서 이러한 부분에 대해서 고려를 해본적은 없습니다. 하지만 이번에 개발팀으로부터 특정 어플리케이션에 대해서 직접 접근을 통해서 부정한 요청을 할 수 있으니 요청을 차단해달라는 요구사항을 접수하여 해당 내용을 진행하게 됐습니다.

1. Kubernetes NetworkPolicy란 무엇인가요?

Kubernetes NetworkPolicy는 Kubernetes 클러스터 내에서 파드 간 트래픽을 제어하기 위해 사용되는 정책 기능입니다. 이를 통해 특정 파트 또는 파드 그룹 간의 통신을 제한하거나 허용할 수 있습니다.

NetworkPolicy는 파드의 라벨을 기반으로 정책을 적용하며, 트래픽의 소스 및 대상 IP주소, 포트 및 프로토콜 등을 기준으로 통신을 제어할 수 있습니다.

2. Kubernetes 어플리케이션 요구사항

요구사항은 다음과 같습니다.

  • 외부의 사용자는 API-GW로부터만 접근이 가능하고 직접 API혹은 INTERAL-API를 호출할수는 없다.
  • Kubernetes Cluster내에서 다른 팀의 다른 어플리케이션이 직접적으로 API혹은 INTERAL-API를 호출할수는 없다.
  • 어플리케이션에 Inbound 트래픽 허용 설정이 필요하다.

다이어그램은 다음과 같습니다.

  • API Server는 API Gatewa에서 들어오는 inbound 트래픽을 허용합니다.
  • Internal API Server는 API Server & Internal API Gateway에서 들어오는 inbound 트래픽을 허용합니다.

따라서, inbound정책만 허용하고 이외에는 deny시키는 것으로 정책을 정하고 구성을 진행하기로했습니다.

3. Network Policy 설정

Network Policy는 OSI 3 또는 4 계층 수준에서 트래픽 흐름을 제어합니다. 제어할 수 있는 규칙은 다음과 같습니다 .

Ingress

  • Pod Selector : 특정 레이블 셀렉터를 사용하여 트래픽의 송신자 또는 수신자 파드를 선택합니다.
  • Namespace Selector : 특정 네임스페이스에서 트래픽을 허용 또는 거부할 수 있습니다.
  • IP Block : CIDR IP 대역으로, 특정 IP 대역에서만 트래픽이 들어오도록 지정할 수 있습니다.
  • Port : 포트 기반으로 트래픽을 제어합니다.
  • Protocol : TCP, UDP 등의 트래픽 프로토콜을 지정합니다.

Egress

  • IP Block : CIDR IP 대역으로, 특정 IP 대역에서만 트래픽이 나가도록 지정할 수 있습니다.
  • Port : 포트 기반으로 트래픽을 제어합니다.
  • Protocol : TCP, UDP 등의 트래픽 프로토콜을 지정합니다.

위의 요구사항중 inbound(ingress)만 허용하면서 특정 어플리케이션을 whitelist하는 방식으로 구성을 하기로했습니다.

Helm Chart 구성

  • api-server helm chart
├── alpha-values.yaml
├── beta-values.yaml
├── Chart.yaml
├── prod-values.yaml
└── templates
    ├── deployment.yaml
    ├── networkpolicy.yaml   --> 신규 추가
    └── service.yaml

helm chart 구성에서 networkpolicy.yaml 파일을 추가했습니다. 해당 내용을 통해서 values 파일에 지정된 app을 whitelist로 적용하도록 설정하겠습니다.

  • alpha-values.yaml
....
networkPolicies:
  - allowlist:
      - api-gateway
  • networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: {{ .Values.phase }}-{{ .Values.projectName }}
  namespace: {{ .Values.namespace }}
  labels:
    link.service.phase: {{ .Values.phase }}
    link.service.name: {{ .Values.namespace }}
    link.project.name: {{ .Values.projectName }}
spec:
  podSelector:
    matchLabels:
      link.service.phase: {{ .Values.phase }}
      link.service.name: {{ .Values.namespace }}
      link.project.name: {{ .Values.projectName }}
  policyTypes:
  - Ingress
{{- range .Values.networkPolicies }}
  {{- $allowlist := .allowlist }}
  {{- if $allowlist }}
  ingress:
    {{- range $allowlist }}
    - from:
        - podSelector:
            matchLabels:
              link.project.name: {{ . }}
    {{- end }}
    - from:
        - namespaceSelector:
            matchLabels:
              app.kubernetes.io/name: ingress-nginx
  {{- else }}
  ingress:
  - {}
  {{- end }}
{{- end }}

위의 내용을 적용하면, api-server에서는 api-gateway만 inbound(ingress)로 허용하기로했습니다. 따라서 values파일에 지정된 api-gateway만 허용되도록 설정이 됩니다.

        - podSelector:
            matchLabels:
              link.project.name: {{ . }}

설정 부분은 pod의 label을 통해서 지정하게 되어있습니다. link.project.name: api-gateway 가 되는 application의 트래픽만을 허용하겠다는 설정입니다.

4. 요청 테스트

  • API Gateway Server에서 API Server호출시 정상 호출
{"responseCode":"NOT_FOUND","responseData":"type: API or static resource is not found"}
  • API Gateway Sever에서 Internal API 호출시 접근 불가
upstream connect error or disconnect/reset before headers. retried and the latest reset reason: connection failure, transport failure reason: delayed connect error: 110

5. 마치며…

이번 시간에는 Kubernetes Networkpolicy에 대해서 정리를 해보았습니다. Kubernetes를 사용하면서 보안에 대해서 크게 생각을 해본적이 없었습니다. 이번 기회에 특정 inbound 혹은 outbound 트래픽 까지 제어를 할 수 있는 부분에 대해서 알 수 있었고, 이러한 설정을 통해서 내부 시스템들을 좀 더 안정적으로 운영할 수 있다는 것을 깨달았습니다.

다음시간에는 istio에서 설정하는 부분도 정리를 해보도록 하겠습니다. 감사합니다.

6. 참고

Network Policy
K8S 네트워크 Policy Management
Kubernetes 쿠버네티스 – Minikube 환경에서 NetworkPolicy 적용하기

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다