cmd/containerboot: serve health on local endpoint (#14246)

* 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>
This commit is contained in:
Tom Proctor
2024-12-02 12:18:09 +00:00
committed by GitHub
parent a68efe2088
commit 24095e4897
7 changed files with 251 additions and 66 deletions

View File

@@ -8,8 +8,6 @@ package main
import (
"fmt"
"io"
"log"
"net"
"net/http"
"tailscale.com/client/tailscale"
@@ -64,28 +62,18 @@ func (m *metrics) handleDebug(w http.ResponseWriter, r *http.Request) {
proxy(w, r, debugURL, http.DefaultClient.Do)
}
// runMetrics runs a simple HTTP metrics endpoint at <addr>/metrics, forwarding
// metricsHandlers registers a simple HTTP metrics handler at /metrics, forwarding
// requests to tailscaled's /localapi/v0/usermetrics API.
//
// In 1.78.x and 1.80.x, it also proxies debug paths to tailscaled's debug
// endpoint if configured to ease migration for a breaking change serving user
// metrics instead of debug metrics on the "metrics" port.
func runMetrics(addr string, m *metrics) {
ln, err := net.Listen("tcp", addr)
if err != nil {
log.Fatalf("error listening on the provided metrics endpoint address %q: %v", addr, err)
func metricsHandlers(mux *http.ServeMux, lc *tailscale.LocalClient, debugAddrPort string) {
m := &metrics{
lc: lc,
debugEndpoint: debugAddrPort,
}
mux := http.NewServeMux()
mux.HandleFunc("GET /metrics", m.handleMetrics)
mux.HandleFunc("/debug/", m.handleDebug) // TODO(tomhjp): Remove for 1.82.0 release.
log.Printf("Running metrics endpoint at %s/metrics", addr)
ms := &http.Server{Handler: mux}
go func() {
if err := ms.Serve(ln); err != nil {
log.Fatalf("failed running metrics endpoint: %v", err)
}
}()
}