이번 포스팅은 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 트래픽을 허용합니다.
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 등의 트래픽 프로토콜을 지정합니다.
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 적용하기함께 보면 좋은 글
- [Kubernetes] Autoscaling 사용하기
- [Kubernetes] Helm Chartmuseum 사용법
- [DevOps] Kubernetes HPA 실전 적용
- [Kubernetes] K8S Cronjob Monitoring
새 글이 올라오면 Threads @wonizz.ai 에도 올립니다. 팔로우해 두면 피드에서 바로 볼 수 있습니다.