From eb902637093d451cca48cb600822de435215804c Mon Sep 17 00:00:00 2001 From: yuyufei Date: Sat, 25 Jul 2026 14:05:13 +0800 Subject: [PATCH] fix: serve root health for alb --- deploy/helm/keystone-stack/README.md | 7 ++-- .../keystone-stack/templates/ingress.yaml | 30 ++-------------- deploy/helm/keystone-stack/values.yaml | 5 --- internal/server/server.go | 5 ++- internal/server/server_test.go | 35 +++++++++++++++++++ 5 files changed, 45 insertions(+), 37 deletions(-) diff --git a/deploy/helm/keystone-stack/README.md b/deploy/helm/keystone-stack/README.md index d85c206..b58f42b 100644 --- a/deploy/helm/keystone-stack/README.md +++ b/deploy/helm/keystone-stack/README.md @@ -169,10 +169,9 @@ Synapse uses the same-origin `/api/v1` path. The chart's HTTP Ingress sends `/api` and `/swagger` to Keystone, `/transfer` and `/recorder` to Keystone's WebSocket ports, and all remaining paths to Synapse. -The chart renders Keystone HTTP paths and the Synapse root path as separate -Ingress resources because the Volcengine ALB health check is configured per -Ingress/server group. Keystone uses `/api/v1/health`; Synapse keeps the default -root health check. +Keystone also serves a root health response for ALB backend health checks. The +public root path still routes to Synapse because the HTTP Ingress sends `/` to +the Synapse Service. The gRPC Ingress is separate so the VKE ALB annotations can select listener `50053` and backend protocol `grpc` without affecting browser/API routing. diff --git a/deploy/helm/keystone-stack/templates/ingress.yaml b/deploy/helm/keystone-stack/templates/ingress.yaml index ee07ad2..365d5bd 100644 --- a/deploy/helm/keystone-stack/templates/ingress.yaml +++ b/deploy/helm/keystone-stack/templates/ingress.yaml @@ -2,11 +2,11 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: {{ include "keystone-stack.componentName" (list . "keystone-ingress") }} + name: {{ include "keystone-stack.componentName" (list . "ingress") }} labels: {{- include "keystone-stack.labels" . | nindent 4 }} - app.kubernetes.io/component: keystone-ingress - {{- with .Values.ingress.keystoneAnnotations }} + app.kubernetes.io/component: ingress + {{- with .Values.ingress.annotations }} annotations: {{- toYaml . | nindent 4 }} {{- end }} @@ -50,30 +50,6 @@ spec: name: {{ include "keystone-stack.componentName" (list . "keystone") }} port: number: {{ .Values.keystone.service.ports.recorderWebSocket }} ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ include "keystone-stack.componentName" (list . "ingress") }} - labels: - {{- include "keystone-stack.labels" . | nindent 4 }} - app.kubernetes.io/component: ingress - {{- with .Values.ingress.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- with .Values.ingress.className }} - ingressClassName: {{ . | quote }} - {{- end }} - {{- with .Values.ingress.tls }} - tls: - {{- toYaml . | nindent 4 }} - {{- end }} - rules: - - host: {{ include "keystone-stack.host" . | quote }} - http: - paths: - path: / pathType: Prefix backend: diff --git a/deploy/helm/keystone-stack/values.yaml b/deploy/helm/keystone-stack/values.yaml index 1a1475c..b8ba046 100644 --- a/deploy/helm/keystone-stack/values.yaml +++ b/deploy/helm/keystone-stack/values.yaml @@ -179,11 +179,6 @@ ingress: ingress.vke.volcengine.com/loadbalancer-port: "443" ingress.vke.volcengine.com/loadbalancer-protocol: https ingress.vke.volcengine.com/loadbalancer-backend-protocol: http - keystoneAnnotations: - ingress.vke.volcengine.com/loadbalancer-port: "443" - ingress.vke.volcengine.com/loadbalancer-protocol: https - ingress.vke.volcengine.com/loadbalancer-backend-protocol: http - ingress.vke.volcengine.com/loadbalancer-healthcheck-path: /api/v1/health host: "" tls: [] grpc: diff --git a/internal/server/server.go b/internal/server/server.go index 0ee8928..0db3543 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -229,7 +229,10 @@ func (s *Server) buildRoutes() http.Handler { // API v1 group v1 := s.engine.Group("/api/v1") - // Health check - register only in API v1 group + // Root health check for load balancers that probe "/" on the Keystone backend. + s.engine.GET("/", s.health.Handler) + + // Health check s.health.RegisterAPI(v1) v1Routes := v1.Group("") diff --git a/internal/server/server_test.go b/internal/server/server_test.go index 028179e..fc77910 100644 --- a/internal/server/server_test.go +++ b/internal/server/server_test.go @@ -5,6 +5,8 @@ package server import ( + "net/http" + "net/http/httptest" "testing" "time" @@ -31,3 +33,36 @@ func TestAxonTransferWriteTimeoutFromConfig(t *testing.T) { }) } } + +func TestHTTPHealthRoutes(t *testing.T) { + srv := New(&config.Config{ + Server: config.ServerConfig{ + BindAddr: ":8080", + }, + AxonTransfer: config.TransferConfig{ + WSPort: 8090, + MaxEvents: 10, + }, + AxonRecorder: config.RecorderConfig{ + WSPort: 8091, + ResponseTimeout: 1, + }, + }, nil, nil, nil) + + tests := []string{ + "/", + "/api/v1/health", + } + for _, path := range tests { + t.Run(path, func(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, path, nil) + w := httptest.NewRecorder() + + srv.httpServer.Handler.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Fatalf("GET %s status=%d want=%d body=%s", path, w.Code, http.StatusOK, w.Body.String()) + } + }) + } +}