91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

kubernetes與CNI Plugin的集成方法是什么

發布時間:2021-12-20 10:16:37 來源:億速云 閱讀:141 作者:iii 欄目:云計算

本篇內容主要講解“kubernetes與CNI Plugin的集成方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“kubernetes與CNI Plugin的集成方法是什么”吧!

libcni

cni項目提供了golang寫的一個library,定義了集成cni插件的應用需調用的cni plugin接口,它就是libcni。其對應的Interface定義如下:

libcni/api.go:51

type CNI interface {
	AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
	DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) error

	AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
	DelNetwork(net *NetworkConfig, rt *RuntimeConf) error
}

CNI Plugin在kubelet管理的PLEG中何時被調用

kubelet Run方法方法中會最終調用syncLoopIteration函數,由它通過各種channel對pod進行sync。

pkg/kubelet/kubelet.go:1794
    
// syncLoopIteration reads from various channels and dispatches pods to the
// given handler.
//
// Arguments:
// 1.  configCh:       a channel to read config events from
// 2.  handler:        the SyncHandler to dispatch pods to
// 3.  syncCh:         a channel to read periodic sync events from
// 4.  houseKeepingCh: a channel to read housekeeping events from
// 5.  plegCh:         a channel to read PLEG updates from
//
// Events are also read from the kubelet liveness manager's update channel.
//
// The workflow is to read from one of the channels, handle that event, and
// update the timestamp in the sync loop monitor.
//
// Here is an appropriate place to note that despite the syntactical
// similarity to the switch statement, the case statements in a select are
// evaluated in a pseudorandom order if there are multiple channels ready to
// read from when the select is evaluated.  In other words, case statements
// are evaluated in random order, and you can not assume that the case
// statements evaluate in order if multiple channels have events.
//
// With that in mind, in truly no particular order, the different channels
// are handled as follows:
//
// * configCh: dispatch the pods for the config change to the appropriate
//             handler callback for the event type
// * plegCh: update the runtime cache; sync pod
// * syncCh: sync all pods waiting for sync
// * houseKeepingCh: trigger cleanup of pods
// * liveness manager: sync pods that have failed or in which one or more
//                     containers have failed liveness checks
func (kl *Kubelet) syncLoopIteration(configCh <-chan kubetypes.PodUpdate, handler SyncHandler,
	syncCh <-chan time.Time, housekeepingCh <-chan time.Time, plegCh <-chan *pleg.PodLifecycleEvent) bool {
	kl.syncLoopMonitor.Store(kl.clock.Now())
	select {
	case u, open := <-configCh:
		// Update from a config source; dispatch it to the right handler
		// callback.
		if !open {
			glog.Errorf("Update channel is closed. Exiting the sync loop.")
			return false
		}
    
		switch u.Op {
		case kubetypes.ADD:
			glog.V(2).Infof("SyncLoop (ADD, %q): %q", u.Source, format.Pods(u.Pods))
			// After restarting, kubelet will get all existing pods through
			// ADD as if they are new pods. These pods will then go through the
			// admission process and *may* be rejected. This can be resolved
			// once we have checkpointing.
			handler.HandlePodAdditions(u.Pods)
		case kubetypes.UPDATE:
			glog.V(2).Infof("SyncLoop (UPDATE, %q): %q", u.Source, format.PodsWithDeletiontimestamps(u.Pods))
			handler.HandlePodUpdates(u.Pods)
		case kubetypes.REMOVE:
			glog.V(2).Infof("SyncLoop (REMOVE, %q): %q", u.Source, format.Pods(u.Pods))
			handler.HandlePodRemoves(u.Pods)
		case kubetypes.RECONCILE:
			glog.V(4).Infof("SyncLoop (RECONCILE, %q): %q", u.Source, format.Pods(u.Pods))
			handler.HandlePodReconcile(u.Pods)
		case kubetypes.DELETE:
			glog.V(2).Infof("SyncLoop (DELETE, %q): %q", u.Source, format.Pods(u.Pods))
			// DELETE is treated as a UPDATE because of graceful deletion.
			handler.HandlePodUpdates(u.Pods)
		case kubetypes.SET:
			// TODO: Do we want to support this?
			glog.Errorf("Kubelet does not support snapshot update")
		}
    
		// Mark the source ready after receiving at least one update from the
		// source. Once all the sources are marked ready, various cleanup
		// routines will start reclaiming resources. It is important that this
		// takes place only after kubelet calls the update handler to process
		// the update to ensure the internal pod cache is up-to-date.
		kl.sourcesReady.AddSource(u.Source)
	case e := <-plegCh:
		if isSyncPodWorthy(e) {
			// PLEG event for a pod; sync it.
			if pod, ok := kl.podManager.GetPodByUID(e.ID); ok {
				glog.V(2).Infof("SyncLoop (PLEG): %q, event: %#v", format.Pod(pod), e)
				handler.HandlePodSyncs([]*v1.Pod{pod})
			} else {
				// If the pod no longer exists, ignore the event.
				glog.V(4).Infof("SyncLoop (PLEG): ignore irrelevant event: %#v", e)
			}
		}
    
		if e.Type == pleg.ContainerDied {
			if containerID, ok := e.Data.(string); ok {
				kl.cleanUpContainersInPod(e.ID, containerID)
			}
		}
	case <-syncCh:
		// Sync pods waiting for sync
		podsToSync := kl.getPodsToSync()
		if len(podsToSync) == 0 {
			break
		}
		glog.V(4).Infof("SyncLoop (SYNC): %d pods; %s", len(podsToSync), format.Pods(podsToSync))
		kl.HandlePodSyncs(podsToSync)
	case update := <-kl.livenessManager.Updates():
		if update.Result == proberesults.Failure {
			// The liveness manager detected a failure; sync the pod.
    
			// We should not use the pod from livenessManager, because it is never updated after
			// initialization.
			pod, ok := kl.podManager.GetPodByUID(update.PodUID)
			if !ok {
				// If the pod no longer exists, ignore the update.
				glog.V(4).Infof("SyncLoop (container unhealthy): ignore irrelevant update: %#v", update)
				break
			}
			glog.V(1).Infof("SyncLoop (container unhealthy): %q", format.Pod(pod))
			handler.HandlePodSyncs([]*v1.Pod{pod})
		}
	case <-housekeepingCh:
		if !kl.sourcesReady.AllReady() {
			// If the sources aren't ready or volume manager has not yet synced the states,
			// skip housekeeping, as we may accidentally delete pods from unready sources.
			glog.V(4).Infof("SyncLoop (housekeeping, skipped): sources aren't ready yet.")
		} else {
			glog.V(4).Infof("SyncLoop (housekeeping)")
			if err := handler.HandlePodCleanups(); err != nil {
				glog.Errorf("Failed cleaning pods: %v", err)
			}
		}
	}
	kl.syncLoopMonitor.Store(kl.clock.Now())
	return true
}

說明:

  • HandlePodSyncs, HandlePodUpdates, HandlePodAdditions最終都是invoke dispatchWork來分發pods到podWorker進行異步的pod sync。

  • HandlePodRemoves調用一下接口,將pod從cache中刪除,kill pod中進程,并 stop Pod的Probe Workers,最終通過捕獲Pod的PLEG Event,通過cleanUpContainersInPod來清理Pod。 pkg/kubelet/kubelet.go:1994 kl.podManager.DeletePod(pod); kl.deletePod(pod); kl.probeManager.RemovePod(pod);

  • HandlePodReconcile中,如果Pod是通過Eviction導致的Failed,則調用kl.containerDeletor.deleteContainersInPod來清除Pod內的容器。

HandlePodSyncs, HandlePodUpdates, HandlePodAdditions

  • Kubelet.dispatchWork最終會invoke podWokers.managePodLoop,podWorkers會嗲用NewMainKubelet時給PodWorkers注冊的syncPodFn= (kl *Kubelet) syncPod(o syncPodOptions)。

  • Kubelet.syncPod會根據runtime類型進行區分,我們只看runtime為docker的情況,會invoke DockerManager.SyncPod。

  • DockerManager.SyncPod會dm.network.SetUpPod,然后根據network plugin類型進行區分,我們只看cni plugin,會對應invoke cniNetworkPlugin.SetUpPod進行網絡設置。

  • cniNetworkPlugin.SetUpPod invoke cniNetwork.addToNetwork,由后者最終調用CNIConfig.AddNetwork,這就是libcni中對應的AddNetwork Interface。

  • CNIConfig.AddNetwork通過封裝好的execPlugin由系統去調用cni plugin bin,到此就完成了pod內的網絡設置。

HandlePodRemoves, HandlePodReconcile

  • 都是通過invoke podContainerDeleter.deleteContainerInPod來清理容器。

  • 對于docker,deleteContainerInPod會調用DockerManager.delteContainer。

  • 在deleteContainer時,通過invoke containerGC.netContainerCleanup進行容器的網絡環境清理。

  • 然后由PluginManger.TearDownPod去調用cniNetworkPlugin.TearDownPod,再執行cniNetwork.deleteFromNetwork。

  • cniNetwork.deleteFromNetwork會調用CNIConfig.DelNetwork,這就是libcni中對應的DelNetwork Interface。

  • CNIConfig.AddNetwork通過封裝好的execPlugin由系統去調用cni plugin bin,到此就完成了pod內的網絡清理。

kubelet中與cni plugin調用的代碼流程圖

kubernetes與CNI Plugin的集成方法是什么

到此,相信大家對“kubernetes與CNI Plugin的集成方法是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

临城县| 合水县| 长海县| 峨眉山市| 柳州市| 昌宁县| 中牟县| 阿瓦提县| 油尖旺区| 仁寿县| 鸡东县| 田东县| 武乡县| 靖宇县| 武冈市| 平塘县| 新和县| 通河县| 象山县| 蓬莱市| 淅川县| 随州市| 玉林市| 东平县| 潍坊市| 文安县| 北川| 区。| 东源县| 甘南县| 桂平市| 北宁市| 达日县| 石城县| 古浪县| 沁阳市| 赞皇县| 湘阴县| 静宁县| 清徐县| 长丰县|