diff --git a/cmd/kube-proxy/app/server.go b/cmd/kube-proxy/app/server.go index 4549d07cdf2..2e465eea3ed 100644 --- a/cmd/kube-proxy/app/server.go +++ b/cmd/kube-proxy/app/server.go @@ -24,7 +24,7 @@ import ( "io/ioutil" "net" "net/http" - _ "net/http/pprof" + "net/http/pprof" "runtime" "strings" "time" @@ -146,6 +146,7 @@ func AddFlags(options *Options, fs *pflag.FlagSet) { &options.config.Conntrack.TCPCloseWaitTimeout.Duration, "conntrack-tcp-timeout-close-wait", options.config.Conntrack.TCPCloseWaitTimeout.Duration, "NAT timeout for TCP connections in the CLOSE_WAIT state") + fs.BoolVar(&options.config.EnableProfiling, "profiling", options.config.EnableProfiling, "If true enables profiling via web interface on /debug/pprof handler.") utilfeature.DefaultFeatureGate.AddFlag(fs) } @@ -298,6 +299,7 @@ type ProxyServer struct { NodeRef *clientv1.ObjectReference CleanupAndExit bool MetricsBindAddress string + EnableProfiling bool OOMScoreAdj *int32 ResourceContainer string ConfigSyncPeriod time.Duration @@ -507,6 +509,7 @@ func NewProxyServer(config *componentconfig.KubeProxyConfiguration, cleanupAndEx ProxyMode: proxyMode, NodeRef: nodeRef, MetricsBindAddress: config.MetricsBindAddress, + EnableProfiling: config.EnableProfiling, OOMScoreAdj: config.OOMScoreAdj, ResourceContainer: config.ResourceContainer, ConfigSyncPeriod: config.ConfigSyncPeriod.Duration, @@ -555,13 +558,20 @@ func (s *ProxyServer) Run() error { // Start up a metrics server if requested if len(s.MetricsBindAddress) > 0 { - http.HandleFunc("/proxyMode", func(w http.ResponseWriter, r *http.Request) { + mux := http.NewServeMux() + mux.HandleFunc("/proxyMode", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "%s", s.ProxyMode) }) - http.Handle("/metrics", prometheus.Handler()) - configz.InstallHandler(http.DefaultServeMux) + mux.Handle("/metrics", prometheus.Handler()) + if s.EnableProfiling { + mux.HandleFunc("/debug/pprof/", pprof.Index) + mux.HandleFunc("/debug/pprof/profile", pprof.Profile) + mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + mux.HandleFunc("/debug/pprof/trace", pprof.Trace) + } + configz.InstallHandler(mux) go wait.Until(func() { - err := http.ListenAndServe(s.MetricsBindAddress, nil) + err := http.ListenAndServe(s.MetricsBindAddress, mux) if err != nil { utilruntime.HandleError(fmt.Errorf("starting metrics server failed: %v", err)) } diff --git a/pkg/apis/componentconfig/types.go b/pkg/apis/componentconfig/types.go index ce5c98c5286..e3f829b4905 100644 --- a/pkg/apis/componentconfig/types.go +++ b/pkg/apis/componentconfig/types.go @@ -101,6 +101,9 @@ type KubeProxyConfiguration struct { // metricsBindAddress is the IP address and port for the metrics server to serve on, // defaulting to 127.0.0.1:10249 (set to 0.0.0.0 for all interfaces) MetricsBindAddress string + // enableProfiling enables profiling via web interface on /debug/pprof handler. + // Profiling handlers will be handled by metrics server. + EnableProfiling bool // clusterCIDR is the CIDR range of the pods in the cluster. It is used to // bridge traffic coming from outside of the cluster. If not provided, // no off-cluster bridging will be performed. diff --git a/pkg/apis/componentconfig/v1alpha1/types.go b/pkg/apis/componentconfig/v1alpha1/types.go index 4be7d2df724..3af83c544e3 100644 --- a/pkg/apis/componentconfig/v1alpha1/types.go +++ b/pkg/apis/componentconfig/v1alpha1/types.go @@ -97,6 +97,9 @@ type KubeProxyConfiguration struct { // metricsBindAddress is the IP address and port for the metrics server to serve on, // defaulting to 127.0.0.1:10249 (set to 0.0.0.0 for all interfaces) MetricsBindAddress string `json:"metricsBindAddress"` + // enableProfiling enables profiling via web interface on /debug/pprof handler. + // Profiling handlers will be handled by metrics server. + EnableProfiling bool `json:"enableProfiling"` // clusterCIDR is the CIDR range of the pods in the cluster. It is used to // bridge traffic coming from outside of the cluster. If not provided, // no off-cluster bridging will be performed. diff --git a/pkg/apis/componentconfig/v1alpha1/zz_generated.conversion.go b/pkg/apis/componentconfig/v1alpha1/zz_generated.conversion.go index a21d6511758..74bb652c358 100644 --- a/pkg/apis/componentconfig/v1alpha1/zz_generated.conversion.go +++ b/pkg/apis/componentconfig/v1alpha1/zz_generated.conversion.go @@ -100,6 +100,7 @@ func autoConvert_v1alpha1_KubeProxyConfiguration_To_componentconfig_KubeProxyCon out.BindAddress = in.BindAddress out.HealthzBindAddress = in.HealthzBindAddress out.MetricsBindAddress = in.MetricsBindAddress + out.EnableProfiling = in.EnableProfiling out.ClusterCIDR = in.ClusterCIDR out.HostnameOverride = in.HostnameOverride if err := Convert_v1alpha1_ClientConnectionConfiguration_To_componentconfig_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil { @@ -130,6 +131,7 @@ func autoConvert_componentconfig_KubeProxyConfiguration_To_v1alpha1_KubeProxyCon out.BindAddress = in.BindAddress out.HealthzBindAddress = in.HealthzBindAddress out.MetricsBindAddress = in.MetricsBindAddress + out.EnableProfiling = in.EnableProfiling out.ClusterCIDR = in.ClusterCIDR out.HostnameOverride = in.HostnameOverride if err := Convert_componentconfig_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil {