diff --git a/cmd/daprd/app/app.go b/cmd/daprd/app/app.go index aab25d7c241..27b7f03aa72 100644 --- a/cmd/daprd/app/app.go +++ b/cmd/daprd/app/app.go @@ -136,44 +136,46 @@ func Run() { } rt, rerr := runtime.FromConfig(ctx, &runtime.Config{ - AppID: opts.AppID, - ActorsService: opts.ActorsService, - RemindersService: opts.RemindersService, - AllowedOrigins: opts.AllowedOrigins, - ResourcesPath: opts.ResourcesPath, - ControlPlaneAddress: opts.ControlPlaneAddress, - AppProtocol: opts.AppProtocol, - Mode: opts.Mode, - DaprHTTPPort: opts.DaprHTTPPort, - DaprInternalGRPCPort: opts.DaprInternalGRPCPort, - DaprAPIGRPCPort: opts.DaprAPIGRPCPort, - DaprAPIListenAddresses: opts.DaprAPIListenAddresses, - DaprPublicPort: opts.DaprPublicPort, - ApplicationPort: opts.AppPort, - ProfilePort: opts.ProfilePort, - EnableProfiling: opts.EnableProfiling, - AppMaxConcurrency: opts.AppMaxConcurrency, - EnableMTLS: opts.EnableMTLS, - SentryAddress: opts.SentryAddress, - MaxRequestSize: opts.MaxRequestSize, - ReadBufferSize: opts.ReadBufferSize, - UnixDomainSocket: opts.UnixDomainSocket, - DaprGracefulShutdownSeconds: opts.DaprGracefulShutdownSeconds, - DaprBlockShutdownDuration: opts.DaprBlockShutdownDuration, - DisableBuiltinK8sSecretStore: opts.DisableBuiltinK8sSecretStore, - EnableAppHealthCheck: opts.EnableAppHealthCheck, - AppHealthCheckPath: opts.AppHealthCheckPath, - AppHealthProbeInterval: opts.AppHealthProbeInterval, - AppHealthProbeTimeout: opts.AppHealthProbeTimeout, - AppHealthThreshold: opts.AppHealthThreshold, - AppChannelAddress: opts.AppChannelAddress, - EnableAPILogging: opts.EnableAPILogging, - Config: opts.Config, - Metrics: opts.Metrics, - AppSSL: opts.AppSSL, - ComponentsPath: opts.ComponentsPath, - Registry: reg, - Security: sec, + AppID: opts.AppID, + ActorsService: opts.ActorsService, + RemindersService: opts.RemindersService, + AllowedOrigins: opts.AllowedOrigins, + ResourcesPath: opts.ResourcesPath, + ControlPlaneAddress: opts.ControlPlaneAddress, + AppProtocol: opts.AppProtocol, + Mode: opts.Mode, + DaprHTTPPort: opts.DaprHTTPPort, + DaprInternalGRPCPort: opts.DaprInternalGRPCPort, + DaprInternalGRPCListenAddress: opts.DaprInternalGRPCListenAddress, + DaprAPIGRPCPort: opts.DaprAPIGRPCPort, + DaprAPIListenAddresses: opts.DaprAPIListenAddresses, + DaprPublicPort: opts.DaprPublicPort, + DaprPublicListenAddress: opts.DaprPublicListenAddress, + ApplicationPort: opts.AppPort, + ProfilePort: opts.ProfilePort, + EnableProfiling: opts.EnableProfiling, + AppMaxConcurrency: opts.AppMaxConcurrency, + EnableMTLS: opts.EnableMTLS, + SentryAddress: opts.SentryAddress, + MaxRequestSize: opts.MaxRequestSize, + ReadBufferSize: opts.ReadBufferSize, + UnixDomainSocket: opts.UnixDomainSocket, + DaprGracefulShutdownSeconds: opts.DaprGracefulShutdownSeconds, + DaprBlockShutdownDuration: opts.DaprBlockShutdownDuration, + DisableBuiltinK8sSecretStore: opts.DisableBuiltinK8sSecretStore, + EnableAppHealthCheck: opts.EnableAppHealthCheck, + AppHealthCheckPath: opts.AppHealthCheckPath, + AppHealthProbeInterval: opts.AppHealthProbeInterval, + AppHealthProbeTimeout: opts.AppHealthProbeTimeout, + AppHealthThreshold: opts.AppHealthThreshold, + AppChannelAddress: opts.AppChannelAddress, + EnableAPILogging: opts.EnableAPILogging, + Config: opts.Config, + Metrics: opts.Metrics, + AppSSL: opts.AppSSL, + ComponentsPath: opts.ComponentsPath, + Registry: reg, + Security: sec, }) if rerr != nil { return rerr diff --git a/cmd/daprd/options/options.go b/cmd/daprd/options/options.go index 45cb0a5990e..aae5166add2 100644 --- a/cmd/daprd/options/options.go +++ b/cmd/daprd/options/options.go @@ -35,49 +35,51 @@ import ( ) type Options struct { - AppID string - ComponentsPath string - ControlPlaneAddress string - ControlPlaneTrustDomain string - ControlPlaneNamespace string - SentryAddress string - TrustAnchors []byte - AllowedOrigins string - EnableProfiling bool - AppMaxConcurrency int - EnableMTLS bool - AppSSL bool - MaxRequestSize int // In bytes - ResourcesPath []string - AppProtocol string - EnableAPILogging *bool - RuntimeVersion bool - BuildInfo bool - WaitCommand bool - DaprHTTPPort string - DaprAPIGRPCPort string - ProfilePort string - DaprInternalGRPCPort string - DaprPublicPort string - AppPort string - DaprGracefulShutdownSeconds int - DaprBlockShutdownDuration *time.Duration - ActorsService string - RemindersService string - DaprAPIListenAddresses string - AppHealthProbeInterval int - AppHealthProbeTimeout int - AppHealthThreshold int - EnableAppHealthCheck bool - Mode string - Config []string - UnixDomainSocket string - ReadBufferSize int // In bytes - DisableBuiltinK8sSecretStore bool - AppHealthCheckPath string - AppChannelAddress string - Logger logger.Options - Metrics *metrics.Options + AppID string + ComponentsPath string + ControlPlaneAddress string + ControlPlaneTrustDomain string + ControlPlaneNamespace string + SentryAddress string + TrustAnchors []byte + AllowedOrigins string + EnableProfiling bool + AppMaxConcurrency int + EnableMTLS bool + AppSSL bool + MaxRequestSize int // In bytes + ResourcesPath []string + AppProtocol string + EnableAPILogging *bool + RuntimeVersion bool + BuildInfo bool + WaitCommand bool + DaprHTTPPort string + DaprAPIGRPCPort string + ProfilePort string + DaprInternalGRPCPort string + DaprInternalGRPCListenAddress string + DaprPublicPort string + DaprPublicListenAddress string + AppPort string + DaprGracefulShutdownSeconds int + DaprBlockShutdownDuration *time.Duration + ActorsService string + RemindersService string + DaprAPIListenAddresses string + AppHealthProbeInterval int + AppHealthProbeTimeout int + AppHealthThreshold int + EnableAppHealthCheck bool + Mode string + Config []string + UnixDomainSocket string + ReadBufferSize int // In bytes + DisableBuiltinK8sSecretStore bool + AppHealthCheckPath string + AppChannelAddress string + Logger logger.Options + Metrics *metrics.Options } func New(origArgs []string) (*Options, error) { @@ -117,8 +119,10 @@ func New(origArgs []string) (*Options, error) { fs.StringVar(&opts.DaprHTTPPort, "dapr-http-port", strconv.Itoa(runtime.DefaultDaprHTTPPort), "HTTP port for Dapr API to listen on") fs.StringVar(&opts.DaprAPIListenAddresses, "dapr-listen-addresses", runtime.DefaultAPIListenAddress, "One or more addresses for the Dapr API to listen on, CSV limited") fs.StringVar(&opts.DaprPublicPort, "dapr-public-port", "", "Public port for Dapr Health and Metadata to listen on") + fs.StringVar(&opts.DaprPublicListenAddress, "dapr-public-listen-address", "", "Public listen address for Dapr Health and Metadata") fs.StringVar(&opts.DaprAPIGRPCPort, "dapr-grpc-port", strconv.Itoa(runtime.DefaultDaprAPIGRPCPort), "gRPC port for the Dapr API to listen on") fs.StringVar(&opts.DaprInternalGRPCPort, "dapr-internal-grpc-port", "", "gRPC port for the Dapr Internal API to listen on") + fs.StringVar(&opts.DaprInternalGRPCListenAddress, "dapr-internal-grpc-listen-address", "", "gRPC listen address for the Dapr Internal API") fs.StringVar(&opts.AppPort, "app-port", "", "The port the application is listening on") fs.StringVar(&opts.ProfilePort, "profile-port", strconv.Itoa(runtime.DefaultProfilePort), "The port for the profile server") fs.StringVar(&opts.AppProtocol, "app-protocol", string(protocol.HTTPProtocol), "Protocol for the application: grpc, grpcs, http, https, h2c") diff --git a/cmd/injector/app/app.go b/cmd/injector/app/app.go index 5a8fd2d20e3..6c3358a3250 100644 --- a/cmd/injector/app/app.go +++ b/cmd/injector/app/app.go @@ -102,6 +102,7 @@ func Run() { inj, err := service.NewInjector(service.Options{ Port: opts.Port, + ListenAddress: opts.ListenAddress, AuthUIDs: uids, Config: cfg, DaprClient: daprClient, @@ -143,7 +144,7 @@ func Run() { return nil }, func(ctx context.Context) error { - healhtzErr := healthzServer.Run(ctx, opts.HealthzPort) + healhtzErr := healthzServer.Run(ctx, opts.HealthzListenAddress, opts.HealthzPort) if healhtzErr != nil { return fmt.Errorf("failed to start healthz server: %w", healhtzErr) } diff --git a/cmd/injector/options/options.go b/cmd/injector/options/options.go index 26ecbfe84f9..b9b14af4af4 100644 --- a/cmd/injector/options/options.go +++ b/cmd/injector/options/options.go @@ -24,11 +24,13 @@ import ( ) type Options struct { - HealthzPort int - Kubeconfig string - Port int - Logger logger.Options - Metrics *metrics.Options + HealthzPort int + HealthzListenAddress string + Kubeconfig string + Port int + ListenAddress string + Logger logger.Options + Metrics *metrics.Options } func New(origArgs []string) *Options { @@ -54,7 +56,9 @@ func New(origArgs []string) *Options { fs.SortFlags = true fs.IntVar(&opts.HealthzPort, "healthz-port", 8080, "The port used for health checks") + fs.StringVar(&opts.HealthzListenAddress, "healthz-listen-address", "", "The listening address for the healthz server") fs.IntVar(&opts.Port, "port", 4000, "The port used for the injector service") + fs.StringVar(&opts.ListenAddress, "listen-address", "", "The listen address for the injector service") if home := homedir.HomeDir(); home != "" { fs.StringVar(&opts.Kubeconfig, "kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") diff --git a/cmd/operator/app/app.go b/cmd/operator/app/app.go index 19b86f27aea..1d57e3c3087 100644 --- a/cmd/operator/app/app.go +++ b/cmd/operator/app/app.go @@ -56,8 +56,11 @@ func Run() { WatchdogInterval: opts.WatchdogInterval, WatchdogCanPatchPodLabels: opts.WatchdogCanPatchPodLabels, APIPort: opts.APIPort, + APIListenAddress: opts.APIListenAddress, HealthzPort: opts.HealthzPort, + HealthzListenAddress: opts.HealthzListenAddress, WebhookServerPort: opts.WebhookServerPort, + WebhookServerListenAddress: opts.WebhookServerListenAddress, }) if err != nil { log.Fatalf("error creating operator: %v", err) diff --git a/cmd/operator/options/options.go b/cmd/operator/options/options.go index 9635e30258a..65826fe0375 100644 --- a/cmd/operator/options/options.go +++ b/cmd/operator/options/options.go @@ -53,8 +53,11 @@ type Options struct { Logger logger.Options Metrics *metrics.Options APIPort int + APIListenAddress string HealthzPort int + HealthzListenAddress string WebhookServerPort int + WebhookServerListenAddress string } func New() *Options { @@ -79,8 +82,11 @@ func New() *Options { flag.StringVar(&opts.TrustAnchorsFile, "trust-anchors-file", securityConsts.ControlPlaneDefaultTrustAnchorsPath, "Filepath to the trust anchors for the Dapr control plane") flag.IntVar(&opts.APIPort, "port", 6500, "The port for the operator API server to listen on") + flag.StringVar(&opts.APIListenAddress, "listen-address", "", "The listening address for the operator API server") flag.IntVar(&opts.HealthzPort, "healthz-port", 8080, "The port for the healthz server to listen on") + flag.StringVar(&opts.HealthzListenAddress, "healthz-listen-address", "", "The listening address for the healthz server") flag.IntVar(&opts.WebhookServerPort, "webhook-server-port", 19443, "The port for the webhook server to listen on") + flag.StringVar(&opts.WebhookServerListenAddress, "webhook-server-listen-address", "", "The listening address for the webhook server") opts.Logger = logger.DefaultOptions() opts.Logger.AttachCmdFlags(flag.StringVar, flag.BoolVar) diff --git a/cmd/placement/app/app.go b/cmd/placement/app/app.go index bbc10e0985d..6565d9535fd 100644 --- a/cmd/placement/app/app.go +++ b/cmd/placement/app/app.go @@ -116,13 +116,13 @@ func Run() { RouterOptions: metadataOptions, }) healthzServer.Ready() - if healthzErr := healthzServer.Run(ctx, opts.HealthzPort); healthzErr != nil { + if healthzErr := healthzServer.Run(ctx, opts.HealthzListenAddress, opts.HealthzPort); healthzErr != nil { return fmt.Errorf("failed to start healthz server: %w", healthzErr) } return nil }, func(ctx context.Context) error { - return apiServer.Run(ctx, strconv.Itoa(opts.PlacementPort)) + return apiServer.Run(ctx, opts.PlacementListenAddress, strconv.Itoa(opts.PlacementPort)) }, ).Run(ctx) if err != nil { diff --git a/cmd/placement/options/options.go b/cmd/placement/options/options.go index be06ecc71b3..b92431f772b 100644 --- a/cmd/placement/options/options.go +++ b/cmd/placement/options/options.go @@ -47,11 +47,13 @@ type Options struct { RaftLogStorePath string // Placement server configurations - PlacementPort int - HealthzPort int - MetadataEnabled bool - MaxAPILevel int - MinAPILevel int + PlacementPort int + PlacementListenAddress string + HealthzPort int + HealthzListenAddress string + MetadataEnabled bool + MaxAPILevel int + MinAPILevel int TLSEnabled bool TrustDomain string @@ -96,7 +98,9 @@ func New(origArgs []string) *Options { fs.BoolVar(&opts.RaftInMemEnabled, "inmem-store-enabled", true, "Enable in-memory log and snapshot store unless --raft-logstore-path is set") fs.StringVar(&opts.RaftLogStorePath, "raft-logstore-path", "", "raft log store path.") fs.IntVar(&opts.PlacementPort, "port", defaultPlacementPort, "sets the gRPC port for the placement service") + fs.StringVar(&opts.PlacementListenAddress, "listen-address", "", "The listening address for the placement service") fs.IntVar(&opts.HealthzPort, "healthz-port", defaultHealthzPort, "sets the HTTP port for the healthz server") + fs.StringVar(&opts.HealthzListenAddress, "healthz-listen-address", "", "The listening address for the healthz server") fs.BoolVar(&opts.TLSEnabled, "tls-enabled", false, "Should TLS be enabled for the placement gRPC server") fs.BoolVar(&opts.MetadataEnabled, "metadata-enabled", opts.MetadataEnabled, "Expose the placement tables on the healthz server") fs.IntVar(&opts.MaxAPILevel, "max-api-level", 10, "If set to >= 0, causes the reported 'api-level' in the cluster to never exceed this value") diff --git a/cmd/sentry/app/app.go b/cmd/sentry/app/app.go index cff34bd00c5..f25f7a907ba 100644 --- a/cmd/sentry/app/app.go +++ b/cmd/sentry/app/app.go @@ -73,6 +73,7 @@ func Run() { cfg.RootCertPath = rootCertPath cfg.TrustDomain = opts.TrustDomain cfg.Port = opts.Port + cfg.ListenAddress = opts.ListenAddress var ( watchDir = filepath.Dir(cfg.IssuerCertPath) @@ -146,7 +147,7 @@ func Run() { err = mngr.Add(func(ctx context.Context) error { healthzServer := health.NewServer(health.Options{Log: log}) healthzServer.Ready() - runErr := healthzServer.Run(ctx, opts.HealthzPort) + runErr := healthzServer.Run(ctx, opts.HealthzListenAddress, opts.HealthzPort) if runErr != nil { return fmt.Errorf("failed to start healthz server: %s", runErr) } diff --git a/cmd/sentry/options/options.go b/cmd/sentry/options/options.go index b194add08cc..5d3b7af1a03 100644 --- a/cmd/sentry/options/options.go +++ b/cmd/sentry/options/options.go @@ -35,7 +35,9 @@ const ( type Options struct { ConfigName string Port int + ListenAddress string HealthzPort int + HealthzListenAddress string IssuerCredentialsPath string TrustDomain string Kubeconfig string @@ -76,7 +78,9 @@ func New(origArgs []string) *Options { fs.StringVar(&opts.IssuerKeyFilename, "issuer-key-filename", config.DefaultIssuerKeyFilename, "Issuer private key filename") fs.StringVar(&opts.TrustDomain, "trust-domain", "localhost", "The CA trust domain") fs.IntVar(&opts.Port, "port", config.DefaultPort, "The port for the sentry server to listen on") + fs.StringVar(&opts.ListenAddress, "listen-address", "", "The listen address for the sentry server") fs.IntVar(&opts.HealthzPort, "healthz-port", 8080, "The port for the healthz server to listen on") + fs.StringVar(&opts.HealthzListenAddress, "healthz-listen-address", "", "The listening address for the healthz server") if home := homedir.HomeDir(); home != "" { fs.StringVar(&opts.Kubeconfig, "kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") diff --git a/pkg/api/http/config.go b/pkg/api/http/config.go index 20d9949fb74..95f814704ee 100644 --- a/pkg/api/http/config.go +++ b/pkg/api/http/config.go @@ -20,6 +20,7 @@ type ServerConfig struct { Port int APIListenAddresses []string PublicPort *int + PublicListenAddress string ProfilePort int AllowedOrigins string EnableProfiling bool diff --git a/pkg/api/http/server.go b/pkg/api/http/server.go index a7c1cd0b039..95da555fee9 100644 --- a/pkg/api/http/server.go +++ b/pkg/api/http/server.go @@ -174,7 +174,7 @@ func (s *server) StartNonBlocking() error { s.setupRoutes(publicR, s.api.PublicEndpoints()) healthServer := &http.Server{ - Addr: fmt.Sprintf(":%d", *s.config.PublicPort), + Addr: fmt.Sprintf("%s:%d", s.config.PublicListenAddress, *s.config.PublicPort), Handler: publicR, ReadHeaderTimeout: 10 * time.Second, MaxHeaderBytes: s.config.ReadBufferSize, diff --git a/pkg/health/server.go b/pkg/health/server.go index 664f5e2c055..4b43dece400 100644 --- a/pkg/health/server.go +++ b/pkg/health/server.go @@ -28,7 +28,7 @@ import ( // Server is the interface for the healthz server. type Server interface { - Run(context.Context, int) error + Run(context.Context, string, int) error Ready() } @@ -107,10 +107,10 @@ func (s *server) Ready() { } // Run starts a net/http server with a healthz endpoint. -func (s *server) Run(ctx context.Context, port int) error { +func (s *server) Run(ctx context.Context, listenAddress string, port int) error { //nolint:gosec srv := &http.Server{ - Addr: fmt.Sprintf(":%d", port), + Addr: fmt.Sprintf("%s:%d", listenAddress, port), Handler: s.router, BaseContext: func(_ net.Listener) context.Context { return ctx }, } diff --git a/pkg/injector/service/injector.go b/pkg/injector/service/injector.go index 841a4a1535a..745736e0ce8 100644 --- a/pkg/injector/service/injector.go +++ b/pkg/injector/service/injector.go @@ -66,11 +66,12 @@ type Injector interface { } type Options struct { - AuthUIDs []string - Config Config - DaprClient scheme.Interface - KubeClient kubernetes.Interface - Port int + AuthUIDs []string + Config Config + DaprClient scheme.Interface + KubeClient kubernetes.Interface + Port int + ListenAddress string ControlPlaneNamespace string ControlPlaneTrustDomain string @@ -138,7 +139,7 @@ func NewInjector(opts Options) (Injector, error) { runtime.NewScheme(), ).UniversalDeserializer(), server: &http.Server{ - Addr: fmt.Sprintf(":%d", opts.Port), + Addr: fmt.Sprintf("%s:%d", opts.ListenAddress, opts.Port), Handler: mux, ReadHeaderTimeout: 10 * time.Second, }, diff --git a/pkg/internal/loader/kubernetes/components_test.go b/pkg/internal/loader/kubernetes/components_test.go index 2a7bac25636..bd16ca9b12f 100644 --- a/pkg/internal/loader/kubernetes/components_test.go +++ b/pkg/internal/loader/kubernetes/components_test.go @@ -82,7 +82,7 @@ func getOperatorClient(address string) operatorv1pb.OperatorClient { func TestLoadComponents(t *testing.T) { port, _ := freeport.GetFreePort() - lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) + lis, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) require.NoError(t, err) s := grpc.NewServer() diff --git a/pkg/metrics/exporter.go b/pkg/metrics/exporter.go index 9d1fad6c55e..77f77cf6c80 100644 --- a/pkg/metrics/exporter.go +++ b/pkg/metrics/exporter.go @@ -90,7 +90,7 @@ func (m *promMetricsExporter) startMetricServer(ctx context.Context) error { return nil } - addr := fmt.Sprintf(":%d", m.options.MetricsPort()) + addr := fmt.Sprintf("%s:%d", m.options.MetricsListenAddress(), m.options.MetricsPort()) if m.ocExporter == nil { return errors.New("exporter was not initialized") diff --git a/pkg/metrics/options.go b/pkg/metrics/options.go index 453d848799e..a2656ea6d49 100644 --- a/pkg/metrics/options.go +++ b/pkg/metrics/options.go @@ -19,6 +19,7 @@ import ( const ( defaultMetricsPort = "9090" + defaultMetricsAddress = "0.0.0.0" defaultMetricsEnabled = true ) @@ -28,12 +29,15 @@ type Options struct { MetricsEnabled bool // Port to start metrics server on. Port string + // ListenAddress is the address that the metrics server listens on. + ListenAddress string } func DefaultMetricOptions() *Options { return &Options{ Port: defaultMetricsPort, MetricsEnabled: defaultMetricsEnabled, + ListenAddress: defaultMetricsAddress, } } @@ -48,6 +52,11 @@ func (o *Options) MetricsPort() uint64 { return port } +// MetricsListenAddress gets metrics listen address. +func (o *Options) MetricsListenAddress() string { + return o.ListenAddress +} + // AttachCmdFlags attaches metrics options to command flags. func (o *Options) AttachCmdFlags( stringVar func(p *string, name string, value string, usage string), @@ -58,6 +67,11 @@ func (o *Options) AttachCmdFlags( "metrics-port", defaultMetricsPort, "The port for the metrics server") + stringVar( + &o.ListenAddress, + "metrics-listen-address", + defaultMetricsAddress, + "The address for the metrics server") boolVar( &o.MetricsEnabled, "enable-metrics", @@ -74,4 +88,9 @@ func (o *Options) AttachCmdFlag( "metrics-port", defaultMetricsPort, "The port for the metrics server") + stringVar( + &o.ListenAddress, + "metrics-listen-address", + defaultMetricsAddress, + "The address for the metrics server") } diff --git a/pkg/operator/api/api.go b/pkg/operator/api/api.go index 5c0365daaf1..7c4310df9ca 100644 --- a/pkg/operator/api/api.go +++ b/pkg/operator/api/api.go @@ -45,10 +45,11 @@ const ( var log = logger.NewLogger("dapr.operator.api") type Options struct { - Client client.Client - Cache cache.Cache - Security security.Provider - Port int + Client client.Client + Cache cache.Cache + Security security.Provider + Port int + ListenAddress string } // Server runs the Dapr API server for components and configurations. @@ -62,9 +63,10 @@ type Server interface { type apiServer struct { operatorv1pb.UnimplementedOperatorServer - Client client.Client - sec security.Provider - port string + Client client.Client + sec security.Provider + port string + listenAddress string compInformer informer.Interface[componentsapi.Component] @@ -85,6 +87,7 @@ func NewAPIServer(opts Options) Server { }), sec: opts.Security, port: strconv.Itoa(opts.Port), + listenAddress: opts.ListenAddress, allEndpointsUpdateChan: make(map[string]chan *httpendpointsapi.HTTPEndpoint), allSubscriptionUpdateChan: make(map[string]chan *SubscriptionUpdateEvent), readyCh: make(chan struct{}), @@ -97,7 +100,7 @@ func (a *apiServer) Run(ctx context.Context) error { return errors.New("api server already running") } - log.Infof("Starting gRPC server on port %s", a.port) + log.Infof("Starting gRPC server on %s:%s", a.listenAddress, a.port) sec, err := a.sec.Handler(ctx) if err != nil { @@ -107,7 +110,7 @@ func (a *apiServer) Run(ctx context.Context) error { s := grpc.NewServer(sec.GRPCServerOptionMTLS()) operatorv1pb.RegisterOperatorServer(s, a) - lis, err := net.Listen("tcp", ":"+a.port) + lis, err := net.Listen("tcp", fmt.Sprintf("%s:%s", a.listenAddress, a.port)) if err != nil { return fmt.Errorf("error starting tcp listener: %w", err) } diff --git a/pkg/operator/operator.go b/pkg/operator/operator.go index 811aaa15a02..364c8059778 100644 --- a/pkg/operator/operator.go +++ b/pkg/operator/operator.go @@ -75,8 +75,11 @@ type Options struct { WatchdogCanPatchPodLabels bool TrustAnchorsFile string APIPort int + APIListenAddress string HealthzPort int + HealthzListenAddress string WebhookServerPort int + WebhookServerListenAddress string } type operator struct { @@ -84,9 +87,10 @@ type operator struct { config *Config - mgr ctrl.Manager - secProvider security.Provider - healthzPort int + mgr ctrl.Manager + secProvider security.Provider + healthzPort int + healthzListenAddress string } // NewOperator returns a new Dapr Operator. @@ -126,6 +130,7 @@ func NewOperator(ctx context.Context, opts Options) (Operator, error) { Logger: logr.Discard(), Scheme: scheme, WebhookServer: webhook.NewServer(webhook.Options{ + Host: opts.WebhookServerListenAddress, Port: opts.WebhookServerPort, TLSOpts: []func(*tls.Config){ func(tlsConfig *tls.Config) { @@ -179,10 +184,11 @@ func NewOperator(ctx context.Context, opts Options) (Operator, error) { } return &operator{ - mgr: mgr, - secProvider: secProvider, - config: config, - healthzPort: opts.HealthzPort, + mgr: mgr, + secProvider: secProvider, + config: config, + healthzPort: opts.HealthzPort, + healthzListenAddress: opts.HealthzListenAddress, apiServer: api.NewAPIServer(api.Options{ Client: mgr.GetClient(), Cache: mgr.GetCache(), @@ -259,7 +265,7 @@ func (o *operator) Run(ctx context.Context) error { }, func(ctx context.Context) error { // start healthz server - if rErr := healthzServer.Run(ctx, o.healthzPort); rErr != nil { + if rErr := healthzServer.Run(ctx, o.healthzListenAddress, o.healthzPort); rErr != nil { return fmt.Errorf("failed to start healthz server: %w", rErr) } return nil diff --git a/pkg/placement/placement.go b/pkg/placement/placement.go index 8c6305eb86a..00abd78b745 100644 --- a/pkg/placement/placement.go +++ b/pkg/placement/placement.go @@ -189,7 +189,7 @@ func NewPlacementService(opts PlacementServiceOpts) *Service { // Run starts the placement service gRPC server. // Blocks until the service is closed and all connections are drained. -func (p *Service) Run(ctx context.Context, port string) error { +func (p *Service) Run(ctx context.Context, listenAddress, port string) error { if p.closed.Load() { return errors.New("placement service is closed") } @@ -203,7 +203,7 @@ func (p *Service) Run(ctx context.Context, port string) error { return err } - serverListener, err := net.Listen("tcp", fmt.Sprintf(":%s", port)) + serverListener, err := net.Listen("tcp", fmt.Sprintf("%s:%s", listenAddress, port)) if err != nil { return fmt.Errorf("failed to listen: %w", err) } diff --git a/pkg/placement/placement_test.go b/pkg/placement/placement_test.go index b69857a55a0..cb3e09006e0 100644 --- a/pkg/placement/placement_test.go +++ b/pkg/placement/placement_test.go @@ -54,7 +54,7 @@ func newTestPlacementServer(t *testing.T, raftServer *raft.Server) (string, *Ser ctx, cancel := context.WithCancel(context.Background()) go func() { defer close(serverStopped) - err := testServer.Run(ctx, strconv.Itoa(port)) + err := testServer.Run(ctx, "127.0.0.1", strconv.Itoa(port)) if !errors.Is(err, grpc.ErrServerStopped) { require.NoError(t, err) } diff --git a/pkg/resiliency/resiliency_test.go b/pkg/resiliency/resiliency_test.go index 1266797f022..d17d849d9df 100644 --- a/pkg/resiliency/resiliency_test.go +++ b/pkg/resiliency/resiliency_test.go @@ -224,7 +224,7 @@ func TestPoliciesForTargets(t *testing.T) { func TestLoadKubernetesResiliency(t *testing.T) { port, _ := freeport.GetFreePort() - lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) + lis, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) require.NoError(t, err) s := grpc.NewServer() @@ -324,7 +324,7 @@ func TestParseMaxRetries(t *testing.T) { func TestResiliencyScopeIsRespected(t *testing.T) { port, _ := freeport.GetFreePort() - lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) + lis, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) require.NoError(t, err) s := grpc.NewServer() diff --git a/pkg/runtime/config.go b/pkg/runtime/config.go index 18edfa9e8e1..4765b436937 100644 --- a/pkg/runtime/config.go +++ b/pkg/runtime/config.go @@ -72,54 +72,58 @@ const ( // Config holds the Dapr Runtime configuration. type Config struct { - AppID string - ControlPlaneAddress string - SentryAddress string - AllowedOrigins string - EnableProfiling bool - AppMaxConcurrency int - EnableMTLS bool - AppSSL bool - MaxRequestSize int // In bytes - ResourcesPath []string - ComponentsPath string - AppProtocol string - EnableAPILogging *bool - DaprHTTPPort string - DaprAPIGRPCPort string - ProfilePort string - DaprInternalGRPCPort string - DaprPublicPort string - ApplicationPort string - DaprGracefulShutdownSeconds int - DaprBlockShutdownDuration *time.Duration - ActorsService string - RemindersService string - DaprAPIListenAddresses string - AppHealthProbeInterval int - AppHealthProbeTimeout int - AppHealthThreshold int - EnableAppHealthCheck bool - Mode string - Config []string - UnixDomainSocket string - ReadBufferSize int // In bytes - DisableBuiltinK8sSecretStore bool - AppHealthCheckPath string - AppChannelAddress string - Metrics *metrics.Options - Registry *registry.Options - Security security.Handler + AppID string + ControlPlaneAddress string + SentryAddress string + AllowedOrigins string + EnableProfiling bool + AppMaxConcurrency int + EnableMTLS bool + AppSSL bool + MaxRequestSize int // In bytes + ResourcesPath []string + ComponentsPath string + AppProtocol string + EnableAPILogging *bool + DaprHTTPPort string + DaprAPIGRPCPort string + ProfilePort string + DaprInternalGRPCPort string + DaprInternalGRPCListenAddress string + DaprPublicPort string + DaprPublicListenAddress string + ApplicationPort string + DaprGracefulShutdownSeconds int + DaprBlockShutdownDuration *time.Duration + ActorsService string + RemindersService string + DaprAPIListenAddresses string + AppHealthProbeInterval int + AppHealthProbeTimeout int + AppHealthThreshold int + EnableAppHealthCheck bool + Mode string + Config []string + UnixDomainSocket string + ReadBufferSize int // In bytes + DisableBuiltinK8sSecretStore bool + AppHealthCheckPath string + AppChannelAddress string + Metrics *metrics.Options + Registry *registry.Options + Security security.Handler } type internalConfig struct { id string httpPort int publicPort *int + publicListenAddress string profilePort int enableProfiling bool apiGRPCPort int internalGRPCPort int + internalGRPCListenAddress string apiListenAddresses []string appConnectionConfig config.AppConnectionConfig mode modes.DaprMode @@ -291,11 +295,13 @@ func (c *Config) toInternal() (*internalConfig, error) { HealthCheckHTTPPath: c.AppHealthCheckPath, MaxConcurrency: c.AppMaxConcurrency, }, - registry: registry.New(c.Registry), - metricsExporter: metrics.NewExporterWithOptions(log, metrics.DefaultMetricNamespace, c.Metrics), - blockShutdownDuration: c.DaprBlockShutdownDuration, - actorsService: c.ActorsService, - remindersService: c.RemindersService, + registry: registry.New(c.Registry), + metricsExporter: metrics.NewExporterWithOptions(log, metrics.DefaultMetricNamespace, c.Metrics), + blockShutdownDuration: c.DaprBlockShutdownDuration, + actorsService: c.ActorsService, + remindersService: c.RemindersService, + publicListenAddress: c.DaprPublicListenAddress, + internalGRPCListenAddress: c.DaprInternalGRPCListenAddress, } if len(intc.standalone.ResourcesPath) == 0 && c.ComponentsPath != "" { diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go index e9fb27ed434..8080142a332 100644 --- a/pkg/runtime/runtime.go +++ b/pkg/runtime/runtime.go @@ -543,7 +543,7 @@ func (a *DaprRuntime) initRuntime(ctx context.Context) error { } // Start HTTP Server - err = a.startHTTPServer(a.runtimeConfig.httpPort, a.runtimeConfig.publicPort, a.runtimeConfig.profilePort, a.runtimeConfig.allowedOrigins) + err = a.startHTTPServer() if err != nil { return fmt.Errorf("failed to start HTTP server: %w", err) } @@ -555,11 +555,11 @@ func (a *DaprRuntime) initRuntime(ctx context.Context) error { log.Infof("The request body size parameter is: %v bytes", a.runtimeConfig.maxRequestBodySize) // Start internal gRPC server (used for sidecar-to-sidecar communication) - err = a.startGRPCInternalServer(a.daprGRPCAPI, a.runtimeConfig.internalGRPCPort) + err = a.startGRPCInternalServer(a.daprGRPCAPI) if err != nil { return fmt.Errorf("failed to start internal gRPC server: %w", err) } - log.Infof("Internal gRPC server is running on port %v", a.runtimeConfig.internalGRPCPort) + log.Infof("Internal gRPC server is running on %s:%d", a.runtimeConfig.internalGRPCListenAddress, a.runtimeConfig.internalGRPCPort) a.initDirectMessaging(a.nameResolver) @@ -774,7 +774,7 @@ func (a *DaprRuntime) initProxy() { }) } -func (a *DaprRuntime) startHTTPServer(port int, publicPort *int, profilePort int, allowedOrigins string) error { +func (a *DaprRuntime) startHTTPServer() error { a.daprHTTPAPI = http.NewAPI(http.APIOpts{ Universal: a.daprUniversal, Channels: a.channels, @@ -788,11 +788,12 @@ func (a *DaprRuntime) startHTTPServer(port int, publicPort *int, profilePort int serverConf := http.ServerConfig{ AppID: a.runtimeConfig.id, HostAddress: a.hostAddress, - Port: port, + Port: a.runtimeConfig.httpPort, APIListenAddresses: a.runtimeConfig.apiListenAddresses, - PublicPort: publicPort, - ProfilePort: profilePort, - AllowedOrigins: allowedOrigins, + PublicPort: a.runtimeConfig.publicPort, + PublicListenAddress: a.runtimeConfig.publicListenAddress, + ProfilePort: a.runtimeConfig.profilePort, + AllowedOrigins: a.runtimeConfig.allowedOrigins, EnableProfiling: a.runtimeConfig.enableProfiling, MaxRequestBodySize: a.runtimeConfig.maxRequestBodySize, UnixDomainSocket: a.runtimeConfig.unixDomainSocket, @@ -831,9 +832,9 @@ func (a *DaprRuntime) startHTTPServer(port int, publicPort *int, profilePort int return nil } -func (a *DaprRuntime) startGRPCInternalServer(api grpc.API, port int) error { +func (a *DaprRuntime) startGRPCInternalServer(api grpc.API) error { // Since GRPCInteralServer is encrypted & authenticated, it is safe to listen on * - serverConf := a.getNewServerConfig([]string{""}, port) + serverConf := a.getNewServerConfig([]string{a.runtimeConfig.internalGRPCListenAddress}, a.runtimeConfig.internalGRPCPort) server := grpc.NewInternalServer(api, serverConf, a.globalConfig.GetTracingSpec(), a.globalConfig.GetMetricsSpec(), a.sec, a.proxy) if err := server.StartNonBlocking(); err != nil { return err @@ -919,11 +920,19 @@ func (a *DaprRuntime) initNameResolution(ctx context.Context) (err error) { if a.globalConfig.Spec.NameResolutionSpec != nil { resolverMetadata.Configuration = a.globalConfig.Spec.NameResolutionSpec.Configuration } + // Override host address if the internal gRPC listen address is localhost. + hostAddress := a.hostAddress + if utils.Contains( + []string{"127.0.0.1", "localhost", "[::1]"}, + a.runtimeConfig.internalGRPCListenAddress, + ) { + hostAddress = a.runtimeConfig.internalGRPCListenAddress + } resolverMetadata.Instance = nr.Instance{ DaprHTTPPort: a.runtimeConfig.httpPort, DaprInternalPort: a.runtimeConfig.internalGRPCPort, AppPort: a.runtimeConfig.appConnectionConfig.Port, - Address: a.hostAddress, + Address: hostAddress, AppID: a.runtimeConfig.id, Namespace: a.namespace, } @@ -958,8 +967,16 @@ func (a *DaprRuntime) initActors(ctx context.Context) error { if !ok { log.Info("actors: state store is not configured - this is okay for clients but services with hosted actors will fail to initialize!") } + // Override host address if the internal gRPC listen address is localhost. + hostAddress := a.hostAddress + if utils.Contains( + []string{"127.0.0.1", "localhost", "[::1]"}, + a.runtimeConfig.internalGRPCListenAddress, + ) { + hostAddress = a.runtimeConfig.internalGRPCListenAddress + } actorConfig := actors.NewConfig(actors.ConfigOpts{ - HostAddress: a.hostAddress, + HostAddress: hostAddress, AppID: a.runtimeConfig.id, ActorsService: a.runtimeConfig.actorsService, RemindersService: a.runtimeConfig.remindersService, diff --git a/pkg/sentry/config/config.go b/pkg/sentry/config/config.go index 949e7ede55d..326fc9acd37 100644 --- a/pkg/sentry/config/config.go +++ b/pkg/sentry/config/config.go @@ -57,6 +57,7 @@ const ( // Config holds the configuration for the Certificate Authority. type Config struct { Port int + ListenAddress string TrustDomain string CAStore string WorkloadCertTTL time.Duration @@ -93,6 +94,7 @@ func IsKubernetesHosted() bool { func getDefaultConfig() Config { return Config{ Port: DefaultPort, + ListenAddress: "0.0.0.0", WorkloadCertTTL: defaultWorkloadCertTTL, AllowedClockSkew: defaultAllowedClockSkew, TrustDomain: defaultTrustDomain, diff --git a/pkg/sentry/server/server.go b/pkg/sentry/server/server.go index d5afbf273e6..32884442e3c 100644 --- a/pkg/sentry/server/server.go +++ b/pkg/sentry/server/server.go @@ -41,6 +41,9 @@ type Options struct { // Port is the port that the server will listen on. Port int + // ListenAddress is the address that the server will listen on. + ListenAddress string + // Security is the security handler for the server. Security security.Handler @@ -63,7 +66,7 @@ type server struct { // Start starts the server. Blocks until the context is cancelled. func Start(ctx context.Context, opts Options) error { - lis, err := net.Listen("tcp", fmt.Sprintf(":%d", opts.Port)) + lis, err := net.Listen("tcp", fmt.Sprintf("%s:%d", opts.ListenAddress, opts.Port)) if err != nil { return fmt.Errorf("could not listen on port %d: %w", opts.Port, err) } diff --git a/pkg/sentry/server/server_test.go b/pkg/sentry/server/server_test.go index b2a2c9667a2..74bfe5effc0 100644 --- a/pkg/sentry/server/server_test.go +++ b/pkg/sentry/server/server_test.go @@ -294,14 +294,14 @@ func TestRun(t *testing.T) { require.Eventually(t, func() bool { var conn net.Conn - conn, err = net.Dial("tcp", fmt.Sprintf(":%d", port)) + conn, err = net.Dial("tcp", fmt.Sprintf("127.0.0.1:%d", port)) if err == nil { conn.Close() } return err == nil }, time.Second, 10*time.Millisecond) - conn, err := grpc.DialContext(ctx, fmt.Sprintf(":%d", port), grpc.WithTransportCredentials(insecure.NewCredentials())) + conn, err := grpc.DialContext(ctx, fmt.Sprintf("127.0.0.1:%d", port), grpc.WithTransportCredentials(insecure.NewCredentials())) require.NoError(t, err) t.Cleanup(func() { require.NoError(t, conn.Close()) diff --git a/pkg/testing/grpc/server.go b/pkg/testing/grpc/server.go index 0a1a9125f71..c68e97d054b 100644 --- a/pkg/testing/grpc/server.go +++ b/pkg/testing/grpc/server.go @@ -98,7 +98,7 @@ func TestServerWithDialer[TServer any](logger logger.Logger, registersvc func(*g } func StartTestAppCallbackGRPCServer(t *testing.T, port int, mockServer runtimev1pb.AppCallbackServer) *grpc.Server { - lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) + lis, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) require.NoError(t, err) grpcServer := grpc.NewServer() go func() { diff --git a/tests/integration/framework/process/daprd/daprd.go b/tests/integration/framework/process/daprd/daprd.go index 623c820a52b..89af52bf4c1 100644 --- a/tests/integration/framework/process/daprd/daprd.go +++ b/tests/integration/framework/process/daprd/daprd.go @@ -102,8 +102,12 @@ func New(t *testing.T, fopts ...Option) *Daprd { "--dapr-grpc-port=" + strconv.Itoa(opts.grpcPort), "--dapr-http-port=" + strconv.Itoa(opts.httpPort), "--dapr-internal-grpc-port=" + strconv.Itoa(opts.internalGRPCPort), + "--dapr-internal-grpc-listen-address=127.0.0.1", + "--dapr-listen-addresses=127.0.0.1", "--dapr-public-port=" + strconv.Itoa(opts.publicPort), + "--dapr-public-listen-address=127.0.0.1", "--metrics-port=" + strconv.Itoa(opts.metricsPort), + "--metrics-listen-address=127.0.0.1", "--profile-port=" + strconv.Itoa(opts.profilePort), "--enable-app-health-check=" + strconv.FormatBool(opts.appHealthCheck), "--app-health-probe-interval=" + strconv.Itoa(opts.appHealthProbeInterval), diff --git a/tests/integration/framework/process/injector/injector.go b/tests/integration/framework/process/injector/injector.go index 3a7cee026fb..5979bcb5b8d 100644 --- a/tests/integration/framework/process/injector/injector.go +++ b/tests/integration/framework/process/injector/injector.go @@ -83,7 +83,10 @@ func New(t *testing.T, fopts ...Option) *Injector { "-log-level=" + opts.logLevel, "-port=" + strconv.Itoa(opts.port), "-metrics-port=" + strconv.Itoa(opts.metricsPort), + "-metrics-listen-address=127.0.0.1", "-healthz-port=" + strconv.Itoa(opts.healthzPort), + "-healthz-listen-address=127.0.0.1", + "-listen-address=127.0.0.1", "-kubeconfig=" + kubeapi.KubeconfigPath(t), } diff --git a/tests/integration/framework/process/operator/operator.go b/tests/integration/framework/process/operator/operator.go index c727fd88d4d..b85d3340a15 100644 --- a/tests/integration/framework/process/operator/operator.go +++ b/tests/integration/framework/process/operator/operator.go @@ -71,12 +71,16 @@ func New(t *testing.T, fopts ...Option) *Operator { args := []string{ "-log-level=" + opts.logLevel, "-port=" + strconv.Itoa(opts.port), + "-listen-address=127.0.0.1", "-healthz-port=" + strconv.Itoa(opts.healthzPort), + "-healthz-listen-address=127.0.0.1", "-metrics-port=" + strconv.Itoa(opts.metricsPort), + "-metrics-listen-address=127.0.0.1", "-trust-anchors-file=" + *opts.trustAnchorsFile, "-disable-leader-election=" + strconv.FormatBool(opts.disableLeaderElection), "-kubeconfig=" + *opts.kubeconfigPath, "-webhook-server-port=" + strconv.Itoa(fp.Port(t)), + "-webhook-server-listen-address=127.0.0.1", } if opts.configPath != nil { diff --git a/tests/integration/framework/process/placement/placement.go b/tests/integration/framework/process/placement/placement.go index ebc27f33ca1..70cbf379fdb 100644 --- a/tests/integration/framework/process/placement/placement.go +++ b/tests/integration/framework/process/placement/placement.go @@ -83,8 +83,11 @@ func New(t *testing.T, fopts ...Option) *Placement { "--log-level=" + opts.logLevel, "--id=" + opts.id, "--port=" + strconv.Itoa(opts.port), + "--listen-address=127.0.0.1", "--healthz-port=" + strconv.Itoa(opts.healthzPort), + "--healthz-listen-address=127.0.0.1", "--metrics-port=" + strconv.Itoa(opts.metricsPort), + "--metrics-listen-address=127.0.0.1", "--initial-cluster=" + opts.initialCluster, "--tls-enabled=" + strconv.FormatBool(opts.tlsEnabled), "--metadata-enabled=" + strconv.FormatBool(opts.metadataEnabled), diff --git a/tests/integration/framework/process/sentry/sentry.go b/tests/integration/framework/process/sentry/sentry.go index c05bdb4ac51..02bffd037cb 100644 --- a/tests/integration/framework/process/sentry/sentry.go +++ b/tests/integration/framework/process/sentry/sentry.go @@ -89,7 +89,10 @@ func New(t *testing.T, fopts ...Option) *Sentry { "-issuer-certificate-filename=issuer.crt", "-issuer-key-filename=issuer.key", "-metrics-port=" + strconv.Itoa(opts.metricsPort), + "-metrics-listen-address=127.0.0.1", "-healthz-port=" + strconv.Itoa(opts.healthzPort), + "-healthz-listen-address=127.0.0.1", + "-listen-address=127.0.0.1", } if opts.writeBundle {