Add custom ping http code when Traefik is terminating
This commit is contained in:
parent
73513f8371
commit
7669f41e8e
6 changed files with 82 additions and 4 deletions
|
@ -81,3 +81,28 @@ ping:
|
||||||
```bash tab="CLI"
|
```bash tab="CLI"
|
||||||
--ping.manualrouting=true
|
--ping.manualrouting=true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `terminatingStatusCode`
|
||||||
|
|
||||||
|
_Optional, Default=503_
|
||||||
|
|
||||||
|
During the period in which Traefik is gracefully shutting down, the ping handler
|
||||||
|
returns a 503 status code by default. If Traefik is behind e.g. a load-balancer
|
||||||
|
doing health checks (such as the Kubernetes LivenessProbe), another code might
|
||||||
|
be expected as the signal for graceful termination. In which case, the
|
||||||
|
terminatingStatusCode can be used to set the code returned by the ping
|
||||||
|
handler during termination.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
[ping]
|
||||||
|
terminatingStatusCode = 204
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
ping:
|
||||||
|
terminatingStatusCode: 204
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash tab="CLI"
|
||||||
|
--ping.terminatingStatusCode=204
|
||||||
|
```
|
||||||
|
|
|
@ -279,6 +279,9 @@ EntryPoint (Default: ```traefik```)
|
||||||
`--ping.manualrouting`:
|
`--ping.manualrouting`:
|
||||||
Manual routing (Default: ```false```)
|
Manual routing (Default: ```false```)
|
||||||
|
|
||||||
|
`--ping.terminatingstatuscode`:
|
||||||
|
Terminating status code (Default: ```503```)
|
||||||
|
|
||||||
`--providers.consul`:
|
`--providers.consul`:
|
||||||
Enable Consul backend with default settings. (Default: ```false```)
|
Enable Consul backend with default settings. (Default: ```false```)
|
||||||
|
|
||||||
|
|
|
@ -279,6 +279,9 @@ EntryPoint (Default: ```traefik```)
|
||||||
`TRAEFIK_PING_MANUALROUTING`:
|
`TRAEFIK_PING_MANUALROUTING`:
|
||||||
Manual routing (Default: ```false```)
|
Manual routing (Default: ```false```)
|
||||||
|
|
||||||
|
`TRAEFIK_PING_TERMINATINGSTATUSCODE`:
|
||||||
|
Terminating status code (Default: ```503```)
|
||||||
|
|
||||||
`TRAEFIK_PROVIDERS_CONSUL`:
|
`TRAEFIK_PROVIDERS_CONSUL`:
|
||||||
Enable Consul backend with default settings. (Default: ```false```)
|
Enable Consul backend with default settings. (Default: ```false```)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
[global]
|
||||||
|
checkNewVersion = false
|
||||||
|
sendAnonymousUsage = false
|
||||||
|
|
||||||
|
[log]
|
||||||
|
level = "DEBUG"
|
||||||
|
|
||||||
|
[entryPoints]
|
||||||
|
|
||||||
|
[entryPoints.traefik]
|
||||||
|
address = ":8001"
|
||||||
|
[entryPoints.traefik.transport.lifeCycle]
|
||||||
|
requestAcceptGraceTimeout = "10s"
|
||||||
|
|
||||||
|
[ping]
|
||||||
|
terminatingStatusCode = 204
|
|
@ -161,6 +161,35 @@ func (s *SimpleSuite) TestRequestAcceptGraceTimeout(c *check.C) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SimpleSuite) TestCustomPingTerminationStatusCode(c *check.C) {
|
||||||
|
file := s.adaptFile(c, "fixtures/custom_ping_termination_status_code.toml", struct{}{})
|
||||||
|
defer os.Remove(file)
|
||||||
|
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||||
|
defer display(c)
|
||||||
|
|
||||||
|
err := cmd.Start()
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
defer cmd.Process.Kill()
|
||||||
|
|
||||||
|
// Wait for Traefik to turn ready.
|
||||||
|
err = try.GetRequest("http://127.0.0.1:8001/", 2*time.Second, try.StatusCodeIs(http.StatusNotFound))
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
// Check that /ping endpoint is responding with 200.
|
||||||
|
err = try.GetRequest("http://127.0.0.1:8001/ping", 3*time.Second, try.StatusCodeIs(http.StatusOK))
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
// Send SIGTERM to Traefik.
|
||||||
|
proc, err := os.FindProcess(cmd.Process.Pid)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
err = proc.Signal(syscall.SIGTERM)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
// ping endpoint should now return a Service Unavailable.
|
||||||
|
err = try.GetRequest("http://127.0.0.1:8001/ping", 2*time.Second, try.StatusCodeIs(http.StatusNoContent))
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SimpleSuite) TestStatsWithMultipleEntryPoint(c *check.C) {
|
func (s *SimpleSuite) TestStatsWithMultipleEntryPoint(c *check.C) {
|
||||||
c.Skip("Stats is missing")
|
c.Skip("Stats is missing")
|
||||||
s.createComposeProject(c, "stats")
|
s.createComposeProject(c, "stats")
|
||||||
|
|
|
@ -10,12 +10,14 @@ import (
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
EntryPoint string `description:"EntryPoint" export:"true" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"`
|
EntryPoint string `description:"EntryPoint" export:"true" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"`
|
||||||
ManualRouting bool `description:"Manual routing" json:"manualRouting,omitempty" toml:"manualRouting,omitempty" yaml:"manualRouting,omitempty"`
|
ManualRouting bool `description:"Manual routing" json:"manualRouting,omitempty" toml:"manualRouting,omitempty" yaml:"manualRouting,omitempty"`
|
||||||
|
TerminatingStatusCode int `description:"Terminating status code" json:"terminatingStatusCode,omitempty" toml:"terminatingStatusCode,omitempty" yaml:"terminatingStatusCode,omitempty"`
|
||||||
terminating bool
|
terminating bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDefaults sets the default values.
|
// SetDefaults sets the default values.
|
||||||
func (h *Handler) SetDefaults() {
|
func (h *Handler) SetDefaults() {
|
||||||
h.EntryPoint = "traefik"
|
h.EntryPoint = "traefik"
|
||||||
|
h.TerminatingStatusCode = http.StatusServiceUnavailable
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithContext causes the ping endpoint to serve non 200 responses.
|
// WithContext causes the ping endpoint to serve non 200 responses.
|
||||||
|
@ -29,7 +31,7 @@ func (h *Handler) WithContext(ctx context.Context) {
|
||||||
func (h *Handler) ServeHTTP(response http.ResponseWriter, request *http.Request) {
|
func (h *Handler) ServeHTTP(response http.ResponseWriter, request *http.Request) {
|
||||||
statusCode := http.StatusOK
|
statusCode := http.StatusOK
|
||||||
if h.terminating {
|
if h.terminating {
|
||||||
statusCode = http.StatusServiceUnavailable
|
statusCode = h.TerminatingStatusCode
|
||||||
}
|
}
|
||||||
response.WriteHeader(statusCode)
|
response.WriteHeader(statusCode)
|
||||||
fmt.Fprint(response, http.StatusText(statusCode))
|
fmt.Fprint(response, http.StatusText(statusCode))
|
||||||
|
|
Loading…
Add table
Reference in a new issue