mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-10 01:53:49 +00:00
24095e4897
* cmd/containerboot: serve health on local endpoint We introduced stable (user) metrics in #14035, and `TS_LOCAL_ADDR_PORT` with it. Rather than requiring users to specify a new addr/port combination for each new local endpoint they want the container to serve, this combines the health check endpoint onto the local addr/port used by metrics if `TS_ENABLE_HEALTH_CHECK` is used instead of `TS_HEALTHCHECK_ADDR_PORT`. `TS_LOCAL_ADDR_PORT` now defaults to binding to all interfaces on 9002 so that it works more seamlessly and with less configuration in environments other than Kubernetes, where the operator always overrides the default anyway. In particular, listening on localhost would not be accessible from outside the container, and many scripted container environments do not know the IP address of the container before it's started. Listening on all interfaces allows users to just set one env var (`TS_ENABLE_METRICS` or `TS_ENABLE_HEALTH_CHECK`) to get a fully functioning local endpoint they can query from outside the container. Updates #14035, #12898 Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
51 lines
1.0 KiB
Go
51 lines
1.0 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
//go:build linux
|
|
|
|
package main
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"sync"
|
|
)
|
|
|
|
// healthz is a simple health check server, if enabled it returns 200 OK if
|
|
// this tailscale node currently has at least one tailnet IP address else
|
|
// returns 503.
|
|
type healthz struct {
|
|
sync.Mutex
|
|
hasAddrs bool
|
|
}
|
|
|
|
func (h *healthz) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
h.Lock()
|
|
defer h.Unlock()
|
|
|
|
if h.hasAddrs {
|
|
w.Write([]byte("ok"))
|
|
} else {
|
|
http.Error(w, "node currently has no tailscale IPs", http.StatusServiceUnavailable)
|
|
}
|
|
}
|
|
|
|
func (h *healthz) update(healthy bool) {
|
|
h.Lock()
|
|
defer h.Unlock()
|
|
|
|
if h.hasAddrs != healthy {
|
|
log.Println("Setting healthy", healthy)
|
|
}
|
|
h.hasAddrs = healthy
|
|
}
|
|
|
|
// healthHandlers registers a simple health handler at /healthz.
|
|
// A containerized tailscale instance is considered healthy if
|
|
// it has at least one tailnet IP address.
|
|
func healthHandlers(mux *http.ServeMux) *healthz {
|
|
h := &healthz{}
|
|
mux.Handle("GET /healthz", h)
|
|
return h
|
|
}
|