From a3038a75c8031f4b43917570bbc1b6df9e994712 Mon Sep 17 00:00:00 2001 From: Markus Pesch Date: Fri, 14 Feb 2025 17:50:56 +0100 Subject: [PATCH] feat(networkPolicies): template custom network policies --- README.md | 85 ++++++++++++- .../_networkPolicies.tpl | 19 +++ .../networkPolicies.yaml | 36 ++++++ unittests/networkPolicies/default.yaml | 118 ++++++++++++++++++ values.yaml | 78 +++++++++++- 5 files changed, 326 insertions(+), 10 deletions(-) create mode 100644 templates/prometheus-postgres-exporter/_networkPolicies.tpl create mode 100644 templates/prometheus-postgres-exporter/networkPolicies.yaml create mode 100644 unittests/networkPolicies/default.yaml diff --git a/README.md b/README.md index 350dc5e..6bbc360 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,75 @@ deployment: - postgres ``` +### Network policies + +Network policies can only take effect, when the used CNI plugin support network policies. The chart supports no custom +network policy implementation of CNI plugins. It's support only the official API resource of `networking.k8s.io/v1`. + +The object networkPolicies can contains multiple networkPolicy definitions. There is currently only one example +predefined - it's named `default`. Further networkPolicy rules can easy be added by defining additional objects. For example: + +> [!NOTE] +> The structure of each custom network policy must be equal like that of default. For this reason don't forget to define +> `annotations`, `labels` and the other properties as well. + +```yaml +networkPolicies: + enabled: false + default: {} + my-custom-network-policy: {} +``` + +The example below is an excerpt of the `values.yaml` file. The network policy `default` contains ingress rules to allow +incoming traffic from Prometheus. Additionally two egress rules are defined, to allow the application outgoing access to +the internal running DNS server `core-dns` and the external running postgres database listen on `10.14.243.12`. + +> [!IMPORTANT] +> Please keep in mind, that the namespace and pod selector labels can be different from environment to environment. For +> this reason, there is are not default network policy rules defined. + +```yaml +networkPolicies: + enabled: true + default: + enabled: true + annotations: {} + labels: {} + policyTypes: + - Egress + - Ingress + egress: + - to: + - ipBlock: + cidr: 10.14.243.12/32 + ports: + - port: 5432 + protocol: TCP + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + podSelector: + matchLabels: + k8s-app: kube-dns + ports: + - port: 53 + protocol: TCP + - port: 53 + protocol: UDP + ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: monitoring + podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + ports: + - port: http + protocol: TCP +``` + ## Parameters ### Global @@ -248,7 +317,7 @@ deployment: | `deployment.replicas` | Number of replicas for the postgres-exporter deployment. | `1` | | `deployment.restartPolicy` | Restart policy of the postgres-exporter deployment. | `""` | | `deployment.securityContext` | Security context of the postgres-exporter deployment. | `{}` | -| `deployment.strategy.type` | Strategy type - `Recreate` or `Rollingupdate`. | `Rollingupdate` | +| `deployment.strategy.type` | Strategy type - `Recreate` or `RollingUpdate`. | `RollingUpdate` | | `deployment.strategy.rollingUpdate.maxSurge` | The maximum number of pods that can be scheduled above the desired number of pods during a rolling update. | `1` | | `deployment.strategy.rollingUpdate.maxUnavailable` | The maximum number of pods that can be unavailable during a rolling update. | `1` | | `deployment.terminationGracePeriodSeconds` | How long to wait until forcefully kill the pod. | `60` | @@ -283,11 +352,17 @@ deployment: | --------------------- | ---------------------- | ----- | | `podDisruptionBudget` | Pod disruption budget. | `{}` | -### Network +### networkPolicies NetworkPolicies -| Name | Description | Value | -| ----------------- | ------------------------------------------------------------------------------------------------------------------ | ----- | -| `networkPolicies` | Deploy network policies based on the used container network interface (CNI) implementation - like calico or weave. | `{}` | +| Name | Description | Value | +| ------------------------------------- | ----------------------------------------------------------------------------------------------------- | ------- | +| `networkPolicies.enabled` | Enable network policies in general. | `false` | +| `networkPolicies.default.enabled` | Enable the network policy for accessing the application by default. For example to scape the metrics. | `false` | +| `networkPolicies.default.annotations` | Additional network policy annotations. | `{}` | +| `networkPolicies.default.labels` | Additional network policy labels. | `{}` | +| `networkPolicies.default.policyTypes` | List of policy types. Supported is ingress, egress or ingress and egress. | `[]` | +| `networkPolicies.default.egress` | Concrete egress network policy implementation. | `[]` | +| `networkPolicies.default.ingress` | Concrete ingress network policy implementation. | `[]` | ### Prometheus diff --git a/templates/prometheus-postgres-exporter/_networkPolicies.tpl b/templates/prometheus-postgres-exporter/_networkPolicies.tpl new file mode 100644 index 0000000..f940ade --- /dev/null +++ b/templates/prometheus-postgres-exporter/_networkPolicies.tpl @@ -0,0 +1,19 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* annotations */}} + +{{- define "prometheus-postgres-exporter.networkPolicies.annotations" -}} +{{ include "prometheus-postgres-exporter.annotations" .context }} +{{- if .networkPolicy.annotations }} +{{ toYaml .networkPolicy.annotations }} +{{- end }} +{{- end }} + +{{/* labels */}} + +{{- define "prometheus-postgres-exporter.networkPolicies.labels" -}} +{{ include "prometheus-postgres-exporter.labels" .context }} +{{- if .networkPolicy.labels }} +{{ toYaml .networkPolicy.labels }} +{{- end }} +{{- end }} diff --git a/templates/prometheus-postgres-exporter/networkPolicies.yaml b/templates/prometheus-postgres-exporter/networkPolicies.yaml new file mode 100644 index 0000000..19df846 --- /dev/null +++ b/templates/prometheus-postgres-exporter/networkPolicies.yaml @@ -0,0 +1,36 @@ +{{- if .Values.networkPolicies.enabled }} +{{- range $key, $value := .Values.networkPolicies -}} +{{- if and (not (eq $key "enabled")) $value.enabled }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + {{- with (include "prometheus-postgres-exporter.networkPolicies.annotations" (dict "networkPolicy" $value "context" $) | fromYaml) }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (include "prometheus-postgres-exporter.networkPolicies.labels" (dict "networkPolicy" $value "context" $) | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ printf "%s-%s" (include "prometheus-postgres-exporter.fullname" $ ) $key }} + namespace: {{ $.Release.Namespace }} +spec: + podSelector: + matchLabels: + {{- include "prometheus-postgres-exporter.pod.selectorLabels" $ | nindent 6 }} + {{- with $value.policyTypes }} + policyTypes: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with $value.egress }} + egress: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with $value.ingress }} + ingress: + {{- toYaml . | nindent 2 }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/unittests/networkPolicies/default.yaml b/unittests/networkPolicies/default.yaml new file mode 100644 index 0000000..b8c5c85 --- /dev/null +++ b/unittests/networkPolicies/default.yaml @@ -0,0 +1,118 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: NetworkPolicies template (basic) +release: + name: prometheus-postgres-exporter-unittest + namespace: testing +templates: +- templates/prometheus-postgres-exporter/networkPolicies.yaml +tests: +- it: Skip networkPolicies in general disabled. + set: + networkPolicies.enabled: false + asserts: + - hasDocuments: + count: 0 + +- it: Skip networkPolicy 'default' when disabled. + set: + networkPolicies.enabled: true + networkPolicies.default.enabled: false + asserts: + - hasDocuments: + count: 0 + +- it: Loop over networkPolicies + set: + networkPolicies.enabled: true + networkPolicies.default.enabled: false + networkPolicies.nginx.enabled: true + networkPolicies.prometheus.enabled: true + asserts: + - hasDocuments: + count: 2 + +- it: Template networkPolicy 'default' without policyTypes, egress and ingress configuration + set: + networkPolicies.enabled: true + networkPolicies.default.enabled: true + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + name: prometheus-postgres-exporter-unittest-default + namespace: testing + - notExists: + path: metadata.annotations + - equal: + path: metadata.labels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: prometheus-postgres-exporter + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: prometheus-postgres-exporter-0.1.0 + - equal: + path: spec.podSelector.matchLabels + value: + app.kubernetes.io/instance: prometheus-postgres-exporter-unittest + app.kubernetes.io/name: prometheus-postgres-exporter + - notExists: + path: spec.policyTypes + - notExists: + path: spec.egress + - notExists: + path: spec.ingress + +- it: Template networkPolicy 'default' with policyTypes, egress and ingress configuration + set: + networkPolicies.enabled: true + networkPolicies.default.enabled: true + networkPolicies.default.policyTypes: + - Egress + - Ingress + networkPolicies.default.ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: khv-production + podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + networkPolicies.default.egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: database + podSelector: + matchLabels: + app.kubernetes.io/name: oracle + asserts: + - equal: + path: spec.policyTypes + value: + - Egress + - Ingress + - equal: + path: spec.egress + value: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: database + podSelector: + matchLabels: + app.kubernetes.io/name: oracle + - equal: + path: spec.ingress + value: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: khv-production + podSelector: + matchLabels: + app.kubernetes.io/name: prometheus diff --git a/values.yaml b/values.yaml index 49de4d0..c11149d 100644 --- a/values.yaml +++ b/values.yaml @@ -224,11 +224,11 @@ deployment: securityContext: {} # fsGroup: 2000 - ## @param deployment.strategy.type Strategy type - `Recreate` or `Rollingupdate`. + ## @param deployment.strategy.type Strategy type - `Recreate` or `RollingUpdate`. ## @param deployment.strategy.rollingUpdate.maxSurge The maximum number of pods that can be scheduled above the desired number of pods during a rolling update. ## @param deployment.strategy.rollingUpdate.maxUnavailable The maximum number of pods that can be unavailable during a rolling update. strategy: - type: "Rollingupdate" + type: "RollingUpdate" rollingUpdate: maxSurge: 1 maxUnavailable: 1 @@ -311,9 +311,77 @@ podDisruptionBudget: {} # maxUnavailable: 1 # minAvailable: 1 -## @section Network -## @param networkPolicies Deploy network policies based on the used container network interface (CNI) implementation - like calico or weave. -networkPolicies: {} +## @section networkPolicies NetworkPolicies +## @param networkPolicies.enabled Enable network policies in general. +networkPolicies: + enabled: false + + ## @param networkPolicies.default.enabled Enable the network policy for accessing the application by default. For example to scape the metrics. + ## @param networkPolicies.default.annotations Additional network policy annotations. + ## @param networkPolicies.default.labels Additional network policy labels. + ## @param networkPolicies.default.policyTypes List of policy types. Supported is ingress, egress or ingress and egress. + ## @param networkPolicies.default.egress Concrete egress network policy implementation. + ## @skip networkPolicies.default.egress Skip individual egress configuration. + ## @param networkPolicies.default.ingress Concrete ingress network policy implementation. + ## @skip networkPolicies.default.ingress Skip individual ingress configuration. + default: + enabled: false + annotations: {} + labels: {} + policyTypes: [] + # - Egress + # - Ingress + egress: [] + # Allow outgoing traffic to database host + # + # - to: + # - ipBlock: + # cidr: 192.168.179.1/32 + # ports: + # - port: 5432 + # protocol: TCP + + # Allow outgoing DNS traffic to the internal running DNS-Server. For example core-dns. + # + # - to: + # - namespaceSelector: + # matchLabels: + # kubernetes.io/metadata.name: kube-system + # podSelector: + # matchLabels: + # k8s-app: kube-dns + # ports: + # - port: 53 + # protocol: TCP + # - port: 53 + # protocol: UDP + + ingress: [] + # Allow incoming HTTP traffic from prometheus. + # + # - from: + # - namespaceSelector: + # matchLabels: + # kubernetes.io/metadata.name: monitoring + # podSelector: + # matchLabels: + # app.kubernetes.io/name: prometheus + # ports: + # - port: http + # protocol: TCP + + # Allow incoming HTTP traffic from ingress-nginx. + # + # - from: + # - namespaceSelector: + # matchLabels: + # kubernetes.io/metadata.name: ingress-nginx + # podSelector: + # matchLabels: + # app.kubernetes.io/name: ingress-nginx + # ports: + # - port: http + # protocol: TCP ## @section Prometheus prometheus: