Kubernetes的Main函数怎么理解

发布时间:2021-12-20 10:38:05 作者:iii
来源:亿速云 阅读:155

本篇内容主要讲解“Kubernetes的Main函数怎么理解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Kubernetes的Main函数怎么理解”吧!

Main函数:

读过Kubernetes的源码就会发现,Kubernetes使用的是corba框架,所以各个组件的Main函数都大同小异,如下是kube-controller-manager的main函数,

k8s.io/kubernetes/cmd/kube-controller-manager/controller-manager.go

func main() {
   rand.Seed(time.Now().UTC().UnixNano())

   command := app.NewControllerManagerCommand()  //生成corba格式的Command,添加flag及初始化Command的各个函数

   // TODO: once we switch everything over to Cobra commands, we can go back to calling
   // utilflag.InitFlags() (by removing its pflag.Parse() call). For now, we have to set the
   // normalize func and add the go flag set by hand.
   pflag.CommandLine.SetNormalizeFunc(utilflag.WordSepNormalizeFunc)
   pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
   // utilflag.InitFlags()
   logs.InitLogs()
   defer logs.FlushLogs()

   if err := command.Execute(); err != nil {  //执行Command  fmt.Fprintf(os.Stderr, "%v\n", err)
      os.Exit(1)
   }
}

NewControllerManagerCommand函数:

k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go:77func NewControllerManagerCommand() *cobra.Command {
   s, err := options.NewKubeControllerManagerOptions()  //生成KubeControllerManagerOptions结构体
   if err != nil {
      glog.Fatalf("unable to initialize command options: %v", err)
   }

   cmd := &cobra.Command{  //生成kube-controller-manager的Command  Use: "kube-controller-manager",
      Long: `The Kubernetes controller manager is a daemon that embeds
the core control loops shipped with Kubernetes. In applications of robotics and
automation, a control loop is a non-terminating loop that regulates the state of
the system. In Kubernetes, a controller is a control loop that watches the shared
state of the cluster through the apiserver and makes changes attempting to move the
current state towards the desired state. Examples of controllers that ship with
Kubernetes today are the replication controller, endpoints controller, namespace
controller, and serviceaccounts controller.`,
      Run: func(cmd *cobra.Command, args []string) {
         verflag.PrintAndExitIfRequested()
         utilflag.PrintFlags(cmd.Flags())

         c, err := s.Config(KnownControllers(), ControllersDisabledByDefault.List())
         if err != nil {
            fmt.Fprintf(os.Stderr, "%v\n", err)
            os.Exit(1)
         }

         if err := Run(c.Complete(), wait.NeverStop); err != nil {
            fmt.Fprintf(os.Stderr, "%v\n", err)
            os.Exit(1)
         }
      },
   }

   fs := cmd.Flags()
   namedFlagSets := s.Flags(KnownControllers(), ControllersDisabledByDefault.List()) //生成controller-manager各个controller的参数
   for _, f := range namedFlagSets.FlagSets {  //将各个controller的参数添加到Command的flag中  fs.AddFlagSet(f)
   }
   usageFmt := "Usage:\n  %s\n"
   cols, _, _ := apiserverflag.TerminalSize(cmd.OutOrStdout())
   cmd.SetUsageFunc(func(cmd *cobra.Command) error {   //设置Kube-controller-manager的Usage函数  fmt.Fprintf(cmd.OutOrStderr(), usageFmt, cmd.UseLine())
      apiserverflag.PrintSections(cmd.OutOrStderr(), namedFlagSets, cols)
      return nil
   })
   cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) {  //设置Kube-controller-manager的help函数  fmt.Fprintf(cmd.OutOrStdout(), "%s\n\n"+usageFmt, cmd.Long, cmd.UseLine())
      apiserverflag.PrintSections(cmd.OutOrStdout(), namedFlagSets, cols)
   })

   return cmd
}

command.Execute,即command.Run函数

生成command以后,就执行command.Execute函数,即执行上一步NewKubeControllerManagerOptions函数中给command定义的Run函数。注:corba的command.Execute方法是有很多检查的,会有parent command及command本身也会有很多函数(i.e PreRun,PostRun),有兴趣的可以阅读github.com/spf13/cobra项目,因为kube-controller-manager只定义了Run函数,所以这里就直接看Run函数。

k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go:93Run: func(cmd *cobra.Command, args []string) {
   verflag.PrintAndExitIfRequested()  //检查是否带了--version参数,如果有,则打印Kubernetes的version并退出程序
   utilflag.PrintFlags(cmd.Flags())   //将所有的参数及参数的value打印到日志   //Config方法对所有的controller做validation,并根据options的Master,Kubeconfig,ContentType,Qps,Burst参数生成controller manager config objective
   c, err := s.Config(KnownControllers(), ControllersDisabledByDefault.List())
   if err != nil {
      fmt.Fprintf(os.Stderr, "%v\n", err)
      os.Exit(1)
   }

   if err := Run(c.Complete(), wait.NeverStop); err != nil { //执行本包中的Run函数  fmt.Fprintf(os.Stderr, "%v\n", err)
      os.Exit(1)
   }
}

controllermanager.go包的Run函数

k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go:141func Run(c *config.CompletedConfig, stopCh <-chan struct{}) error {
   // To help debugging, immediately log version
   glog.Infof("Version: %+v", version.Get())

   if cfgz, err := configz.New("componentconfig"); err == nil {
      cfgz.Set(c.ComponentConfig)
   } else {
      glog.Errorf("unable to register configz: %c", err)
   }

   // 启动http服务,提供health接口,以及给prometheus提供metrics接口
   // Start the controller manager HTTP server
   // unsecuredMux is the handler for these controller *after* authn/authz filters have been applied
   var unsecuredMux *mux.PathRecorderMux
   if c.SecureServing != nil {
      unsecuredMux = genericcontrollermanager.NewBaseHandler(&c.ComponentConfig.Generic.Debugging)
      handler := genericcontrollermanager.BuildHandlerChain(unsecuredMux, &c.Authorization, &c.Authentication)
      if err := c.SecureServing.Serve(handler, 0, stopCh); err != nil {
         return err
      }
   }
   if c.InsecureServing != nil {
      unsecuredMux = genericcontrollermanager.NewBaseHandler(&c.ComponentConfig.Generic.Debugging)
      insecureSuperuserAuthn := server.AuthenticationInfo{Authenticator: &server.InsecureSuperuser{}}
      handler := genericcontrollermanager.BuildHandlerChain(unsecuredMux, nil, &insecureSuperuserAuthn)
      if err := c.InsecureServing.Serve(handler, 0, stopCh); err != nil {
         return err
      }
   }

   //定义run函数
   run := func(ctx context.Context) {
      rootClientBuilder := controller.SimpleControllerClientBuilder{  //定义rootrootClientBuilder ClientConfig: c.Kubeconfig,
      }
      var clientBuilder controller.ControllerClientBuilder
      //如果设置了UseServiceAccountCredentials,设clientBuilder为SAControllerClientBuilder(带授权),否则为普通的rootClientBuilder  if c.ComponentConfig.KubeCloudShared.UseServiceAccountCredentials { 
         if len(c.ComponentConfig.SAController.ServiceAccountKeyFile) == 0 {
            // It'c possible another controller process is creating the tokens for us.
            // If one isn't, we'll timeout and exit when our client builder is unable to create the tokens.
            glog.Warningf("--use-service-account-credentials was specified without providing a --service-account-private-key-file")
         }
         clientBuilder = controller.SAControllerClientBuilder{ 
            ClientConfig:         restclient.AnonymousClientConfig(c.Kubeconfig),
            CoreClient:           c.Client.CoreV1(),
            AuthenticationClient: c.Client.AuthenticationV1(),
            Namespace:            "kube-system",
         }
      } else {
         clientBuilder = rootClientBuilder
      }
      controllerContext, err := CreateControllerContext(c, rootClientBuilder, clientBuilder, ctx.Done())
      if err != nil {
         glog.Fatalf("error building controller context: %v", err)
      }
      //定义saTokenControllerInitFunc  saTokenControllerInitFunc := serviceAccountTokenControllerStarter{rootClientBuilder: rootClientBuilder}.startServiceAccountTokenController

      //启动所有的controller,NewControllerInitializers函数中有所有的controller  if err := StartControllers(controllerContext, saTokenControllerInitFunc, NewControllerInitializers(controllerContext.LoopMode), unsecuredMux); err != nil {
         glog.Fatalf("error starting controllers: %v", err)
      }

      controllerContext.InformerFactory.Start(controllerContext.Stop)
      close(controllerContext.InformersStarted)

      select {}
   }

   if !c.ComponentConfig.Generic.LeaderElection.LeaderElect { //如果没有启用leader-elect,则直接执行上面的run函数  run(context.TODO())
      panic("unreachable")
   }

   id, err := os.Hostname()
   if err != nil {
      return err
   }

   //如果启用了leader-elect,在选举以后,再执行上面看的run函数
   // add a uniquifier so that two processes on the same host don't accidentally both become active
   id = id + "_" + string(uuid.NewUUID())
   rl, err := resourcelock.New(c.ComponentConfig.Generic.LeaderElection.ResourceLock,
      "kube-system",
      "kube-controller-manager",
      c.LeaderElectionClient.CoreV1(),
      resourcelock.ResourceLockConfig{
         Identity:      id,
         EventRecorder: c.EventRecorder,
      })
   if err != nil {
      glog.Fatalf("error creating lock: %v", err)
   }

   leaderelection.RunOrDie(context.TODO(), leaderelection.LeaderElectionConfig{
      Lock:          rl,
      LeaseDuration: c.ComponentConfig.Generic.LeaderElection.LeaseDuration.Duration,
      RenewDeadline: c.ComponentConfig.Generic.LeaderElection.RenewDeadline.Duration,
      RetryPeriod:   c.ComponentConfig.Generic.LeaderElection.RetryPeriod.Duration,
      Callbacks: leaderelection.LeaderCallbacks{
         OnStartedLeading: run,
         OnStoppedLeading: func() {
            glog.Fatalf("leaderelection lost")
         },
      },
   })
   panic("unreachable")
}

到此,相信大家对“Kubernetes的Main函数怎么理解”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

推荐阅读:
  1. 如何理解kubernetes的配置中心configmap
  2. kubernetes关于statefulset的理解

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

main kubernetes

上一篇:ShardingSphere中如何进行Sharding-JDBC分库的实战

下一篇:openstack环境部署遇到的问题怎么解决

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》