k8s源码分析-----kubelet协程分析

(1) 垃圾筒收集协程

在KubeletConfig CreateAndInitKubelet函数中,调用k.StartGarbageCollection()启动

k8s.io\kubernetes\cmd\kubelet\app\server.go:982

// Starts garbage collection threads.
func (kl *Kubelet) StartGarbageCollection() {
       go wait.Until(func() {
              if err := kl.containerGC.GarbageCollect(kl.sourcesReady.AllReady()); err != nil {
                     glog.Errorf("Container garbage collection failed: %v", err)
              }
       }, ContainerGCPeriod, wait.NeverStop)

       go wait.Until(func() {
              if err := kl.imageManager.GarbageCollect(); err != nil {
                     glog.Errorf("Image garbage collection failed: %v", err)
              }
       }, ImageGCPeriod, wait.NeverStop)
}


(2) initializeModule函数中启动了四个协程


func (kl *Kubelet) Run 调用initializeModules -》 imageManager.Start

k8s.io/kubernetes/pkg/kubelet.(*realImageManager).Start
k8s.io/kubernetes/pkg/kubelet/cm.(*containerManagerImpl).Start
k8s.io/kubernetes/pkg/kubelet.(*realOOMWatcher).Start
k8s.io/kubernetes/pkg/kubelet/server/stats.(*fsResourceAnalyzer).Start

// initializeModules will initialize internal modules that do not require the container runtime to be up.
// Note that the modules here must not depend on modules that are not initialized here.
func (kl *Kubelet) initializeModules() error {
       // Step 1: Promethues metrics.
       metrics.Register(kl.runtimeCache)

       // Step 2: Setup filesystem directories.
       if err := kl.setupDataDirs(); err != nil {
              return err
       }

       // Step 3: If the container logs directory does not exist, create it.
       if _, err := os.Stat(containerLogsDir); err != nil {
              if err := kl.os.MkdirAll(containerLogsDir, 0755); err != nil {
                     glog.Errorf("Failed to create directory %q: %v", containerLogsDir, err)
              }
       }

       // Step 4: Start the image manager.
       if err := kl.imageManager.Start(); err != nil {
              return fmt.Errorf("Failed to start ImageManager, images may not be garbage collected: %v", err)
       }

       // Step 5: Start container manager.
       if err := kl.containerManager.Start(); err != nil {
              return fmt.Errorf("Failed to start ContainerManager %v", err)
       }

       // Step 6: Start out of memory watcher.
       if err := kl.oomWatcher.Start(kl.nodeRef); err != nil {
              return fmt.Errorf("Failed to start OOM watcher %v", err)
       }

       // Step 7: Start resource analyzer
       kl.resourceAnalyzer.Start()

       return nil
}

(3)Kubelet Run函数中启动的协程


Kubelet Run函数中启动大多数的协程

// Run starts the kubelet reacting to config updates
func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) {
       if kl.logServer == nil {
              kl.logServer = http.StripPrefix("/logs/", http.FileServer(http.Dir("/var/log/")))
       }
       if kl.kubeClient == nil {
              glog.Warning("No api server defined - no node status update will be sent.")
       }
       if err := kl.initializeModules(); err != nil {
              kl.recorder.Eventf(kl.nodeRef, api.EventTypeWarning, kubecontainer.KubeletSetupFailed, err.Error())
              glog.Error(err)
              kl.runtimeState.setInitError(err)
       }

       // Start volume manager
       go kl.volumeManager.Run(wait.NeverStop)

       if kl.kubeClient != nil {
              // Start syncing node status immediately, this may set up things the runtime needs to run.
              go wait.Until(kl.syncNodeStatus, kl.nodeStatusUpdateFrequency, wait.NeverStop)
       }
       go wait.Until(kl.syncNetworkStatus, 30*time.Second, wait.NeverStop)
       go wait.Until(kl.updateRuntimeUp, 5*time.Second, wait.NeverStop)

       // Start a goroutine responsible for killing pods (that are not properly
       // handled by pod workers).
       go wait.Until(kl.podKiller, 1*time.Second, wait.NeverStop)

       // Start component sync loops.
       kl.statusManager.Start()
       kl.probeManager.Start()
       kl.evictionManager.Start(kl.getActivePods, evictionMonitoringPeriod)

       // Start the pod lifecycle event generator.
       kl.pleg.Start()
       kl.syncLoop(updates, kl)
}

(4)server.go的run函数中启动Healthz的协程


代码位置为:k8s.io\kubernetes\cmd\kubelet\app\server.go:396

在server.go的run函数中

if s.HealthzPort > 0 {
       healthz.DefaultHealthz()
       go wait.Until(func() {
              err := http.ListenAndServe(net.JoinHostPort(s.HealthzBindAddress, strconv.Itoa(int(s.HealthzPort))), nil)
              if err != nil {
                     glog.Errorf("Starting health server failed: %v", err)
              }
       }, 5*time.Second, wait.NeverStop)
}

(5) 日志flush的协程


main函数中: util.InitLogs()

// InitLogs initializes logs the way we want for kubernetes.
func InitLogs() {
       log.SetOutput(GlogWriter{})
       log.SetFlags(0)
       // The default glog flush interval is 30 seconds, which is frighteningly long.
       go wait.Until(glog.Flush, *logFlushFreq, wait.NeverStop)
}

(6) SourceFile携程

func NewSourceFile(path string, nodeName string, period time.Duration, updates chan<- interface{}) {
       config := &sourceFile{
              path:     path,
              nodeName: nodeName,
              updates:  updates,
       }
       glog.V(1).Infof("Watching path %q", path)
       go wait.Until(config.run, period, wait.NeverStop)
}


调用链为run-> RunKubelet -> CreateAndInitKubelet ->makePodSourceConfig->NewSourceFile

(7)  SourceURL 协程


func NewSourceURL(url string, header http.Header, nodeName string, period time.Duration, updates chan<- interface{}) {
       config := &sourceURL{
              url:      url,
              header:   header,
              nodeName: nodeName,
              updates:  updates,
              data:     nil,
              // Timing out requests leads to retries. This client is only used to
              // read the the manifest URL passed to kubelet.
              client: &http.Client{Timeout: 10 * time.Second},
       }
       glog.V(1).Infof("Watching URL %s", url)
       go wait.Until(config.run, period, wait.NeverStop)
}


调用链为run-> RunKubelet -> CreateAndInitKubelet ->makePodSourceConfig->NewSourceURL

(8)  APIService Watch协程


// NewSourceApiserver creates a config source that watches and pulls from the apiserver.
func NewSourceApiserver(c *clientset.Clientset, nodeName string, updates chan<- interface{}) {
       lw := cache.NewListWatchFromClient(c.CoreClient, "pods", api.NamespaceAll, fields.OneTermEqualSelector(api.PodHostField, nodeName))
       newSourceApiserverFromLW(lw, updates)
}

// newSourceApiserverFromLW holds creates a config source that watches and pulls from the apiserver.
func newSourceApiserverFromLW(lw cache.ListerWatcher, updates chan<- interface{}) {
       send := func(objs []interface{}) {
              var pods []*api.Pod
              for _, o := range objs {
                     pods = append(pods, o.(*api.Pod))
              }
              updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.ApiserverSource}
       }
       cache.NewReflector(lw, &api.Pod{}, cache.NewUndeltaStore(send, cache.MetaNamespaceKeyFunc), 0).Run()
}

// Run starts a watch and handles watch events. Will restart the watch if it is closed.
// Run starts a goroutine and returns immediately.
func (r *Reflector) Run() {
       glog.V(3).Infof("Starting reflector %v (%s) from %s", r.expectedType, r.resyncPeriod, r.name)
       go wait.Until(func() {
              if err := r.ListAndWatch(wait.NeverStop); err != nil {
                     utilruntime.HandleError(err)
              }
       }, r.period, wait.NeverStop)
}


调用链为run-> RunKubelet -> CreateAndInitKubelet ->makePodSourceConfig->NewSourceURL


(9)  start the kubelet server协程

该协程在Run函数的协程都启动完成之后启动

func startKubelet(k KubeletBootstrap, podCfg *config.PodConfig, kc *KubeletConfig) {
       // start the kubelet
       go wait.Until(func() { k.Run(podCfg.Updates()) }, 0, wait.NeverStop)

       // start the kubelet server
       if kc.EnableServer {
              go wait.Until(func() {
                     k.ListenAndServe(kc.Address, kc.Port, kc.TLSOptions, kc.Auth, kc.EnableDebuggingHandlers)
              }, 0, wait.NeverStop)
       }
       if kc.ReadOnlyPort > 0 {
              go wait.Until(func() {
                     k.ListenAndServeReadOnly(kc.Address, kc.ReadOnlyPort)
              }, 0, wait.NeverStop)
       }
}

// 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)
}


// ListenAndServeKubeletServer initializes a server to respond to HTTP network requests on the Kubelet.
func ListenAndServeKubeletServer(
       host HostInterface,
       resourceAnalyzer stats.ResourceAnalyzer,
       address net.IP,
       port uint,
       tlsOptions *TLSOptions,
       auth AuthInterface,
       enableDebuggingHandlers bool,
       runtime kubecontainer.Runtime) {
       glog.Infof("Starting to listen on %s:%d", address, port)
       handler := NewServer(host, resourceAnalyzer, auth, enableDebuggingHandlers, runtime)
       s := &http.Server{
              Addr:           net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)),
              Handler:        &handler,
              MaxHeaderBytes: 1 << 20,
       }
       if tlsOptions != nil {
              s.TLSConfig = tlsOptions.Config
              glog.Fatal(s.ListenAndServeTLS(tlsOptions.CertFile, tlsOptions.KeyFile))
       } else {
              glog.Fatal(s.ListenAndServe())
       }
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值