diff --git a/k8s/charts/seaweedfs/templates/s3/s3-deployment.yaml b/k8s/charts/seaweedfs/templates/s3/s3-deployment.yaml index 1fff9dbc4..d0e4fe7f3 100644 --- a/k8s/charts/seaweedfs/templates/s3/s3-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/s3/s3-deployment.yaml @@ -149,6 +149,7 @@ spec: {{- if .Values.s3.icebergPort }} -port.iceberg={{ .Values.s3.icebergPort }} \ {{- end }} + -port.lance={{ .Values.s3.lancePort | default 0 }} \ {{- range .Values.s3.extraArgs }} {{ . }} \ {{- end }} @@ -198,6 +199,10 @@ spec: - containerPort: {{ .Values.s3.icebergPort }} name: swfs-iceberg {{- end }} + {{- if .Values.s3.lancePort }} + - containerPort: {{ .Values.s3.lancePort }} + name: swfs-lance + {{- end }} {{- if .Values.s3.metricsPort }} - containerPort: {{ .Values.s3.metricsPort }} name: metrics diff --git a/k8s/charts/seaweedfs/templates/s3/s3-lance-ingress.yaml b/k8s/charts/seaweedfs/templates/s3/s3-lance-ingress.yaml new file mode 100644 index 000000000..32033a8f1 --- /dev/null +++ b/k8s/charts/seaweedfs/templates/s3/s3-lance-ingress.yaml @@ -0,0 +1,61 @@ +{{- define "seaweedfs.s3.lance.ingress.paths" -}} +paths: +- path: {{ .Values.s3.lanceIngress.path | quote }} + pathType: {{ .Values.s3.lanceIngress.pathType | quote }} + backend: + {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} + service: + name: {{ include "seaweedfs.componentName" (list . "s3") }} + port: + number: {{ .Values.s3.lancePort }} + {{- else }} + serviceName: {{ include "seaweedfs.componentName" (list . "s3") }} + servicePort: {{ .Values.s3.lancePort }} + {{- end }} +{{- end -}} +{{- if and .Values.s3.enabled .Values.s3.lancePort .Values.s3.lanceIngress.enabled }} +{{- $hosts := list }} +{{- if kindIs "slice" .Values.s3.lanceIngress.host }} + {{- $hosts = .Values.s3.lanceIngress.host }} +{{- else if .Values.s3.lanceIngress.host }} + {{- $hosts = list .Values.s3.lanceIngress.host }} +{{- end }} +{{- 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" . }}-s3-lance + namespace: {{ .Release.Namespace }} + {{- with .Values.s3.lanceIngress.annotations }} + 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: s3-lance +spec: + {{- if .Values.s3.lanceIngress.className }} + ingressClassName: {{ .Values.s3.lanceIngress.className | quote }} + {{- end }} + tls: + {{ .Values.s3.lanceIngress.tls | default list | toYaml | nindent 6}} + rules: +{{- if $hosts }} +{{- range $host := $hosts }} + - host: {{ $host | quote }} + http: + {{- include "seaweedfs.s3.lance.ingress.paths" $ | nindent 6 }} +{{- end }} +{{- else }} + - http: + {{- include "seaweedfs.s3.lance.ingress.paths" . | nindent 4 }} +{{- end }} +{{- end }} diff --git a/k8s/charts/seaweedfs/templates/s3/s3-service.yaml b/k8s/charts/seaweedfs/templates/s3/s3-service.yaml index 4a4e6a410..b5aba6a86 100644 --- a/k8s/charts/seaweedfs/templates/s3/s3-service.yaml +++ b/k8s/charts/seaweedfs/templates/s3/s3-service.yaml @@ -44,6 +44,15 @@ spec: {{- end }} protocol: TCP {{- end }} +{{- if and .Values.s3.enabled .Values.s3.lancePort }} + - name: "swfs-lance" + port: {{ .Values.s3.lancePort }} + targetPort: {{ .Values.s3.lancePort }} +{{- if $nodePorts.lance }} + nodePort: {{ $nodePorts.lance }} +{{- end }} + protocol: TCP +{{- end }} {{- if and .Values.s3.enabled .Values.s3.httpsPort }} - name: "swfs-s3-tls" port: {{ .Values.s3.httpsPort }} diff --git a/k8s/charts/seaweedfs/templates/shared/_helpers.tpl b/k8s/charts/seaweedfs/templates/shared/_helpers.tpl index 71ac9c62b..3ac343075 100644 --- a/k8s/charts/seaweedfs/templates/shared/_helpers.tpl +++ b/k8s/charts/seaweedfs/templates/shared/_helpers.tpl @@ -148,6 +148,15 @@ true {{- end -}} {{- end -}} +{{/* Lance namespace URL the worker's Lance container maintains; empty when unreachable */}} +{{- define "seaweedfs.worker.lanceNamespaceUrl" -}} +{{- if .Values.worker.namespaceUrl -}} +{{- .Values.worker.namespaceUrl -}} +{{- else if and .Values.s3.enabled .Values.s3.lancePort -}} +{{- printf "http://%s.%s:%d" (include "seaweedfs.componentName" (list . "s3")) .Release.Namespace (int .Values.s3.lancePort) -}} +{{- end -}} +{{- end -}} + {{/* Return the proper volume image */}} {{- define "seaweedfs.volume.image" -}} {{- if .Values.volume.imageOverride -}} diff --git a/k8s/charts/seaweedfs/templates/shared/networkpolicy.yaml b/k8s/charts/seaweedfs/templates/shared/networkpolicy.yaml index 91f41bee1..92404a754 100644 --- a/k8s/charts/seaweedfs/templates/shared/networkpolicy.yaml +++ b/k8s/charts/seaweedfs/templates/shared/networkpolicy.yaml @@ -73,6 +73,9 @@ {{- if .Values.s3.icebergPort }} {{- $ports = append $ports .Values.s3.icebergPort }} {{- end }} +{{- if .Values.s3.lancePort }} +{{- $ports = append $ports .Values.s3.lancePort }} +{{- end }} {{- if .Values.s3.metricsPort }} {{- $ports = append $ports .Values.s3.metricsPort }} {{- end }} @@ -97,6 +100,9 @@ {{- if .Values.worker.metricsPort }} {{- $ports = append $ports .Values.worker.metricsPort }} {{- end }} +{{- if and .Values.worker.lanceMetricsPort (include "seaweedfs.worker.lanceNamespaceUrl" .) }} +{{- $ports = append $ports .Values.worker.lanceMetricsPort }} +{{- end }} {{- $targets = append $targets (dict "component" "worker" "ports" $ports) }} {{- end }} diff --git a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml index b2b4892da..75b438cd9 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-deployment.yaml @@ -223,6 +223,81 @@ spec: {{- if .Values.worker.containerSecurityContext.enabled }} securityContext: {{- omit .Values.worker.containerSecurityContext "enabled" | toYaml | nindent 12 }} {{- end }} + {{- if include "seaweedfs.worker.lanceNamespaceUrl" . }} + - name: worker-lance + image: {{ template "seaweedfs.worker.image" . }} + imagePullPolicy: {{ default "IfNotPresent" .Values.global.seaweedfs.imagePullPolicy }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + # The URL reaches the shell below; a value with metacharacters must + # arrive as data, not syntax. + - name: LANCE_NAMESPACE_URL + value: {{ include "seaweedfs.worker.lanceNamespaceUrl" . | quote }} + command: + - "/bin/sh" + - "-ec" + - | + if [ ! -s /usr/bin/weed-worker ]; then + echo "the Rust worker is not available on this platform ($(uname -m)); it ships for amd64 and arm64" >&2 + exit 1 + fi + exec /usr/bin/weed-worker \ + --id="$POD_NAME" \ + {{- if .Values.worker.adminServer }} + --admin={{ .Values.worker.adminServer }} \ + {{- else }} + --admin={{ template "seaweedfs.fullname" . }}-admin.{{ .Release.Namespace }}:{{ .Values.admin.port }}{{ if .Values.admin.grpcPort }}.{{ .Values.admin.grpcPort }}{{ end }} \ + {{- end }} + --namespace="$LANCE_NAMESPACE_URL" \ + {{- if .Values.global.seaweedfs.enableSecurity }} + --tls-ca=/usr/local/share/ca-certificates/ca/tls.crt \ + --tls-cert=/usr/local/share/ca-certificates/worker/tls.crt \ + --tls-key=/usr/local/share/ca-certificates/worker/tls.key \ + {{- end }} + {{- if .Values.worker.lanceMetricsPort }} + --metrics-port={{ .Values.worker.lanceMetricsPort }} \ + --metrics-ip=0.0.0.0 \ + {{- end }} + --max-concurrency={{ .Values.worker.maxExecute }} + {{- if .Values.global.seaweedfs.enableSecurity }} + volumeMounts: + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: worker-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/worker/ + {{- end }} + {{- if .Values.worker.lanceMetricsPort }} + ports: + - containerPort: {{ .Values.worker.lanceMetricsPort }} + name: lance-metrics + livenessProbe: + httpGet: + path: /health + port: lance-metrics + initialDelaySeconds: 30 + periodSeconds: 60 + successThreshold: 1 + failureThreshold: 5 + timeoutSeconds: 10 + readinessProbe: + httpGet: + path: /ready + port: lance-metrics + initialDelaySeconds: 20 + periodSeconds: 15 + successThreshold: 1 + failureThreshold: 3 + timeoutSeconds: 10 + {{- end }} + {{- if .Values.worker.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.worker.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- end }} {{- if .Values.worker.sidecars }} {{- include "seaweedfs.tplvalues.render" (dict "value" .Values.worker.sidecars "context" $) | nindent 8 }} {{- end }} diff --git a/k8s/charts/seaweedfs/templates/worker/worker-service.yaml b/k8s/charts/seaweedfs/templates/worker/worker-service.yaml index d78e0cf78..6c0ae8b70 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-service.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-service.yaml @@ -12,13 +12,22 @@ metadata: app.kubernetes.io/component: worker spec: clusterIP: None # Headless service - {{- if .Values.worker.metricsPort }} + {{- $lanceMetrics := and .Values.worker.lanceMetricsPort (include "seaweedfs.worker.lanceNamespaceUrl" .) }} + {{- if or .Values.worker.metricsPort $lanceMetrics }} ports: + {{- if .Values.worker.metricsPort }} - name: "metrics" port: {{ .Values.worker.metricsPort }} targetPort: {{ .Values.worker.metricsPort }} protocol: TCP {{- end }} + {{- if $lanceMetrics }} + - name: "lance-metrics" + port: {{ .Values.worker.lanceMetricsPort }} + targetPort: {{ .Values.worker.lanceMetricsPort }} + protocol: TCP + {{- end }} + {{- end }} selector: app.kubernetes.io/name: {{ template "seaweedfs.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml b/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml index 8ec4be870..50cb04f48 100644 --- a/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml +++ b/k8s/charts/seaweedfs/templates/worker/worker-servicemonitor.yaml @@ -1,6 +1,7 @@ {{- include "seaweedfs.compat" . -}} {{- if .Values.worker.enabled }} -{{- if .Values.worker.metricsPort }} +{{- $lanceMetrics := and .Values.worker.lanceMetricsPort (include "seaweedfs.worker.lanceNamespaceUrl" .) }} +{{- if or .Values.worker.metricsPort $lanceMetrics }} {{- if .Values.global.seaweedfs.monitoring.enabled }} apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor @@ -22,9 +23,16 @@ metadata: {{- end }} spec: endpoints: + {{- if .Values.worker.metricsPort }} - interval: 30s port: metrics scrapeTimeout: 5s + {{- end }} + {{- if $lanceMetrics }} + - interval: 30s + port: lance-metrics + scrapeTimeout: 5s + {{- end }} selector: matchLabels: app.kubernetes.io/name: {{ template "seaweedfs.name" . }} diff --git a/k8s/charts/seaweedfs/values.yaml b/k8s/charts/seaweedfs/values.yaml index 460fc8eb3..10878d43d 100644 --- a/k8s/charts/seaweedfs/values.yaml +++ b/k8s/charts/seaweedfs/values.yaml @@ -1006,6 +1006,10 @@ s3: # Iceberg catalog REST port (Apache Iceberg REST Catalog API) # Set to a port number to enable, or 0/null to disable icebergPort: null + # Lance Namespace REST port (Lance Namespace API), on by default like + # standalone `weed s3`. Set to 0 to disable; that also drops the worker's + # Lance maintenance container. + lancePort: 9101 loggingOverrideLevel: null # enable user & permission to s3 (need to inject to all services) enableAuth: false @@ -1193,6 +1197,7 @@ s3: http: null https: null iceberg: null + lance: null metrics: null icebergIngress: @@ -1204,6 +1209,15 @@ s3: annotations: {} tls: [] + lanceIngress: + enabled: false + className: "" + host: "seaweedfs-lance.cluster.local" + path: "/" + pathType: Prefix + annotations: {} + tls: [] + sftp: enabled: false imageOverride: null @@ -1460,6 +1474,23 @@ worker: metricsPort: 9327 metricsIp: "" # If empty, defaults to 0.0.0.0 + # The Lance maintenance worker (/usr/bin/weed-worker, Rust) runs as a + # second container beside `weed worker` whenever its namespace is + # reachable: namespaceUrl set, or s3 enabled with a nonzero s3.lancePort. + # It runs alongside rather than instead, because the job families are + # disjoint: the Go worker serves vacuum, balance, EC and + # iceberg_maintenance; only the Rust worker serves lance_compact, + # lance_optimize_indices and lance_cleanup_versions. The binary ships for + # amd64 and arm64; on an armv7/386-only cluster set s3.lancePort: 0, or + # the container exits at startup naming the platform. + + # Lance namespace URL override. When empty, derived from this release's + # S3 service and s3.lancePort. + namespaceUrl: "" + + # Metrics port for the Lance worker container; the Go worker keeps metricsPort + lanceMetricsPort: 9328 + # Admin server to connect to adminServer: ""