From 0535ee5348bf86398704cbe073bfaf9fe7e59c58 Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Thu, 18 Sep 2025 08:31:08 +0200 Subject: [PATCH 1/8] feat(network-nodes): add reliability controls --- .vscode/settings.json | 3 +- charts/network/charts/network-nodes/README.md | 21 ++++ .../templates/networkpolicy.yaml | 54 +++++++++ .../templates/poddisruptionbudgets.yaml | 48 ++++++++ .../network/charts/network-nodes/values.yaml | 104 ++++++++++++++++++ 5 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 charts/network/charts/network-nodes/templates/networkpolicy.yaml create mode 100644 charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml diff --git a/.vscode/settings.json b/.vscode/settings.json index 33d286c..a224322 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -147,5 +147,6 @@ "workbench.editor.revealIfOpen": true, "workbench.fontAliasing": "auto", "workbench.tips.enabled": false, - "workbench.tree.enableStickyScroll": true + "workbench.tree.enableStickyScroll": true, + "chatgpt.openOnStartup": false } diff --git a/charts/network/charts/network-nodes/README.md b/charts/network/charts/network-nodes/README.md index 20bbc07..0025d59 100644 --- a/charts/network/charts/network-nodes/README.md +++ b/charts/network/charts/network-nodes/README.md @@ -88,6 +88,13 @@ A Helm chart for Kubernetes | livenessProbe.periodSeconds | int | `10` | Frequency of liveness checks in seconds. | | livenessProbe.timeoutSeconds | int | `2` | Timeout in seconds before marking the probe as failed. | | nameOverride | string | `""` | Override for the short chart name used in resource naming. | +| networkPolicy.annotations | object | `{}` | Additional annotations to add to the NetworkPolicy metadata. | +| networkPolicy.egress | list | `[{"ports":[{"port":53,"protocol":"UDP"}],"to":[{"namespaceSelector":{},"podSelector":{"matchLabels":{"k8s-app":"kube-dns"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"namespaceSelector":{}}]}]` | NetworkPolicy egress rules. Leave empty to deny all egress when enabled. | +| networkPolicy.enabled | bool | `false` | Create a NetworkPolicy restricting Besu pod ingress and egress. | +| networkPolicy.ingress | list | `[{"from":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"txsigner"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"erpc"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"blockscout-stack"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"graph-node"}}},{"podSelector":{}}],"ports":[{"port":8545,"protocol":"TCP"},{"port":8546,"protocol":"TCP"},{"port":8547,"protocol":"TCP"},{"port":9545,"protocol":"TCP"}]},{"from":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}],"ports":[{"port":30303,"protocol":"TCP"}]}]` | NetworkPolicy ingress rules. Leave empty to deny all ingress when enabled. | +| networkPolicy.labels | object | `{}` | Additional labels to add to the NetworkPolicy metadata. | +| networkPolicy.podSelector | object | `{}` | Optional override for the default pod selector; defaults to Besu workload labels when empty. | +| networkPolicy.policyTypes | list | `[]` | Policy types enforced by the NetworkPolicy. When empty, inferred from ingress/egress rules or defaults to both. | | nodeSelector | object | `{}` | | | openShiftRoute.alternateBackends | list | `[]` | Additional backend references to balance traffic across services. | | openShiftRoute.annotations | object | `{}` | | @@ -116,6 +123,20 @@ A Helm chart for Kubernetes | podAnnotations."prometheus.io/port" | string | `"9545"` | Container port value used by Prometheus to scrape metrics. | | podAnnotations."prometheus.io/scheme" | string | `"http"` | HTTP scheme (http or https) used for metrics scraping. | | podAnnotations."prometheus.io/scrape" | string | `"true"` | Enables Prometheus scraping of the Besu metrics endpoint. | +| podDisruptionBudgets.rpc | object | `{"annotations":{},"enabled":false,"labels":{},"maxUnavailable":null,"minAvailable":1,"unhealthyPodEvictionPolicy":""}` | PodDisruptionBudget governing RPC pods. | +| podDisruptionBudgets.rpc.annotations | object | `{}` | Additional annotations applied to the RPC PodDisruptionBudget. | +| podDisruptionBudgets.rpc.enabled | bool | `false` | Enable the RPC PodDisruptionBudget. | +| podDisruptionBudgets.rpc.labels | object | `{}` | Additional labels applied to the RPC PodDisruptionBudget. | +| podDisruptionBudgets.rpc.maxUnavailable | string | `nil` | Maximum RPC pods that can be disrupted at once. Accepts integers or percentages. | +| podDisruptionBudgets.rpc.minAvailable | int | `1` | Minimum RPC pods that must remain available; ignored when maxUnavailable is set. | +| podDisruptionBudgets.rpc.unhealthyPodEvictionPolicy | string | `""` | Optional unhealthy pod eviction policy (Default or AlwaysAllow). | +| podDisruptionBudgets.validator | object | `{"annotations":{},"enabled":false,"labels":{},"maxUnavailable":null,"minAvailable":1,"unhealthyPodEvictionPolicy":""}` | PodDisruptionBudget controlling voluntary disruptions for validator pods. | +| podDisruptionBudgets.validator.annotations | object | `{}` | Additional annotations applied to the validator PodDisruptionBudget. | +| podDisruptionBudgets.validator.enabled | bool | `false` | Enable the validator PodDisruptionBudget. | +| podDisruptionBudgets.validator.labels | object | `{}` | Additional labels applied to the validator PodDisruptionBudget. | +| podDisruptionBudgets.validator.maxUnavailable | string | `nil` | Maximum validator pods that can be disrupted at once. Accepts integers or percentages. | +| podDisruptionBudgets.validator.minAvailable | int | `1` | Minimum validator pods that must remain available; ignored when maxUnavailable is set. | +| podDisruptionBudgets.validator.unhealthyPodEvictionPolicy | string | `""` | Optional unhealthy pod eviction policy (Default or AlwaysAllow). | | podLabels | object | `{}` | | | podSecurityContext | object | `{}` | | | readinessProbe | string | `nil` | | diff --git a/charts/network/charts/network-nodes/templates/networkpolicy.yaml b/charts/network/charts/network-nodes/templates/networkpolicy.yaml new file mode 100644 index 0000000..783782f --- /dev/null +++ b/charts/network/charts/network-nodes/templates/networkpolicy.yaml @@ -0,0 +1,54 @@ +{{- if .Values.networkPolicy.enabled }} +{{- $root := . -}} +{{- $np := .Values.networkPolicy | default (dict) -}} +{{- $labels := get $np "labels" | default (dict) -}} +{{- $annotations := get $np "annotations" | default (dict) -}} +{{- $podSelector := get $np "podSelector" | default (dict) -}} +{{- $hasCustomSelector := gt (len $podSelector) 0 -}} +{{- $ingress := get $np "ingress" | default (list) -}} +{{- $egress := get $np "egress" | default (list) -}} +{{- $policyTypes := get $np "policyTypes" | default (list) -}} +{{- if not $policyTypes }} + {{- if gt (len $ingress) 0 }} + {{- $policyTypes = append $policyTypes "Ingress" -}} + {{- end }} + {{- if gt (len $egress) 0 }} + {{- $policyTypes = append $policyTypes "Egress" -}} + {{- end }} + {{- if eq (len $policyTypes) 0 }} + {{- $policyTypes = list "Ingress" "Egress" -}} + {{- end }} +{{- end }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "nodes.fullname" $root }} + labels: + {{- include "nodes.labels" $root | nindent 4 }} + {{- with $labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + podSelector: + {{- if $hasCustomSelector }} + {{- toYaml $podSelector | nindent 4 }} + {{- else }} + matchLabels: + {{- include "nodes.selectorLabels" $root | nindent 6 }} + {{- end }} + policyTypes: + {{- toYaml $policyTypes | nindent 4 }} + {{- if gt (len $ingress) 0 }} + ingress: + {{- toYaml $ingress | nindent 4 }} + {{- end }} + {{- if gt (len $egress) 0 }} + egress: + {{- toYaml $egress | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml b/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml new file mode 100644 index 0000000..98b4af7 --- /dev/null +++ b/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml @@ -0,0 +1,48 @@ +{{- $root := . -}} +{{- $pdbValues := .Values.podDisruptionBudgets | default (dict) -}} +{{- $components := list + (dict "name" "validator" "config" (default (dict) (get $pdbValues "validator"))) + (dict "name" "rpc" "config" (default (dict) (get $pdbValues "rpc"))) +-}} +{{- range $component := $components }} + {{- $cfg := $component.config -}} + {{- if and $cfg (get $cfg "enabled") }} + {{- $minRaw := get $cfg "minAvailable" -}} + {{- $hasMin := and (hasKey $cfg "minAvailable") (ne $minRaw nil) (not (and (kindIs "string" $minRaw) (eq $minRaw ""))) -}} + {{- $maxRaw := get $cfg "maxUnavailable" -}} + {{- $hasMax := and (hasKey $cfg "maxUnavailable") (ne $maxRaw nil) (not (and (kindIs "string" $maxRaw) (eq $maxRaw ""))) -}} + {{- if not (or $hasMin $hasMax) }} + {{- fail (printf "podDisruptionBudgets.%s requires minAvailable or maxUnavailable" $component.name) -}} + {{- end }} +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "nodes.fullname" $root }}-{{ $component.name }} + labels: + {{- include "nodes.labels" $root | nindent 4 }} + app.kubernetes.io/component: {{ $component.name }} + {{- with (get $cfg "labels") }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with (get $cfg "annotations") }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if $hasMin }} + minAvailable: {{ $minRaw }} + {{- end }} + {{- if $hasMax }} + maxUnavailable: {{ $maxRaw }} + {{- end }} + {{- $policy := get $cfg "unhealthyPodEvictionPolicy" -}} + {{- if and $policy (ne $policy "") }} + unhealthyPodEvictionPolicy: {{ $policy }} + {{- end }} + selector: + matchLabels: + {{- include "nodes.selectorLabels" $root | nindent 6 }} + app.kubernetes.io/component: {{ $component.name }} + {{- end }} +{{- end }} diff --git a/charts/network/charts/network-nodes/values.yaml b/charts/network/charts/network-nodes/values.yaml index c5e65c3..c6d58dc 100644 --- a/charts/network/charts/network-nodes/values.yaml +++ b/charts/network/charts/network-nodes/values.yaml @@ -49,6 +49,110 @@ podAnnotations: # Additional labels applied to all Besu pods. podLabels: {} +# PodDisruptionBudget configuration for validator and RPC workloads. +podDisruptionBudgets: + # -- PodDisruptionBudget controlling voluntary disruptions for validator pods. + validator: + # -- Enable the validator PodDisruptionBudget. + enabled: false + # -- Minimum validator pods that must remain available; ignored when maxUnavailable is set. + minAvailable: 1 + # -- Maximum validator pods that can be disrupted at once. Accepts integers or percentages. + maxUnavailable: + # -- Optional unhealthy pod eviction policy (Default or AlwaysAllow). + unhealthyPodEvictionPolicy: "" + # -- Additional annotations applied to the validator PodDisruptionBudget. + annotations: {} + # -- Additional labels applied to the validator PodDisruptionBudget. + labels: {} + # -- PodDisruptionBudget governing RPC pods. + rpc: + # -- Enable the RPC PodDisruptionBudget. + enabled: false + # -- Minimum RPC pods that must remain available; ignored when maxUnavailable is set. + minAvailable: 1 + # -- Maximum RPC pods that can be disrupted at once. Accepts integers or percentages. + maxUnavailable: + # -- Optional unhealthy pod eviction policy (Default or AlwaysAllow). + unhealthyPodEvictionPolicy: "" + # -- Additional annotations applied to the RPC PodDisruptionBudget. + annotations: {} + # -- Additional labels applied to the RPC PodDisruptionBudget. + labels: {} + +# NetworkPolicy configuration applied to Besu pods. +networkPolicy: + # -- Create a NetworkPolicy restricting Besu pod ingress and egress. + enabled: false + # -- Optional override for the default pod selector; defaults to Besu workload labels when empty. + podSelector: {} + # -- Policy types enforced by the NetworkPolicy. When empty, inferred from ingress/egress rules or defaults to both. + policyTypes: [] + # -- Additional labels to add to the NetworkPolicy metadata. + labels: {} + # -- Additional annotations to add to the NetworkPolicy metadata. + annotations: {} + # -- NetworkPolicy ingress rules. Leave empty to deny all ingress when enabled. + ingress: + # Allow blockchain clients to reach RPC, WS, GraphQL, and metrics endpoints. + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: txsigner + - podSelector: + matchLabels: + app.kubernetes.io/name: erpc + - podSelector: + matchLabels: + app.kubernetes.io/name: blockscout-stack + - podSelector: + matchLabels: + app.kubernetes.io/name: graph-node + - podSelector: {} + ports: + - protocol: TCP + port: 8545 + - protocol: TCP + port: 8546 + - protocol: TCP + port: 8547 + - protocol: TCP + port: 9545 + # Permit intra-cluster P2P traffic among Besu nodes. + - from: + - podSelector: + matchLabels: + app.kubernetes.io/name: besu-statefulset + ports: + - protocol: TCP + port: 30303 + + # -- NetworkPolicy egress rules. Leave empty to deny all egress when enabled. + egress: + # Allow DNS resolution for outbound hosts. + - to: + - namespaceSelector: {} + podSelector: + matchLabels: + k8s-app: kube-dns + ports: + - protocol: UDP + port: 53 + # Permit Besu pods to speak to peers inside the namespace. + - to: + - podSelector: + matchLabels: + app.kubernetes.io/name: besu-statefulset + ports: + - protocol: TCP + port: 30303 + # Allow outbound P2P connections to external peers (public networks). + - to: + - namespaceSelector: {} + ports: + - protocol: TCP + port: 30303 + # Pod-level security context shared by all containers. podSecurityContext: {} From cbeb42a5d7a0befacdd8b3e8d9ca0b3c1a3e4697 Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Thu, 18 Sep 2025 08:33:06 +0200 Subject: [PATCH 2/8] feat(network-nodes): allow priority classes --- charts/network/charts/network-nodes/README.md | 2 ++ .../charts/network-nodes/templates/statefulset-rpc.yaml | 5 +++++ .../network-nodes/templates/statefulset-validator.yaml | 5 +++++ charts/network/charts/network-nodes/values.yaml | 7 +++++++ 4 files changed, 19 insertions(+) diff --git a/charts/network/charts/network-nodes/README.md b/charts/network/charts/network-nodes/README.md index 0025d59..545495c 100644 --- a/charts/network/charts/network-nodes/README.md +++ b/charts/network/charts/network-nodes/README.md @@ -139,6 +139,8 @@ A Helm chart for Kubernetes | podDisruptionBudgets.validator.unhealthyPodEvictionPolicy | string | `""` | Optional unhealthy pod eviction policy (Default or AlwaysAllow). | | podLabels | object | `{}` | | | podSecurityContext | object | `{}` | | +| priorityClassNames.rpc | string | `""` | PriorityClass name assigned to RPC pods. Leave empty to inherit namespace defaults. | +| priorityClassNames.validator | string | `""` | PriorityClass name assigned to validator pods. Leave empty to inherit namespace defaults. | | readinessProbe | string | `nil` | | | resources | object | `{}` | | | rpcReplicaCount | int | `2` | Number of RPC node replicas provisioned via StatefulSet. | diff --git a/charts/network/charts/network-nodes/templates/statefulset-rpc.yaml b/charts/network/charts/network-nodes/templates/statefulset-rpc.yaml index 4ef0ea9..d2c3f22 100644 --- a/charts/network/charts/network-nodes/templates/statefulset-rpc.yaml +++ b/charts/network/charts/network-nodes/templates/statefulset-rpc.yaml @@ -31,6 +31,8 @@ spec: {{- $privateKeyFilename := default "privateKey" .Values.config.privateKeyFilename }} {{- $shouldMountPersistence := $persistenceEnabled }} {{- $rpcReplicaBudget := .Values.rpcReplicaCount | int }} + {{- $priorityClasses := .Values.priorityClassNames | default (dict) }} + {{- $rpcPriorityClass := default "" (get $priorityClasses "rpc") }} {{- $initContainers := .Values.initContainers | default (dict) }} {{- $sharedInitContainers := get $initContainers "shared" }} {{- $rpcInitContainers := get $initContainers "rpc" }} @@ -68,6 +70,9 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "nodes.serviceAccountName" . }} + {{- if $rpcPriorityClass }} + priorityClassName: {{ $rpcPriorityClass | quote }} + {{- end }} {{- with .Values.podSecurityContext }} securityContext: {{- toYaml . | nindent 8 }} diff --git a/charts/network/charts/network-nodes/templates/statefulset-validator.yaml b/charts/network/charts/network-nodes/templates/statefulset-validator.yaml index 6d9141b..4ca9f7c 100644 --- a/charts/network/charts/network-nodes/templates/statefulset-validator.yaml +++ b/charts/network/charts/network-nodes/templates/statefulset-validator.yaml @@ -32,6 +32,8 @@ spec: {{- $staticNodesConfigMapName := default "besu-static-nodes" (get $globalNodes "staticNodesConfigMapName") }} {{- $validatorPodPrefix := default "besu-node-validator" (get $globalNodes "podPrefix") }} {{- $validatorReplicaBudget := (include "nodes.validatorReplicaCount" . | int) }} + {{- $priorityClasses := .Values.priorityClassNames | default (dict) }} + {{- $validatorPriorityClass := default "" (get $priorityClasses "validator") }} {{- $initContainers := .Values.initContainers | default (dict) }} {{- $sharedInitContainers := get $initContainers "shared" }} {{- $validatorInitContainers := get $initContainers "validator" }} @@ -69,6 +71,9 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "nodes.serviceAccountName" . }} + {{- if $validatorPriorityClass }} + priorityClassName: {{ $validatorPriorityClass | quote }} + {{- end }} {{- with .Values.podSecurityContext }} securityContext: {{- toYaml . | nindent 8 }} diff --git a/charts/network/charts/network-nodes/values.yaml b/charts/network/charts/network-nodes/values.yaml index c6d58dc..a83c746 100644 --- a/charts/network/charts/network-nodes/values.yaml +++ b/charts/network/charts/network-nodes/values.yaml @@ -153,6 +153,13 @@ networkPolicy: - protocol: TCP port: 30303 +# PriorityClass configuration applied to Besu workloads. +priorityClassNames: + # -- PriorityClass name assigned to validator pods. Leave empty to inherit namespace defaults. + validator: "" + # -- PriorityClass name assigned to RPC pods. Leave empty to inherit namespace defaults. + rpc: "" + # Pod-level security context shared by all containers. podSecurityContext: {} From 9b2394b0d965c12a86bac309a6bf48733465caa7 Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Thu, 18 Sep 2025 08:35:32 +0200 Subject: [PATCH 3/8] fix(network-nodes): guard mutually exclusive pdb fields --- .../charts/network-nodes/templates/poddisruptionbudgets.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml b/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml index 98b4af7..b81d6b9 100644 --- a/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml +++ b/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml @@ -11,7 +11,9 @@ {{- $hasMin := and (hasKey $cfg "minAvailable") (ne $minRaw nil) (not (and (kindIs "string" $minRaw) (eq $minRaw ""))) -}} {{- $maxRaw := get $cfg "maxUnavailable" -}} {{- $hasMax := and (hasKey $cfg "maxUnavailable") (ne $maxRaw nil) (not (and (kindIs "string" $maxRaw) (eq $maxRaw ""))) -}} - {{- if not (or $hasMin $hasMax) }} + {{- if and $hasMin $hasMax }} + {{- fail (printf "podDisruptionBudgets.%s: minAvailable and maxUnavailable are mutually exclusive" $component.name) -}} + {{- else if not (or $hasMin $hasMax) }} {{- fail (printf "podDisruptionBudgets.%s requires minAvailable or maxUnavailable" $component.name) -}} {{- end }} --- From 42f4c4c3749c1ad79433789a77c3db944046c73b Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Thu, 18 Sep 2025 08:36:52 +0200 Subject: [PATCH 4/8] fix(network-nodes): drop minAvailable when max set --- .../network-nodes/templates/poddisruptionbudgets.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml b/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml index b81d6b9..fc8b7c4 100644 --- a/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml +++ b/charts/network/charts/network-nodes/templates/poddisruptionbudgets.yaml @@ -11,9 +11,8 @@ {{- $hasMin := and (hasKey $cfg "minAvailable") (ne $minRaw nil) (not (and (kindIs "string" $minRaw) (eq $minRaw ""))) -}} {{- $maxRaw := get $cfg "maxUnavailable" -}} {{- $hasMax := and (hasKey $cfg "maxUnavailable") (ne $maxRaw nil) (not (and (kindIs "string" $maxRaw) (eq $maxRaw ""))) -}} - {{- if and $hasMin $hasMax }} - {{- fail (printf "podDisruptionBudgets.%s: minAvailable and maxUnavailable are mutually exclusive" $component.name) -}} - {{- else if not (or $hasMin $hasMax) }} + {{- $effectiveHasMin := and $hasMin (not $hasMax) -}} + {{- if not (or $effectiveHasMin $hasMax) }} {{- fail (printf "podDisruptionBudgets.%s requires minAvailable or maxUnavailable" $component.name) -}} {{- end }} --- @@ -32,7 +31,7 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: - {{- if $hasMin }} + {{- if $effectiveHasMin }} minAvailable: {{ $minRaw }} {{- end }} {{- if $hasMax }} From 06ee1f606225d0a7fc233a53a0e56e9c2b040f9a Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Thu, 18 Sep 2025 08:38:05 +0200 Subject: [PATCH 5/8] docs(network-nodes): clarify pdb exclusivity --- charts/network/charts/network-nodes/README.md | 8 ++++---- charts/network/charts/network-nodes/values.yaml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/charts/network/charts/network-nodes/README.md b/charts/network/charts/network-nodes/README.md index 545495c..40e3005 100644 --- a/charts/network/charts/network-nodes/README.md +++ b/charts/network/charts/network-nodes/README.md @@ -127,15 +127,15 @@ A Helm chart for Kubernetes | podDisruptionBudgets.rpc.annotations | object | `{}` | Additional annotations applied to the RPC PodDisruptionBudget. | | podDisruptionBudgets.rpc.enabled | bool | `false` | Enable the RPC PodDisruptionBudget. | | podDisruptionBudgets.rpc.labels | object | `{}` | Additional labels applied to the RPC PodDisruptionBudget. | -| podDisruptionBudgets.rpc.maxUnavailable | string | `nil` | Maximum RPC pods that can be disrupted at once. Accepts integers or percentages. | -| podDisruptionBudgets.rpc.minAvailable | int | `1` | Minimum RPC pods that must remain available; ignored when maxUnavailable is set. | +| podDisruptionBudgets.rpc.maxUnavailable | string | `nil` | Maximum RPC pods that can be disrupted at once. Mutually exclusive with minAvailable. | +| podDisruptionBudgets.rpc.minAvailable | int | `1` | Minimum RPC pods that must remain available. Mutually exclusive with maxUnavailable. | | podDisruptionBudgets.rpc.unhealthyPodEvictionPolicy | string | `""` | Optional unhealthy pod eviction policy (Default or AlwaysAllow). | | podDisruptionBudgets.validator | object | `{"annotations":{},"enabled":false,"labels":{},"maxUnavailable":null,"minAvailable":1,"unhealthyPodEvictionPolicy":""}` | PodDisruptionBudget controlling voluntary disruptions for validator pods. | | podDisruptionBudgets.validator.annotations | object | `{}` | Additional annotations applied to the validator PodDisruptionBudget. | | podDisruptionBudgets.validator.enabled | bool | `false` | Enable the validator PodDisruptionBudget. | | podDisruptionBudgets.validator.labels | object | `{}` | Additional labels applied to the validator PodDisruptionBudget. | -| podDisruptionBudgets.validator.maxUnavailable | string | `nil` | Maximum validator pods that can be disrupted at once. Accepts integers or percentages. | -| podDisruptionBudgets.validator.minAvailable | int | `1` | Minimum validator pods that must remain available; ignored when maxUnavailable is set. | +| podDisruptionBudgets.validator.maxUnavailable | string | `nil` | Maximum validator pods that can be disrupted at once. Mutually exclusive with minAvailable. | +| podDisruptionBudgets.validator.minAvailable | int | `1` | Minimum validator pods that must remain available. Mutually exclusive with maxUnavailable. | | podDisruptionBudgets.validator.unhealthyPodEvictionPolicy | string | `""` | Optional unhealthy pod eviction policy (Default or AlwaysAllow). | | podLabels | object | `{}` | | | podSecurityContext | object | `{}` | | diff --git a/charts/network/charts/network-nodes/values.yaml b/charts/network/charts/network-nodes/values.yaml index a83c746..9102f05 100644 --- a/charts/network/charts/network-nodes/values.yaml +++ b/charts/network/charts/network-nodes/values.yaml @@ -55,9 +55,9 @@ podDisruptionBudgets: validator: # -- Enable the validator PodDisruptionBudget. enabled: false - # -- Minimum validator pods that must remain available; ignored when maxUnavailable is set. + # -- Minimum validator pods that must remain available. Mutually exclusive with maxUnavailable. minAvailable: 1 - # -- Maximum validator pods that can be disrupted at once. Accepts integers or percentages. + # -- Maximum validator pods that can be disrupted at once. Mutually exclusive with minAvailable. maxUnavailable: # -- Optional unhealthy pod eviction policy (Default or AlwaysAllow). unhealthyPodEvictionPolicy: "" @@ -69,9 +69,9 @@ podDisruptionBudgets: rpc: # -- Enable the RPC PodDisruptionBudget. enabled: false - # -- Minimum RPC pods that must remain available; ignored when maxUnavailable is set. + # -- Minimum RPC pods that must remain available. Mutually exclusive with maxUnavailable. minAvailable: 1 - # -- Maximum RPC pods that can be disrupted at once. Accepts integers or percentages. + # -- Maximum RPC pods that can be disrupted at once. Mutually exclusive with minAvailable. maxUnavailable: # -- Optional unhealthy pod eviction policy (Default or AlwaysAllow). unhealthyPodEvictionPolicy: "" From a56ff6300d660dbef39809b91ece7a72bd3d1782 Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Thu, 18 Sep 2025 08:39:21 +0200 Subject: [PATCH 6/8] fix(network-nodes): tighten default ingress scope --- charts/network/charts/network-nodes/README.md | 2 +- charts/network/charts/network-nodes/values.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/network/charts/network-nodes/README.md b/charts/network/charts/network-nodes/README.md index 40e3005..ac5686c 100644 --- a/charts/network/charts/network-nodes/README.md +++ b/charts/network/charts/network-nodes/README.md @@ -91,7 +91,7 @@ A Helm chart for Kubernetes | networkPolicy.annotations | object | `{}` | Additional annotations to add to the NetworkPolicy metadata. | | networkPolicy.egress | list | `[{"ports":[{"port":53,"protocol":"UDP"}],"to":[{"namespaceSelector":{},"podSelector":{"matchLabels":{"k8s-app":"kube-dns"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"namespaceSelector":{}}]}]` | NetworkPolicy egress rules. Leave empty to deny all egress when enabled. | | networkPolicy.enabled | bool | `false` | Create a NetworkPolicy restricting Besu pod ingress and egress. | -| networkPolicy.ingress | list | `[{"from":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"txsigner"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"erpc"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"blockscout-stack"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"graph-node"}}},{"podSelector":{}}],"ports":[{"port":8545,"protocol":"TCP"},{"port":8546,"protocol":"TCP"},{"port":8547,"protocol":"TCP"},{"port":9545,"protocol":"TCP"}]},{"from":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}],"ports":[{"port":30303,"protocol":"TCP"}]}]` | NetworkPolicy ingress rules. Leave empty to deny all ingress when enabled. | +| networkPolicy.ingress | list | `[{"from":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"txsigner"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"erpc"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"blockscout-stack"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"graph-node"}}}],"ports":[{"port":8545,"protocol":"TCP"},{"port":8546,"protocol":"TCP"},{"port":8547,"protocol":"TCP"},{"port":9545,"protocol":"TCP"}]},{"from":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}],"ports":[{"port":30303,"protocol":"TCP"}]}]` | NetworkPolicy ingress rules. Leave empty to deny all ingress when enabled. | | networkPolicy.labels | object | `{}` | Additional labels to add to the NetworkPolicy metadata. | | networkPolicy.podSelector | object | `{}` | Optional override for the default pod selector; defaults to Besu workload labels when empty. | | networkPolicy.policyTypes | list | `[]` | Policy types enforced by the NetworkPolicy. When empty, inferred from ingress/egress rules or defaults to both. | diff --git a/charts/network/charts/network-nodes/values.yaml b/charts/network/charts/network-nodes/values.yaml index 9102f05..224c1f1 100644 --- a/charts/network/charts/network-nodes/values.yaml +++ b/charts/network/charts/network-nodes/values.yaml @@ -108,7 +108,7 @@ networkPolicy: - podSelector: matchLabels: app.kubernetes.io/name: graph-node - - podSelector: {} + # - podSelector: {} # Uncomment to allow any pod within the namespace. ports: - protocol: TCP port: 8545 From 2103cfe9ca2606caef5833af21e7139d69dfb8d4 Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Thu, 18 Sep 2025 08:40:54 +0200 Subject: [PATCH 7/8] fix(network-nodes): open external p2p egress --- charts/network/charts/network-nodes/README.md | 2 +- charts/network/charts/network-nodes/values.yaml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/charts/network/charts/network-nodes/README.md b/charts/network/charts/network-nodes/README.md index ac5686c..533e5ce 100644 --- a/charts/network/charts/network-nodes/README.md +++ b/charts/network/charts/network-nodes/README.md @@ -89,7 +89,7 @@ A Helm chart for Kubernetes | livenessProbe.timeoutSeconds | int | `2` | Timeout in seconds before marking the probe as failed. | | nameOverride | string | `""` | Override for the short chart name used in resource naming. | | networkPolicy.annotations | object | `{}` | Additional annotations to add to the NetworkPolicy metadata. | -| networkPolicy.egress | list | `[{"ports":[{"port":53,"protocol":"UDP"}],"to":[{"namespaceSelector":{},"podSelector":{"matchLabels":{"k8s-app":"kube-dns"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"namespaceSelector":{}}]}]` | NetworkPolicy egress rules. Leave empty to deny all egress when enabled. | +| networkPolicy.egress | list | `[{"ports":[{"port":53,"protocol":"UDP"}],"to":[{"namespaceSelector":{},"podSelector":{"matchLabels":{"k8s-app":"kube-dns"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"ipBlock":{"cidr":"0.0.0.0/0"}}]}]` | NetworkPolicy egress rules. Leave empty to deny all egress when enabled. | | networkPolicy.enabled | bool | `false` | Create a NetworkPolicy restricting Besu pod ingress and egress. | | networkPolicy.ingress | list | `[{"from":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"txsigner"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"erpc"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"blockscout-stack"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"graph-node"}}}],"ports":[{"port":8545,"protocol":"TCP"},{"port":8546,"protocol":"TCP"},{"port":8547,"protocol":"TCP"},{"port":9545,"protocol":"TCP"}]},{"from":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}],"ports":[{"port":30303,"protocol":"TCP"}]}]` | NetworkPolicy ingress rules. Leave empty to deny all ingress when enabled. | | networkPolicy.labels | object | `{}` | Additional labels to add to the NetworkPolicy metadata. | diff --git a/charts/network/charts/network-nodes/values.yaml b/charts/network/charts/network-nodes/values.yaml index 224c1f1..bcd0960 100644 --- a/charts/network/charts/network-nodes/values.yaml +++ b/charts/network/charts/network-nodes/values.yaml @@ -148,7 +148,8 @@ networkPolicy: port: 30303 # Allow outbound P2P connections to external peers (public networks). - to: - - namespaceSelector: {} + - ipBlock: + cidr: 0.0.0.0/0 ports: - protocol: TCP port: 30303 From 2935da9ffdc5fdc0a99947ea90797d3f7ea9d979 Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Thu, 18 Sep 2025 08:42:38 +0200 Subject: [PATCH 8/8] fix(network-nodes): align egress ipBlock with docs --- charts/network/charts/network-nodes/README.md | 2 +- charts/network/charts/network-nodes/values.yaml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/charts/network/charts/network-nodes/README.md b/charts/network/charts/network-nodes/README.md index 533e5ce..ff014bc 100644 --- a/charts/network/charts/network-nodes/README.md +++ b/charts/network/charts/network-nodes/README.md @@ -89,7 +89,7 @@ A Helm chart for Kubernetes | livenessProbe.timeoutSeconds | int | `2` | Timeout in seconds before marking the probe as failed. | | nameOverride | string | `""` | Override for the short chart name used in resource naming. | | networkPolicy.annotations | object | `{}` | Additional annotations to add to the NetworkPolicy metadata. | -| networkPolicy.egress | list | `[{"ports":[{"port":53,"protocol":"UDP"}],"to":[{"namespaceSelector":{},"podSelector":{"matchLabels":{"k8s-app":"kube-dns"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"ipBlock":{"cidr":"0.0.0.0/0"}}]}]` | NetworkPolicy egress rules. Leave empty to deny all egress when enabled. | +| networkPolicy.egress | list | `[{"ports":[{"port":53,"protocol":"UDP"}],"to":[{"namespaceSelector":{},"podSelector":{"matchLabels":{"k8s-app":"kube-dns"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}]},{"ports":[{"port":30303,"protocol":"TCP"}],"to":[{"ipBlock":{"cidr":"0.0.0.0/0","except":["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16"]}}]}]` | NetworkPolicy egress rules. Leave empty to deny all egress when enabled. | | networkPolicy.enabled | bool | `false` | Create a NetworkPolicy restricting Besu pod ingress and egress. | | networkPolicy.ingress | list | `[{"from":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"txsigner"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"erpc"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"blockscout-stack"}}},{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"graph-node"}}}],"ports":[{"port":8545,"protocol":"TCP"},{"port":8546,"protocol":"TCP"},{"port":8547,"protocol":"TCP"},{"port":9545,"protocol":"TCP"}]},{"from":[{"podSelector":{"matchLabels":{"app.kubernetes.io/name":"besu-statefulset"}}}],"ports":[{"port":30303,"protocol":"TCP"}]}]` | NetworkPolicy ingress rules. Leave empty to deny all ingress when enabled. | | networkPolicy.labels | object | `{}` | Additional labels to add to the NetworkPolicy metadata. | diff --git a/charts/network/charts/network-nodes/values.yaml b/charts/network/charts/network-nodes/values.yaml index bcd0960..143f2b0 100644 --- a/charts/network/charts/network-nodes/values.yaml +++ b/charts/network/charts/network-nodes/values.yaml @@ -150,6 +150,11 @@ networkPolicy: - to: - ipBlock: cidr: 0.0.0.0/0 + except: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + # Adjust the except list to match internal cluster CIDRs to avoid bypassing other policies. ports: - protocol: TCP port: 30303