From dc05770b261379da6c64fb5e4a3a43645f908419 Mon Sep 17 00:00:00 2001 From: Sebastian Daberdaku Date: Sat, 5 Oct 2024 21:23:02 +0200 Subject: [PATCH] Add `NetworkPolicy` support --- .github/workflows/ci-cd.yaml | 2 + charts/trino/README.md | 78 ++++++++++++--- charts/trino/templates/networkpolicy.yaml | 35 +++++++ .../templates/tests/test-connection.yaml | 1 - .../tests/test-graceful-shutdown.yaml | 1 - charts/trino/templates/tests/test-jmx.yaml | 1 - .../templates/tests/test-networkpolicy.yaml | 28 ++++++ charts/trino/values.yaml | 99 +++++++++++++++---- test-networkpolicy.yaml | 9 ++ test.sh | 3 +- 10 files changed, 218 insertions(+), 39 deletions(-) create mode 100644 charts/trino/templates/networkpolicy.yaml create mode 100644 charts/trino/templates/tests/test-networkpolicy.yaml create mode 100644 test-networkpolicy.yaml diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index f460fca2..b661a2a7 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -52,6 +52,8 @@ jobs: uses: helm/chart-testing-action@v2.6.1 - name: Create kind cluster uses: helm/kind-action@v1.10.0 + with: + version: 0.24.0 - name: Run tests run: ./test.sh ${{ matrix.args }} diff --git a/charts/trino/README.md b/charts/trino/README.md index fa6e6d9e..08a473f3 100644 --- a/charts/trino/README.md +++ b/charts/trino/README.md @@ -62,17 +62,14 @@ Fast distributed SQL query engine for big data analytics that helps you explore * `server.config.query.maxMemory` - string, default: `"4GB"` * `server.exchangeManager` - object, default: `{}` - Mandatory [exchange manager configuration](https://trino.io/docs/current/admin/fault-tolerant-execution.html#id1). - Used to set the name and location(s) of the spooling storage destination. - * To enable fault-tolerant execution, you must set the `retry-policy` property in `additionalConfigProperties`. - * Additional exchange manager configurations can be added to `additionalExchangeManagerProperties`. + Mandatory [exchange manager configuration](https://trino.io/docs/current/admin/fault-tolerant-execution.html#id1). Used to set the name and location(s) of the spooling storage destination. To enable fault-tolerant execution, set the `retry-policy` property in `additionalConfigProperties`. Additional exchange manager configurations can be added to `additionalExchangeManagerProperties`. Example: ```yaml - server: - exchangeManager: - name: "filesystem" - baseDir: "/tmp/trino-local-file-system-exchange-manager" - additionalConfigProperties: + server: + exchangeManager: + name: "filesystem" + baseDir: "/tmp/trino-local-file-system-exchange-manager" + additionalConfigProperties: - retry-policy=TASK additionalExchangeManagerProperties: - exchange.sink-buffer-pool-min-size=10 @@ -306,7 +303,7 @@ Fast distributed SQL query engine for big data analytics that helps you explore ``` * `envFrom` - list, default: `[]` - additional environment variables added to every pod, specified as a list of either ConfigMap or Secret references + additional environment variables added to every pod, specified as a list of either `ConfigMap` or `Secret` references Example: ```yaml - secretRef: @@ -354,7 +351,7 @@ Fast distributed SQL query engine for big data analytics that helps you explore Control whether a process can gain more privileges than its parent process. * `containerSecurityContext.capabilities.drop` - list, default: `["ALL"]` - A list of the Linux kernel capabilities that are dropped from every container. Valid values are listed at https://man7.org/linux/man-pages/man7/capabilities.7.html Ensure to remove the "CAP_" prefix which the kernel attaches to the names of permissions. + A list of the Linux kernel capabilities that are dropped from every container. Valid values are listed in [the capabilities manual page](https://man7.org/linux/man-pages/man7/capabilities.7.html). Ensure # to remove the "CAP_" prefix which the kernel attaches to the names of permissions. * `shareProcessNamespace.coordinator` - bool, default: `false` * `shareProcessNamespace.worker` - bool, default: `false` * `service.annotations` - object, default: `{}` @@ -362,7 +359,7 @@ Fast distributed SQL query engine for big data analytics that helps you explore * `service.port` - int, default: `8080` * `service.nodePort` - string, default: `""` - The port the service listens on the host, for NodePort type. If not set, Kubernetes will [allocate a port automatically](https://kubernetes.io/docs/concepts/services-networking/service/#nodeport-custom-port). + The port the service listens on the host, for the `NodePort` type. If not set, Kubernetes will [allocate a port automatically](https://kubernetes.io/docs/concepts/services-networking/service/#nodeport-custom-port). * `auth` - object, default: `{}` Available authentication methods. @@ -683,7 +680,7 @@ Fast distributed SQL query engine for big data analytics that helps you explore * `jmx.exporter.port` - int, default: `5556` * `jmx.exporter.configProperties` - string, default: `""` - The string value is templated using `tpl`. JMX Config Properties is mounted to /etc/jmx-exporter/jmx-exporter-config.yaml + The string value is templated using `tpl`. The JMX config properties file is mounted to `/etc/jmx-exporter/jmx-exporter-config.yaml`. Example: ```yaml configProperties: |- @@ -706,6 +703,7 @@ Fast distributed SQL query engine for big data analytics that helps you explore value: '$2' help: 'ThreadCount (java.lang<>ThreadCount)' type: UNTYPED + ``` * `jmx.exporter.securityContext` - object, default: `{}` * `jmx.exporter.resources` - object, default: `{}` @@ -788,7 +786,59 @@ Fast distributed SQL query engine for big data analytics that helps you explore - path: / pathType: ImplementationSpecific ``` -* `ingress.tls` - list, default: `[]` +* `ingress.tls` - list, default: `[]` + + Ingress [TLS](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) configuration. + Example: + ```yaml + - secretName: chart-example-tls + hosts: + - chart-example.local + ``` +* `networkPolicy.enabled` - bool, default: `false` + + Set to true to enable Trino Pod protection with a [Network Policy](https://kubernetes.io/docs/concepts/services-networking/network-policies/). By default, the policy will only allow Trino Pods to communicate with each other. + > [!NOTE] + > - NetworkPolicies cannot block the ingress traffic coming directly + > from the Kubernetes node on which the Pod is running, + > and are thus incompatible with Services of type `NodePort`. + > - When using Network Policies together with JMX metrics export, + > additional ingress rules might be required to allow metric scraping. +* `networkPolicy.ingress` - list, default: `[]` + + Additional ingress rules to apply to the Trino Pods. + Example: + ```yaml + - from: + - ipBlock: + cidr: 172.17.0.0/16 + except: + - 172.17.1.0/24 + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: prometheus + - podSelector: + matchLabels: + role: backend-app + ports: + - protocol: TCP + port: 8080 + - protocol: TCP + port: 5556 + ``` +* `networkPolicy.egress` - list, default: `[]` + + Egress rules to apply to the Trino Pods. + Example: + ```yaml + - to: + - podSelector: + matchLabels: + role: log-ingestor + ports: + - protocol: TCP + port: 9999 + ``` ---------------------------------------------- Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2) diff --git a/charts/trino/templates/networkpolicy.yaml b/charts/trino/templates/networkpolicy.yaml new file mode 100644 index 00000000..c4081aa0 --- /dev/null +++ b/charts/trino/templates/networkpolicy.yaml @@ -0,0 +1,35 @@ +{{- if .Values.networkPolicy.enabled }} +{{- if eq "NodePort" .Values.service.type}} +{{- fail "NetworkPolicy enforcement is not supported with NodePort Services, as traffic reaches the Pod through the node itself, bypassing Pod-level network controls." }} +{{- end }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "trino.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "trino.labels" . | nindent 4 }} + app.kubernetes.io/component: network-policy +spec: + podSelector: + matchLabels: + {{- include "trino.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + {{- with .Values.networkPolicy.egress }} + - Egress + egress: + {{- toYaml . | nindent 4 }} + {{- end }} + ingress: + - from: + - podSelector: + matchLabels: + {{- include "trino.selectorLabels" . | nindent 14 }} + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ .Release.Namespace }} + {{- with .Values.networkPolicy.ingress }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/trino/templates/tests/test-connection.yaml b/charts/trino/templates/tests/test-connection.yaml index 4e4a5f20..0083f233 100644 --- a/charts/trino/templates/tests/test-connection.yaml +++ b/charts/trino/templates/tests/test-connection.yaml @@ -3,7 +3,6 @@ kind: Pod metadata: name: {{ include "trino.fullname" . }}-test-connection labels: - {{- include "trino.labels" . | nindent 4 }} app.kubernetes.io/component: test test: connection annotations: diff --git a/charts/trino/templates/tests/test-graceful-shutdown.yaml b/charts/trino/templates/tests/test-graceful-shutdown.yaml index 79d93531..5496efa0 100644 --- a/charts/trino/templates/tests/test-graceful-shutdown.yaml +++ b/charts/trino/templates/tests/test-graceful-shutdown.yaml @@ -5,7 +5,6 @@ metadata: name: {{ include "trino.fullname" . }}-pod-manager namespace: {{ .Release.Namespace }} labels: - {{- include "trino.labels" . | nindent 4 }} app.kubernetes.io/component: test test: graceful-shutdown annotations: diff --git a/charts/trino/templates/tests/test-jmx.yaml b/charts/trino/templates/tests/test-jmx.yaml index a968cc8f..c5e0e31b 100644 --- a/charts/trino/templates/tests/test-jmx.yaml +++ b/charts/trino/templates/tests/test-jmx.yaml @@ -8,7 +8,6 @@ kind: Pod metadata: name: {{ include "trino.fullname" . }}-test-jmx labels: - {{- include "trino.labels" . | nindent 4 }} app.kubernetes.io/component: test test: jmx annotations: diff --git a/charts/trino/templates/tests/test-networkpolicy.yaml b/charts/trino/templates/tests/test-networkpolicy.yaml new file mode 100644 index 00000000..265b415f --- /dev/null +++ b/charts/trino/templates/tests/test-networkpolicy.yaml @@ -0,0 +1,28 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "trino.fullname" . }}-test-networkpolicy + labels: + app.kubernetes.io/component: test + test: network-policy + annotations: + "helm.sh/hook": test + "helm.sh/hook-weight": "0" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + containers: + - name: check-connection + image: {{ include "trino.image" . }} + command: [ "/bin/bash", "-c" ] + args: + - >- + curl + {{ include "trino.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.port }} + --head + --fail + --connect-timeout 10 + --max-time 10 + 2>&1 | grep -q "timed out" + restartPolicy: Never +{{- end }} diff --git a/charts/trino/values.yaml b/charts/trino/values.yaml index dea9d48f..c4700496 100644 --- a/charts/trino/values.yaml +++ b/charts/trino/values.yaml @@ -62,17 +62,17 @@ server: exchangeManager: {} # server.exchangeManager -- Mandatory [exchange manager # configuration](https://trino.io/docs/current/admin/fault-tolerant-execution.html#id1). + # Used to set the name and location(s) of the spooling storage destination. To enable fault-tolerant execution, + # set the `retry-policy` property in `additionalConfigProperties`. Additional exchange manager configurations can be + # added to `additionalExchangeManagerProperties`. # @raw - # Used to set the name and location(s) of the spooling storage destination. - # * To enable fault-tolerant execution, you must set the `retry-policy` property in `additionalConfigProperties`. - # * Additional exchange manager configurations can be added to `additionalExchangeManagerProperties`. # Example: # ```yaml - # server: - # exchangeManager: - # name: "filesystem" - # baseDir: "/tmp/trino-local-file-system-exchange-manager" - # additionalConfigProperties: + # server: + # exchangeManager: + # name: "filesystem" + # baseDir: "/tmp/trino-local-file-system-exchange-manager" + # additionalConfigProperties: # - retry-policy=TASK # additionalExchangeManagerProperties: # - exchange.sink-buffer-pool-min-size=10 @@ -85,9 +85,11 @@ server: autoscaling: enabled: false maxReplicas: 5 - # -- Target average CPU utilization, represented as a percentage of requested CPU. To disable scaling based on CPU, set to an empty string. + # -- Target average CPU utilization, represented as a percentage of requested CPU. To disable scaling based on CPU, + # set to an empty string. targetCPUUtilizationPercentage: 50 - # -- Target average memory utilization, represented as a percentage of requested memory. To disable scaling based on memory, set to an empty string. + # -- Target average memory utilization, represented as a percentage of requested memory. To disable scaling + # based on memory, set to an empty string. targetMemoryUtilizationPercentage: 80 behavior: {} # server.autoscaling.behavior -- Configuration for scaling up and down. @@ -334,7 +336,8 @@ env: [] # ``` envFrom: [] -# envFrom -- additional environment variables added to every pod, specified as a list of either ConfigMap or Secret references +# envFrom -- additional environment variables added to every pod, specified as a list of either `ConfigMap` +# or `Secret` references # @raw # Example: # ```yaml @@ -390,7 +393,9 @@ containerSecurityContext: # -- Control whether a process can gain more privileges than its parent process. allowPrivilegeEscalation: false capabilities: - # -- A list of the Linux kernel capabilities that are dropped from every container. Valid values are listed at https://man7.org/linux/man-pages/man7/capabilities.7.html Ensure to remove the "CAP_" prefix which the kernel attaches to the names of permissions. + # -- A list of the Linux kernel capabilities that are dropped from every container. Valid values are listed in + # [the capabilities manual page](https://man7.org/linux/man-pages/man7/capabilities.7.html). Ensure # to remove + # the "CAP_" prefix which the kernel attaches to the names of permissions. drop: - ALL @@ -402,7 +407,9 @@ service: annotations: {} type: ClusterIP port: 8080 - # service.nodePort -- The port the service listens on the host, for NodePort type. If not set, Kubernetes will [allocate a port automatically](https://kubernetes.io/docs/concepts/services-networking/service/#nodeport-custom-port). + # service.nodePort -- The port the service listens on the host, for the `NodePort` type. If not set, Kubernetes will + # [allocate a port + # automatically](https://kubernetes.io/docs/concepts/services-networking/service/#nodeport-custom-port). nodePort: "" auth: {} @@ -684,12 +691,11 @@ worker: enabled: false gracePeriodSeconds: 120 # worker.gracefulShutdown -- Configure [graceful - # shutdown](https://trino.io/docs/current/admin/graceful-shutdown.html) - # in order to ensure that workers terminate without affecting running queries, - # given a sufficient grace period. - # When enabled, the value of `worker.terminationGracePeriodSeconds` must be at least two times greater than the configured `gracePeriodSeconds`. - # Enabling `worker.gracefulShutdown` conflicts with `worker.lifecycle`. When a custom - # `worker.lifecycle` configuration needs to be used, graceful shutdown must be configured manually. + # shutdown](https://trino.io/docs/current/admin/graceful-shutdown.html) in order to ensure that workers terminate + # without affecting running queries, given a sufficient grace period. When enabled, the value of + # `worker.terminationGracePeriodSeconds` must be at least two times greater than the configured `gracePeriodSeconds`. + # Enabling `worker.gracefulShutdown` conflicts with `worker.lifecycle`. When a custom `worker.lifecycle` configuration + # needs to be used, graceful shutdown must be configured manually. # # @raw # Example: @@ -815,7 +821,8 @@ jmx: pullPolicy: Always port: 5556 configProperties: "" - # jmx.exporter.configProperties -- The string value is templated using `tpl`. JMX Config Properties is mounted to /etc/jmx-exporter/jmx-exporter-config.yaml + # jmx.exporter.configProperties -- The string value is templated using `tpl`. The JMX config properties file + # is mounted to `/etc/jmx-exporter/jmx-exporter-config.yaml`. # @raw # Example: # ```yaml @@ -839,6 +846,7 @@ jmx: # value: '$2' # help: 'ThreadCount (java.lang<>ThreadCount)' # type: UNTYPED + # ``` securityContext: {} resources: {} # jmx.exporter.resources -- It is recommended not to specify default resources @@ -882,7 +890,8 @@ jmx: # ``` serviceMonitor: - # serviceMonitor.enabled -- Set to true to create resources for the [prometheus-operator](https://github.com/prometheus-operator/prometheus-operator). + # serviceMonitor.enabled -- Set to true to create resources for the + # [prometheus-operator](https://github.com/prometheus-operator/prometheus-operator). enabled: false # serviceMonitor.labels -- Labels for serviceMonitor, so that Prometheus can select it labels: @@ -939,3 +948,51 @@ ingress: # hosts: # - chart-example.local # ``` + +networkPolicy: + # networkPolicy.enabled -- Set to true to enable Trino Pod protection with a [Network + # Policy](https://kubernetes.io/docs/concepts/services-networking/network-policies/). + # By default, the policy will only allow Trino Pods to communicate with each other. + # @raw + # > [!NOTE] + # > - NetworkPolicies cannot block the ingress traffic coming directly + # > from the Kubernetes node on which the Pod is running, + # > and are thus incompatible with Services of type `NodePort`. + # > - When using Network Policies together with JMX metrics export, + # > additional ingress rules might be required to allow metric scraping. + enabled: false + # networkPolicy.ingress -- Additional ingress rules to apply to the Trino Pods. + # @raw + # Example: + # ```yaml + # - from: + # - ipBlock: + # cidr: 172.17.0.0/16 + # except: + # - 172.17.1.0/24 + # - namespaceSelector: + # matchLabels: + # kubernetes.io/metadata.name: prometheus + # - podSelector: + # matchLabels: + # role: backend-app + # ports: + # - protocol: TCP + # port: 8080 + # - protocol: TCP + # port: 5556 + # ``` + ingress: [] + # networkPolicy.egress -- Egress rules to apply to the Trino Pods. + # @raw + # Example: + # ```yaml + # - to: + # - podSelector: + # matchLabels: + # role: log-ingestor + # ports: + # - protocol: TCP + # port: 9999 + # ``` + egress: [] diff --git a/test-networkpolicy.yaml b/test-networkpolicy.yaml new file mode 100644 index 00000000..9215833a --- /dev/null +++ b/test-networkpolicy.yaml @@ -0,0 +1,9 @@ +networkPolicy: + enabled: true + ingress: + - from: + - podSelector: + matchExpressions: + - key: test + operator: NotIn + values: [network-policy] diff --git a/test.sh b/test.sh index 0b208033..5b105b02 100755 --- a/test.sh +++ b/test.sh @@ -10,6 +10,7 @@ declare -A testCases=( [access_control_properties_values]="--values test-access-control-properties-values.yaml" [exchange_manager_values]="--values test-exchange-manager-values.yaml" [graceful_shutdown]="--values test-graceful-shutdown-values.yaml" + [network_policy]="--values test-networkpolicy.yaml" ) function join_by { @@ -24,7 +25,7 @@ NAMESPACE=trino-$(LC_ALL=C tr -dc 'a-z0-9' &2