feat(gateway): add Gateway API routes for tenant-level services

Add per-component Gateway + HTTPRoute/TLSRoute for tenant-level
services. Each component creates its own Gateway with specific
hostname HTTPS listener and cert-manager annotation for automatic
certificate provisioning via HTTP01 or DNS01.

All Gateways within a tenant share a single LoadBalancer IP through
infrastructure.labels (cozystack.io/gateway: {tenant-name}), matching
the current ingress-nginx model of one LB per tenant.

HTTPRoute (per-component Gateway with TLS terminate):
- monitoring/grafana: routes to grafana-service:3000
- monitoring/alerta: routes to alerta:80
- bucket: routes to {bucketName}-ui:8080
- apps/harbor: routes to {release}:80
- extra/bootbox: routes to bootbox:8080

TLSRoute (per-component Gateway with TLS passthrough):
- extra/seaweedfs: passthrough to filer-external:18888

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Kirill Ilin <stitch14@yandex.ru>
This commit is contained in:
Kirill Ilin 2026-03-13 12:09:32 +05:00
parent 73965bfa06
commit fb06e0ce1d
No known key found for this signature in database
GPG key ID: E902D8B383F7675E
6 changed files with 331 additions and 0 deletions

View file

@ -0,0 +1,58 @@
{{- $gatewayAPI := (index .Values._cluster "gateway-api") | default "false" }}
{{- $clusterIssuer := (index .Values._cluster "issuer-name") | default "letsencrypt-prod" }}
{{- $gateway := .Values._namespace.gateway | default "" }}
{{- $host := .Values._namespace.host }}
{{- $harborHost := .Values.host | default (printf "%s.%s" .Release.Name $host) }}
{{- if and (eq $gatewayAPI "true") (ne $gateway "") }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: {{ .Release.Name }}-harbor
annotations:
cert-manager.io/cluster-issuer: {{ $clusterIssuer }}
spec:
gatewayClassName: cilium
infrastructure:
labels:
cozystack.io/gateway: {{ $gateway }}
listeners:
- name: http
protocol: HTTP
port: 80
hostname: {{ $harborHost | quote }}
allowedRoutes:
namespaces:
from: Same
- name: https
protocol: HTTPS
port: 443
hostname: {{ $harborHost | quote }}
tls:
mode: Terminate
certificateRefs:
- name: {{ .Release.Name }}-harbor-gateway-tls
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: {{ .Release.Name }}-harbor
spec:
parentRefs:
- name: {{ .Release.Name }}-harbor
sectionName: https
hostnames:
- {{ $harborHost | quote }}
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: {{ .Release.Name }}
port: 80
{{- end }}

View file

@ -0,0 +1,58 @@
{{- $gatewayAPI := (index .Values._cluster "gateway-api") | default "false" }}
{{- $clusterIssuer := (index .Values._cluster "issuer-name") | default "letsencrypt-prod" }}
{{- $gateway := .Values._namespace.gateway | default "" }}
{{- $host := .Values._namespace.host }}
{{- $bootboxHost := printf "bootbox.%s" (.Values.host | default $host) }}
{{- if and (eq $gatewayAPI "true") (ne $gateway "") }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: bootbox
annotations:
cert-manager.io/cluster-issuer: {{ $clusterIssuer }}
spec:
gatewayClassName: cilium
infrastructure:
labels:
cozystack.io/gateway: {{ $gateway }}
listeners:
- name: http
protocol: HTTP
port: 80
hostname: {{ $bootboxHost | quote }}
allowedRoutes:
namespaces:
from: Same
- name: https
protocol: HTTPS
port: 443
hostname: {{ $bootboxHost | quote }}
tls:
mode: Terminate
certificateRefs:
- name: bootbox-gateway-tls
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: bootbox
spec:
parentRefs:
- name: bootbox
sectionName: https
hostnames:
- {{ $bootboxHost | quote }}
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: bootbox
port: 8080
{{- end }}

View file

@ -0,0 +1,41 @@
{{- $gatewayAPI := (index .Values._cluster "gateway-api") | default "false" }}
{{- $gateway := .Values._namespace.gateway | default "" }}
{{- $host := .Values._namespace.host }}
{{- if and (eq $gatewayAPI "true") (ne $gateway "") (not (eq .Values.topology "Client")) (.Values.filer.grpcHost) }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: seaweedfs-filer
spec:
gatewayClassName: cilium
infrastructure:
labels:
cozystack.io/gateway: {{ $gateway }}
listeners:
- name: tls-passthrough
protocol: TLS
port: 443
hostname: {{ .Values.filer.grpcHost | default (printf "filer.%s" $host) | quote }}
tls:
mode: Passthrough
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TLSRoute
metadata:
name: seaweedfs-filer
spec:
parentRefs:
- name: seaweedfs-filer
sectionName: tls-passthrough
hostnames:
- {{ .Values.filer.grpcHost | default (printf "filer.%s" $host) | quote }}
rules:
- backendRefs:
- name: {{ $.Release.Name }}-filer-external
port: 18888
{{- end }}

View file

@ -0,0 +1,58 @@
{{- $gatewayAPI := (index .Values._cluster "gateway-api") | default "false" }}
{{- $clusterIssuer := (index .Values._cluster "issuer-name") | default "letsencrypt-prod" }}
{{- $gateway := .Values._namespace.gateway | default "" }}
{{- $host := .Values._namespace.host }}
{{- $bucketHost := printf "%s.%s" .Values.bucketName $host }}
{{- if and (eq $gatewayAPI "true") (ne $gateway "") }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: {{ .Values.bucketName }}-ui
annotations:
cert-manager.io/cluster-issuer: {{ $clusterIssuer }}
spec:
gatewayClassName: cilium
infrastructure:
labels:
cozystack.io/gateway: {{ $gateway }}
listeners:
- name: http
protocol: HTTP
port: 80
hostname: {{ $bucketHost | quote }}
allowedRoutes:
namespaces:
from: Same
- name: https
protocol: HTTPS
port: 443
hostname: {{ $bucketHost | quote }}
tls:
mode: Terminate
certificateRefs:
- name: {{ .Values.bucketName }}-ui-gateway-tls
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: {{ .Values.bucketName }}-ui
spec:
parentRefs:
- name: {{ .Values.bucketName }}-ui
sectionName: https
hostnames:
- {{ $bucketHost | quote }}
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: {{ .Values.bucketName }}-ui
port: 8080
{{- end }}

View file

@ -0,0 +1,58 @@
{{- $gatewayAPI := (index .Values._cluster "gateway-api") | default "false" }}
{{- $clusterIssuer := (index .Values._cluster "issuer-name") | default "letsencrypt-prod" }}
{{- $gateway := .Values._namespace.gateway | default "" }}
{{- $host := .Values._namespace.host }}
{{- $alertaHost := printf "alerta.%s" (.Values.host | default $host) }}
{{- if and (eq $gatewayAPI "true") (ne $gateway "") }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: alerta
annotations:
cert-manager.io/cluster-issuer: {{ $clusterIssuer }}
spec:
gatewayClassName: cilium
infrastructure:
labels:
cozystack.io/gateway: {{ $gateway }}
listeners:
- name: http
protocol: HTTP
port: 80
hostname: {{ $alertaHost | quote }}
allowedRoutes:
namespaces:
from: Same
- name: https
protocol: HTTPS
port: 443
hostname: {{ $alertaHost | quote }}
tls:
mode: Terminate
certificateRefs:
- name: alerta-gateway-tls
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: alerta
spec:
parentRefs:
- name: alerta
sectionName: https
hostnames:
- {{ $alertaHost | quote }}
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: alerta
port: 80
{{- end }}

View file

@ -0,0 +1,58 @@
{{- $gatewayAPI := (index .Values._cluster "gateway-api") | default "false" }}
{{- $clusterIssuer := (index .Values._cluster "issuer-name") | default "letsencrypt-prod" }}
{{- $gateway := .Values._namespace.gateway | default "" }}
{{- $host := .Values._namespace.host }}
{{- $grafanaHost := printf "grafana.%s" (.Values.host | default $host) }}
{{- if and (eq $gatewayAPI "true") (ne $gateway "") }}
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: grafana
annotations:
cert-manager.io/cluster-issuer: {{ $clusterIssuer }}
spec:
gatewayClassName: cilium
infrastructure:
labels:
cozystack.io/gateway: {{ $gateway }}
listeners:
- name: http
protocol: HTTP
port: 80
hostname: {{ $grafanaHost | quote }}
allowedRoutes:
namespaces:
from: Same
- name: https
protocol: HTTPS
port: 443
hostname: {{ $grafanaHost | quote }}
tls:
mode: Terminate
certificateRefs:
- name: grafana-gateway-tls
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: grafana
spec:
parentRefs:
- name: grafana
sectionName: https
hostnames:
- {{ $grafanaHost | quote }}
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: grafana-service
port: 3000
{{- end }}