diff --git a/.github/workflows/helm-chart.yml b/.github/workflows/helm-chart.yml index 9a9a0441c22..62eda1a58b0 100644 --- a/.github/workflows/helm-chart.yml +++ b/.github/workflows/helm-chart.yml @@ -63,9 +63,9 @@ jobs: # which a folder exists at # https://github.com/yannh/kubernetes-json-schema/ k8s: - - v1.28.13 - - v1.29.8 - - v1.30.4 + - v1.33.7 + - v1.34.3 + - v1.35.1 steps: - name: Checkout uses: actions/checkout@v6 @@ -92,9 +92,9 @@ jobs: # available for the docker.io/kindest/node image # https://hub.docker.com/r/kindest/node/tags k8s: - - v1.28.13 - - v1.29.8 - - v1.30.4 + - v1.33.7 + - v1.34.3 + - v1.35.1 steps: - name: Checkout uses: actions/checkout@v6 diff --git a/deployment/helm/ditto/Chart.yaml b/deployment/helm/ditto/Chart.yaml index 6e40119e311..1bc58246896 100644 --- a/deployment/helm/ditto/Chart.yaml +++ b/deployment/helm/ditto/Chart.yaml @@ -16,8 +16,8 @@ description: | A digital twin is a virtual, cloud based, representation of his real world counterpart (real world “Things”, e.g. devices like sensors, smart heating, connected cars, smart grids, EV charging stations etc). type: application -version: 3.8.19 # chart version is effectively set by release-job -appVersion: 3.9.0-M2 +version: 4.0.0 # chart version is effectively set by release-job +appVersion: 3.9.0-M3 keywords: - iot-chart - digital-twin diff --git a/deployment/helm/ditto/ci/ci-workflow-values.yaml b/deployment/helm/ditto/ci/ci-workflow-values.yaml index f47e2e3a19c..6f441790d0b 100644 --- a/deployment/helm/ditto/ci/ci-workflow-values.yaml +++ b/deployment/helm/ditto/ci/ci-workflow-values.yaml @@ -18,8 +18,6 @@ ingress: enabled: true host: ditto.example.com - annotations: - # kubernetes.io/tls-acme: "true" tls: - secretName: ditto-tls hosts: diff --git a/deployment/helm/ditto/templates/nginx-ingress-api.yaml b/deployment/helm/ditto/templates/ingress-api.yaml similarity index 56% rename from deployment/helm/ditto/templates/nginx-ingress-api.yaml rename to deployment/helm/ditto/templates/ingress-api.yaml index 96394c2fd7a..0702d37f5b7 100644 --- a/deployment/helm/ditto/templates/nginx-ingress-api.yaml +++ b/deployment/helm/ditto/templates/ingress-api.yaml @@ -8,7 +8,7 @@ # http://www.eclipse.org/legal/epl-2.0 # # SPDX-License-Identifier: EPL-2.0 -{{- if .Values.ingress.enabled -}} +{{- if and .Values.ingress.enabled .Values.ingress.api.enabled }} {{- $fullName := include "ditto.fullname" . -}} --- apiVersion: networking.k8s.io/v1 @@ -17,48 +17,32 @@ metadata: name: {{ $fullName }}-api namespace: {{ .Release.Namespace }} labels: - app.kubernetes.io/name: {{ include "ditto.name" . }}-nginx -{{ include "ditto.labels" . | indent 4 }} - annotations: - {{- with .Values.ingress.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{ tpl .Values.ingress.api.kubernetesAuthAnnotations . | nindent 4}} + {{- include "ditto.labels" . | nindent 4 }} {{- with .Values.ingress.api.annotations }} + annotations: {{- toYaml . | nindent 4 }} {{- end }} spec: + {{- if .Values.ingress.className }} ingressClassName: {{ .Values.ingress.className }} - defaultBackend: - service: - name: {{ $fullName }}-{{ .Values.ingress.defaultBackendSuffix }} - port: - name: http -{{- if .Values.ingress.tls }} + {{- end }} + {{- if .Values.ingress.tls }} tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} + {{- toYaml .Values.ingress.tls | nindent 4 }} {{- end }} -{{- end }} rules: - - host: {{ .Values.ingress.host | quote }} + - {{- if .Values.ingress.host }} + host: {{ .Values.ingress.host | quote }} + {{- end }} http: paths: {{- range .Values.ingress.api.paths }} - path: {{ .path }} - {{- if .pathType }} pathType: {{ .pathType }} - {{- else }} - pathType: Prefix - {{- end }} backend: service: - name: {{ $fullName }}-{{ .backendSuffix }} + name: {{ $fullName }}-{{ .service.name }} port: name: http {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/deployment/helm/ditto/templates/nginx-ingress-devops.yaml b/deployment/helm/ditto/templates/ingress-devops.yaml similarity index 54% rename from deployment/helm/ditto/templates/nginx-ingress-devops.yaml rename to deployment/helm/ditto/templates/ingress-devops.yaml index d01c7ea9016..f938344d0f4 100644 --- a/deployment/helm/ditto/templates/nginx-ingress-devops.yaml +++ b/deployment/helm/ditto/templates/ingress-devops.yaml @@ -8,7 +8,7 @@ # http://www.eclipse.org/legal/epl-2.0 # # SPDX-License-Identifier: EPL-2.0 -{{- if .Values.ingress.enabled -}} +{{- if and .Values.ingress.enabled .Values.ingress.devops.enabled }} {{- $fullName := include "ditto.fullname" . -}} --- apiVersion: networking.k8s.io/v1 @@ -17,54 +17,32 @@ metadata: name: {{ $fullName }}-devops namespace: {{ .Release.Namespace }} labels: - app.kubernetes.io/name: {{ include "ditto.name" . }}-nginx -{{ include "ditto.labels" . | indent 4 }} - annotations: - {{- with .Values.ingress.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- if .Values.ingress.devops.annotations }} + {{- include "ditto.labels" . | nindent 4 }} {{- with .Values.ingress.devops.annotations }} + annotations: {{- toYaml . | nindent 4 }} {{- end }} - {{- else }} - {{- with .Values.ingress.api.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- end }} - spec: + {{- if .Values.ingress.className }} ingressClassName: {{ .Values.ingress.className }} - defaultBackend: - service: - name: {{ $fullName }}-{{ .Values.ingress.defaultBackendSuffix }} - port: - name: http -{{- if .Values.ingress.tls }} + {{- end }} + {{- if .Values.ingress.tls }} tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} + {{- toYaml .Values.ingress.tls | nindent 4 }} {{- end }} -{{- end }} rules: - - host: {{ .Values.ingress.host | quote }} + - {{- if .Values.ingress.host }} + host: {{ .Values.ingress.host | quote }} + {{- end }} http: paths: {{- range .Values.ingress.devops.paths }} - path: {{ .path }} - {{- if .pathType }} pathType: {{ .pathType }} - {{- else }} - pathType: Prefix - {{- end }} backend: service: - name: {{ $fullName }}-{{ .backendSuffix }} + name: {{ $fullName }}-{{ .service.name }} port: name: http {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/deployment/helm/ditto/templates/nginx-ingress-ui.yaml b/deployment/helm/ditto/templates/ingress-ui.yaml similarity index 62% rename from deployment/helm/ditto/templates/nginx-ingress-ui.yaml rename to deployment/helm/ditto/templates/ingress-ui.yaml index e1d7b999603..c73cdabaaae 100644 --- a/deployment/helm/ditto/templates/nginx-ingress-ui.yaml +++ b/deployment/helm/ditto/templates/ingress-ui.yaml @@ -8,7 +8,7 @@ # http://www.eclipse.org/legal/epl-2.0 # # SPDX-License-Identifier: EPL-2.0 -{{- if .Values.ingress.enabled -}} +{{- if and .Values.ingress.enabled .Values.ingress.ui.enabled }} {{- $fullName := include "ditto.fullname" . -}} --- apiVersion: networking.k8s.io/v1 @@ -17,47 +17,39 @@ metadata: name: {{ $fullName }}-ui namespace: {{ .Release.Namespace }} labels: - app.kubernetes.io/name: {{ include "ditto.name" . }}-nginx -{{ include "ditto.labels" . | indent 4 }} - annotations: - {{- with .Values.ingress.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} + {{- include "ditto.labels" . | nindent 4 }} {{- with .Values.ingress.ui.annotations }} + annotations: {{- toYaml . | nindent 4 }} {{- end }} spec: + {{- if .Values.ingress.className }} ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.ui.defaultBackend }} defaultBackend: service: - name: {{ $fullName }}-{{ .Values.ingress.defaultBackendSuffix }} + name: {{ $fullName }}-{{ .Values.ingress.ui.defaultBackend.service.name }} port: name: http -{{- if .Values.ingress.tls }} + {{- end }} + {{- if .Values.ingress.tls }} tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} + {{- toYaml .Values.ingress.tls | nindent 4 }} {{- end }} -{{- end }} rules: - - host: {{ .Values.ingress.host | quote }} + - {{- if .Values.ingress.host }} + host: {{ .Values.ingress.host | quote }} + {{- end }} http: paths: {{- range .Values.ingress.ui.paths }} - path: {{ .path }} - {{- if .pathType }} pathType: {{ .pathType }} - {{- else }} - pathType: Prefix - {{- end }} backend: service: - name: {{ $fullName }}-{{ .backendSuffix }} + name: {{ $fullName }}-{{ .service.name }} port: name: http {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/deployment/helm/ditto/templates/nginx-ingress-ws.yaml b/deployment/helm/ditto/templates/ingress-ws.yaml similarity index 56% rename from deployment/helm/ditto/templates/nginx-ingress-ws.yaml rename to deployment/helm/ditto/templates/ingress-ws.yaml index 02d1656d757..d5c11760225 100644 --- a/deployment/helm/ditto/templates/nginx-ingress-ws.yaml +++ b/deployment/helm/ditto/templates/ingress-ws.yaml @@ -8,7 +8,7 @@ # http://www.eclipse.org/legal/epl-2.0 # # SPDX-License-Identifier: EPL-2.0 -{{- if .Values.ingress.enabled -}} +{{- if and .Values.ingress.enabled .Values.ingress.ws.enabled }} {{- $fullName := include "ditto.fullname" . -}} --- apiVersion: networking.k8s.io/v1 @@ -17,48 +17,32 @@ metadata: name: {{ $fullName }}-ws namespace: {{ .Release.Namespace }} labels: - app.kubernetes.io/name: {{ include "ditto.name" . }}-nginx -{{ include "ditto.labels" . | indent 4 }} - annotations: - {{- with .Values.ingress.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} + {{- include "ditto.labels" . | nindent 4 }} {{- with .Values.ingress.ws.annotations }} + annotations: {{- toYaml . | nindent 4 }} {{- end }} - {{ tpl .Values.ingress.api.kubernetesAuthAnnotations . | nindent 4}} spec: + {{- if .Values.ingress.className }} ingressClassName: {{ .Values.ingress.className }} - defaultBackend: - service: - name: {{ $fullName }}-{{ .Values.ingress.defaultBackendSuffix }} - port: - name: http -{{- if .Values.ingress.tls }} + {{- end }} + {{- if .Values.ingress.tls }} tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} + {{- toYaml .Values.ingress.tls | nindent 4 }} {{- end }} -{{- end }} rules: - - host: {{ .Values.ingress.host | quote }} + - {{- if .Values.ingress.host }} + host: {{ .Values.ingress.host | quote }} + {{- end }} http: paths: {{- range .Values.ingress.ws.paths }} - path: {{ .path }} - {{- if .pathType }} pathType: {{ .pathType }} - {{- else }} - pathType: Prefix - {{- end }} backend: service: - name: {{ $fullName }}-{{ .backendSuffix }} + name: {{ $fullName }}-{{ .service.name }} port: name: http {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/deployment/helm/ditto/templates/nginx-ingress-auth.yaml b/deployment/helm/ditto/templates/nginx-ingress-auth.yaml deleted file mode 100644 index 6d2adeb77f7..00000000000 --- a/deployment/helm/ditto/templates/nginx-ingress-auth.yaml +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (c) 2023 Contributors to the Eclipse Foundation -# -# See the NOTICE file(s) distributed with this work for additional -# information regarding copyright ownership. -# -# This program and the accompanying materials are made available under the -# terms of the Eclipse Public License 2.0 which is available at -# http://www.eclipse.org/legal/epl-2.0 -# -# SPDX-License-Identifier: EPL-2.0 -{{- if .Values.ingress.enabled -}} -{{- $releaseName := .Release.Name -}} -{{- $name := include "ditto.name" . -}} -{{- $labels := include "ditto.labels" . -}} ---- -apiVersion: v1 -kind: Secret -metadata: - name: {{ $releaseName }}-nginx-ingress-htpasswd - namespace: {{ .Release.Namespace }} - labels: - app.kubernetes.io/name: {{ $name }}-nginx-ingress-config -{{ $labels | indent 4 }} -type: Opaque -stringData: - auth: |- -{{- if .Values.global.hashedBasicAuthUsers }} - {{ range .Values.global.hashedBasicAuthUsers }} - {{- . | indent 4 }} - {{ end }} -{{- else }} - {{- if (quote .Values.global.existingSecret | empty) }} - {{ range $key, $value := .Values.global.basicAuthUsers }} - {{- (htpasswd $value.user $value.password) | indent 4 }} - {{ end }} - {{- else }} - {{- $secret := lookup "v1" "Secret" $.Release.Namespace .Values.global.existingSecret }} - {{- if $secret }} - {{- range $user, $password := $secret.data }} - {{ htpasswd $user ($password | b64dec) | indent 4 }} - {{- end }} - {{- else}} - {{- fail (printf "Missing provided existingSecret for basicAuthUsers: %s" .Values.global.existingSecret) }} - {{- end }} - {{ end }} -{{ end }} ---- -{{- end }} diff --git a/deployment/helm/ditto/templates/nginx-ingress-root.yaml b/deployment/helm/ditto/templates/nginx-ingress-root.yaml deleted file mode 100644 index ef292c2409d..00000000000 --- a/deployment/helm/ditto/templates/nginx-ingress-root.yaml +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (c) 2023 Contributors to the Eclipse Foundation -# -# See the NOTICE file(s) distributed with this work for additional -# information regarding copyright ownership. -# -# This program and the accompanying materials are made available under the -# terms of the Eclipse Public License 2.0 which is available at -# http://www.eclipse.org/legal/epl-2.0 -# -# SPDX-License-Identifier: EPL-2.0 -{{- if .Values.ingress.enabled -}} -{{- $fullName := include "ditto.fullname" . -}} ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ $fullName }}-root - namespace: {{ .Release.Namespace }} - labels: - app.kubernetes.io/name: {{ include "ditto.name" . }}-nginx -{{ include "ditto.labels" . | indent 4 }} - annotations: - {{- with .Values.ingress.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} - {{- with .Values.ingress.root.annotations }} - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - ingressClassName: {{ .Values.ingress.className }} - defaultBackend: - service: - name: {{ $fullName }}-{{ .Values.ingress.defaultBackendSuffix }} - port: - name: http -{{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} -{{- end }} - rules: - - host: {{ .Values.ingress.host | quote }} - http: - paths: - {{- range .Values.ingress.root.paths }} - - path: {{ .path }} - {{- if .pathType }} - pathType: {{ .pathType }} - {{- else }} - pathType: Prefix - {{- end }} - backend: - service: - name: {{ $fullName }}-{{ .backendSuffix }} - port: - name: http - {{- end }} -{{- end }} diff --git a/deployment/helm/ditto/templates/nginx-ingress.yaml b/deployment/helm/ditto/templates/nginx-ingress.yaml deleted file mode 100644 index b6e337cdde6..00000000000 --- a/deployment/helm/ditto/templates/nginx-ingress.yaml +++ /dev/null @@ -1,854 +0,0 @@ -# Copyright (c) 2023 Contributors to the Eclipse Foundation -# -# See the NOTICE file(s) distributed with this work for additional -# information regarding copyright ownership. -# -# This program and the accompanying materials are made available under the -# terms of the Eclipse Public License 2.0 which is available at -# http://www.eclipse.org/legal/epl-2.0 -# -# SPDX-License-Identifier: EPL-2.0 -{{- if .Values.ingress.controller.enabled -}} ---- -apiVersion: v1 -kind: Namespace -metadata: - name: "{{ .Values.ingress.controller.namespace }}" - labels: - name: "{{ .Values.ingress.controller.namespace }}" ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: nginx-node-health-check-conf - namespace: "{{ .Values.ingress.controller.namespace }}" -data: - nginx-node-health-check.conf: | - # config for health check container running together with the ingress controller - worker_processes 1; - - events { - worker_connections 1024; - } - - http { - charset utf-8; - - server { - listen 8080; - server_name localhost; - - location /healthz { - add_header Content-Type text-plain; - return 200 'ok'; - } - - } - } - ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.namespace }}" - name: "{{ .Values.ingress.controller.namespace }}" - namespace: "{{ .Values.ingress.controller.namespace }}" -spec: - selector: - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - ports: - - name: tcp - port: 80 - protocol: TCP - ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxIngressVersion }}" - name: nginx-ingress-controller-admission - namespace: "{{ .Values.ingress.controller.namespace }}" -spec: - ports: - - appProtocol: https - name: https-webhook - port: 443 - targetPort: webhook - selector: - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - type: ClusterIP - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-configuration - namespace: "{{ .Values.ingress.controller.namespace }}" -data: - allow-snippet-annotations: "True" - worker-processes: "{{ .Values.ingress.controller.config.workerProcesses }}" - max-worker-connections: "{{ .Values.ingress.controller.config.workerConnections }}" # 0 will use the value of max-worker-open-files - max-worker-open-files: "{{ .Values.ingress.controller.config.workerOpenFiles }}" # the default of 0 means "max open files (system's limit) / worker-processes - 1024" - server-tokens: "False" - use-gzip: "True" - gzip-level: "6" - gzip-types: "text/plain text/css text/js text/xml text/javascript application/javascript application/x-javascript application/json application/xml application/xml+rss" - location-snippet: | - more_set_headers "Strict-Transport-Security: max-age=31536000; includeSubDomains"; - more_set_headers 'X-Content-Type-Options: "nosniff"'; - more_set_headers 'X-Frame-Options: "SAMEORIGIN"'; - more_set_headers 'X-XSS-Protection: "1; mode=block"'; - default_type application/octet-stream; - gzip_disable "msie6"; - gzip_min_length 1100; - gzip_buffers 16 8k; - gzip_proxied any; - gunzip on; - gzip_static always; - gzip_vary on; - - tcp_nopush on; - - # timeouts are configured slightly higher than gateway read-timeout of 60 seconds - send_timeout 70; # seconds, default: 60 - - # ignore X-Original-URI in the request - proxy_hide_header X-Original-URI; - - - # set ditto-specific forwarded headers - needed in the location for registry.k8s.io/ingress-nginx/controller - proxy_set_header X-Forwarded-User $remote_user; - proxy_set_header x-ditto-pre-authenticated "nginx:$remote_user"; - - proxy-connect-timeout: "10" # seconds, default: 60 - # timeouts are configured slightly higher than gateway read-timeout of 60 seconds - proxy-send-timeout: "70" # seconds, default: 60 - proxy-read-timeout: "70" # seconds, default: 60 - # will try another upstream if an error or timeout occurred during the connection - # or if the upstream returns 502 response - proxy-next-upstream: "error timeout http_502" - # will retry up to 4 times to find another upstream to connect to - proxy-next-upstream-tries: "4" - # will try for max. 50s to find another upstream to connect to - proxy-next-upstream-timeout: "50" - client-header-buffer-size: "8k" # allow longer URIs + headers (default: 1k) - large-client-header-buffers: "4 16k" - keep-alive: "75" #seconds, default: 75 - log-format-upstream: '$remote_addr - "$remote_user" [$time_local] "$host" "$request" $status $bytes_sent "$upstream_addr" "$http_referer" "$http_user_agent" "$http_origin" "$http_content_type"' - use-forwarded-headers: "True" - http-snippet: | - charset utf-8; - sendfile on; - - # timeouts are configured slightly higher than gateway read-timeout of 60 seconds - send_timeout 70; # seconds, default: 60 - - merge_slashes off; # allow multiple slashes for CRS Authentication - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: tcp-services - namespace: "{{ .Values.ingress.controller.namespace }}" - ---- -apiVersion: v1 -kind: ConfigMap -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: udp-services - namespace: "{{ .Values.ingress.controller.namespace }}" - ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-serviceaccount - namespace: "{{ .Values.ingress.controller.namespace }}" - ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/component: admission-webhook - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-admission - namespace: "{{ .Values.ingress.controller.namespace }}" - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-role - namespace: "{{ .Values.ingress.controller.namespace }}" -rules: - - apiGroups: - - "" - resources: - - namespaces - verbs: - - get - - apiGroups: - - "" - resources: - - configmaps - - pods - - secrets - - endpoints - - services - verbs: - - get - - list - - watch - - apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - get - - list - - watch - - apiGroups: - - networking.k8s.io - resources: - - ingresses/status - verbs: - - update - - apiGroups: - - networking.k8s.io - resources: - - ingressclasses - verbs: - - get - - list - - watch - - apiGroups: - - "" - resourceNames: - - ingress-controller-leader - resources: - - configmaps - verbs: - - get - - update - - apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - apiGroups: - - coordination.k8s.io - resourceNames: - - ingress-controller-leader - resources: - - leases - verbs: - - get - - update - - apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - create - - apiGroups: - - "" - resources: - - events - verbs: - - create - - patch - - apiGroups: - - discovery.k8s.io - resources: - - endpointslices - verbs: - - list - - watch - - get - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - labels: - app.kubernetes.io/component: admission-webhook - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-admission - namespace: "{{ .Values.ingress.controller.namespace }}" -rules: - - apiGroups: - - "" - resources: - - secrets - verbs: - - get - - create - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: "{{ .Values.ingress.controller.namespace }}-clusterrole" -rules: - - apiGroups: - - "" - resources: - - configmaps - - endpoints - - nodes - - pods - - secrets - - namespaces - verbs: - - list - - watch - - apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - list - - watch - - apiGroups: - - "" - resources: - - nodes - verbs: - - get - - apiGroups: - - "" - resources: - - services - verbs: - - get - - list - - watch - - apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - get - - list - - watch - - apiGroups: - - "" - resources: - - events - verbs: - - create - - patch - - apiGroups: - - networking.k8s.io - resources: - - ingresses/status - verbs: - - update - - apiGroups: - - networking.k8s.io - resources: - - ingressclasses - verbs: - - get - - list - - watch - - apiGroups: - - discovery.k8s.io - resources: - - endpointslices - verbs: - - list - - watch - - get - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/component: admission-webhook - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-admission -rules: - - apiGroups: - - admissionregistration.k8s.io - resources: - - validatingwebhookconfigurations - verbs: - - get - - update - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-role-binding - namespace: "{{ .Values.ingress.controller.namespace }}" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: nginx-ingress-role -subjects: -- kind: ServiceAccount - name: nginx-ingress-serviceaccount - namespace: "{{ .Values.ingress.controller.namespace }}" - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - labels: - app.kubernetes.io/component: admission-webhook - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-admission - namespace: "{{ .Values.ingress.controller.namespace }}" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: nginx-ingress-admission -subjects: - - kind: ServiceAccount - name: nginx-ingress-admission - namespace: "{{ .Values.ingress.controller.namespace }}" - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: "{{ .Values.ingress.controller.namespace }}-clusterrole-binding" -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: "{{ .Values.ingress.controller.namespace }}-clusterrole" -subjects: -- kind: ServiceAccount - name: nginx-ingress-serviceaccount - namespace: "{{ .Values.ingress.controller.namespace }}" - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/component: admission-webhook - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-admission -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: nginx-ingress-admission -subjects: - - kind: ServiceAccount - name: nginx-ingress-admission - namespace: "{{ .Values.ingress.controller.namespace }}" - ---- -apiVersion: scheduling.k8s.io/v1 -kind: PriorityClass -metadata: - name: high-priority -value: 1000000 -globalDefault: false -description: "This priority class is used for the things and gateway service pods only." - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-controller - namespace: "{{ .Values.ingress.controller.namespace }}" -spec: - replicas: {{ .Values.ingress.controller.replicaCount }} - selector: - matchLabels: - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - strategy: - type: {{ .Values.ingress.controller.updateStrategy.type }} - rollingUpdate: - maxSurge: {{ .Values.ingress.controller.updateStrategy.rollingUpdate.maxSurge }} - maxUnavailable: {{ .Values.ingress.controller.updateStrategy.rollingUpdate.maxUnavailable }} - minReadySeconds: {{ .Values.ingress.controller.minReadySeconds }} - revisionHistoryLimit: {{ .Values.ingress.controller.revisionHistoryLimit }} - template: - metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - annotations: - prometheus.io/port: "10254" - prometheus.io/scrape: "true" - checksum/nginx-auth: {{ include (print $.Template.BasePath "/nginx-ingress-auth.yaml") . | sha256sum }} - spec: - priorityClassName: high-priority - serviceAccountName: nginx-ingress-serviceaccount - dnsPolicy: ClusterFirst - nodeSelector: - ingress.node: "master" - terminationGracePeriodSeconds: 100 - imagePullSecrets: - - name: acr-secret - securityContext: - fsGroup: 101 - supplementalGroups: [101] - seccompProfile: - type: RuntimeDefault - topologySpreadConstraints: - - maxSkew: {{ .Values.ingress.controller.topologySpreadConstraints.maxSkew }} - topologyKey: {{ .Values.ingress.controller.topologySpreadConstraints.topologyKey }} - whenUnsatisfiable: {{ .Values.ingress.controller.topologySpreadConstraints.whenUnsatisfiable }} - labelSelector: - matchLabels: - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - containers: - - name: nginx-node-health-check - image: docker.io/library/nginx:{{ .Values.ingress.controller.nginxVersion }} - imagePullPolicy: Always - ports: - - name: healthz-port - containerPort: 8080 - hostPort: 31005 - livenessProbe: - httpGet: - path: /healthz - port: 8080 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 15 - timeoutSeconds: 6 - successThreshold: 1 - failureThreshold: 4 - readinessProbe: - httpGet: - path: /healthz - port: 8080 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 10 - timeoutSeconds: 2 - failureThreshold: 3 - successThreshold: 1 - volumeMounts: - - name: nginx-node-health-check-conf - mountPath: /etc/nginx/nginx.conf - subPath: nginx-node-health-check.conf - - name: nginx-ingress-controller - image: registry.k8s.io/ingress-nginx/controller:{{ .Values.ingress.controller.nginxIngressVersion }} - imagePullPolicy: IfNotPresent - args: - - /nginx-ingress-controller - - --publish-service=$(POD_NAMESPACE)/{{ .Values.ingress.controller.namespace }} - - --election-id=ingress-controller-leader - - --controller-class=k8s.io/{{ .Values.ingress.controller.namespace }} - - --ingress-class={{ .Values.ingress.className }} - - --configmap=$(POD_NAMESPACE)/nginx-configuration - - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - - --shutdown-grace-period=65 - - --validating-webhook=:8443 - - --validating-webhook-certificate=/usr/local/certificates/cert - - --validating-webhook-key=/usr/local/certificates/key - securityContext: - capabilities: - drop: - - ALL - add: - - NET_BIND_SERVICE - # www-data -> 101 - runAsUser: 101 - runAsGroup: 101 - runAsNonRoot: true - allowPrivilegeEscalation: true - seccompProfile: - type: RuntimeDefault - lifecycle: - preStop: - exec: - command: ["sleep", "{{ .Values.ingress.controller.preStopWait }}"] - env: - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: LD_PRELOAD - value: /usr/local/lib/libmimalloc.so - ports: - - name: http - containerPort: 80 - hostPort: 30005 - - name: https - containerPort: 443 - protocol: TCP - - name: health - containerPort: 10254 - - name: webhook - containerPort: 8443 - protocol: TCP - livenessProbe: - httpGet: - path: /healthz - port: 10254 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 15 - timeoutSeconds: 6 - successThreshold: 1 - failureThreshold: 4 - readinessProbe: - httpGet: - path: /healthz - port: 10254 - scheme: HTTP - initialDelaySeconds: 10 - periodSeconds: 10 - timeoutSeconds: 2 - failureThreshold: 3 - successThreshold: 1 - resources: - requests: - cpu: {{ mulf .Values.ingress.controller.resources.cpu 1000 }}m - memory: {{ .Values.ingress.controller.resources.memoryMi }}Mi - volumeMounts: - - mountPath: /usr/local/certificates/ - name: webhook-cert - readOnly: true - volumes: - - name: nginx-node-health-check-conf - configMap: - name: nginx-node-health-check-conf - - name: webhook-cert - secret: - secretName: nginx-ingress-admission ---- -apiVersion: batch/v1 -kind: Job -metadata: - labels: - app.kubernetes.io/component: admission-webhook - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-admission-create - namespace: "{{ .Values.ingress.controller.namespace }}" -spec: - template: - metadata: - labels: - app.kubernetes.io/component: admission-webhook - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-admission-create - spec: - containers: - - args: - - create - - --host=nginx-ingress-controller-admission.$(POD_NAMESPACE).svc - - --namespace=$(POD_NAMESPACE) - - --secret-name=nginx-ingress-admission - env: - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f - imagePullPolicy: IfNotPresent - name: create - securityContext: - allowPrivilegeEscalation: false - nodeSelector: - kubernetes.io/os: linux - restartPolicy: OnFailure - securityContext: - fsGroup: 2000 - runAsNonRoot: true - runAsUser: 2000 - serviceAccountName: nginx-ingress-admission - ---- -apiVersion: batch/v1 -kind: Job -metadata: - labels: - app.kubernetes.io/component: admission-webhook - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-admission-patch - namespace: "{{ .Values.ingress.controller.namespace }}" -spec: - template: - metadata: - labels: - app.kubernetes.io/component: admission-webhook - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-admission-patch - spec: - containers: - - args: - - patch - - --webhook-name=nginx-ingress-admission-{{ .Values.ingress.controller.namespace }} - - --namespace=$(POD_NAMESPACE) - - --patch-mutating=false - - --secret-name=nginx-ingress-admission - - --patch-failure-policy=Fail - env: - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20220916-gd32f8c343@sha256:39c5b2e3310dc4264d638ad28d9d1d96c4cbb2b2dcfb52368fe4e3c63f61e10f - imagePullPolicy: IfNotPresent - name: patch - securityContext: - allowPrivilegeEscalation: false - nodeSelector: - kubernetes.io/os: linux - restartPolicy: OnFailure - securityContext: - fsGroup: 2000 - runAsNonRoot: true - runAsUser: 2000 - serviceAccountName: nginx-ingress-admission - ---- -apiVersion: networking.k8s.io/v1 -kind: IngressClass -metadata: - labels: - app.kubernetes.io/component: controller - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: "{{ .Values.ingress.className }}" -spec: - controller: k8s.io/{{ .Values.ingress.controller.namespace }} - ---- -apiVersion: admissionregistration.k8s.io/v1 -kind: ValidatingWebhookConfiguration -metadata: - labels: - app.kubernetes.io/component: admission-webhook - app.kubernetes.io/instance: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/name: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/part-of: "{{ .Values.ingress.controller.namespace }}" - app.kubernetes.io/version: "{{ .Values.ingress.controller.nginxVersion }}" - name: nginx-ingress-admission-{{ .Values.ingress.controller.namespace }} -webhooks: - - admissionReviewVersions: - - v1 - clientConfig: - service: - name: nginx-ingress-controller-admission - namespace: "{{ .Values.ingress.controller.namespace }}" - path: /networking/v1/ingresses - failurePolicy: Fail - matchPolicy: Equivalent - name: validate.nginx.ingress.kubernetes.io - rules: - - apiGroups: - - networking.k8s.io - apiVersions: - - v1 - operations: - - CREATE - - UPDATE - resources: - - ingresses - sideEffects: None -{{- end }} diff --git a/deployment/helm/ditto/values.yaml b/deployment/helm/ditto/values.yaml index 08013402233..8ce1b3d5597 100644 --- a/deployment/helm/ditto/values.yaml +++ b/deployment/helm/ditto/values.yaml @@ -355,244 +355,96 @@ dbconfig: # uriSecret: my-uri-secret ## ---------------------------------------------------------------------------- -## ingress configures the Ingress +## ingress configures the Ingress resources +## Users must bring their own ingress controller (e.g. ingress-nginx, traefik, haproxy, etc.) +## Controller-specific behavior (auth, CORS, timeouts, etc.) should be configured via annotations ingress: - # enabled whether Ingress should be enabled as alternative to the contained nginx + # enabled controls whether Ingress resources are created enabled: false - # className is the 'ingressClassName' to configure in the Ingress spec - className: nginx - # host the hostname of the Ingress shared for all: api, ws and ui - host: localhost - # defaultBackendSuffix the suffix to add to the internal fullname to use as Ingress "defaultBackend" - defaultBackendSuffix: nginx - # annotations common annotations for all 3 Ingresses of Ditto - controller: - # enabled whether Ingress controller should be enabled - enabled: false - # replicaCount configuration for the ingress controller - replicaCount: 1 - # Exposes the ingress controller settings in order to configure its behavior. - config: - # Sets the number of worker processes that should be started by the ingress controller. - # Depending on the load of the ingress controller, this value can be increased or decreased. - # When not sure setting it to auto is also fine, but take cares as that will increase RAM usage. - workerProcesses: 2 - # Sets the maximum number of simultaneous connections that can be opened by each worker process. - # 0 will use the value of max-worker-open-files. default: 16384 - workerConnections: 0 - # Sets the maximum number of files that can be opened by each worker process. - # The default of 0 means "max open files (system's limit) - 1024". - workerOpenFiles: 0 - updateStrategy: - type: RollingUpdate - rollingUpdate: - maxSurge: 1 - maxUnavailable: 1 - # minReadySeconds configures the minimum number of seconds for which a newly created Pod should be ready without any - # of its containers crashing, for it to be considered available - # ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#min-ready-seconds - minReadySeconds: 10 - # as NGINX Ingress Controller on its pod shutdown tends to interrupt connections, we need to include - # some wait time so that existing connections are fully handled before the pod is really shut down. - # ref: https://medium.com/codecademy-engineering/kubernetes-nginx-and-zero-downtime-in-production-2c910c6a5ed8 - preStopWait: 15 - # specify how many old ReplicaSets for ingress controller deployment will be retained - # ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy - revisionHistoryLimit: 5 - # resources configures the resources available/to use for the policies service - resources: - # cpu defines the "required" CPU of a node so that the service is placed there - cpu: 0.75 - # memoryMi defines the memory in mebibyte (MiB) used as "required" and "limit" in k8s - memoryMi: 1024 - # ephemeralStorageMi defines the storage in mebibyte (MiB) used as "required" and "limit" in k8s - ephemeralStorageMi: 2048 - # namespace for ingress controller, managed by helm, should not be created manually - namespace: ingress-nginx - # Ingress-NGINX version. Check Supported Versions table from https://github.com/kubernetes/ingress-nginx to match k8s version. - nginxIngressVersion: "v1.11.5" - # Nginx Version. Check Supported Versions table from https://github.com/kubernetes/ingress-nginx to match k8s version. - nginxVersion: "1.25.5" - # Pod topology spread constraints for nginx-ingress controller - # ref: https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ - topologySpreadConstraints: - maxSkew: 1 - topologyKey: topology.kubernetes.io/zone - whenUnsatisfiable: ScheduleAnyway - annotations: - nginx.ingress.kubernetes.io/service-upstream: "true" - nginx.ingress.kubernetes.io/server-snippet: | - charset utf-8; - default_type application/json; - chunked_transfer_encoding off; - - send_timeout 70; # seconds, default: 60 - client_header_buffer_size 8k; # allow longer URIs + headers (default: 1k) - large_client_header_buffers 4 16k; + # className is the IngressClass to use — set to your ingress controller's class name + className: "" + # host is the optional hostname for all Ingress resources — if empty, no host rule is set (catch-all) + host: "" + # tls configures TLS for ingress + tls: [] + # - secretName: ditto-tls + # hosts: + # - ditto.example.com - proxy_http_version 1.1; - proxy_set_header X-Forwarded-Host $http_host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header Host $host; - # api the /api, /stats and /overall Ingress configuration + # api configures the Ingress for API routes (/api, /stats, /overall) api: - # paths configures ingress paths + enabled: true + # annotations for controller-specific configuration (auth, timeouts, CORS, etc.) + annotations: {} paths: - # negative lookahead, so we don't accept /api/2/connections, which is devops responsibility - - path: /api/2/(?!connections) - pathType: ImplementationSpecific - backendSuffix: gateway + - path: /api + pathType: Prefix + service: + name: gateway - path: /stats - backendSuffix: gateway + pathType: Prefix + service: + name: gateway - path: /overall - backendSuffix: gateway - kubernetesAuthAnnotations: | - nginx.ingress.kubernetes.io/auth-type: basic - nginx.ingress.kubernetes.io/auth-secret: {{ .Release.Name }}-nginx-ingress-htpasswd - nginx.ingress.kubernetes.io/auth-realm: 'Authentication required to use HTTP API!' - # annotations defines k8s annotations to add to the Ingress - annotations: - nginx.ingress.kubernetes.io/proxy-connect-timeout: "10" - nginx.ingress.kubernetes.io/proxy-send-timeout: "70" - nginx.ingress.kubernetes.io/proxy-read-timeout: "70" - nginx.ingress.kubernetes.io/proxy-next-upstream: "error timeout http_502" - nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "4" - nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "50" - nginx.ingress.kubernetes.io/proxy-buffer-size: "16k" - nginx.ingress.kubernetes.io/configuration-snippet: | - set $cors $http_origin; - - # Allow-listed origins for CORS - enforces https for those - #if ($http_origin ~ '^https://eclipse-ditto\.github\.io(:\d+)?)$') { - # set $cors $http_origin; - #} - # Allows http for localhost (on any port) - #if ($http_origin ~ '^http://(localhost|127\.0\.0\.1)(:\d+)?') { - # set $cors $http_origin; - #} - - if ($cors != "") { - add_header 'Access-Control-Allow-Origin' '$cors' always; - add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE, OPTIONS' always; - add_header 'Access-Control-Allow-Credentials' 'true' always; - add_header 'Access-Control-Allow-Headers' '$http_access_control_request_headers' always; - add_header 'Access-Control-Expose-Headers' 'correlation-id, response-required, dry-run, channel, etag, ditto-originator, requested-acks, timeout, location, ditto-metadata, traceparent, tracestate, entity-revision' always; - } + pathType: Prefix + service: + name: gateway - if ($request_method = 'OPTIONS') { - # Tell client that this pre-flight info is valid for 20 days - add_header 'Access-Control-Max-Age' 1728000; - add_header 'Access-Control-Allow-Origin' '$cors' always; - add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, PATCH, DELETE, OPTIONS' always; - add_header 'Access-Control-Allow-Credentials' 'true' always; - add_header 'Access-Control-Allow-Headers' '$http_access_control_request_headers' always; - add_header 'Access-Control-Expose-Headers' 'correlation-id, response-required, dry-run, channel, etag, ditto-originator, requested-acks, timeout, location, ditto-metadata, traceparent, tracestate, entity-revision' always; - add_header 'Content-Type' 'text/plain charset=UTF-8'; - add_header 'Content-Length' 0; - return 204; - } - - # security relevant headers: - add_header "Content-Security-Policy" "default-src 'none'; frame-ancestors 'none'" always; - add_header "Strict-Transport-Security" "max-age=63072000; includeSubdomains;" always; - add_header "Cache-Control" "no-cache" always; - add_header "X-Content-Type-Options" "nosniff" always; - add_header "X-Frame-Options" "SAMEORIGIN" always; - add_header "X-XSS-Protection" "1; mode=block" always; - - # set ditto-specific forwarded headers - proxy_set_header X-Forwarded-User $remote_user; - proxy_set_header x-ditto-pre-authenticated "nginx:$remote_user"; - # ws the /ws (WebSocket) Ingress configuration + # ws configures the Ingress for WebSocket routes (/ws) ws: - # paths configures ingress paths + enabled: true + # annotations for controller-specific configuration (long timeouts, buffering, etc.) + annotations: {} paths: - path: /ws - backendSuffix: gateway - # annotations defines k8s annotations to add to the Ingress - annotations: - nginx.ingress.kubernetes.io/proxy-send-timeout: "86400" - nginx.ingress.kubernetes.io/proxy-read-timeout: "86400" - nginx.ingress.kubernetes.io/proxy-next-upstream: "error timeout http_502" - nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "4" - nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "50" - nginx.ingress.kubernetes.io/proxy-buffering: "off" - # the / Ingress configuration for serving the landing page and static resources - root: - # paths configures ingress paths - paths: - - path: / - pathType: Exact - backendSuffix: nginx - - path: /index.html - pathType: ImplementationSpecific - backendSuffix: nginx - - path: /ditto-up.svg - pathType: ImplementationSpecific - backendSuffix: nginx - - path: /ditto-down.svg - pathType: ImplementationSpecific - backendSuffix: nginx - # annotations defines k8s annotations to add to the Ingress - annotations: - nginx.ingress.kubernetes.io/proxy-connect-timeout: "10" - nginx.ingress.kubernetes.io/configuration-snippet: | - # security relevant headers: - add_header "Content-Security-Policy" "default-src 'self'; script-src-elem 'self' 'sha256-Kq9eqc/CtX2tgHPLJUEf8vDO9eNiGaRBrwAYYXTroVc=' https://cdnjs.cloudflare.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com; worker-src 'self' blob:; object-src 'none';" always; - add_header "Strict-Transport-Security" "max-age=63072000; includeSubdomains;" always; - add_header "Cache-Control" "no-cache" always; - add_header "X-Content-Type-Options" "nosniff" always; - add_header "X-Frame-Options" "SAMEORIGIN" always; - add_header "X-XSS-Protection" "1; mode=block" always; - # ui the /ui and /apidoc Ingress configuration + pathType: Prefix + service: + name: gateway + + # ui configures the Ingress for the landing page, Ditto UI and Swagger API docs ui: - # paths configures ingress paths + enabled: true + # annotations for controller-specific configuration (URL rewriting, etc.) + annotations: {} + # defaultBackend serves as the catch-all for unmatched paths (e.g. the landing page) + defaultBackend: + service: + name: nginx paths: - path: / pathType: Exact - backendSuffix: nginx - - path: /apidoc(/|$)(.*) - pathType: ImplementationSpecific - backendSuffix: swaggerui - - path: /ui(/|$)(.*) - pathType: ImplementationSpecific - backendSuffix: dittoui - # annotations defines k8s annotations to add to the Ingress - annotations: - nginx.ingress.kubernetes.io/use-regex: "true" - nginx.ingress.kubernetes.io/rewrite-target: /$2 - nginx.ingress.kubernetes.io/proxy-connect-timeout: "10" - nginx.ingress.kubernetes.io/configuration-snippet: | - # security relevant headers: - add_header "Content-Security-Policy" "default-src 'self'; script-src-elem 'self' 'sha256-Ve/Ec/6YDEeTc+9y+QCJ+e9OhyGWAj3bYxCzNGfOn6U=' 'sha256-Kq9eqc/CtX2tgHPLJUEf8vDO9eNiGaRBrwAYYXTroVc=' https://cdnjs.cloudflare.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com; img-src 'self' data: https://raw.githubusercontent.com; font-src 'self' https://cdnjs.cloudflare.com; worker-src 'self' blob:; connect-src 'self' localhost http://localhost:8080; object-src 'none';" always; - add_header "Strict-Transport-Security" "max-age=63072000; includeSubdomains;" always; - add_header "Cache-Control" "no-cache" always; - add_header "X-Content-Type-Options" "nosniff" always; - add_header "X-Frame-Options" "SAMEORIGIN" always; - add_header "X-XSS-Protection" "1; mode=block" always; - rewrite ^(/ui)$ $1/ permanent; - rewrite ^(/apidoc)$ $1/ permanent; - # devops the /devops, /api/2/connections, /status and /health commands Ingress configuration + service: + name: nginx + - path: /apidoc + pathType: Prefix + service: + name: swaggerui + - path: /ui + pathType: Prefix + service: + name: dittoui + + # devops configures the Ingress for DevOps routes (/devops, /health, /status, /api/2/connections) devops: - # paths configures ingress paths + enabled: true + annotations: {} paths: - path: /devops - backendSuffix: gateway - - path: /status - backendSuffix: gateway + pathType: Prefix + service: + name: gateway - path: /health - backendSuffix: gateway + pathType: Prefix + service: + name: gateway + - path: /status + pathType: Prefix + service: + name: gateway - path: /api/2/connections - backendSuffix: gateway - # annotations defines k8s annotations to add to the Ingress - # if undefined, api ingress annotations are reused - annotations: - # tls configures the TLS for ingress - tls: [] - # - secretName: ditto-tls - # hosts: - # - localhost + pathType: Prefix + service: + name: gateway ## ---------------------------------------------------------------------------- diff --git a/documentation/src/main/resources/_posts/2026-04-01-ingress-controller-agnostic-helm-chart.md b/documentation/src/main/resources/_posts/2026-04-01-ingress-controller-agnostic-helm-chart.md new file mode 100644 index 00000000000..dac5b17c956 --- /dev/null +++ b/documentation/src/main/resources/_posts/2026-04-01-ingress-controller-agnostic-helm-chart.md @@ -0,0 +1,267 @@ +--- +title: "Helm chart now ingress controller agnostic" +published: true +permalink: 2026-04-01-ingress-controller-agnostic-helm-chart.html +layout: post +author: kalin_kostashki +tags: [blog, kubernetes, helm] +hide_sidebar: true +sidebar: false +toc: true +--- + +Starting with Helm chart version 4.0.0, Eclipse Ditto's Kubernetes deployment is no longer tied to a specific ingress +controller. The chart now provides clean, standard Kubernetes Ingress resources that work with **any** ingress controller +— whether you use ingress-nginx, Traefik, HAProxy, Kong, or any other implementation. + +## What changed + +Previously, the Ditto Helm chart bundled an entire **ingress-nginx controller deployment** (854 lines of RBAC, +Deployments, Services, admission webhooks, and IngressClass) and hardcoded `nginx.ingress.kubernetes.io/*` annotations +across all Ingress resource templates. This forced users to use ingress-nginx and prevented adoption of other ingress +controllers. + +In version 4.0.0, we made the following changes: + +- **Removed** the bundled ingress-nginx controller deployment — users bring their own ingress controller +- **Removed** all nginx-specific annotations from Ingress resources — annotations are now empty by default +- **Simplified** path types to standard `Prefix` and `Exact` — no more controller-specific regex paths +- **Added** per-group `enabled` flags — each route group (api, ws, ui, devops) can be independently toggled +- **Replaced** the `backendSuffix` pattern with explicit `service.name` references + +## Breaking changes + +This is a **major version bump** (`3.x` → `4.0.0`) with breaking changes to `values.yaml`: + +- `ingress.controller.*` — entire block removed (no longer deploying a controller) +- `ingress.annotations` — global nginx-specific annotations removed +- `ingress.api.kubernetesAuthAnnotations` — removed +- `ingress.className` — default changed from `"nginx"` to `""` (empty) +- `ingress.host` — default changed from `"localhost"` to `""` (catch-all) +- `backendSuffix` — replaced by `service.name` in each path entry +- All per-group nginx-specific annotation blocks — removed + +## New values.yaml structure + +The ingress section is now clean and controller-agnostic: + +```yaml +ingress: + enabled: false + className: "" # Set to your controller's IngressClass + host: "" # Optional hostname — if empty, no host rule (catch-all) + tls: [] + + api: + enabled: true + annotations: {} # Add your controller-specific annotations here + paths: + - path: /api + pathType: Prefix + service: + name: gateway + - path: /stats + pathType: Prefix + service: + name: gateway + - path: /overall + pathType: Prefix + service: + name: gateway + + ws: + enabled: true + annotations: {} + paths: + - path: /ws + pathType: Prefix + service: + name: gateway + + ui: + enabled: true + annotations: {} + # defaultBackend serves as the catch-all for unmatched paths (e.g. the landing page) + defaultBackend: + service: + name: nginx + paths: + - path: / + pathType: Exact + service: + name: nginx + - path: /apidoc + pathType: Prefix + service: + name: swaggerui + - path: /ui + pathType: Prefix + service: + name: dittoui + + devops: + enabled: true + annotations: {} + paths: + - path: /devops + pathType: Prefix + service: + name: gateway + - path: /health + pathType: Prefix + service: + name: gateway + - path: /status + pathType: Prefix + service: + name: gateway + - path: /api/2/connections + pathType: Prefix + service: + name: gateway +``` + +## Deployment modes + +The chart supports three deployment modes: + +### Standalone nginx pod (default, unchanged) + +The standalone nginx reverse proxy remains the default for local and development setups. +No ingress controller needed — access Ditto via port-forward: + +```bash +helm install ditto ditto/ditto +kubectl port-forward svc/ditto-nginx 8080:8080 +``` + +### Ingress with nginx pod + +Use Ingress resources for external access while keeping the nginx pod for the landing page and static resources: + +```bash +helm install ditto ditto/ditto \ + --set ingress.enabled=true \ + --set ingress.className=nginx \ + --set ingress.host=ditto.example.com +``` + +### Ingress only (no nginx pod) + +For production setups where the landing page is not needed, disable the nginx pod and the UI ingress's root path: + +```bash +helm install ditto ditto/ditto \ + --set ingress.enabled=true \ + --set ingress.className=nginx \ + --set ingress.host=ditto.example.com \ + --set nginx.enabled=false +``` + +## Controller-specific configuration + +Since controller-specific behavior (authentication, CORS, timeouts, URL rewriting) is now the user's responsibility, +here are examples for common ingress controllers. + +### ingress-nginx + +For the Ditto UI and Swagger API docs, ingress-nginx requires regex paths and a rewrite annotation to strip the +path prefix before forwarding to the backend. + +Note that when `use-regex` is enabled, the root path `/` must be specified as `/$` with `pathType: ImplementationSpecific` +to ensure it matches only the exact root path and does not conflict with the ingress controller's default catch-all: + +```yaml +ingress: + enabled: true + className: nginx + host: ditto.example.com + api: + annotations: + nginx.ingress.kubernetes.io/proxy-read-timeout: "70" + nginx.ingress.kubernetes.io/proxy-send-timeout: "70" + ws: + annotations: + nginx.ingress.kubernetes.io/proxy-read-timeout: "86400" + nginx.ingress.kubernetes.io/proxy-send-timeout: "86400" + nginx.ingress.kubernetes.io/proxy-buffering: "off" + ui: + annotations: + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 + paths: + - path: /$ + pathType: ImplementationSpecific + service: + name: nginx + - path: /apidoc(/|$)(.*) + pathType: ImplementationSpecific + service: + name: swaggerui + - path: /ui(/|$)(.*) + pathType: ImplementationSpecific + service: + name: dittoui +``` + +### Traefik + +Traefik requires a `Middleware` CRD to strip path prefixes. First, create the middleware in the Ditto namespace: + +```yaml +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: strip-prefix + namespace: ditto +spec: + stripPrefix: + prefixes: + - /ui + - /apidoc +``` + +Then reference it in the ingress configuration: + +```yaml +ingress: + enabled: true + className: traefik + host: ditto.example.com + ui: + annotations: + traefik.ingress.kubernetes.io/router.middlewares: ditto-strip-prefix@kubernetescrd +``` + +### HAProxy + +```yaml +ingress: + enabled: true + className: haproxy + host: ditto.example.com + ui: + annotations: + haproxy.org/path-rewrite: "/ /" +``` + +## What stays the same + +- The **standalone nginx pod** for local/development deployments is unchanged +- The **OpenShift Route** template is unchanged +- All **Ditto service templates** (gateway, things, policies, connectivity, etc.) are unchanged +- The **4 route groups** (api, ws, ui, devops) cover all Ditto endpoints — the root landing page is now part of the ui group + +## Migrating from 3.x + +1. **Install your ingress controller separately** (e.g., via its own Helm chart) +2. **Update your values.yaml** to match the new structure — replace `backendSuffix` with `service.name`, + remove `ingress.controller.*` and global annotations +3. **Add controller-specific annotations** to the appropriate route groups +4. **Upgrade the chart** to version 4.0.0 + +
+
+{% include image.html file="ditto.svg" alt="Ditto" max-width=500 %} +--
+The Eclipse Ditto team