mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-20 14:17:07 +00:00
feat(k8s): filer HTTP + gRPC ingress for the Helm chart (#10205)
* feat(k8s): add HTTP + gRPC Ingress templates for filer Add HTTP and gRPC Ingress templates for the filer component in both standalone and all-in-one modes. The HTTP ingress handles REST API traffic, the gRPC ingress exposes the gRPC endpoint with proper annotations for nginx and Traefik. Additionally add Traefik IngressRouteTCP for mTLS filer gRPC passthrough. When the filer has mTLS enabled, the standard HTTP Ingress terminates TLS at the ingress level which conflicts with the filer's mutual-TLS requirement. IngressRouteTCP forwards raw TCP with tls.passthrough: true so the TLS negotiation happens directly between client and filer. Refs: PR #10035 (original fix-grpc-filer) Co-Authored-By: Athena 🏛️ <hermes-agent@local> (custom / Qwen3.6-35B-A3B-UD-Q4_K_XL.gguf) * feat(k8s): restructure filer ingress into ingresses.{http,grpc} Split the single filer ingress value into http and grpc sub-structures so the HTTP Ingress and gRPC Ingress templates each have their own configuration. * k8s: document nginx ssl-passthrough for end-to-end mTLS gRPC The filer's mTLS gRPC needs the TLS stream to reach the filer intact, which an L7 Ingress can't do when it terminates TLS. Document the ingress-nginx ssl-passthrough annotation on the gRPC ingress so the whole chart stays on the standard Ingress kind, no controller-specific CRD required. * k8s: align filer ingress with the volume/admin ingress pattern Only render ingressClassName when a class is set (an empty value opts out of the cluster's default IngressClass), fall back to the kubernetes.io/ingress.class annotation on k8s <1.18, version-gate pathType, and quote the host so wildcard hosts stay valid YAML. * k8s: route the filer gRPC ingress at / with Prefix gRPC methods are called at /<package>.<Service>/<Method>; the HTTP UI regex path never matches them, so gRPC requests would 404. --------- Co-authored-by: MorezMartin <martin.morez@morez.org>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
{{- /* Filer ingress works for both normal mode (filer.enabled) and all-in-one mode (allInOne.enabled) */}}
|
||||
{{- /* Filer ingresses work for both normal mode (filer.enabled) and all-in-one mode (allInOne.enabled) */}}
|
||||
{{- $filerEnabled := or .Values.filer.enabled .Values.allInOne.enabled }}
|
||||
{{- if and $filerEnabled .Values.filer.ingress.enabled }}
|
||||
|
||||
{{- /* HTTP Ingress */}}
|
||||
{{- if and $filerEnabled .Values.filer.ingresses.http.enabled }}
|
||||
{{- /* Determine service name based on deployment mode */}}
|
||||
{{- $serviceName := ternary (include "seaweedfs.componentName" (list . "all-in-one")) (include "seaweedfs.componentName" (list . "filer")) .Values.allInOne.enabled }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
@@ -12,10 +14,13 @@ apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-{{ include "seaweedfs.fullname" . }}-filer
|
||||
name: ingress-{{ include "seaweedfs.fullname" . }}-filer-http
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- with .Values.filer.ingress.annotations }}
|
||||
annotations:
|
||||
{{- if and (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) .Values.filer.ingresses.http.className }}
|
||||
kubernetes.io/ingress.class: {{ .Values.filer.ingresses.http.className }}
|
||||
{{- end }}
|
||||
{{- with .Values.filer.ingresses.http.annotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
@@ -25,14 +30,21 @@ metadata:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: filer
|
||||
spec:
|
||||
ingressClassName: {{ .Values.filer.ingress.className | quote }}
|
||||
{{- if and (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) .Values.filer.ingresses.http.className }}
|
||||
ingressClassName: {{ .Values.filer.ingresses.http.className | quote }}
|
||||
{{- end }}
|
||||
tls:
|
||||
{{ .Values.filer.ingress.tls | default list | toYaml | nindent 6}}
|
||||
{{ .Values.filer.ingresses.http.tls | default list | toYaml | nindent 6}}
|
||||
rules:
|
||||
- http:
|
||||
- {{- if .Values.filer.ingresses.http.host }}
|
||||
host: {{ .Values.filer.ingresses.http.host | quote }}
|
||||
{{- end }}
|
||||
http:
|
||||
paths:
|
||||
- path: {{ .Values.filer.ingress.path | quote }}
|
||||
pathType: {{ .Values.filer.ingress.pathType | quote }}
|
||||
- path: {{ .Values.filer.ingresses.http.path | quote }}
|
||||
{{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
pathType: {{ .Values.filer.ingresses.http.pathType | quote }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
@@ -43,7 +55,62 @@ spec:
|
||||
serviceName: {{ $serviceName }}
|
||||
servicePort: {{ .Values.filer.port }}
|
||||
{{- end }}
|
||||
{{- if .Values.filer.ingress.host }}
|
||||
host: {{ .Values.filer.ingress.host }}
|
||||
{{- end }}
|
||||
|
||||
---
|
||||
|
||||
{{- /* gRPC Ingress */}}
|
||||
{{- if and $filerEnabled .Values.filer.ingresses.grpc.enabled }}
|
||||
{{- /* Determine service name based on deployment mode */}}
|
||||
{{- $serviceName := ternary (include "seaweedfs.componentName" (list . "all-in-one")) (include "seaweedfs.componentName" (list . "filer")) .Values.allInOne.enabled }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else }}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: ingress-{{ include "seaweedfs.fullname" . }}-filer-grpc
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
{{- if and (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) .Values.filer.ingresses.grpc.className }}
|
||||
kubernetes.io/ingress.class: {{ .Values.filer.ingresses.grpc.className }}
|
||||
{{- end }}
|
||||
{{- with .Values.filer.ingresses.grpc.annotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: filer
|
||||
spec:
|
||||
{{- if and (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) .Values.filer.ingresses.grpc.className }}
|
||||
ingressClassName: {{ .Values.filer.ingresses.grpc.className | quote }}
|
||||
{{- end }}
|
||||
tls:
|
||||
{{ .Values.filer.ingresses.grpc.tls | default list | toYaml | nindent 6}}
|
||||
rules:
|
||||
- {{- if .Values.filer.ingresses.grpc.host }}
|
||||
host: {{ .Values.filer.ingresses.grpc.host | quote }}
|
||||
{{- end }}
|
||||
http:
|
||||
paths:
|
||||
- path: {{ .Values.filer.ingresses.grpc.path | quote }}
|
||||
{{- if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
pathType: {{ .Values.filer.ingresses.grpc.pathType | quote }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $serviceName }}
|
||||
port:
|
||||
number: {{ .Values.filer.grpcPort }}
|
||||
{{- else }}
|
||||
serviceName: {{ $serviceName }}
|
||||
servicePort: {{ .Values.filer.grpcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -824,30 +824,50 @@ filer:
|
||||
# allowPrivilegeEscalation: false
|
||||
containerSecurityContext: {}
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
# host: false for "*" hostname
|
||||
host: "seaweedfs.cluster.local"
|
||||
path: "/sw-filer/?(.*)"
|
||||
pathType: ImplementationSpecific
|
||||
annotations: {}
|
||||
# nginx.ingress.kubernetes.io/backend-protocol: GRPC
|
||||
# nginx.ingress.kubernetes.io/auth-type: "basic"
|
||||
# nginx.ingress.kubernetes.io/auth-secret: "default/ingress-basic-auth-secret"
|
||||
# nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - SW-Filer'
|
||||
# nginx.ingress.kubernetes.io/service-upstream: "true"
|
||||
# nginx.ingress.kubernetes.io/rewrite-target: /$1
|
||||
# nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
# nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
|
||||
# nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||||
# nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
|
||||
# nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
# sub_filter '<head>' '<head> <base href="/sw-filer/">'; #add base url
|
||||
# sub_filter '="/' '="./'; #make absolute paths to relative
|
||||
# sub_filter '=/' '=./';
|
||||
# sub_filter '/seaweedfsstatic' './seaweedfsstatic';
|
||||
# sub_filter_once off;
|
||||
ingresses:
|
||||
http:
|
||||
enabled: false
|
||||
className: ""
|
||||
# host: false for "*" hostname
|
||||
host: "seaweedfs.cluster.local"
|
||||
path: "/sw-filer/?(.*)"
|
||||
pathType: ImplementationSpecific
|
||||
annotations: {}
|
||||
# nginx.ingress.kubernetes.io/backend-protocol: GRPC
|
||||
# nginx.ingress.kubernetes.io/auth-type: "basic"
|
||||
# nginx.ingress.kubernetes.io/auth-secret: "default/ingress-basic-auth-secret"
|
||||
# nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - SW-Filer'
|
||||
# nginx.ingress.kubernetes.io/service-upstream: "true"
|
||||
# nginx.ingress.kubernetes.io/rewrite-target: /$1
|
||||
# nginx.ingress.kubernetes.io/use-regex: "true"
|
||||
# nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
|
||||
# nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||||
# nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
|
||||
# nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
# sub_filter '<head>' '<head> <base href="/sw-filer/">'; #add base url
|
||||
# sub_filter '="/' '="./'; #make absolute paths to relative
|
||||
# sub_filter '=/' '=./';
|
||||
# sub_filter '/seaweedfsstatic' './seaweedfsstatic';
|
||||
# sub_filter_once off;
|
||||
tls: []
|
||||
grpc:
|
||||
enabled: false
|
||||
className: ""
|
||||
host: "seaweedfs.cluster.local"
|
||||
# gRPC methods are called at /<package>.<Service>/<Method>, so route the
|
||||
# whole host, not the HTTP UI's regex path.
|
||||
path: "/"
|
||||
pathType: Prefix
|
||||
annotations:
|
||||
# Ingress terminates TLS and re-originates gRPC (HTTP/2) to the filer.
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
|
||||
# For end-to-end mTLS (the filer's own TLS reaches the client, not
|
||||
# terminated at the edge), drop backend-protocol above and use TLS
|
||||
# passthrough instead:
|
||||
# nginx.ingress.kubernetes.io/ssl-passthrough: "true"
|
||||
# Passthrough routes by SNI (set `host` above), ignores `path`, and
|
||||
# requires ingress-nginx to run with --enable-ssl-passthrough.
|
||||
tls: []
|
||||
|
||||
# extraEnvVars is a list of extra environment variables to set with the stateful set.
|
||||
extraEnvironmentVars:
|
||||
|
||||
Reference in New Issue
Block a user