Skip to content

Commit 826bc42

Browse files
heschigopherbot
authored andcommitted
internal/https: add health checking support and use it
CL 454935 broke the Kubernetes ingress by requiring IAP on health checks. Move /healthz handling into internal/https, where it automatically bypasses authentication and removes some duplicate trivial implementations. Unfortunately, GKE is not capable of inferring health check parameters from a multi-container pod like relui, so we have to change our BackendConfig. That sets off a yak shave -- I made the questionable decision to use the same backend for all our IAP services, and the coordinator doesn't currently support /healthz. Split all them up and delete the devapp configuration I was using for testing way back in the day. Change-Id: I45e866d30508a07e9a805de70af731dd64c22d7f Reviewed-on: https://go-review.googlesource.com/c/build/+/455215 Reviewed-by: Dmitri Shuralyov <[email protected]> Auto-Submit: Heschi Kreinick <[email protected]> Run-TryBot: Heschi Kreinick <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 5b51d6f commit 826bc42

File tree

8 files changed

+58
-60
lines changed

8 files changed

+58
-60
lines changed

cmd/coordinator/deployment-prod.yaml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ metadata:
6767
namespace: prod
6868
name: coordinator-internal-iap
6969
annotations:
70-
cloud.google.com/backend-config: '{"default": "build-ingress-iap-backend"}'
70+
cloud.google.com/backend-config: '{"default": "coordinator-iap-backend"}'
7171
cloud.google.com/neg: '{"ingress": false}'
7272
cloud.google.com/app-protocols: '{"https":"HTTP2"}'
7373
spec:
@@ -95,3 +95,15 @@ spec:
9595
selector:
9696
app: coordinator
9797
type: NodePort
98+
---
99+
apiVersion: cloud.google.com/v1
100+
kind: BackendConfig
101+
metadata:
102+
namespace: prod
103+
name: coordinator-iap-backend
104+
spec:
105+
iap:
106+
enabled: true
107+
oauthclientCredentials:
108+
secretName: iap-oauth
109+
timeoutSec: 86400 # For long-running gomote RPCs. See https://go.dev/issue/56423.

cmd/relui/deployment-prod.yaml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ spec:
4343
- "--serving-files-base=gs://golang"
4444
- "--edge-cache-url=https://dl.google.com/go"
4545
- "--website-upload-url=https://go.dev/dl/upload"
46+
readinessProbe:
47+
httpGet:
48+
path: /healthz
49+
port: 444
50+
scheme: HTTPS
4651
ports:
4752
- containerPort: 444
4853
env:
@@ -100,7 +105,7 @@ metadata:
100105
namespace: prod
101106
name: relui-internal
102107
annotations:
103-
cloud.google.com/backend-config: '{"default": "build-ingress-iap-backend"}'
108+
cloud.google.com/backend-config: '{"default": "relui-iap-backend"}'
104109
cloud.google.com/neg: '{"ingress": false}'
105110
cloud.google.com/app-protocols: '{"https":"HTTP2"}'
106111
spec:
@@ -111,3 +116,19 @@ spec:
111116
selector:
112117
app: relui
113118
type: NodePort
119+
---
120+
apiVersion: cloud.google.com/v1
121+
kind: BackendConfig
122+
metadata:
123+
namespace: prod
124+
name: relui-iap-backend
125+
spec:
126+
iap:
127+
enabled: true
128+
oauthclientCredentials:
129+
secretName: iap-oauth
130+
healthCheck:
131+
timeoutSec: 10
132+
checkIntervalSec: 15
133+
type: HTTPS
134+
requestPath: /healthz

deploy/build-ingress.yaml

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,6 @@ spec:
1717
- host: dev-test.golang.org
1818
http:
1919
paths:
20-
- pathType: ImplementationSpecific
21-
path: /owners
22-
backend:
23-
service:
24-
name: devapp-internal-iap
25-
port:
26-
number: 444
2720
- pathType: ImplementationSpecific
2821
path: /*
2922
backend:
@@ -137,26 +130,6 @@ spec:
137130
enabled: true
138131
responseCodeName: FOUND
139132
---
140-
apiVersion: cloud.google.com/v1
141-
kind: BackendConfig
142-
metadata:
143-
namespace: prod
144-
name: build-ingress-iap-backend
145-
spec:
146-
iap:
147-
enabled: true
148-
oauthclientCredentials:
149-
secretName: iap-oauth
150-
timeoutSec: 86400 # For long-running gomote RPCs. See https://go.dev/issue/56423.
151-
---
152-
apiVersion: cloud.google.com/v1
153-
kind: BackendConfig
154-
metadata:
155-
namespace: prod
156-
name: build-ingress-maintnerd-backend
157-
spec:
158-
timeoutSec: 60 # For long-poll support on the /logs endpoint. See go.dev/issue/53569.
159-
---
160133
apiVersion: networking.gke.io/v1
161134
kind: ManagedCertificate
162135
metadata:

devapp/deployment-prod.yaml

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,24 +44,6 @@ spec:
4444
---
4545
apiVersion: v1
4646
kind: Service
47-
metadata:
48-
namespace: prod
49-
name: devapp-internal-iap
50-
annotations:
51-
cloud.google.com/backend-config: '{"default": "build-ingress-iap-backend"}'
52-
cloud.google.com/neg: '{"ingress": false}'
53-
cloud.google.com/app-protocols: '{"https":"HTTP2"}'
54-
spec:
55-
ports:
56-
- port: 444
57-
targetPort: 444
58-
name: https
59-
selector:
60-
app: devapp
61-
type: NodePort
62-
---
63-
apiVersion: v1
64-
kind: Service
6547
metadata:
6648
namespace: prod
6749
name: devapp-internal

devapp/server.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ func newServer(mux *http.ServeMux, staticDir, templateDir string, reloadTmpls bo
6464
userMapping: map[int]*maintner.GitHubUser{},
6565
}
6666
s.mux.Handle("/", http.FileServer(http.Dir(s.staticDir)))
67-
s.mux.HandleFunc("/healthz", handleHealthz)
6867
s.mux.HandleFunc("/favicon.ico", s.handleFavicon)
6968
s.mux.HandleFunc("/release", s.withTemplate("/release.tmpl", s.handleRelease))
7069
s.mux.HandleFunc("/reviews", s.withTemplate("/reviews.tmpl", s.handleReviews))
@@ -203,11 +202,6 @@ func (s *server) filteredHelpWantedIssues(pkgs ...string) []issueData {
203202
return issues
204203
}
205204

206-
func handleHealthz(w http.ResponseWriter, r *http.Request) {
207-
w.WriteHeader(http.StatusOK)
208-
w.Write([]byte("ok"))
209-
}
210-
211205
func (s *server) handleFavicon(w http.ResponseWriter, r *http.Request) {
212206
// Need to specify content type for consistent tests, without this it's
213207
// determined from mime.types on the box the test is running on

internal/https/https.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ type Options struct {
3434
SelfSignedAddr string
3535
// If non-empty, listen on this address and serve HTTP.
3636
HTTPAddr string
37+
// If non-empty, respond unconditionally with 200 OK to requests on this path.
38+
HealthPath string
3739
}
3840

3941
var DefaultOptions = &Options{}
@@ -47,6 +49,7 @@ func RegisterFlags(set *flag.FlagSet) {
4749
set.StringVar(&DefaultOptions.AutocertAddr, "listen-https-autocert", "", "if non-empty, listen on this address and serve HTTPS using a Let's Encrypt cert stored in autocert-bucket")
4850
set.StringVar(&DefaultOptions.SelfSignedAddr, "listen-https-selfsigned", "", "if non-empty, listen on this address and serve HTTPS using a self-signed cert")
4951
set.StringVar(&DefaultOptions.HTTPAddr, "listen-http", "", "if non-empty, listen on this address and serve HTTP")
52+
set.StringVar(&DefaultOptions.HealthPath, "health-path", "/healthz", "if non-empty, respond unconditionally with 200 OK to requests on this path")
5053
}
5154

5255
// ListenAndServe runs the servers configured by DefaultOptions. It always
@@ -60,6 +63,18 @@ func ListenAndServe(ctx context.Context, handler http.Handler) error {
6063
func ListenAndServeOpts(ctx context.Context, handler http.Handler, opts *Options) error {
6164
errc := make(chan error, 3)
6265

66+
if opts.HealthPath != "" {
67+
wrapped := handler
68+
handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
69+
if r.URL.Path == opts.HealthPath {
70+
w.WriteHeader(http.StatusOK)
71+
w.Write([]byte("ok"))
72+
} else {
73+
wrapped.ServeHTTP(w, r)
74+
}
75+
})
76+
}
77+
6378
if opts.HTTPAddr != "" {
6479
server := &http.Server{Addr: opts.HTTPAddr, Handler: handler}
6580
defer server.Close()

maintner/maintnerd/deployment-prod.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,11 @@ spec:
7474
selector:
7575
app: maintnerd
7676
type: NodePort
77+
---
78+
apiVersion: cloud.google.com/v1
79+
kind: BackendConfig
80+
metadata:
81+
namespace: prod
82+
name: build-ingress-maintnerd-backend
83+
spec:
84+
timeoutSec: 60 # For long-poll support on the /logs endpoint. See go.dev/issue/53569.

perf/app/app.go

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ func (a *App) RegisterOnMux(mux *http.ServeMux) {
5959
mux.HandleFunc("/search", a.search)
6060
mux.HandleFunc("/compare", a.compare)
6161
mux.HandleFunc("/cron/syncinflux", a.syncInflux)
62-
mux.HandleFunc("/healthz", a.healthz)
6362
a.dashboardRegisterOnMux(mux)
6463
}
6564

@@ -82,9 +81,3 @@ func (a *App) search(w http.ResponseWriter, r *http.Request) {
8281
//q := r.Form.Get("q")
8382
a.compare(w, r)
8483
}
85-
86-
// healthz handles /healthz.
87-
func (a *App) healthz(w http.ResponseWriter, r *http.Request) {
88-
w.WriteHeader(http.StatusOK)
89-
w.Write([]byte("ok"))
90-
}

0 commit comments

Comments
 (0)