From b9a8633d4409f37714e361806613be821e605f76 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Wed, 13 Nov 2024 16:16:51 -0500 Subject: [PATCH 1/4] feat(network): enable optional egress network policy --- charts/cryostat/README.md | 33 +++++---- .../templates/networkpolicy_egress.yaml | 40 ++++++++++ .../tests/networkpolicy_egress_test.yaml | 74 +++++++++++++++++++ charts/cryostat/values.schema.json | 12 ++- charts/cryostat/values.yaml | 5 +- 5 files changed, 147 insertions(+), 17 deletions(-) create mode 100644 charts/cryostat/templates/networkpolicy_egress.yaml create mode 100644 charts/cryostat/tests/networkpolicy_egress_test.yaml diff --git a/charts/cryostat/README.md b/charts/cryostat/README.md index 11476b51..0c0df02f 100644 --- a/charts/cryostat/README.md +++ b/charts/cryostat/README.md @@ -312,18 +312,21 @@ certificate issuance and rotation. ### Other Parameters -| Name | Description | Value | -| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -| `imagePullSecrets` | Image pull secrets to be used for the Cryostat deployment | `[]` | -| `nameOverride` | Overrides the name of this Chart | `""` | -| `fullnameOverride` | Overrides the fully qualified application name of `[release name]-[chart name]` | `""` | -| `rbac.create` | Specifies whether RBAC resources should be created | `true` | -| `serviceAccount.create` | Specifies whether a service account should be created | `true` | -| `serviceAccount.annotations` | Annotations to add to the service account | `{}` | -| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `""` | -| `podAnnotations` | Annotations to be applied to the various Pods | `{}` | -| `podSecurityContext` | Security Context for the Cryostat Pod. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [PodSecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context) | `{}` | -| `networkPolicy.ingress.enabled` | whether a NetworkPolicy for restricting Cryostat component Pods' traffic is installed. This prevents other Pods from sending unwanted traffic to Cryostat's Pods. Traffic should flow via the Service (or Route, or other Ingress) only, not by directly targeting Pods | `true` | -| `nodeSelector` | default Node Selector for the various Pods. Any Pod which does not have an individual nodeSelector setting will default to this. See: [NodeSelector](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) | `{}` | -| `tolerations` | default Tolerations for the various Pods. See: [Tolerations](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) | `[]` | -| `affinity` | default Affinity for the various Pods. See: [Affinity](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) | `{}` | +| Name | Description | Value | +| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| `imagePullSecrets` | Image pull secrets to be used for the Cryostat deployment | `[]` | +| `nameOverride` | Overrides the name of this Chart | `""` | +| `fullnameOverride` | Overrides the fully qualified application name of `[release name]-[chart name]` | `""` | +| `rbac.create` | Specifies whether RBAC resources should be created | `true` | +| `serviceAccount.create` | Specifies whether a service account should be created | `true` | +| `serviceAccount.annotations` | Annotations to add to the service account | `{}` | +| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `""` | +| `podAnnotations` | Annotations to be applied to the various Pods | `{}` | +| `podSecurityContext` | Security Context for the Cryostat Pod. Defaults to meet "restricted" [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). See: [PodSecurityContext](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context) | `{}` | +| `networkPolicy.ingress.enabled` | whether a NetworkPolicy for restricting Cryostat component Pods' inbound traffic is installed. This prevents other Pods from sending unwanted traffic to Cryostat's Pods. Traffic should flow via the Service (or Route, or other Ingress) only, not by directly targeting Pods. | `true` | +| `networkPolicy.egress.enabled` | whether a NetworkPolicy for restricting Cryostat component Pods' outbound traffic is installed. This prevents Cryostat's component Pods from opening connections to unexpected destinations. The policy will allow Cryostat's Pods to communicate with each other, to the cluster API server, and to any target namespaces (core.discovery.kubernetes.namespaces). This is off by default since some cluster network plugins cause JDBC connectivity issues between Cryostat and its database when this policy is activated. When enabled, Cryostat users will not be able to define Custom Targets that are located outside of the target namespaces defined at installation time. | `false` | +| `nodeSelector` | default Node Selector for the various Pods. Any Pod which does not have an individual nodeSelector setting will default to this. See: [NodeSelector](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) | `{}` | +| `tolerations` | default Tolerations for the various Pods. See: [Tolerations](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) | `[]` | +| `affinity` | default Affinity for the various Pods. See: [Affinity](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) | `{}` | + +>>>>>>> 8ca4149 (feat(network): enable optional egress network policy) diff --git a/charts/cryostat/templates/networkpolicy_egress.yaml b/charts/cryostat/templates/networkpolicy_egress.yaml new file mode 100644 index 00000000..21869c62 --- /dev/null +++ b/charts/cryostat/templates/networkpolicy_egress.yaml @@ -0,0 +1,40 @@ +{{- if ((.Values.networkPolicy.egress).enabled) }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Release.Name }}-internal-egress + namespace: {{ .Release.Namespace }} +spec: + policyTypes: + - Egress + podSelector: + matchLabels: + {{- include "cryostat.selectorLabels" $ | nindent 6 }} + app.kubernetes.io/component: cryostat + egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ .Release.Namespace }} +{{- if .Values.authentication.openshift.enabled }} +{{- $kubernetesEndpoint := lookup "v1" "Endpoints" "default" "kubernetes" }} +{{- $kubernetesAddress := (first $kubernetesEndpoint.subsets).addresses }} +{{- $kubernetesIP := (first $kubernetesAddress).ip }} + - to: + - ipBlock: + cidr: {{ $kubernetesIP }}/32 +{{- end }} + - to: + - namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: In + values: + - default + - kube-system + - openshift + - {{ .Release.Namespace }} + {{- range .Values.core.discovery.kubernetes.namespaces }} + - {{ . }} + {{- end }} +{{- end }} diff --git a/charts/cryostat/tests/networkpolicy_egress_test.yaml b/charts/cryostat/tests/networkpolicy_egress_test.yaml new file mode 100644 index 00000000..96247b5e --- /dev/null +++ b/charts/cryostat/tests/networkpolicy_egress_test.yaml @@ -0,0 +1,74 @@ +suite: test networkpolicy_egress.yaml +templates: + - networkpolicy_egress.yaml + +tests: + - it: should be disabled by default + asserts: + - hasDocuments: + count: 0 + + - it: should create an internal-access policy + set: + networkPolicy.egress.enabled: true + asserts: + - equal: + path: kind + value: NetworkPolicy + - equal: + path: metadata.name + value: RELEASE-NAME-internal-egress + - equal: + path: metadata.namespace + value: NAMESPACE + - equal: + path: spec.podSelector + value: + matchLabels: + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/name: cryostat + app.kubernetes.io/component: cryostat + - equal: + path: spec.egress + value: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: NAMESPACE + - to: + - namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: In + values: + - default + - kube-system + - openshift + - NAMESPACE + + - it: should allow additional egress to target namespaces + set: + networkPolicy.egress.enabled: true + core.discovery.kubernetes.namespaces: + - apps1 + - apps2 + asserts: + - equal: + path: spec.egress + value: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: NAMESPACE + - to: + - namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: In + values: + - default + - kube-system + - openshift + - NAMESPACE + - apps1 + - apps2 diff --git a/charts/cryostat/values.schema.json b/charts/cryostat/values.schema.json index ba767440..889f6236 100644 --- a/charts/cryostat/values.schema.json +++ b/charts/cryostat/values.schema.json @@ -1540,10 +1540,20 @@ "properties": { "enabled": { "type": "boolean", - "description": "whether a NetworkPolicy for restricting Cryostat component Pods' traffic is installed. This prevents other Pods from sending unwanted traffic to Cryostat's Pods. Traffic should flow via the Service (or Route, or other Ingress) only, not by directly targeting Pods", + "description": "whether a NetworkPolicy for restricting Cryostat component Pods' inbound traffic is installed. This prevents other Pods from sending unwanted traffic to Cryostat's Pods. Traffic should flow via the Service (or Route, or other Ingress) only, not by directly targeting Pods.", "default": true } } + }, + "egress": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "whether a NetworkPolicy for restricting Cryostat component Pods' outbound traffic is installed. This prevents Cryostat's component Pods from opening connections to unexpected destinations. The policy will allow Cryostat's Pods to communicate with each other, to the cluster API server, and to any target namespaces (core.discovery.kubernetes.namespaces). This is off by default since some cluster network plugins cause JDBC connectivity issues between Cryostat and its database when this policy is activated. When enabled, Cryostat users will not be able to define Custom Targets that are located outside of the target namespaces defined at installation time.", + "default": false + } + } } } }, diff --git a/charts/cryostat/values.yaml b/charts/cryostat/values.yaml index 4b7e4bbc..4326f02c 100644 --- a/charts/cryostat/values.yaml +++ b/charts/cryostat/values.yaml @@ -599,8 +599,11 @@ podSecurityContext: networkPolicy: ingress: - ## @param networkPolicy.ingress.enabled whether a NetworkPolicy for restricting Cryostat component Pods' traffic is installed. This prevents other Pods from sending unwanted traffic to Cryostat's Pods. Traffic should flow via the Service (or Route, or other Ingress) only, not by directly targeting Pods + ## @param networkPolicy.ingress.enabled whether a NetworkPolicy for restricting Cryostat component Pods' inbound traffic is installed. This prevents other Pods from sending unwanted traffic to Cryostat's Pods. Traffic should flow via the Service (or Route, or other Ingress) only, not by directly targeting Pods. enabled: true + egress: + ## @param networkPolicy.egress.enabled whether a NetworkPolicy for restricting Cryostat component Pods' outbound traffic is installed. This prevents Cryostat's component Pods from opening connections to unexpected destinations. The policy will allow Cryostat's Pods to communicate with each other, to the cluster API server, and to any target namespaces (core.discovery.kubernetes.namespaces). This is off by default since some cluster network plugins cause JDBC connectivity issues between Cryostat and its database when this policy is activated. When enabled, Cryostat users will not be able to define Custom Targets that are located outside of the target namespaces defined at installation time. + enabled: false ## @param nodeSelector [object] default Node Selector for the various Pods. Any Pod which does not have an individual nodeSelector setting will default to this. See: [NodeSelector](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) nodeSelector: {} From 472ebb2511da453003ff2646a5700ec04cc12d78 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Fri, 13 Jun 2025 15:03:50 -0400 Subject: [PATCH 2/4] fixup! feat(network): enable optional egress network policy --- charts/cryostat/tests/networkpolicy_egress_test.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/charts/cryostat/tests/networkpolicy_egress_test.yaml b/charts/cryostat/tests/networkpolicy_egress_test.yaml index 96247b5e..98cc9634 100644 --- a/charts/cryostat/tests/networkpolicy_egress_test.yaml +++ b/charts/cryostat/tests/networkpolicy_egress_test.yaml @@ -28,6 +28,7 @@ tests: app.kubernetes.io/instance: RELEASE-NAME app.kubernetes.io/name: cryostat app.kubernetes.io/component: cryostat + app.kubernetes.io/part-of: cryostat - equal: path: spec.egress value: From 49644828452409206fdcf6ecece71a6f0b44f75a Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Thu, 28 Aug 2025 10:18:47 -0400 Subject: [PATCH 3/4] refactor, remove 'default' namespace egress --- .../templates/networkpolicy_egress.yaml | 25 ++++++++++--------- .../tests/networkpolicy_egress_test.yaml | 10 ++------ 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/charts/cryostat/templates/networkpolicy_egress.yaml b/charts/cryostat/templates/networkpolicy_egress.yaml index 21869c62..ba914d98 100644 --- a/charts/cryostat/templates/networkpolicy_egress.yaml +++ b/charts/cryostat/templates/networkpolicy_egress.yaml @@ -15,26 +15,27 @@ spec: - to: - namespaceSelector: matchLabels: - kubernetes.io/metadata.name: {{ .Release.Namespace }} -{{- if .Values.authentication.openshift.enabled }} -{{- $kubernetesEndpoint := lookup "v1" "Endpoints" "default" "kubernetes" }} -{{- $kubernetesAddress := (first $kubernetesEndpoint.subsets).addresses }} -{{- $kubernetesIP := (first $kubernetesAddress).ip }} - - to: - - ipBlock: - cidr: {{ $kubernetesIP }}/32 -{{- end }} + kubernetes.io/metadata.name: kube-system - to: - namespaceSelector: matchExpressions: - key: kubernetes.io/metadata.name operator: In values: - - default - - kube-system - - openshift - {{ .Release.Namespace }} {{- range .Values.core.discovery.kubernetes.namespaces }} - {{ . }} {{- end }} +{{- if .Values.authentication.openshift.enabled }} +{{- $kubernetesEndpoint := lookup "v1" "Endpoints" "default" "kubernetes" }} +{{- $kubernetesAddress := (first $kubernetesEndpoint.subsets).addresses }} +{{- $kubernetesIP := (first $kubernetesAddress).ip }} + - to: + - ipBlock: + cidr: {{ $kubernetesIP }}/32 + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: openshift +{{- end }} {{- end }} diff --git a/charts/cryostat/tests/networkpolicy_egress_test.yaml b/charts/cryostat/tests/networkpolicy_egress_test.yaml index 98cc9634..a820b61b 100644 --- a/charts/cryostat/tests/networkpolicy_egress_test.yaml +++ b/charts/cryostat/tests/networkpolicy_egress_test.yaml @@ -35,16 +35,13 @@ tests: - to: - namespaceSelector: matchLabels: - kubernetes.io/metadata.name: NAMESPACE + kubernetes.io/metadata.name: kube-system - to: - namespaceSelector: matchExpressions: - key: kubernetes.io/metadata.name operator: In values: - - default - - kube-system - - openshift - NAMESPACE - it: should allow additional egress to target namespaces @@ -60,16 +57,13 @@ tests: - to: - namespaceSelector: matchLabels: - kubernetes.io/metadata.name: NAMESPACE + kubernetes.io/metadata.name: kube-system - to: - namespaceSelector: matchExpressions: - key: kubernetes.io/metadata.name operator: In values: - - default - - kube-system - - openshift - NAMESPACE - apps1 - apps2 From f787604b6bb9dfc668291b2fce1dca16b2292e55 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Thu, 9 Oct 2025 15:27:17 -0400 Subject: [PATCH 4/4] fixup! feat(network): enable optional egress network policy --- charts/cryostat/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/charts/cryostat/README.md b/charts/cryostat/README.md index 0c0df02f..ec5e9864 100644 --- a/charts/cryostat/README.md +++ b/charts/cryostat/README.md @@ -328,5 +328,3 @@ certificate issuance and rotation. | `nodeSelector` | default Node Selector for the various Pods. Any Pod which does not have an individual nodeSelector setting will default to this. See: [NodeSelector](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) | `{}` | | `tolerations` | default Tolerations for the various Pods. See: [Tolerations](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) | `[]` | | `affinity` | default Affinity for the various Pods. See: [Affinity](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) | `{}` | - ->>>>>>> 8ca4149 (feat(network): enable optional egress network policy)