Skip to content

Commit 2af6da5

Browse files
pstibranycodesome
authored andcommitted
/ready now returns 200, not 204 (cortexproject#2330)
* /ready now returns 200, not 204 Signed-off-by: Peter Štibraný <[email protected]> * HTTP service now takes a range of expected status codes. Updated CHANGELOG.md Signed-off-by: Peter Štibraný <[email protected]>
1 parent b943055 commit 2af6da5

File tree

6 files changed

+35
-24
lines changed

6 files changed

+35
-24
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* [CHANGE] Utilize separate protos for rule state and storage. Experimental ruler API will not be functional until the rollout is complete. #2226
77
* [CHANGE] Frontend worker in querier now starts after all Querier module dependencies are started. This fixes issue where frontend worker started to send queries to querier before it was ready to serve them (mostly visible when using experimental blocks storage). #2246
88
* [CHANGE] Lifecycler component now enters Failed state on errors, and doesn't exit the process. (Important if you're vendoring Cortex and use Lifecycler) #2251
9+
* [CHANGE] `/ready` handler now returns 200 instead of 204. #2330
910
* [FEATURE] Added experimental storage API to the ruler service that is enabled when the `-experimental.ruler.enable-api` is set to true #2269
1011
* `-ruler.storage.type` flag now allows `s3`,`gcs`, and `azure` values
1112
* `-ruler.storage.(s3|gcs|azure)` flags exist to allow the configuration of object clients set for rule storage

integration/backward_compatibility_test.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ var (
2020
// If you change the image tag, remember to update it in the preloading done
2121
// by CircleCI too (see .circleci/config.yml).
2222
previousVersionImages = []string{
23+
// 0.6.0 used 204 status code for querier and ingester
24+
// distributor didn't have /ready page, and we used check on the /ring page instead
2325
"quay.io/cortexproject/cortex:v0.6.0",
26+
27+
// 0.7.0 used 204 status code for all components
2428
"quay.io/cortexproject/cortex:v0.7.0",
2529
}
2630
)
@@ -90,11 +94,14 @@ func runBackwardCompatibilityTestWithChunksStorage(t *testing.T, previousImage s
9094

9195
// Query the new ingester both with the old and the new querier.
9296
for _, image := range []string{previousImage, ""} {
93-
flags := ChunksStorageFlags
97+
var querier *e2ecortex.CortexService
98+
9499
if image == previousImage {
95-
flags = flagsForOldImage
100+
querier = e2ecortex.NewQuerier("querier", consul.NetworkHTTPEndpoint(), flagsForOldImage, image)
101+
} else {
102+
querier = e2ecortex.NewQuerier("querier", consul.NetworkHTTPEndpoint(), ChunksStorageFlags, image)
96103
}
97-
querier := e2ecortex.NewQuerier("querier", consul.NetworkHTTPEndpoint(), flags, image)
104+
98105
require.NoError(t, s.StartAndWaitReady(querier))
99106

100107
// Wait until the querier has updated the ring.

integration/e2e/db/db.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func NewMinio(port int, bktName string) *e2e.HTTPService {
2525
"minio/minio:RELEASE.2019-12-30T05-45-39Z",
2626
// Create the "cortex" bucket before starting minio
2727
e2e.NewCommandWithoutEntrypoint("sh", "-c", fmt.Sprintf("mkdir -p /data/%s && minio server --address :%v --quiet /data", bktName, port)),
28-
e2e.NewHTTPReadinessProbe(port, "/minio/health/ready", 200),
28+
e2e.NewHTTPReadinessProbe(port, "/minio/health/ready", 200, 200),
2929
port,
3030
)
3131
m.SetEnvVars(map[string]string{
@@ -78,7 +78,7 @@ func NewDynamoDB() *e2e.HTTPService {
7878
"amazon/dynamodb-local:1.11.477",
7979
e2e.NewCommand("-jar", "DynamoDBLocal.jar", "-inMemory", "-sharedDb"),
8080
// DynamoDB doesn't have a readiness probe, so we check if the / works even if returns 400
81-
e2e.NewHTTPReadinessProbe(8000, "/", 400),
81+
e2e.NewHTTPReadinessProbe(8000, "/", 400, 400),
8282
8000,
8383
)
8484
}

integration/e2e/service.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -361,16 +361,18 @@ type ReadinessProbe interface {
361361

362362
// HTTPReadinessProbe checks readiness by making HTTP call and checking for expected HTTP status code
363363
type HTTPReadinessProbe struct {
364-
port int
365-
path string
366-
expectedStatus int
364+
port int
365+
path string
366+
expectedStatusRangeStart int
367+
expectedStatusRangeEnd int
367368
}
368369

369-
func NewHTTPReadinessProbe(port int, path string, expectedStatus int) *HTTPReadinessProbe {
370+
func NewHTTPReadinessProbe(port int, path string, expectedStatusRangeStart, expectedStatusRangeEnd int) *HTTPReadinessProbe {
370371
return &HTTPReadinessProbe{
371-
port: port,
372-
path: path,
373-
expectedStatus: expectedStatus,
372+
port: port,
373+
path: path,
374+
expectedStatusRangeStart: expectedStatusRangeStart,
375+
expectedStatusRangeEnd: expectedStatusRangeEnd,
374376
}
375377
}
376378

@@ -389,11 +391,11 @@ func (p *HTTPReadinessProbe) Ready(service *ConcreteService) (err error) {
389391

390392
defer runutil.ExhaustCloseWithErrCapture(&err, res.Body, "response readiness")
391393

392-
if res.StatusCode == p.expectedStatus {
394+
if p.expectedStatusRangeStart <= res.StatusCode && res.StatusCode <= p.expectedStatusRangeEnd {
393395
return nil
394396
}
395397

396-
return fmt.Errorf("got no expected status code: %v, expected: %v", res.StatusCode, p.expectedStatus)
398+
return fmt.Errorf("got status code: %v, expected code in range: [%v, %v]", res.StatusCode, p.expectedStatusRangeStart, p.expectedStatusRangeEnd)
397399
}
398400

399401
// TCPReadinessProbe checks readiness by ensure a TCP connection can be established.

integration/e2ecortex/services.go

+8-9
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func NewDistributorWithConfigFile(name, consulAddress, configFile string, flags
4848
"-ring.store": "consul",
4949
"-consul.hostname": consulAddress,
5050
}, flags))...),
51-
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 204),
51+
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 200, 299),
5252
httpPort,
5353
grpcPort,
5454
)
@@ -83,7 +83,7 @@ func NewQuerierWithConfigFile(name, consulAddress, configFile string, flags map[
8383
"-querier.frontend-client.backoff-retries": "1",
8484
"-querier.worker-parallelism": "1",
8585
}, flags))...),
86-
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 204),
86+
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 200, 299),
8787
httpPort,
8888
grpcPort,
8989
)
@@ -117,7 +117,7 @@ func NewIngesterWithConfigFile(name, consulAddress, configFile string, flags map
117117
"-ring.store": "consul",
118118
"-consul.hostname": consulAddress,
119119
}, flags))...),
120-
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 204),
120+
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 200, 299),
121121
httpPort,
122122
grpcPort,
123123
)
@@ -143,7 +143,7 @@ func NewTableManagerWithConfigFile(name, configFile string, flags map[string]str
143143
"-target": "table-manager",
144144
"-log.level": "warn",
145145
}, flags))...),
146-
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 204),
146+
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 200, 299),
147147
httpPort,
148148
grpcPort,
149149
)
@@ -169,7 +169,7 @@ func NewQueryFrontendWithConfigFile(name, configFile string, flags map[string]st
169169
"-target": "query-frontend",
170170
"-log.level": "warn",
171171
}, flags))...),
172-
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 204),
172+
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 200, 299),
173173
httpPort,
174174
grpcPort,
175175
)
@@ -186,7 +186,7 @@ func NewSingleBinary(name string, flags map[string]string, image string, httpPor
186186
e2e.NewCommandWithoutEntrypoint("cortex", e2e.BuildArgs(e2e.MergeFlags(map[string]string{
187187
"-log.level": "warn",
188188
}, flags))...),
189-
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 204),
189+
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 200, 299),
190190
httpPort,
191191
grpcPort,
192192
otherPorts...,
@@ -205,7 +205,7 @@ func NewAlertmanager(name string, flags map[string]string, image string) *Cortex
205205
"-target": "alertmanager",
206206
"-log.level": "warn",
207207
}, flags))...),
208-
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 204),
208+
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 200, 299),
209209
httpPort,
210210
grpcPort,
211211
)
@@ -223,8 +223,7 @@ func NewRuler(name string, flags map[string]string, image string) *CortexService
223223
"-target": "ruler",
224224
"-log.level": "warn",
225225
}, flags))...),
226-
// The alertmanager doesn't expose a readiness probe, so we just check if the / returns 200
227-
e2e.NewHTTPReadinessProbe(httpPort, "/", 200),
226+
e2e.NewHTTPReadinessProbe(httpPort, "/ready", 200, 299),
228227
httpPort,
229228
grpcPort,
230229
)

pkg/cortex/cortex.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,11 @@ func (t *Cortex) readyHandler(sm *services.Manager) http.HandlerFunc {
401401
if t.ingester != nil {
402402
if err := t.ingester.CheckReady(r.Context()); err != nil {
403403
http.Error(w, "Ingester not ready: "+err.Error(), http.StatusServiceUnavailable)
404+
return
404405
}
405406
}
406-
w.WriteHeader(http.StatusNoContent)
407+
408+
http.Error(w, "ready", http.StatusOK)
407409
}
408410
}
409411

0 commit comments

Comments
 (0)