跳转至

启动流程

通用源码入口

在此之前,需要知道所有的 kubevirt 组件都是从 cmd/virt-* 开始的

启动流程

首先调用入口函数

kubevirt/cmd/virt-controller/virt-controller.go
import (
    _ "kubevirt.io/kubevirt/pkg/monitoring/client/prometheus"    // import for prometheus metrics
    _ "kubevirt.io/kubevirt/pkg/monitoring/reflector/prometheus" // import for prometheus metrics
    _ "kubevirt.io/kubevirt/pkg/monitoring/workqueue/prometheus" // import for prometheus metrics
    "kubevirt.io/kubevirt/pkg/virt-controller/watch"
)

func main() {
    watch.Execute()
}
直接调用kubevirt/pkg/virt-controller/watch/application.go中的Execute函数启动virt-controller。下面主要分析Execute函数中的内容。

获取leaderElectionConfiguration

获取leaderElectionConfiguration, 可通过leaderelectionconfig包获取:

kubevirt/pkg/virt-controller/watch/application.go
app.LeaderElection = leaderelectionconfig.DefaultLeaderElectionConfiguration()

获取KubevirtClient

kubevirt/pkg/virt-controller/watch/application.go
1
2
3
4
5
6
7
8
9
clientConfig, err := kubecli.GetKubevirtClientConfig()
if err != nil {
    panic(err)
}
clientConfig.RateLimiter = app.reloadableRateLimiter
app.clientSet, err = kubecli.GetKubevirtClientFromRESTConfig(clientConfig)
if err != nil {
    golog.Fatal(err)
}

获取informerFactory

获取informerFactory,并实例化一系列具体资源类型的Informer,例如crdInformerkubeVirtInformervmiInformerkvPodInformernodeInformervmInformermigrationInformer

kubevirt/pkg/virt-controller/watch/application.go
1
2
3
4
5
6
app.informerFactory = controller.NewKubeInformerFactory(app.restClient, app.clientSet, nil, app.kubevirtNamespace)

// 实例化各资源类型的informer
app.crdInformer = app.informerFactory.CRD()
app.kubeVirtInformer = app.informerFactory.KubeVirt()
// ...

初始化一系列controller

这一系列controller主要包括vmiControllernodeControllermigrationControllervmControllerevacuationControllersnapshotControllerrestoreControllerreplicaSetControllerdisruptionBudgetController

kubevirt/pkg/virt-controller/watch/application.go
// 初始化一系列controller
app.initCommon()
app.initReplicaSet()
app.initPool()
app.initVirtualMachines()
app.initDisruptionBudgetController()
app.initEvacuationController()
app.initSnapshotController()
app.initRestoreController()
app.initExportController()
app.initWorkloadUpdaterController()
app.initCloneController()

通过leaderElector启动virt-controller

通过leaderElector来启动virt-controller,并在leaderElector中启动各个controller的Run函数。

kubevirt/pkg/virt-controller/watch/application.go
func (vca *VirtControllerApp) Run() {
  logger := log.Log

  promCertManager := bootstrap.NewFileCertificateManager(vca.promCertFilePath, vca.promKeyFilePath)
  go promCertManager.Start()
  promTLSConfig := kvtls.SetupPromTLS(promCertManager, vca.clusterConfig)

  go func() {
    httpLogger := logger.With("service", "http")
    _ = httpLogger.Level(log.INFO).Log("action", "listening", "interface", vca.BindAddress, "port", vca.Port)
    http.Handle("/metrics", promhttp.Handler())
    server := http.Server{
        Addr:      vca.Address(),
        Handler:   http.DefaultServeMux,
        TLSConfig: promTLSConfig,
    }
    if err := server.ListenAndServeTLS("", ""); err != nil {
        golog.Fatal(err)
    }
  }()

  if err := vca.setupLeaderElector(); err != nil {
    golog.Fatal(err)
  }

  readyGauge.Set(1)
  vca.leaderElector.Run(vca.ctx)
  readyGauge.Set(0)
  panic("unreachable")
}

virt-controller分析


最后更新: 2023-08-16
创建日期: 2023-08-14

评论