diff --git a/cmd/cri-containerd/cri_containerd.go b/cmd/cri-containerd/cri_containerd.go index 8ffed0f9a..d8068a919 100644 --- a/cmd/cri-containerd/cri_containerd.go +++ b/cmd/cri-containerd/cri_containerd.go @@ -19,6 +19,9 @@ package main import ( "flag" "fmt" + "net" + "net/http" + "net/http/pprof" "os" "os/signal" "path/filepath" @@ -129,6 +132,12 @@ func main() { glog.V(0).Infof("Run cri-containerd %+v", o) + // Start profiling server if enable. + if o.EnableProfiling { + glog.V(2).Info("Start profiling server") + go startProfilingServer(o.ProfilingAddress, o.ProfilingPort) + } + glog.V(2).Infof("Run cri-containerd grpc server on socket %q", o.SocketPath) s, err := server.NewCRIContainerdService(o.Config) if err != nil { @@ -182,3 +191,16 @@ func dumpStacks() { } glog.V(0).Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf) } + +// startProfilingServer start http server to profiling via web interface +func startProfilingServer(host string, port string) { + endpoint := net.JoinHostPort(host, port) + mux := http.NewServeMux() + 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) + if err := http.ListenAndServe(endpoint, mux); err != nil { + glog.Errorf("Failed to start profiling server: %v", err) + } +} diff --git a/cmd/cri-containerd/options/options.go b/cmd/cri-containerd/options/options.go index fd5e7d0b6..d18634301 100644 --- a/cmd/cri-containerd/options/options.go +++ b/cmd/cri-containerd/options/options.go @@ -90,6 +90,12 @@ type Config struct { SystemdCgroup bool `toml:"systemd_cgroup"` // OOMScore adjust the cri-containerd's oom score OOMScore int `toml:"oom_score"` + // EnableProfiling is used for enable profiling via host:port/debug/pprof/ + EnableProfiling bool `toml:"profiling"` + // ProfilingPort is the port for profiling via host:port/debug/pprof/ + ProfilingPort string `toml:"profiling_port"` + // ProfilingAddress is address for profiling via host:port/debug/pprof/ + ProfilingAddress string `toml:"profiling_addr"` } // CRIContainerdOptions contains cri-containerd command line and toml options. @@ -146,6 +152,12 @@ func (c *CRIContainerdOptions) AddFlags(fs *pflag.FlagSet) { defaults.SystemdCgroup, "Enables systemd cgroup support. By default not enabled.") fs.IntVar(&c.OOMScore, "oom-score", defaults.OOMScore, "Adjust the cri-containerd's oom score.") + fs.BoolVar(&c.EnableProfiling, "profiling", + defaults.EnableProfiling, "Enable profiling via web interface host:port/debug/pprof/.") + fs.StringVar(&c.ProfilingPort, "profiling-port", + defaults.ProfilingPort, "Profiling port for web interface host:port/debug/pprof/.") + fs.StringVar(&c.ProfilingAddress, "profiling-addr", + defaults.ProfilingAddress, "Profiling address for web interface host:port/debug/pprof/.") } // InitFlags load configurations from config file, and then overwrite with flags. @@ -213,5 +225,8 @@ func defaultConfig() Config { StatsCollectPeriod: 10, SystemdCgroup: false, OOMScore: -999, + EnableProfiling: true, + ProfilingPort: "10011", + ProfilingAddress: "127.0.0.1", } }