天天看點

kube-controller-manager 啟動流程controller manager啟動流程

controller manager啟動流程

一 Run

1.首先啟動加載command

(k8s自定義了cobra的指令行參數),加載完command會執行command.Execute(),執行execute的時候會回調command的run

2.在加載command的時候首先會定義一個command

run是在執行execute回調用的 在這裡的run封裝了一些東西具體如下

(1)根據服務是否安全也就是判斷SecureServing 和InsecureServing

相同的操作為

注冊檢查相關 genericcontrollermanager.NewBaseHandler

BuildHandlerChain使用基本處理程式和CompletedConfig建構處理程式鍊。(這裡也包括認證檢查)

服務運作安全的http伺服器,僅當無法加載證書或初始偵聽調用失敗時,它才會失敗,實際的伺服器循環(可通過關閉stopCh來停止)在go例程中運作,即Serve不會阻塞,傳回所有未劫持的活動請求都已處理後關閉的StoppedCh

不同的操作為

如果是不安全 會初始化一個server.AuthenticationInfo如果 安全我們會用方法對應結構體本身的AuthenticationInfo

(2)初始化run run是一個參數為context.Context 沒有傳回值的函數,在 這個函數中

第一步檢測sa的認證方式

第二步建立一個上下文結構,該結構包含對控制器,例如雲提供商和clientBuilder。 rootClientBuilder僅用于共享資訊用戶端和令牌控制器

第三步StartControllers 使用指定的ControllerContext啟動一組控制器 ,啟動控制器的過程中首先會對控制器init 初始化

在初始化的過程中會得倒一個 新的控制器封裝 然後把他run起來 例如deployment controller 我們會調用 deployment.NewDeploymentController 獲得一個初始化的deployment controller 并且在gorouting 中run起來,run起來之後他會調用informer的特性來實作資源的監聽 例如deployment

(deployment controller 利用了 informer 的工作能力,實作了資源的監聽,同時與其他 controller 協同工作。主要使用了三個 shared informer —— deployment informer、rs informer、pod informer,首先 deployment controller 會向三個 shared informer 中注冊鈎子函數,三個鈎子函數會在相應事件到來時,将相關的 deployment 推進 workqueue 中。deployment controller 啟動時會有一個 worker 來控制 syncHandler 函數,實時地将 workqueue 中的 item 推出,根據 item 來執行任務。主要包括:領養和棄養 rs、向 eventRecorder 分發事件、根據更新政策決定如何處理下級資源)[這裡引用了https://mp.weixin.qq.com/s/J97lvKzix2fX4536_iWnXw]

(3)informerfactory start 允許通路控制器的通知程式 ,這裡調用了sharedInformerFactory start

(4)objectormetadatainformerfactory start

// ObjectOrMetadataInformerFactory 允許通路類型資源的通知者

// 和動态資源的中繼資料。 目前使用的所有通用控制器

// 對象中繼資料-如果将來的控制器需要通路完整的對象,則此

// 将成為GenericInformerFactory并接受一個動态用戶端。

這裡會調用sharedInformerFactory start以及i.metadataInformerFactory.Start

(5)close(controllerContext.InformersStarted)

// 所有控制器初始化并運作後, InformersStarted 關閉。 在此之後,這是安全的, 由單個控制器啟動共享通知者。 在關閉之前,他們不應該這樣做。

注*sharedInformerFactory啟動過程,這裡他内部informers

map[reflect.Type]cache.SharedIndexInformer 根據type 區分不同的informer會周遊所有的informer 如果狀态标記為true 表示已啟動 如果标記 false 啟動并且标記為true,informer的run調用了sharedIndexInformer的run,其中會建立一個fifo隊列并且會調用controller的run,而controller的run,會調用reflector的run,refector的run會調用listandwatch,listandwatch啟動的時候會重新整理緩存,并且watchhandler也就是watch一個event,并且插入fifo隊列,是以說這裡根據reflect.type 會挨個啟動

metadataSharedInformerFactory Start與informers,類似不過他的結構是map[schema.GroupVersionResource]informers.GenericInformer根據不同的groupversionresource基于,sharedInformers 不過多了一個lister一個通用的索引器 啟動流程與sharedInformerFactory類似
kube-controller-manager 啟動流程controller manager啟動流程
func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) {
	f.lock.Lock()
	defer f.lock.Unlock()

	for informerType, informer := range f.informers {
		//如果informer是 false  也就是未啟動狀态 那麼!false=true
		if !f.startedInformers[informerType] {
			//啟動這個informer
			go informer.Run(stopCh)
			//啟動之後做标記
			f.startedInformers[informerType] = true
		}
	}
}
           

(3)resourcelock.New

根據給定的類型 給鎖

(4)leaderelection.RunOrDie

RunOrDie 使用提供的配置啟動用戶端,如果配置失敗,驗證失敗

參數

ctx context.Context

在這裡傳入的是context.TODO()

/ /TODO 傳回一個非空的Context。 代碼何時應使用context.TODO

使用場景為:

// 尚不清楚要使用哪個上下文,或者尚不可用(因為

// 周圍函數尚未擴充為接受上下文參數)。

lec LeaderElectionConfig

總結一下這個主要是做 主從搶占 也就是阻塞機制 當叢集模式部署controller manager 那麼一個master 多個slave 通過鎖的租期以及續租 以及狀态的鎖的解除來做搶占
type LeaderElectionConfig struct { 
     // 用于鎖定的資源 
     Lock rl . Interface 
// 等待強迫獲得上司。 這是針對時間最後觀察到的确認。 
// 客戶需要等待完整的 LeaseDuration ,而無需觀察到對可以嘗試接管的記錄。 當所有客戶都關閉,然後以不同的名稱啟動一組新的用戶端相同的上司者記錄,他們必須等待完整的 LeaseDuration 之後嘗試擷取租約。 是以 LeaseDuration 應該盡可能短 
// 可能(在時鐘偏斜率的公差範圍内)以避免可能在方案中長時間等待。 
// 核心用戶端的預設值是 15 秒。 
//簡單描述就是這個是一個租約 到時間了需要取續租約 (租期) 
     LeaseDuration time . Duration 
// RenewDeadline是代理主要重試的持續時間 
//在放棄之前重新整理上司。 
//核心用戶端的預設值是10秒。 
//續約期限 
     RenewDeadline time . Duration 
// RetryPeriod是LeaderElector客戶應等待的持續時間 
//在兩次嘗試之間。核心用戶端将此值預設為2秒。 
//重試時間 
     RetryPeriod time . Duration 
//回調是在特定生命周期内觸發的回調 
// LeaderElector的事件 
     Callbacks LeaderCallbacks 
     //這裡初始化了一個lec将run傳遞進去
// 關聯的健康檢查器 
     WatchDog * HealthzAdaptor 
//如果應釋放鎖,則應将ReleaseOnCancel設定為true 
//取消運作上下文時。 如果将其設定為true,則必須 
//確定此租約保護的所有代碼均已成功完成 
//在取消上下文之前,否則您可能有兩個過程 
//同時作用于關鍵路徑。 
     ReleaseOnCancel bool 
// Name是用于調試的資源鎖的名稱 
     Name string 
} 
           
// LeaderCallbacks是在特定時間段内觸發的回調 
// LeaderElector的生命周期事件。 這些是異步調用的。 
// 
//将來可能的回調: 
// * OnChallenge() 
type LeaderCallbacks struct { 
//當LeaderElector用戶端開始上司時調用OnStartedLeading 
     // OnStartedLeading is called when a LeaderElector client starts leading 
     OnStartedLeading func ( context . Context ) 
     // OnStoppedLeading is called when a LeaderElector client stops leading 
//當LeaderElector用戶端停止引導時調用OnStoppedLeading 
     OnStoppedLeading func () 
     // OnNewLeader is called when the client observes a leader that is 
    // not the previously observed leader. This includes the first observed 
    // leader when the client starts. 
//當用戶端觀察到上司者時,将調用OnNewLeader 
//不是先前觀察到的上司者。 這包括第一次觀察到的 
//用戶端啟動時的上司者。 
     OnNewLeader func ( identity string ) 
} 
           

二 .在加載command的時候進行參數解析

參數解析分為以下幾個過程

(1)Flags 通過傳入 controllers 以及預設的controllers 來做各個controller的指令行參數解析

(2)注冊global全局參數

(3)将flags 解析的參數 轉移到我們定義的command的flags上

(4)定義usage的使用方法

(5)定義help的使用方法

繼續閱讀