基于1.1.2版本kubelet源码阅读(1)

本文深入解析kubelet的启动过程,从cmd/kubelet/kubelet.go的main函数开始,逐步剖析NewKubeletServer、RunKubelet、createAndInitKubelet等关键函数,以及pod资源的获取和处理流程。通过syncLoop迭代,kubelet如何管理和运行pod,实现与apiserver的交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kubelet的主体流程部分,主要是为了理解kubelet组件的主体流程是如何运行的,是如何获取pod信息,然后如何对pod进行部署和update等操作。
(主要是根据网上一些公开的信息,再根据自己的理解来进行整合,加深自己对k8s源码的学习)

1、从cmd/kubelet/kubelet.go开始main()函数

  func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    //kubelet 的main函数入口,新建一个NewKubeletServer
    //NewKubeletServer()初始化kubelet Server的fields为默认值。然后在初始化flags和logs之后就可开始Run kubelet Server
    s := app.NewKubeletServer()
    //解析flag
    s.AddFlags(pflag.CommandLine)
    //future work:后面要了解参数是如何写到系统里面的?是InitFlags如何运作么?
    util.InitFlags()
    util.InitLogs()
    defer util.FlushLogs()
    verflag.PrintAndExitIfRequested()
    if err := s.Run(nil); err != nil {
   
        fmt.Fprintf(os.Stderr, "%v\n", err)
        os.Exit(1)
    }
}

main函数主要执行NewKubeletServer()、AddFlags(pflag.CommandLine)、 s.Run(nil)这三个步骤,下面具体分析这三个函数

2、NewKubeletServer()解析

定义在cmd/kubelet/server.go
NewKubeletServer()创建一个KubeletServer,主要是完成参数的初始化—with default values
return &KubeletServer{…}
下面 给出部分参数的含义:

        Address:                     net.ParseIP("0.0.0.0"),
        ContainerRuntime:            "docker",
        DockerExecHandlerName:       "native",
        HealthzBindAddress:          net.ParseIP("127.0.0.1"),
        HealthzPort:                 10248,
        ImageGCHighThresholdPercent: 90,//表示此盘利用率超过90%的时候,会一直对image资源进行回收
        ImageGCLowThresholdPercent:  80,//表示此盘利用率低于80%的时候,不会进行GC
        KubeConfig:                  util.NewStringFlag("/var/lib/kubelet/kubeconfig"),
        MaxContainerCount:           100, //每个节点最多保留100个死亡实例
        MaxPerPodContainerCount:     2,   //每个容器最多保留2个死亡实例
        RegisterNode:        true, // will be ignored if no apiserver is configured     
        ResourceContainer:   "/kubelet",    
        RootDirectory:       defaultRootDir, //默认值是/var/lib/kubelet,存放配置及VM卷等数据

3、 s.Run(nil)

定义在cmd/kubelet/server.go

/*
    Run 基于指定的KubeletConfig运行一个KubeletServer,never exist!
    KubeletConfig可能是nil的。If nil, 在KubeletServer中利用默认值完成初始化设置
    If not nil,the default values 会被忽略
*/
func (s *KubeletServer) Run(kcfg *KubeletConfig) error {
    if kcfg == nil {
        //第一次是通过s.Run(nil)来调用
        //准备一个KubeletConfig,配置一些参数
        //KubeletConfig会返回适合运行的KubeletConfig,如果服务器设置无效,则返回错误。 它不会启动任何后台进程。
        cfg, err := s.KubeletConfig()**[1]**
        if err != nil {
            return err
        }
        kcfg = cfg
        //调用CreateAPIServerClientConfig初始化clientConfig
        //CreateAPIServerClientConfig使用command line flags来生成 client.Config,including api-server-list
        //KubeClient是kubelet 和 Api server传递信息的唯一途径。
        CreateAPIServerClientConfig根据用户的传递--kubeconfig或者默认.kubeconfig文件来解析client配置。
        clientConfig, err := s.CreateAPIServerClientConfig()
        if err == nil {
            /*
                最终初始化KubeClient。
                定义在client "k8s.io/kubernetes/pkg/client/unversioned/helper.go"
                New(c *Config)为指定的配置创建一个Kubernetes client。
                该client可以对pods,replication controllers, daemons, and services这些对象执行list, get, update and delete操作。
                如果提供的配置无效,则返回错误。
            */
            kcfg.KubeClient, err = client.New(clientConfig)
        }
        if err != nil && len(s.APIServerList) > 0 {
            glog.Warningf("No API client: %v", err)
        }
        //cloudprovider 和IaaS云商有关
        cloud, err := cloudprovider.InitCloudProvider(s.CloudProvider, s.CloudConfigFile)
        if err != nil {
            return err
        }
        glog.V(2).Infof("Successfully initialized cloud provider: %q from the config file: %q\n", s.CloudProvider, s.CloudConfigFile)
        kcfg.Cloud = cloud
    }
    /*
        启动cadvisor来监控本地的容器
        通过CAdvisor我们可以看到kuberlet管理的机器上container的资源统计信息
        cadvisor源码在pkg/kubelet/cadvisor/cadvisor_linux.go中
    */
    if kcfg.CAdvisorInterface == nil {
        ca, err := cadvisor.New(s.CAdvisorPort)
        if err != nil {
            return err
        }
        kcfg.CAdvisorInterface = ca
    }

    util.ReallyCrash = s.ReallyCrashForTesting
    rand.Seed(time.Now().UTC().UnixNano())
    /*
        设置preferred Dockercfg 文件path,这个是为了读取.dockercfg文件,
        该文件中的secret可用于pull/push docker registry中的docker镜像,默认的路径为:/var/lib/kubelet
    */
    credentialprovider.SetPreferredDockercfgPath(s.RootDirectory)

    glog.V(2).Infof("Using root directory: %v", s.RootDirectory)

    // TODO(vmarmol): Do this through container config.
    oomAdjuster := oom.NewOomAdjuster()
    /*
         linux的oom机制,当系统发生OOM时,oom_adj值越小,越不容易被系统kill掉    kubelet一般设置自身oom值为 -900  取值范围是[-1000,+1000]
        主要是通过设置/proc/ /oom_score_adj来控制
        设置为-1000,该进程就被排除在OOM Killer强制终止的对象外
    */
    if err := oomAdjuster.ApplyOomScoreAdj(0, s.OOMScoreAdj); err != nil {
   
        glog.Warning(err)
    }
    /*
         ---代码中RunKubelet是下一个入口******
        RunKubelet中会新起一个goroutine来异步运行kubelet;
        接下来的代码还会执行:if s.HealthzPort > 0提供健康检查的http服务
    */
    if err := RunKubelet(kcfg, nil); err != nil {**[2]**
        return err
    }

    if s.HealthzPort > 0 {
        /*
            这段code会启动一个http server来提供health check功能,其实目前就提供了一个/healthz/ping的endpoint,返回的http status code为200就正常。

            Kubernetes默认提供的http端口如下(在pkg/master/ports/ports.go中定义):
            KubeletStatusPort = 10248 // kubelet的health port,就是上面的HealthzPort。
            ProxyStatusPort = 10249 // kube proxy的health port。
            KubeletPort = 10250 // kubelet server的port。
            SchedulerPort = 10251 // kube scheduler的port。
            ControllerManagerPort = 10252 // kube controller manager 的port。
            KubeletReadOnlyPort = 10255 // 用于heapster监控和收集kubelet信息使用。
        */

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

    if s.RunOnce
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值