mirror of https://github.com/k3s-io/k3s
Add pprof trace support
Add pprof trace support and --enable-contention-profiling to those components that don't already have it.pull/6/head
parent
302aab9ba2
commit
b011529d8a
|
@ -22,6 +22,7 @@ import (
|
|||
"net/http"
|
||||
"net/http/pprof"
|
||||
"os"
|
||||
goruntime "runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
|
@ -111,6 +112,10 @@ func Run(s *options.CloudControllerManagerServer, cloud cloudprovider.Interface)
|
|||
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 s.EnableContentionProfiling {
|
||||
goruntime.SetBlockProfileRate(1)
|
||||
}
|
||||
}
|
||||
configz.InstallHandler(mux)
|
||||
mux.Handle("/metrics", prometheus.Handler())
|
||||
|
|
|
@ -75,6 +75,7 @@ func (s *CloudControllerManagerServer) AddFlags(fs *pflag.FlagSet) {
|
|||
fs.DurationVar(&s.RouteReconciliationPeriod.Duration, "route-reconciliation-period", s.RouteReconciliationPeriod.Duration, "The period for reconciling routes created for Nodes by cloud provider.")
|
||||
fs.BoolVar(&s.ConfigureCloudRoutes, "configure-cloud-routes", true, "Should CIDRs allocated by allocate-node-cidrs be configured on the cloud provider.")
|
||||
fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/")
|
||||
fs.BoolVar(&s.EnableContentionProfiling, "contention-profiling", false, "Enable lock contention profiling, if profiling is enabled")
|
||||
fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods in cluster.")
|
||||
fs.BoolVar(&s.AllocateNodeCIDRs, "allocate-node-cidrs", false, "Should CIDRs for Pods be allocated and set on the cloud provider.")
|
||||
fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)")
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"net/http"
|
||||
"net/http/pprof"
|
||||
"os"
|
||||
goruntime "runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
|
@ -135,6 +136,10 @@ func Run(s *options.CMServer) error {
|
|||
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 s.EnableContentionProfiling {
|
||||
goruntime.SetBlockProfileRate(1)
|
||||
}
|
||||
}
|
||||
configz.InstallHandler(mux)
|
||||
mux.Handle("/metrics", prometheus.Handler())
|
||||
|
|
|
@ -178,6 +178,7 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet, allControllers []string, disabled
|
|||
fs.StringVar(&s.ClusterSigningKeyFile, "cluster-signing-key-file", s.ClusterSigningKeyFile, "Filename containing a PEM-encoded RSA or ECDSA private key used to sign cluster-scoped certificates")
|
||||
fs.StringVar(&s.ApproveAllKubeletCSRsForGroup, "insecure-experimental-approve-all-kubelet-csrs-for-group", s.ApproveAllKubeletCSRsForGroup, "The group for which the controller-manager will auto approve all CSRs for kubelet client certificates.")
|
||||
fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/")
|
||||
fs.BoolVar(&s.EnableContentionProfiling, "contention-profiling", false, "Enable lock contention profiling, if profiling is enabled")
|
||||
fs.StringVar(&s.ClusterName, "cluster-name", s.ClusterName, "The instance prefix for the cluster")
|
||||
fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods in cluster.")
|
||||
fs.StringVar(&s.ServiceCIDR, "service-cluster-ip-range", s.ServiceCIDR, "CIDR Range for Services in cluster.")
|
||||
|
|
|
@ -150,6 +150,7 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) {
|
|||
fs.Int32Var(&s.EventBurst, "event-burst", s.EventBurst, "Maximum size of a bursty event records, temporarily allows event records to burst to this number, while still not exceeding event-qps. Only used if --event-qps > 0")
|
||||
fs.BoolVar(&s.RunOnce, "runonce", s.RunOnce, "If true, exit after spawning pods from local manifests or remote urls. Exclusive with --api-servers, and --enable-server")
|
||||
fs.BoolVar(&s.EnableDebuggingHandlers, "enable-debugging-handlers", s.EnableDebuggingHandlers, "Enables server endpoints for log collection and local running of containers and commands")
|
||||
fs.BoolVar(&s.EnableContentionProfiling, "contention-profiling", false, "Enable lock contention profiling, if profiling is enabled")
|
||||
fs.DurationVar(&s.MinimumGCAge.Duration, "minimum-container-ttl-duration", s.MinimumGCAge.Duration, "Minimum age for a finished container before it is garbage collected. Examples: '300ms', '10s' or '2h45m'")
|
||||
fs.MarkDeprecated("minimum-container-ttl-duration", "Use --eviction-hard or --eviction-soft instead. Will be removed in a future version.")
|
||||
fs.Int32Var(&s.MaxPerPodContainerCount, "maximum-dead-containers-per-container", s.MaxPerPodContainerCount, "Maximum number of old instances to retain per container. Each container takes up some disk space. Default: 1.")
|
||||
|
|
|
@ -878,7 +878,7 @@ func startKubelet(k kubelet.KubeletBootstrap, podCfg *config.PodConfig, kubeCfg
|
|||
// start the kubelet server
|
||||
if kubeCfg.EnableServer {
|
||||
go wait.Until(func() {
|
||||
k.ListenAndServe(net.ParseIP(kubeCfg.Address), uint(kubeCfg.Port), kubeDeps.TLSOptions, kubeDeps.Auth, kubeCfg.EnableDebuggingHandlers)
|
||||
k.ListenAndServe(net.ParseIP(kubeCfg.Address), uint(kubeCfg.Port), kubeDeps.TLSOptions, kubeDeps.Auth, kubeCfg.EnableDebuggingHandlers, kubeCfg.EnableContentionProfiling)
|
||||
}, 0, wait.NeverStop)
|
||||
}
|
||||
if kubeCfg.ReadOnlyPort > 0 {
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"net/http/pprof"
|
||||
goruntime "runtime"
|
||||
"strconv"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
@ -131,6 +132,10 @@ func Run(s *options.CMServer) error {
|
|||
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 s.EnableContentionProfiling {
|
||||
goruntime.SetBlockProfileRate(1)
|
||||
}
|
||||
}
|
||||
mux.Handle("/metrics", prometheus.Handler())
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ type ControllerManagerConfiguration struct {
|
|||
APIServerBurst int `json:"federatedAPIBurst"`
|
||||
// enableProfiling enables profiling via web interface host:port/debug/pprof/
|
||||
EnableProfiling bool `json:"enableProfiling"`
|
||||
// enableContentionProfiling enables lock contention profiling, if enableProfiling is true.
|
||||
EnableContentionProfiling bool `json:"enableContentionProfiling"`
|
||||
// leaderElection defines the configuration of leader election client.
|
||||
LeaderElection componentconfig.LeaderElectionConfiguration `json:"leaderElection"`
|
||||
// contentType is contentType of requests sent to apiserver.
|
||||
|
@ -115,6 +117,7 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet) {
|
|||
fs.IntVar(&s.ConcurrentReplicaSetSyncs, "concurrent-replicaset-syncs", s.ConcurrentReplicaSetSyncs, "The number of ReplicaSets syncing operations that will be done concurrently. Larger number = faster endpoint updating, but more CPU (and network) load")
|
||||
fs.DurationVar(&s.ClusterMonitorPeriod.Duration, "cluster-monitor-period", s.ClusterMonitorPeriod.Duration, "The period for syncing ClusterStatus in ClusterController.")
|
||||
fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/")
|
||||
fs.BoolVar(&s.EnableContentionProfiling, "contention-profiling", false, "Enable lock contention profiling, if profiling is enabled")
|
||||
fs.StringVar(&s.Master, "master", s.Master, "The address of the federation API server (overrides any value in kubeconfig)")
|
||||
fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.")
|
||||
fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "ContentType of requests sent to apiserver. Passing application/vnd.kubernetes.protobuf is an experimental feature now.")
|
||||
|
|
|
@ -210,6 +210,8 @@ type KubeletConfiguration struct {
|
|||
// enableDebuggingHandlers enables server endpoints for log collection
|
||||
// and local running of containers and commands
|
||||
EnableDebuggingHandlers bool
|
||||
// enableContentionProfiling enables lock contention profiling, if enableDebuggingHandlers is true.
|
||||
EnableContentionProfiling bool
|
||||
// minimumGCAge is the minimum age for a finished container before it is
|
||||
// garbage collected.
|
||||
MinimumGCAge metav1.Duration
|
||||
|
@ -757,6 +759,8 @@ type KubeControllerManagerConfiguration struct {
|
|||
ApproveAllKubeletCSRsForGroup string
|
||||
// enableProfiling enables profiling via web interface host:port/debug/pprof/
|
||||
EnableProfiling bool
|
||||
// enableContentionProfiling enables lock contention profiling, if enableProfiling is true.
|
||||
EnableContentionProfiling bool
|
||||
// clusterName is the instance prefix for the cluster.
|
||||
ClusterName string
|
||||
// clusterCIDR is CIDR Range for Pods in cluster.
|
||||
|
|
|
@ -264,6 +264,8 @@ type KubeletConfiguration struct {
|
|||
// enableDebuggingHandlers enables server endpoints for log collection
|
||||
// and local running of containers and commands
|
||||
EnableDebuggingHandlers *bool `json:"enableDebuggingHandlers"`
|
||||
// enableContentionProfiling enables lock contention profiling, if enableDebuggingHandlers is true.
|
||||
EnableContentionProfiling bool `json:"enableContentionProfiling"`
|
||||
// minimumGCAge is the minimum age for a finished container before it is
|
||||
// garbage collected.
|
||||
MinimumGCAge metav1.Duration `json:"minimumGCAge"`
|
||||
|
|
|
@ -180,7 +180,7 @@ type KubeletBootstrap interface {
|
|||
GetConfiguration() componentconfig.KubeletConfiguration
|
||||
BirthCry()
|
||||
StartGarbageCollection()
|
||||
ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableDebuggingHandlers bool)
|
||||
ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableDebuggingHandlers, enableContentionProfiling bool)
|
||||
ListenAndServeReadOnly(address net.IP, port uint)
|
||||
Run(<-chan kubetypes.PodUpdate)
|
||||
RunOnce(<-chan kubetypes.PodUpdate) ([]RunPodResult, error)
|
||||
|
@ -2120,8 +2120,8 @@ func (kl *Kubelet) ResyncInterval() time.Duration {
|
|||
}
|
||||
|
||||
// ListenAndServe runs the kubelet HTTP server.
|
||||
func (kl *Kubelet) ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableDebuggingHandlers bool) {
|
||||
server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, address, port, tlsOptions, auth, enableDebuggingHandlers, kl.containerRuntime, kl.criHandler)
|
||||
func (kl *Kubelet) ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableDebuggingHandlers, enableContentionProfiling bool) {
|
||||
server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, address, port, tlsOptions, auth, enableDebuggingHandlers, enableContentionProfiling, kl.containerRuntime, kl.criHandler)
|
||||
}
|
||||
|
||||
// ListenAndServeReadOnly runs the kubelet HTTP server in read-only mode.
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"net/http/pprof"
|
||||
"net/url"
|
||||
"reflect"
|
||||
goruntime "runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -119,11 +120,12 @@ func ListenAndServeKubeletServer(
|
|||
port uint,
|
||||
tlsOptions *TLSOptions,
|
||||
auth AuthInterface,
|
||||
enableDebuggingHandlers bool,
|
||||
enableDebuggingHandlers,
|
||||
enableContentionProfiling bool,
|
||||
runtime kubecontainer.Runtime,
|
||||
criHandler http.Handler) {
|
||||
glog.Infof("Starting to listen on %s:%d", address, port)
|
||||
handler := NewServer(host, resourceAnalyzer, auth, enableDebuggingHandlers, runtime, criHandler)
|
||||
handler := NewServer(host, resourceAnalyzer, auth, enableDebuggingHandlers, enableContentionProfiling, runtime, criHandler)
|
||||
s := &http.Server{
|
||||
Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)),
|
||||
Handler: &handler,
|
||||
|
@ -140,7 +142,7 @@ func ListenAndServeKubeletServer(
|
|||
// ListenAndServeKubeletReadOnlyServer initializes a server to respond to HTTP network requests on the Kubelet.
|
||||
func ListenAndServeKubeletReadOnlyServer(host HostInterface, resourceAnalyzer stats.ResourceAnalyzer, address net.IP, port uint, runtime kubecontainer.Runtime) {
|
||||
glog.V(1).Infof("Starting to listen read-only on %s:%d", address, port)
|
||||
s := NewServer(host, resourceAnalyzer, nil, false, runtime, nil)
|
||||
s := NewServer(host, resourceAnalyzer, nil, false, false, runtime, nil)
|
||||
|
||||
server := &http.Server{
|
||||
Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)),
|
||||
|
@ -192,7 +194,8 @@ func NewServer(
|
|||
host HostInterface,
|
||||
resourceAnalyzer stats.ResourceAnalyzer,
|
||||
auth AuthInterface,
|
||||
enableDebuggingHandlers bool,
|
||||
enableDebuggingHandlers,
|
||||
enableContentionProfiling bool,
|
||||
runtime kubecontainer.Runtime,
|
||||
criHandler http.Handler) Server {
|
||||
server := Server{
|
||||
|
@ -208,6 +211,9 @@ func NewServer(
|
|||
server.InstallDefaultHandlers()
|
||||
if enableDebuggingHandlers {
|
||||
server.InstallDebuggingHandlers(criHandler)
|
||||
if enableContentionProfiling {
|
||||
goruntime.SetBlockProfileRate(1)
|
||||
}
|
||||
}
|
||||
return server
|
||||
}
|
||||
|
@ -381,6 +387,8 @@ func (s *Server) InstallDebuggingHandlers(criHandler http.Handler) {
|
|||
pprof.Symbol(resp, req.Request)
|
||||
case "cmdline":
|
||||
pprof.Cmdline(resp, req.Request)
|
||||
case "trace":
|
||||
pprof.Trace(resp, req.Request)
|
||||
default:
|
||||
pprof.Index(resp, req.Request)
|
||||
}
|
||||
|
|
|
@ -240,6 +240,7 @@ func newServerTest() *serverTestFramework {
|
|||
stats.NewResourceAnalyzer(fw.fakeKubelet, time.Minute, &kubecontainertesting.FakeRuntime{}),
|
||||
fw.fakeAuth,
|
||||
true,
|
||||
false,
|
||||
&kubecontainertesting.Mock{},
|
||||
fw.criHandler)
|
||||
fw.serverUnderTest = &server
|
||||
|
|
|
@ -146,6 +146,7 @@ func startHTTP(s *options.SchedulerServer) {
|
|||
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 s.EnableContentionProfiling {
|
||||
goruntime.SetBlockProfileRate(1)
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ func (o *FeatureOptions) AddFlags(fs *pflag.FlagSet) {
|
|||
fs.BoolVar(&o.EnableProfiling, "profiling", o.EnableProfiling,
|
||||
"Enable profiling via web interface host:port/debug/pprof/")
|
||||
fs.BoolVar(&o.EnableContentionProfiling, "contention-profiling", o.EnableContentionProfiling,
|
||||
"Enable contention profiling. Requires --profiling to be set to work.")
|
||||
"Enable lock contention profiling, if profiling is enabled")
|
||||
fs.BoolVar(&o.EnableSwaggerUI, "enable-swagger-ui", o.EnableSwaggerUI,
|
||||
"Enables swagger ui on the apiserver at /swagger-ui")
|
||||
}
|
||||
|
|
|
@ -30,4 +30,5 @@ func (d Profiling) Install(c *mux.APIContainer) {
|
|||
c.UnlistedRoutes.HandleFunc("/debug/pprof/", pprof.Index)
|
||||
c.UnlistedRoutes.HandleFunc("/debug/pprof/profile", pprof.Profile)
|
||||
c.UnlistedRoutes.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
|
||||
c.UnlistedRoutes.HandleFunc("/debug/pprof/trace", pprof.Trace)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue