mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 07:16:38 +00:00
[self-hosted] add netbird server (#5232)
* Unified NetBird combined server (Management, Signal, Relay, STUN) as a single executable with richer YAML configuration, validation, and defaults. * Official Dockerfile/image for single-container deployment. * Optional in-process profiling endpoint for diagnostics. * Multiplexing to route HTTP/gRPC/WebSocket traffic via one port; runtime hooks to inject custom handlers. * **Chores** * Updated deployment scripts, compose files, and reverse-proxy templates to target the combined server; added example configs and getting-started updates.
This commit is contained in:
@@ -40,7 +40,6 @@ func Execute() error {
|
||||
func init() {
|
||||
stopCh = make(chan int)
|
||||
defaultLogFile = "/var/log/netbird/signal.log"
|
||||
defaultSignalSSLDir = "/var/lib/netbird/"
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
defaultLogFile = os.Getenv("PROGRAMDATA") + "\\Netbird\\" + "signal.log"
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"golang.org/x/net/http2"
|
||||
"golang.org/x/net/http2/h2c"
|
||||
|
||||
"github.com/netbirdio/netbird/signal/metrics"
|
||||
"github.com/netbirdio/netbird/shared/metrics"
|
||||
|
||||
"github.com/netbirdio/netbird/encryption"
|
||||
"github.com/netbirdio/netbird/shared/signal/proto"
|
||||
@@ -38,13 +38,13 @@ import (
|
||||
const legacyGRPCPort = 10000
|
||||
|
||||
var (
|
||||
signalPort int
|
||||
metricsPort int
|
||||
signalLetsencryptDomain string
|
||||
signalSSLDir string
|
||||
defaultSignalSSLDir string
|
||||
signalCertFile string
|
||||
signalCertKey string
|
||||
signalPort int
|
||||
metricsPort int
|
||||
signalLetsencryptDomain string
|
||||
signalLetsencryptEmail string
|
||||
signalLetsencryptDataDir string
|
||||
signalCertFile string
|
||||
signalCertKey string
|
||||
|
||||
signalKaep = grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{
|
||||
MinTime: 5 * time.Second,
|
||||
@@ -216,7 +216,7 @@ func getTLSConfigurations() ([]grpc.ServerOption, *autocert.Manager, *tls.Config
|
||||
}
|
||||
|
||||
if signalLetsencryptDomain != "" {
|
||||
certManager, err = encryption.CreateCertManager(signalSSLDir, signalLetsencryptDomain)
|
||||
certManager, err = encryption.CreateCertManager(signalLetsencryptDataDir, signalLetsencryptDomain)
|
||||
if err != nil {
|
||||
return nil, certManager, nil, err
|
||||
}
|
||||
@@ -326,9 +326,11 @@ func loadTLSConfig(certFile string, certKey string) (*tls.Config, error) {
|
||||
func init() {
|
||||
runCmd.PersistentFlags().IntVar(&signalPort, "port", 80, "Server port to listen on (defaults to 443 if TLS is enabled, 80 otherwise")
|
||||
runCmd.Flags().IntVar(&metricsPort, "metrics-port", 9090, "metrics endpoint http port. Metrics are accessible under host:metrics-port/metrics")
|
||||
runCmd.Flags().StringVar(&signalSSLDir, "ssl-dir", defaultSignalSSLDir, "server ssl directory location. *Required only for Let's Encrypt certificates.")
|
||||
runCmd.Flags().StringVar(&signalLetsencryptDomain, "letsencrypt-domain", "", "a domain to issue Let's Encrypt certificate for. Enables TLS using Let's Encrypt. Will fetch and renew certificate, and run the server with TLS")
|
||||
runCmd.Flags().StringVar(&signalCertFile, "cert-file", "", "Location of your SSL certificate. Can be used when you have an existing certificate and don't want a new certificate be generated automatically. If letsencrypt-domain is specified this property has no effect")
|
||||
runCmd.Flags().StringVar(&signalCertKey, "cert-key", "", "Location of your SSL certificate private key. Can be used when you have an existing certificate and don't want a new certificate be generated automatically. If letsencrypt-domain is specified this property has no effect")
|
||||
runCmd.PersistentFlags().StringVar(&signalLetsencryptDataDir, "letsencrypt-data-dir", "", "a directory to store Let's Encrypt data. Required if Let's Encrypt is enabled.")
|
||||
runCmd.PersistentFlags().StringVar(&signalLetsencryptDataDir, "ssl-dir", "", "server ssl directory location. *Required only for Let's Encrypt certificates. Deprecated: use --letsencrypt-data-dir")
|
||||
runCmd.PersistentFlags().StringVar(&signalLetsencryptDomain, "letsencrypt-domain", "", "a domain to issue Let's Encrypt certificate for. Enables TLS using Let's Encrypt. Will fetch and renew certificate, and run the server with TLS")
|
||||
runCmd.PersistentFlags().StringVar(&signalLetsencryptEmail, "letsencrypt-email", "", "email address to use for Let's Encrypt certificate registration")
|
||||
runCmd.PersistentFlags().StringVar(&signalCertFile, "cert-file", "", "Location of your SSL certificate. Can be used when you have an existing certificate and don't want a new certificate be generated automatically. If letsencrypt-domain is specified this property has no effect")
|
||||
runCmd.PersistentFlags().StringVar(&signalCertKey, "cert-key", "", "Location of your SSL certificate private key. Can be used when you have an existing certificate and don't want a new certificate be generated automatically. If letsencrypt-domain is specified this property has no effect")
|
||||
setFlagsFromEnvVars(runCmd)
|
||||
}
|
||||
|
||||
@@ -24,15 +24,19 @@ type AppMetrics struct {
|
||||
MessageSize metric.Int64Histogram
|
||||
}
|
||||
|
||||
func NewAppMetrics(meter metric.Meter) (*AppMetrics, error) {
|
||||
activePeers, err := meter.Int64UpDownCounter("active_peers",
|
||||
func NewAppMetrics(meter metric.Meter, prefix ...string) (*AppMetrics, error) {
|
||||
p := ""
|
||||
if len(prefix) > 0 {
|
||||
p = prefix[0]
|
||||
}
|
||||
activePeers, err := meter.Int64UpDownCounter(p+"active_peers",
|
||||
metric.WithDescription("Number of active connected peers"),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
peerConnectionDuration, err := meter.Int64Histogram("peer_connection_duration_seconds",
|
||||
peerConnectionDuration, err := meter.Int64Histogram(p+"peer_connection_duration_seconds",
|
||||
metric.WithExplicitBucketBoundaries(getPeerConnectionDurationBucketBoundaries()...),
|
||||
metric.WithDescription("Duration of how long a peer was connected"),
|
||||
)
|
||||
@@ -40,28 +44,28 @@ func NewAppMetrics(meter metric.Meter) (*AppMetrics, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
registrations, err := meter.Int64Counter("registrations_total",
|
||||
registrations, err := meter.Int64Counter(p+"registrations_total",
|
||||
metric.WithDescription("Total number of peer registrations"),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
deregistrations, err := meter.Int64Counter("deregistrations_total",
|
||||
deregistrations, err := meter.Int64Counter(p+"deregistrations_total",
|
||||
metric.WithDescription("Total number of peer deregistrations"),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
registrationFailures, err := meter.Int64Counter("registration_failures_total",
|
||||
registrationFailures, err := meter.Int64Counter(p+"registration_failures_total",
|
||||
metric.WithDescription("Total number of peer registration failures"),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
registrationDelay, err := meter.Float64Histogram("registration_delay_milliseconds",
|
||||
registrationDelay, err := meter.Float64Histogram(p+"registration_delay_milliseconds",
|
||||
metric.WithExplicitBucketBoundaries(getStandardBucketBoundaries()...),
|
||||
metric.WithDescription("Duration of how long it takes to register a peer"),
|
||||
)
|
||||
@@ -69,7 +73,7 @@ func NewAppMetrics(meter metric.Meter) (*AppMetrics, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
getRegistrationDelay, err := meter.Float64Histogram("get_registration_delay_milliseconds",
|
||||
getRegistrationDelay, err := meter.Float64Histogram(p+"get_registration_delay_milliseconds",
|
||||
metric.WithExplicitBucketBoundaries(getStandardBucketBoundaries()...),
|
||||
metric.WithDescription("Duration of how long it takes to load a connection from the registry"),
|
||||
)
|
||||
@@ -77,21 +81,21 @@ func NewAppMetrics(meter metric.Meter) (*AppMetrics, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
messagesForwarded, err := meter.Int64Counter("messages_forwarded_total",
|
||||
messagesForwarded, err := meter.Int64Counter(p+"messages_forwarded_total",
|
||||
metric.WithDescription("Total number of messages forwarded to peers"),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
messageForwardFailures, err := meter.Int64Counter("message_forward_failures_total",
|
||||
messageForwardFailures, err := meter.Int64Counter(p+"message_forward_failures_total",
|
||||
metric.WithDescription("Total number of message forwarding failures"),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
messageForwardLatency, err := meter.Float64Histogram("message_forward_latency_milliseconds",
|
||||
messageForwardLatency, err := meter.Float64Histogram(p+"message_forward_latency_milliseconds",
|
||||
metric.WithExplicitBucketBoundaries(getStandardBucketBoundaries()...),
|
||||
metric.WithDescription("Duration of how long it takes to forward a message to a peer"),
|
||||
)
|
||||
@@ -100,7 +104,7 @@ func NewAppMetrics(meter metric.Meter) (*AppMetrics, error) {
|
||||
}
|
||||
|
||||
messageSize, err := meter.Int64Histogram(
|
||||
"message.size.bytes",
|
||||
p+"message.size.bytes",
|
||||
metric.WithUnit("bytes"),
|
||||
metric.WithExplicitBucketBoundaries(getMessageSizeBucketBoundaries()...),
|
||||
metric.WithDescription("Records the size of each message sent"),
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
prometheus2 "github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/exporters/prometheus"
|
||||
api "go.opentelemetry.io/otel/metric"
|
||||
"go.opentelemetry.io/otel/sdk/metric"
|
||||
)
|
||||
|
||||
const defaultEndpoint = "/metrics"
|
||||
|
||||
// Metrics holds the metrics information and exposes it
|
||||
type Metrics struct {
|
||||
Meter api.Meter
|
||||
provider *metric.MeterProvider
|
||||
Endpoint string
|
||||
|
||||
*http.Server
|
||||
}
|
||||
|
||||
// NewServer initializes and returns a new Metrics instance
|
||||
func NewServer(port int, endpoint string) (*Metrics, error) {
|
||||
exporter, err := prometheus.New()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
provider := metric.NewMeterProvider(metric.WithReader(exporter))
|
||||
otel.SetMeterProvider(provider)
|
||||
|
||||
pkg := reflect.TypeOf(defaultEndpoint).PkgPath()
|
||||
meter := provider.Meter(pkg)
|
||||
|
||||
if endpoint == "" {
|
||||
endpoint = defaultEndpoint
|
||||
}
|
||||
|
||||
router := http.NewServeMux()
|
||||
router.Handle(endpoint, promhttp.HandlerFor(
|
||||
prometheus2.DefaultGatherer,
|
||||
promhttp.HandlerOpts{EnableOpenMetrics: true}))
|
||||
|
||||
server := &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", port),
|
||||
Handler: router,
|
||||
}
|
||||
|
||||
return &Metrics{
|
||||
Meter: meter,
|
||||
provider: provider,
|
||||
Endpoint: endpoint,
|
||||
Server: server,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Shutdown stops the metrics server
|
||||
func (m *Metrics) Shutdown(ctx context.Context) error {
|
||||
if err := m.Server.Shutdown(ctx); err != nil {
|
||||
return fmt.Errorf("http server: %w", err)
|
||||
}
|
||||
|
||||
if err := m.provider.Shutdown(ctx); err != nil {
|
||||
return fmt.Errorf("meter provider: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -62,8 +62,8 @@ type Server struct {
|
||||
}
|
||||
|
||||
// NewServer creates a new Signal server
|
||||
func NewServer(ctx context.Context, meter metric.Meter) (*Server, error) {
|
||||
appMetrics, err := metrics.NewAppMetrics(meter)
|
||||
func NewServer(ctx context.Context, meter metric.Meter, metricsPrefix ...string) (*Server, error) {
|
||||
appMetrics, err := metrics.NewAppMetrics(meter, metricsPrefix...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating app metrics: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user