From d1be8b04aefa778ac66807b3521c480fa807a47a Mon Sep 17 00:00:00 2001 From: Artem Torubarov Date: Fri, 14 Aug 2026 13:26:18 +0200 Subject: [PATCH] ingress helm examples Signed-off-by: Artem Torubarov --- deploy/chorus/Chart.yaml | 2 +- deploy/chorus/README.md | 35 +++++++++ .../chorus/examples/values-ingress-nginx.yaml | 77 +++++++++++++++++++ .../examples/values-ingress-traefik.yaml | 75 ++++++++++++++++++ deploy/chorus/templates/proxy/ingress.yaml | 2 +- deploy/chorus/templates/ui/ingress.yaml | 2 +- .../templates/worker/ingress-webhook.yaml | 24 +++--- deploy/chorus/templates/worker/ingress.yaml | 2 +- deploy/chorus/values.yaml | 11 +-- 9 files changed, 205 insertions(+), 25 deletions(-) create mode 100644 deploy/chorus/examples/values-ingress-nginx.yaml create mode 100644 deploy/chorus/examples/values-ingress-traefik.yaml diff --git a/deploy/chorus/Chart.yaml b/deploy/chorus/Chart.yaml index b3651d00..4aee1742 100644 --- a/deploy/chorus/Chart.yaml +++ b/deploy/chorus/Chart.yaml @@ -4,7 +4,7 @@ description: Helm chart for Chorus S3 management software. keywords: ["S3", "Backup", "Replication", "Migration"] home: https://github.com/clyso/chorus type: application -version: 0.3.0 +version: 0.4.0 appVersion: "v0.7.7" dependencies: - name: redis diff --git a/deploy/chorus/README.md b/deploy/chorus/README.md index d8defd60..434b7a4b 100644 --- a/deploy/chorus/README.md +++ b/deploy/chorus/README.md @@ -25,6 +25,8 @@ See the [examples/](./examples/) directory for ready-to-use configurations: | [values-webhook.yaml](./examples/values-webhook.yaml) | Webhook-based replication (without proxy) | | [values-dynamic-credentials.yaml](./examples/values-dynamic-credentials.yaml) | Manage credentials via API | | [values-external-redis.yaml](./examples/values-external-redis.yaml) | External Redis configuration | +| [values-ingress-nginx.yaml](./examples/values-ingress-nginx.yaml) | Ingress overlay for ingress-nginx | +| [values-ingress-traefik.yaml](./examples/values-ingress-traefik.yaml) | Ingress overlay for Traefik | ## Configuration @@ -139,6 +141,39 @@ client: Go runtime metrics (`go_*`, see and process metrics (`process_*`, see [Prometheus process metrics](https://prometheus.io/docs/instrumenting/writing_clientlibs/#process-metrics)). +### Ingress + +The chart can create four Ingresses, all disabled by default. Enable one with +`ingress..enabled: true` and at least one entry in `hosts`. + +| Values key | Backend Service | Port (default) | Backend exists only when | +|------------|-----------------|----------------|--------------------------| +| `ingress.proxy` | `-proxy` | 9669 | `proxy.enabled: true` | +| `ingress.api` | `-rest` | 9671 | `worker.config.api.enabled: true` | +| `ingress.webhook` | `-webhook` on separate webhook ports, else `-rest` | `webhook.httpPort` / 9671 | `worker.config.api.webhook.enabled: true` | +| `ingress.ui` | `-ui` | 9672 | `ui.enabled: true` | + +Before enabling an ingress, make sure its component is enabled — see the last +column above. + +Any Kubernetes ingress controller is supported: the chart emits no +controller-specific annotations. Set `className` for your controller and put +controller-specific tuning under `annotations`. See +[values-ingress-nginx.yaml](./examples/values-ingress-nginx.yaml) and +[values-ingress-traefik.yaml](./examples/values-ingress-traefik.yaml). + +> **The management API has no authentication.** Anyone who can reach +> `ingress.api` can change replication policies, read the proxy's S3 +> credentials, and write storage credentials when `dynamicCredentials.enabled` +> is set. Enforce authentication at the ingress, or keep it on a private +> network. + +Set `worker.config.api.webhook.grpcPort` / `httpPort` to run the webhook on its +own ports and Service. Do that when exposing the webhook publicly: on the shared +ports its ingress backend is `-rest`, which also serves the management +API described above. Set `worker.config.api.webhook.baseUrl` to the externally +reachable URL when the storage pushes events from outside the cluster. + ### Images Each component's image is set via `.image` (`repository`, `tag`, diff --git a/deploy/chorus/examples/values-ingress-nginx.yaml b/deploy/chorus/examples/values-ingress-nginx.yaml new file mode 100644 index 00000000..84f3c9aa --- /dev/null +++ b/deploy/chorus/examples/values-ingress-nginx.yaml @@ -0,0 +1,77 @@ +# Example: exposing Chorus with ingress-nginx. +# +# An overlay — combine it with a storage example, e.g. +# helm install chorus ./deploy/chorus \ +# -f examples/values-s3.yaml -f examples/values-ingress-nginx.yaml +# +# WARNING: ingress.api has no authentication. Enable it behind auth at the +# ingress, or on a private network only. See README.md -> Ingress. + +ingress: + proxy: + enabled: true + className: nginx + annotations: + # S3 objects exceed ingress-nginx's 1m default body limit, which rejects + # larger uploads with 413. "0" disables the limit. + nginx.ingress.kubernetes.io/proxy-body-size: "0" + hosts: + - host: s3.chorus.example.com + paths: + - path: / + tls: + - secretName: chorus-s3-tls + hosts: + - s3.chorus.example.com + + api: + enabled: true + className: nginx + hosts: + - host: chorus-api.example.com + paths: + - path: / + tls: + - secretName: chorus-api-tls + hosts: + - chorus-api.example.com + + webhook: + enabled: true + className: nginx + hosts: + - host: chorus-webhook.example.com + paths: + - path: / + tls: + - secretName: chorus-webhook-tls + hosts: + - chorus-webhook.example.com + + ui: + enabled: true + className: nginx + hosts: + - host: chorus.example.com + paths: + - path: / + tls: + - secretName: chorus-ui-tls + hosts: + - chorus.example.com + +ui: + enabled: true + +worker: + config: + api: + webhook: + enabled: true + baseUrl: "https://chorus-webhook.example.com" + # Separate ports put the webhook on its own Service, away from the + # management API. Omit to serve webhooks on the main REST port. + grpcPort: 9680 + httpPort: 9681 + +# TLS secrets are not created by this chart. diff --git a/deploy/chorus/examples/values-ingress-traefik.yaml b/deploy/chorus/examples/values-ingress-traefik.yaml new file mode 100644 index 00000000..154328fb --- /dev/null +++ b/deploy/chorus/examples/values-ingress-traefik.yaml @@ -0,0 +1,75 @@ +# Example: exposing Chorus with Traefik. +# +# An overlay — combine it with a storage example, e.g. +# helm install chorus ./deploy/chorus \ +# -f examples/values-s3.yaml -f examples/values-ingress-traefik.yaml +# +# WARNING: ingress.api has no authentication. Enable it behind auth at the +# ingress, or on a private network only. See README.md -> Ingress. + +ingress: + proxy: + enabled: true + className: traefik + # No body-size annotation needed: Traefik does not limit request bodies by + # default. Attach a Buffering middleware if you want a limit. + hosts: + - host: s3.chorus.example.com + paths: + - path: / + tls: + - secretName: chorus-s3-tls + hosts: + - s3.chorus.example.com + + api: + enabled: true + className: traefik + hosts: + - host: chorus-api.example.com + paths: + - path: / + tls: + - secretName: chorus-api-tls + hosts: + - chorus-api.example.com + + webhook: + enabled: true + className: traefik + hosts: + - host: chorus-webhook.example.com + paths: + - path: / + tls: + - secretName: chorus-webhook-tls + hosts: + - chorus-webhook.example.com + + ui: + enabled: true + className: traefik + hosts: + - host: chorus.example.com + paths: + - path: / + tls: + - secretName: chorus-ui-tls + hosts: + - chorus.example.com + +ui: + enabled: true + +worker: + config: + api: + webhook: + enabled: true + baseUrl: "https://chorus-webhook.example.com" + # Separate ports put the webhook on its own Service, away from the + # management API. Omit to serve webhooks on the main REST port. + grpcPort: 9680 + httpPort: 9681 + +# TLS secrets are not created by this chart. diff --git a/deploy/chorus/templates/proxy/ingress.yaml b/deploy/chorus/templates/proxy/ingress.yaml index 20703a92..80a207ce 100644 --- a/deploy/chorus/templates/proxy/ingress.yaml +++ b/deploy/chorus/templates/proxy/ingress.yaml @@ -31,7 +31,7 @@ spec: paths: {{- range .paths }} - path: {{ .path }} - pathType: {{ .pathType }} + pathType: {{ .pathType | default "Prefix" }} backend: service: name: {{ include "chorus.fullname" $ }}-proxy diff --git a/deploy/chorus/templates/ui/ingress.yaml b/deploy/chorus/templates/ui/ingress.yaml index 161dfaf3..ea425ddc 100644 --- a/deploy/chorus/templates/ui/ingress.yaml +++ b/deploy/chorus/templates/ui/ingress.yaml @@ -31,7 +31,7 @@ spec: paths: {{- range .paths }} - path: {{ .path }} - pathType: {{ .pathType }} + pathType: {{ .pathType | default "Prefix" }} backend: service: name: {{ include "chorus.fullname" $ }}-ui diff --git a/deploy/chorus/templates/worker/ingress-webhook.yaml b/deploy/chorus/templates/worker/ingress-webhook.yaml index 77c9c917..f343dc4f 100644 --- a/deploy/chorus/templates/worker/ingress-webhook.yaml +++ b/deploy/chorus/templates/worker/ingress-webhook.yaml @@ -1,4 +1,8 @@ {{- if .Values.ingress.webhook.enabled }} +{{- /* grpc: false was a shipped default, so only reject a deliberate true. */}} +{{- if .Values.ingress.webhook.grpc }} +{{- fail "ingress.webhook.grpc is no longer supported: the webhook ingress always routes HTTP. Remove the key." }} +{{- end }} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: @@ -6,15 +10,9 @@ metadata: labels: {{- include "chorus.labels" . | nindent 4 }} app.kubernetes.io/component: worker - {{- $annotations := include "chorus.annotations" (list .Values.ingress.webhook.annotations .) }} - {{- if or .Values.ingress.webhook.grpc $annotations }} + {{- with (include "chorus.annotations" (list .Values.ingress.webhook.annotations .)) }} annotations: - {{- if .Values.ingress.webhook.grpc }} - nginx.ingress.kubernetes.io/backend-protocol: GRPC - {{- end }} - {{- with $annotations }} {{- . | nindent 4 }} - {{- end }} {{- end }} spec: {{- if .Values.ingress.webhook.className }} @@ -37,17 +35,15 @@ spec: paths: {{- range .paths }} - path: {{ .path }} - pathType: {{ .pathType }} + pathType: {{ .pathType | default "Prefix" }} backend: service: - {{- if gt (int ($.Values.worker.config.api.webhook.grpcPort | default 0)) 0 }} + {{- /* Dedicated webhook Service when the worker runs the webhook + on its own ports, otherwise the main REST API. */}} + {{- if and $.Values.worker.config.api.webhook.enabled (gt (int ($.Values.worker.config.api.webhook.grpcPort | default 0)) 0) }} name: {{ include "chorus.fullname" $ }}-webhook port: - name: {{ if $.Values.ingress.webhook.grpc }}grpc{{ else }}http{{ end }} - {{- else if $.Values.ingress.webhook.grpc }} - name: {{ include "chorus.fullname" $ }}-grpc - port: - name: grpc + name: http {{- else }} name: {{ include "chorus.fullname" $ }}-rest port: diff --git a/deploy/chorus/templates/worker/ingress.yaml b/deploy/chorus/templates/worker/ingress.yaml index 68cfda36..f55664df 100644 --- a/deploy/chorus/templates/worker/ingress.yaml +++ b/deploy/chorus/templates/worker/ingress.yaml @@ -31,7 +31,7 @@ spec: paths: {{- range .paths }} - path: {{ .path }} - pathType: {{ .pathType }} + pathType: {{ .pathType | default "Prefix" }} backend: service: name: {{ include "chorus.fullname" $ }}-rest diff --git a/deploy/chorus/values.yaml b/deploy/chorus/values.yaml index 0aff557d..903b3861 100644 --- a/deploy/chorus/values.yaml +++ b/deploy/chorus/values.yaml @@ -373,7 +373,7 @@ ingress: # - host: s3.example.com # paths: # - path: / - # pathType: Prefix + # pathType: Prefix # optional, defaults to Prefix tls: [] # - secretName: s3-tls # hosts: @@ -388,7 +388,7 @@ ingress: # - host: chorus-api.example.com # paths: # - path: / - # pathType: Prefix + # pathType: Prefix # optional, defaults to Prefix tls: [] # Ingress for webhook endpoints (S3 notifications, Swift events). @@ -398,14 +398,11 @@ ingress: className: "" annotations: {} # nginx.ingress.kubernetes.io/proxy-body-size: "0" - # Route to webhook gRPC port instead of HTTP. - # Adds nginx.ingress.kubernetes.io/backend-protocol: GRPC automatically. - grpc: false hosts: [] # - host: chorus-webhook.example.com # paths: # - path: / - # pathType: Prefix + # pathType: Prefix # optional, defaults to Prefix tls: [] # Ingress for Web UI @@ -417,5 +414,5 @@ ingress: # - host: chorus.example.com # paths: # - path: / - # pathType: Prefix + # pathType: Prefix # optional, defaults to Prefix tls: []