Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make /metrics listen on a different address #344

Merged
merged 13 commits into from
Mar 2, 2022
Merged
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

- Boundaries between Namespaces has been removed and all nodes can communicate by default [#357](https://github.com/juanfont/headscale/pull/357)
- To limit access between nodes, use [ACLs](./docs/acls.md).
- `/metrics` is now a configurable host:port endpoint: [#344](https://github.com/juanfont/headscale/pull/344). You must update your `config.yaml` file to include:
```yaml
metrics_listen_addr: 127.0.0.1:9090
```

### Features

Expand Down
34 changes: 31 additions & 3 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const (
type Config struct {
ServerURL string
Addr string
MetricsAddr string
GRPCAddr string
GRPCAllowInsecure bool
EphemeralNodeInactivityTimeout time.Duration
Expand Down Expand Up @@ -433,11 +434,17 @@ func (h *Headscale) ensureUnixSocketIsAbsent() error {
return os.Remove(h.cfg.UnixSocket)
}

func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *gin.Engine {
router := gin.Default()
func (h *Headscale) createPrometheusRouter() *gin.Engine {
promRouter := gin.Default()

prometheus := ginprometheus.NewPrometheus("gin")
prometheus.Use(router)
prometheus.Use(promRouter)

return promRouter
}

func (h *Headscale) createRouter(grpcMux *runtime.ServeMux) *gin.Engine {
router := gin.Default()

router.GET(
"/health",
Expand Down Expand Up @@ -649,6 +656,27 @@ func (h *Headscale) Serve() error {
log.Info().
Msgf("listening and serving HTTP on: %s", h.cfg.Addr)

promRouter := h.createPrometheusRouter()

promHTTPServer := &http.Server{
Addr: h.cfg.MetricsAddr,
Handler: promRouter,
ReadTimeout: HTTPReadTimeout,
WriteTimeout: 0,
}

var promHTTPListener net.Listener
promHTTPListener, err = net.Listen("tcp", h.cfg.MetricsAddr)

if err != nil {
return fmt.Errorf("failed to bind to TCP address: %w", err)
}

errorGroup.Go(func() error { return promHTTPServer.Serve(promHTTPListener) })

log.Info().
Msgf("listening and serving metrics on: %s", h.cfg.MetricsAddr)

return errorGroup.Wait()
}

Expand Down
1 change: 1 addition & 0 deletions cmd/headscale/cli/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ func getHeadscaleConfig() headscale.Config {
return headscale.Config{
ServerURL: viper.GetString("server_url"),
Addr: viper.GetString("listen_addr"),
MetricsAddr: viper.GetString("metrics_listen_addr"),
GRPCAddr: viper.GetString("grpc_listen_addr"),
GRPCAllowInsecure: viper.GetBool("grpc_allow_insecure"),

Expand Down
1 change: 1 addition & 0 deletions cmd/headscale/headscale_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func (*Suite) TestConfigLoading(c *check.C) {
// Test that config file was interpreted correctly
c.Assert(viper.GetString("server_url"), check.Equals, "http://127.0.0.1:8080")
c.Assert(viper.GetString("listen_addr"), check.Equals, "0.0.0.0:8080")
c.Assert(viper.GetString("metrics_listen_addr"), check.Equals, "127.0.0.1:9090")
c.Assert(viper.GetString("db_type"), check.Equals, "sqlite3")
c.Assert(viper.GetString("db_path"), check.Equals, "/var/lib/headscale/db.sqlite")
c.Assert(viper.GetString("tls_letsencrypt_hostname"), check.Equals, "")
Expand Down
6 changes: 6 additions & 0 deletions config-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ server_url: http://127.0.0.1:8080
#
listen_addr: 0.0.0.0:8080

# Address to listen to /metrics, you may want
# to keep this endpoint private to your internal
# network
#
metrics_listen_addr: 127.0.0.1:9090

# Address to listen for gRPC.
# gRPC is used for controlling a headscale server
# remotely with the CLI
Expand Down
1 change: 1 addition & 0 deletions docs/examples/kustomize/base/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ metadata:
data:
server_url: $(PUBLIC_PROTO)://$(PUBLIC_HOSTNAME)
listen_addr: "0.0.0.0:8080"
metrics_listen_addr: "127.0.0.1:9090"
ephemeral_node_inactivity_timeout: "30m"
5 changes: 5 additions & 0 deletions docs/examples/kustomize/postgres/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ spec:
configMapKeyRef:
name: headscale-config
key: listen_addr
- name: METRICS_LISTEN_ADDR
valueFrom:
configMapKeyRef:
name: headscale-config
key: metrics_listen_addr
- name: DERP_MAP_PATH
value: /vol/config/derp.yaml
- name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT
Expand Down
5 changes: 5 additions & 0 deletions docs/examples/kustomize/sqlite/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ spec:
configMapKeyRef:
name: headscale-config
key: listen_addr
- name: METRICS_LISTEN_ADDR
valueFrom:
configMapKeyRef:
name: headscale-config
key: metrics_listen_addr
- name: DERP_MAP_PATH
value: /vol/config/derp.yaml
- name: EPHEMERAL_NODE_INACTIVITY_TIMEOUT
Expand Down
1 change: 1 addition & 0 deletions integration_test/etc/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dns_config:
db_path: /tmp/integration_test_db.sqlite3
private_key_path: private.key
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 127.0.0.1:9090
server_url: http://headscale:8080

derp:
Expand Down