feat(deploy): add the searchhost worker and the sandbox fanout route
app/searchhost is a worker-only binary, so it gets a Deployment without probes; search jobs are claimed with a CAS update, so running it next to the synchost indexers cannot double-process a job. The web app streams sandbox run events straight from the browser, so the chart can expose <host>/sandbox through a traefik IngressRoute. Because traefik does not resolve services across namespaces here, the route points at an ExternalName Service for sandbox-agent-server.
ZhenYi committed
Added chart/templates/sandbox-fanout.yaml chart/templates/sandbox-fanout.yaml +71 −0 View chart/templates/sandbox-fanout.yaml
@@ -0,0 +1,71 @@
1{{- /*
2 浏览器直连的 sandbox 运行事件流(SSE)。
3
4 web 端拿着短时令牌直接连 `${fanout_endpoint}/v1/sessions/...`,所以这条路由必须
5 对公网可用。sandbox-agent-server 在 agent-sandbox-system 命名空间,而 traefik 的
6 kubernetesCRD provider 没有开 allowCrossNamespace,所以这里用 ExternalName Service
7 把跨命名空间的 service 映射成同命名空间的名字,再由 IngressRoute 去掉 /sandbox
8 前缀转发(与 web 开发期的 vite 代理行为一致)。
9
10 仅在 ingress.controller=traefik 时可用。
11*/}}
12{{- if and .Values.sandboxFanout.enabled .Values.sandboxFanout.host }}
13{{- $fullName := include "gitdata.fullname" . }}
14{{- $prefix := default "/sandbox" .Values.sandboxFanout.pathPrefix }}
15{{- $name := printf "%s-sandbox-fanout" $fullName }}
16{{- $tlsSecret := default (printf "%s-tls" $fullName) .Values.ingress.tls.secretName }}
17apiVersion: v1
18kind: Service
19metadata:
20 name: {{ $name }}
21 labels:
22 {{- include "gitdata.labels" . | nindent 4 }}
23 app.kubernetes.io/component: sandbox-fanout
24spec:
25 type: ExternalName
26 externalName: {{ printf "%s.%s.svc.cluster.local" .Values.sandboxFanout.service .Values.sandboxFanout.namespace | quote }}
27 ports:
28 - name: http
29 port: {{ .Values.sandboxFanout.port }}
30 targetPort: {{ .Values.sandboxFanout.port }}
31 protocol: TCP
32---
33apiVersion: traefik.io/v1alpha1
34kind: Middleware
35metadata:
36 name: {{ $name }}
37 labels:
38 {{- include "gitdata.labels" . | nindent 4 }}
39 app.kubernetes.io/component: sandbox-fanout
40spec:
41 stripPrefix:
42 prefixes:
43 - {{ $prefix | quote }}
44---
45apiVersion: traefik.io/v1alpha1
46kind: IngressRoute
47metadata:
48 name: {{ $name }}
49 labels:
50 {{- include "gitdata.labels" . | nindent 4 }}
51 app.kubernetes.io/component: sandbox-fanout
52spec:
53 entryPoints:
54 - web
55 - websecure
56 routes:
57 # 优先级高于主 IngressRoute/Ingress 的 "/",避免被 apihost 抢走
58 - kind: Rule
59 match: Host(`{{ .Values.sandboxFanout.host }}`) && PathPrefix(`{{ $prefix }}`)
60 priority: 1200
61 middlewares:
62 - name: {{ $name }}
63 services:
64 - name: {{ $name }}
65 port: {{ .Values.sandboxFanout.port }}
66 passHostHeader: true
67 {{- if .Values.ingress.tls.enabled }}
68 tls:
69 secretName: {{ $tlsSecret }}
70 {{- end }}
71{{- end }}
No newline at end of file
Added chart/templates/searchhost.yaml chart/templates/searchhost.yaml +67 −0 View chart/templates/searchhost.yaml
@@ -0,0 +1,67 @@
1{{- if .Values.searchhost.enabled }}
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: {{ printf "%s-searchhost" (include "gitdata.fullname" .) }}
6 labels:
7 {{- include "gitdata.labels" . | nindent 4 }}
8 app.kubernetes.io/component: searchhost
9spec:
10 replicas: {{ .Values.searchhost.replicaCount }}
11 revisionHistoryLimit: 3
12 selector:
13 matchLabels:
14 {{- include "gitdata.selectorLabels" . | nindent 6 }}
15 app.kubernetes.io/component: searchhost
16 template:
17 metadata:
18 labels:
19 {{- include "gitdata.selectorLabels" . | nindent 8 }}
20 app.kubernetes.io/component: searchhost
21 {{- with .Values.podLabels }}
22 {{- toYaml . | nindent 8 }}
23 {{- end }}
24 annotations:
25 checksum/env: {{ toYaml .Values.config.env | sha256sum }}
26 {{- with .Values.podAnnotations }}
27 {{- toYaml . | nindent 8 }}
28 {{- end }}
29 spec:
30 serviceAccountName: {{ include "gitdata.serviceAccountName" . }}
31 {{- include "gitdata.imagePullSecrets" . | nindent 6 }}
32 # 索引任务会在 git 子进程里读仓库,留足 drain 时间
33 terminationGracePeriodSeconds: 600
34 securityContext:
35 {{- toYaml .Values.podSecurityContext | nindent 8 }}
36 containers:
37 # app/searchhost 只跑 SearchWorker,不监听 HTTP 端口,所以没有探针;
38 # 进程退出即由 kubelet 重启。
39 - name: searchhost
40 image: {{ include "gitdata.image" . }}
41 imagePullPolicy: {{ .Values.image.pullPolicy }}
42 args: ["searchhost"]
43 {{- include "gitdata.envFrom" . | nindent 10 }}
44 env:
45 {{- include "gitdata.env" . | nindent 12 }}
46 {{- with .Values.searchhost.extraEnv }}
47 {{- toYaml . | nindent 12 }}
48 {{- end }}
49 securityContext:
50 {{- toYaml .Values.securityContext | nindent 12 }}
51 resources:
52 {{- toYaml .Values.searchhost.resources | nindent 12 }}
53 volumeMounts:
54 - name: repos
55 mountPath: {{ .Values.persistence.repos.mountPath }}
56 volumes:
57 - name: repos
58 {{- if .Values.persistence.repos.existingClaim }}
59 persistentVolumeClaim:
60 claimName: {{ .Values.persistence.repos.existingClaim }}
61 {{- else if .Values.persistence.repos.enabled }}
62 persistentVolumeClaim:
63 claimName: {{ printf "%s-repos" (include "gitdata.fullname" .) }}
64 {{- else }}
65 emptyDir: {}
66 {{- end }}
67{{- end }}
No newline at end of file
Modified chart/values.yaml chart/values.yaml +20 −0 View chart/values.yaml
@@ -165,6 +165,26 @@
165165 limits: { memory: 768Mi }
166166 extraEnv: []
167167
168# 独立增量索引 worker(app/searchhost)。二进制不监听端口,因此没有探针。
169searchhost:
170 enabled: false
171 replicaCount: 1
172 resources:
173 requests: { cpu: 200m, memory: 256Mi }
174 limits: { memory: 1Gi }
175 extraEnv: []
176
177# 浏览器直连的 sandbox 运行事件流(SSE)。chart 在 <host><pathPrefix> 上建
178# IngressRoute + stripPrefix 中间件,并用 ExternalName Service 跨命名空间指向
179# sandbox-agent-server(traefik 专用;controller=nginx 时不要开启)。
180sandboxFanout:
181 enabled: false
182 host: ""
183 pathPrefix: /sandbox
184 namespace: agent-sandbox-system
185 service: sandbox-agent-server
186 port: 8090
187
168188mails:
169189 enabled: true
170190 replicaCount: 1