feat(ingress): add traefik support with a githost IngressRoute
ZhenYi committed
Modified chart/templates/ingress.yaml chart/templates/ingress.yaml +11 −3 View chart/templates/ingress.yaml
@@ -1,6 +1,10 @@
11{{- if .Values.ingress.enabled }}
22{{- $fullName := include "gitdata.fullname" . }}
3{{- $controller := default "nginx" .Values.ingress.controller }}
34{{- $tlsSecret := default (printf "%s-tls" $fullName) .Values.ingress.tls.secretName }}
5{{- $annotations := deepCopy .Values.ingress.annotations }}
6{{- if eq $controller "nginx" }}
7{{- /* ingress-nginx:正则路由 + 大包/长连接超时(用户 annotations 优先于这里的默认值) */}}
48{{- $nginxDefaults := dict
59 "nginx.ingress.kubernetes.io/use-regex" "true"
610 "nginx.ingress.kubernetes.io/proxy-body-size" .Values.ingress.proxyBodySize
@@ -8,7 +12,8 @@
812 "nginx.ingress.kubernetes.io/proxy-send-timeout" (printf "%v" .Values.ingress.proxySendTimeout)
913 "nginx.ingress.kubernetes.io/proxy-connect-timeout" (printf "%v" .Values.ingress.proxyConnectTimeout)
1014 }}
11{{- $annotations := merge (deepCopy .Values.ingress.annotations) (mustFromJson (toJson $nginxDefaults)) }}
15{{- $annotations = merge (mustFromJson (toJson $nginxDefaults)) $annotations }}
16{{- end }}
1217{{- if and .Values.ingress.tls.enabled .Values.ingress.tls.clusterIssuer }}
1318{{- $_ := set $annotations "cert-manager.io/cluster-issuer" .Values.ingress.tls.clusterIssuer }}
1419{{- end }}
@@ -18,8 +23,10 @@
1823 name: {{ $fullName }}
1924 labels:
2025 {{- include "gitdata.labels" . | nindent 4 }}
26 {{- if $annotations }}
2127 annotations:
2228 {{- toYaml $annotations | nindent 4 }}
29 {{- end }}
2330spec:
2431 {{- with .Values.ingress.className }}
2532 ingressClassName: {{ . }}
@@ -34,8 +41,9 @@
3441 - host: {{ .Values.ingress.host | quote }}
3542 http:
3643 paths:
37 # *.git 必须路由到 githost(反代契约 §3.1),排在 "/" 之前
38 {{- if .Values.githost.enabled }}
44 # *.git 必须路由到 githost(反代契约 §3.1),排在 "/" 之前。
45 # 仅 nginx 走这里;traefik 见 templates/ingressroute-githost.yaml
46 {{- if and .Values.githost.enabled (eq $controller "nginx") }}
3947 - path: {{ .Values.ingress.githostPath | quote }}
4048 pathType: ImplementationSpecific
4149 backend:
Added chart/templates/ingressroute-githost.yaml chart/templates/ingressroute-githost.yaml +39 −0 View chart/templates/ingressroute-githost.yaml
@@ -0,0 +1,39 @@
1{{- /*
2 traefik 专用:把 *.git 的 git smart-HTTP 请求路由到 githost。
3
4 traefik 的 Kubernetes Ingress provider 只支持 Prefix/Exact,`ImplementationSpecific`
5 会被当作字面前缀,所以主 Ingress 里那条 `/(.*\.git)(/|$)` 正则在这里用
6 IngressRoute + PathRegexp 表达。cert-manager 的证书仍由主 Ingress 上的
7 `cert-manager.io/cluster-issuer` 注解签发,两边共用同一个 TLS secret。
8
9 仅在 .Values.githost.enabled 且 ingress.controller=traefik 时渲染。
10*/}}
11{{- if and .Values.ingress.enabled .Values.githost.enabled (eq (default "nginx" .Values.ingress.controller) "traefik") }}
12{{- $fullName := include "gitdata.fullname" . }}
13{{- $tlsSecret := default (printf "%s-tls" $fullName) .Values.ingress.tls.secretName }}
14apiVersion: traefik.io/v1alpha1
15kind: IngressRoute
16metadata:
17 name: {{ printf "%s-githost" $fullName }}
18 labels:
19 {{- include "gitdata.labels" . | nindent 4 }}
20 app.kubernetes.io/component: githost
21spec:
22 entryPoints:
23 - web
24 - websecure
25 routes:
26 # priority 高于主 Ingress 的 "/"(traefik 默认按 rule 长度比优先级,这里显式钉住)
27 - kind: Rule
28 match: Host(`{{ .Values.ingress.host }}`) && PathRegexp(`{{ .Values.ingress.githostPathRegexp }}`)
29 priority: 1000
30 services:
31 - name: {{ printf "%s-githost" $fullName }}
32 port: smart-http
33 # git push/pull 是长连接大包传输:不要做响应缓冲
34 passHostHeader: true
35 {{- if .Values.ingress.tls.enabled }}
36 tls:
37 secretName: {{ $tlsSecret }}
38 {{- end }}
39{{- end }}
Modified chart/values.yaml chart/values.yaml +11 −2 View chart/values.yaml
@@ -264,14 +264,23 @@
264264
265265# ---------------------------------------------------------------------------
266266# Ingress:同源 TLS 终结;*.git -> githost,/ws/v1 -> im,其余 -> apihost
267# 默认按 ingress-nginx 生成(regex path + ImplementationSpecific)
267#
268# controller 决定路由怎么写:
269# nginx —— 主 Ingress 用 regex path + ImplementationSpecific(配 use-regex 注解)
270# traefik —— 主 Ingress 只写前缀路由;*.git 由 templates/ingressroute-githost.yaml
271# 的 IngressRoute(PathRegexp)接管 —— traefik 的 Ingress provider 不支持
272# 正则 path,ImplementationSpecific 会被当字面前缀处理。
273# 其它控制器请把 controller 设成非 nginx 值,并按需在 className/annotations 里给出自己的语义。
268274# ---------------------------------------------------------------------------
269275ingress:
270276 enabled: true
277 controller: nginx
271278 className: nginx
272279 host: gitdata.example.com
273 # githost 路由匹配(ingress-nginx 需 use-regex)。其它控制器可改为独立 host/path
280 # githost 路由匹配(仅 controller=nginx 使用)
274281 githostPath: "/(.*\\.git)(/|$)"
282 # traefik 用的正则(覆盖 owner/repo.git 与多级 group)
283 githostPathRegexp: "^/.+\\.git(/|$)"
275284 annotations: {}
276285 tls:
277286 enabled: true
Modified deploy/values/prod.yaml deploy/values/prod.yaml +37 −22 View deploy/values/prod.yaml
@@ -1,6 +1,8 @@
11image:
22 repository: harbor.gitdata.me/app/gitdata
3 tag: ""
3 # 原来留空由 CI 传 --set image.tag=sha-<short>;CI 已删(81f2cbd5),改成钉住版本。
4 # 对应 commit d46785a6(oxcache→共享 Redis、移除 sagent 之后的第一版)。
5 tag: "sha-d46785a"
46 pullPolicy: IfNotPresent
57
68serviceAccount:
@@ -11,12 +13,15 @@
1113 APP_REDIS__MODE: "cluster"
1214 APP_REDIS__POOL_SIZE: "8"
1315 APP_S3__ENDPOINT: "http://rustfs-svc.rustfs.svc.cluster.local:9000"
14 APP_S3__PUBLIC_ENDPOINT: "https://s3.gitdata.ai"
16 # 浏览器可见的预签名 URL 主机。本集群 rustfs 的对外 S3 入口是 object.gitdata.ai
17 # (Ingress rustfs-s3;旧的 s3.gitdata.ai 在本集群没有路由,取图会 HTTP 000)
18 APP_S3__PUBLIC_ENDPOINT: "https://object.gitdata.ai"
1519 APP_S3__BUCKET: "gitdata"
1620 APP_S3__REGION: "us-east-1"
1721 APP_S3__PATH_STYLE: "true"
1822 APP_SEARCH__ENABLED: "true"
19 APP_SEARCH__URL: "http://meili-meilisearch.gitdata.svc.cluster.local:7700"
23 # 本集群 meilisearch 的 Service 名(旧集群是 meili-meilisearch.gitdata.svc)
24 APP_SEARCH__URL: "http://meilisearch.meilisearch.svc.cluster.local:7700"
2025 APP_SEARCH__INDEX_PREFIX: "gitdata"
2126 APP_LIVEKIT__ENABLED: "true"
2227 APP_LIVEKIT__URL: "wss://livekit.gitdata.ai"
@@ -41,20 +46,30 @@
4146 OTEL_TRACES_SAMPLER: "parentbased_traceidratio"
4247 OTEL_TRACES_SAMPLER_ARG: "0.2"
4348
49# 集群内 LGTM(monitoring/otel-collector relay:traces->tempo、logs->loki、metrics->mimir)
50# 旧集群推的是外部 OpenObserve https://o2.gitdata.me/api/3JmB4...(其 Authorization headers 已不再需要)
4451metrics:
45 otlpEndpoint: "https://o2.gitdata.me/api/3JmB4YFMnPffh11t8283QXAwW36"
52 otlpEndpoint: "http://otel-collector.monitoring.svc.cluster.local:4318"
4653
4754ingress:
4855 enabled: true
49 className: nginx
56 # 本集群只有 traefik(k3s 自带,3.7.8);*.git 由 chart 里的 IngressRoute + PathRegexp 接管
57 controller: traefik
58 className: traefik
5059 host: gitdata.ai
5160 annotations:
52 nginx.ingress.kubernetes.io/affinity: "cookie"
53 nginx.ingress.kubernetes.io/session-cookie-name: "GD-AFFINITY"
54 nginx.ingress.kubernetes.io/session-cookie-value-strategy: "incremental"
55 nginx.ingress.kubernetes.io/session-cookie-http-only: "true"
56 nginx.ingress.kubernetes.io/session-cookie-samesite: "Lax"
57 nginx.ingress.kubernetes.io/session-cookie-persistent: "false"
61 # 会话保持:traefik 的 sticky cookie(替代原先 nginx 的 affinity cookie 注解)
62 traefik.ingress.kubernetes.io/service.sticky.cookie: "true"
63 traefik.ingress.kubernetes.io/service.sticky.cookie.name: "GD-AFFINITY"
64 traefik.ingress.kubernetes.io/service.sticky.cookie.httpOnly: "true"
65 traefik.ingress.kubernetes.io/service.sticky.cookie.secure: "true"
66 traefik.ingress.kubernetes.io/service.sticky.cookie.sameSite: "Lax"
67 tls:
68 enabled: true
69 secretName: ""
70 # 主域名证书靠这条注解签发(chart 只读 ingress.tls.clusterIssuer;
71 # 原先写在 apihost.tls 下的那份是死配置,chart 从不读)
72 clusterIssuer: cloudflare-acme-cluster-issuer
5873apihost:
5974 resources:
6075 requests: { cpu: 250m, memory: 512Mi }
@@ -82,18 +97,16 @@
8297 - type: Pods
8398 value: 1
8499 periodSeconds: 60
85 tls:
86 enabled: true
87 secretName: ""
88 clusterIssuer: cloudflare-acme-cluster-issuer
89 proxyBodySize: "0"
90 proxyReadTimeout: 3600
91 proxySendTimeout: 3600
92 proxyConnectTimeout: 60
100# 注:apihost.tls.* 与 apihost.proxy* 曾经写在这里,但 chart 的模板只读
101# .Values.ingress.{tls,proxy*} 的同名键,apihost 下这些键没人引用 → 已删除,
102# 对应设置已移到上面 ingress 块(tls)与 chart 的 nginx 默认注解(proxy*)。
93103
94104githost:
95105 enabled: true
96 replicaCount: 2
106 # 首次部署留 1 副本:SSH host key 落在共享 PVC(/opt/gitdata/ssh_host_ed25519),
107 # 空 PVC 上多副本会各自生成一把 key,客户端 known_hosts 会抖动。
108 # 首启后把 key 固化到 PVC,再改回 2。
109 replicaCount: 1
97110 httpPort: 9418
98111 ssh:
99112 enabled: true
@@ -104,6 +117,8 @@
104117 type: LoadBalancer
105118 port: 22
106119 annotations:
120 # 本集群没有 MetalLB,这个注解当前不生效;k3s klipper 会把 22 端口发布到所有节点
121 # (47.239.98.8 是 node.1,ssh.gitdata.ai 指向它)。装了 MetalLB 后可原样用。
107122 metallb.universe.tf/loadBalancerIPs: "47.239.98.8"
108123
109124adminhost:
@@ -111,7 +126,7 @@
111126 ingress:
112127 enabled: true
113128 host: admin.gitdata.ai
114 className: nginx
129 className: traefik
115130 tls:
116131 enabled: true
117132 secretName: ""
@@ -122,7 +137,7 @@
122137 ingress:
123138 enabled: true
124139 host: hooks.gitdata.ai
125 className: nginx
140 className: traefik
126141 tls:
127142 enabled: true
128143 secretName: ""