久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

怎么創建Node Controller

145次閱讀
沒有評論

共計 11547 個字符,預計需要花費 29 分鐘才能閱讀完成。

本篇內容主要講解“怎么創建 Node Controller”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“怎么創建 Node Controller”吧!

NewNodeController 入口

Controller Manager 在啟動時,會啟動一系列的 Controller,Node Controller 也是在 Controller Manager 啟動時 StartControllers 方法中啟動的 Controller 之一,其對應的創建代碼如下。

cmd/kube-controller-manager/app/controllermanager.go:455
nodeController, err := nodecontroller.NewNodeController(sharedInformers.Core().V1().Pods(),
 sharedInformers.Core().V1().Nodes(),
 sharedInformers.Extensions().V1beta1().DaemonSets(),
 cloud,
 clientBuilder.ClientOrDie(node-controller),
 s.PodEvictionTimeout.Duration,
 s.NodeEvictionRate,
 s.SecondaryNodeEvictionRate,
 s.LargeClusterSizeThreshold,
 s.UnhealthyZoneThreshold,
 s.NodeMonitorGracePeriod.Duration,
 s.NodeStartupGracePeriod.Duration,
 s.NodeMonitorPeriod.Duration,
 clusterCIDR,
 serviceCIDR,
 int(s.NodeCIDRMaskSize),
 s.AllocateNodeCIDRs,
 s.EnableTaintManager,
 utilfeature.DefaultFeatureGate.Enabled(features.TaintBasedEvictions),
 )

可見,Node Controller 主要是 ListWatch sharedInformers 中的如下對象:

Pods

Nodes

DaemonSets

另外,需要注意:

s.EnableTaintManager 的默認值為 true,即表示默認開啟 Taint Manager,可通過 –enable-taint-manager 進行設置。

DefaultFeatureGate.Enabled(features.TaintBasedEvictions) 的默認值為 false,可通過 –feature-gates 中添加 TaintBasedEvictions=true 修改為 true,true 即表示 Node 上的 Pods Eviction Operation 通過 TaintManager 來進行。

補充:關于 Kubernetes 的 Default FeaturesGate 的設置見如下代碼:

pkg/features/kube_features.go:100
var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureSpec{ExternalTrafficLocalOnly: {Default: true, PreRelease: utilfeature.Beta},
 AppArmor: {Default: true, PreRelease: utilfeature.Beta},
 DynamicKubeletConfig: {Default: false, PreRelease: utilfeature.Alpha},
 DynamicVolumeProvisioning: {Default: true, PreRelease: utilfeature.Alpha},
 ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: utilfeature.Beta},
 ExperimentalCriticalPodAnnotation: {Default: false, PreRelease: utilfeature.Alpha},
 AffinityInAnnotations: {Default: false, PreRelease: utilfeature.Alpha},
 Accelerators: {Default: false, PreRelease: utilfeature.Alpha},
 TaintBasedEvictions: {Default: false, PreRelease: utilfeature.Alpha},
 // inherited features from generic apiserver, relisted here to get a conflict if it is changed
 // unintentionally on either side:
 StreamingProxyRedirects: {Default: true, PreRelease: utilfeature.Beta},
}

NewNodeController 定義

func NewNodeController(
 podInformer coreinformers.PodInformer,
 nodeInformer coreinformers.NodeInformer,
 daemonSetInformer extensionsinformers.DaemonSetInformer,
 cloud cloudprovider.Interface,
 kubeClient clientset.Interface,
 podEvictionTimeout time.Duration,
 evictionLimiterQPS float32,
 secondaryEvictionLimiterQPS float32,
 largeClusterThreshold int32,
 unhealthyZoneThreshold float32,
 nodeMonitorGracePeriod time.Duration,
 nodeStartupGracePeriod time.Duration,
 nodeMonitorPeriod time.Duration,
 clusterCIDR *net.IPNet,
 serviceCIDR *net.IPNet,
 nodeCIDRMaskSize int,
 allocateNodeCIDRs bool,
 runTaintManager bool,
 useTaintBasedEvictions bool) (*NodeController, error) {
 nc :=  NodeController{
 cloud: cloud,
 knownNodeSet: make(map[string]*v1.Node),
 kubeClient: kubeClient,
 recorder: recorder,
 podEvictionTimeout: podEvictionTimeout,
 maximumGracePeriod: 5 * time.Minute, //  不可配置,表示 The maximum duration before a pod evicted from a node can be forcefully terminated 
 zonePodEvictor: make(map[string]*RateLimitedTimedQueue),
 zoneNotReadyOrUnreachableTainer: make(map[string]*RateLimitedTimedQueue),
 nodeStatusMap: make(map[string]nodeStatusData),
 nodeMonitorGracePeriod: nodeMonitorGracePeriod,
 nodeMonitorPeriod: nodeMonitorPeriod,
 nodeStartupGracePeriod: nodeStartupGracePeriod,
 lookupIP: net.LookupIP,
 now: metav1.Now,
 clusterCIDR: clusterCIDR,
 serviceCIDR: serviceCIDR,
 allocateNodeCIDRs: allocateNodeCIDRs,
 forcefullyDeletePod: func(p *v1.Pod) error { return forcefullyDeletePod(kubeClient, p) },
 nodeExistsInCloudProvider: func(nodeName types.NodeName) (bool, error) { return nodeExistsInCloudProvider(cloud, nodeName) },
 evictionLimiterQPS: evictionLimiterQPS,
 secondaryEvictionLimiterQPS: secondaryEvictionLimiterQPS,
 largeClusterThreshold: largeClusterThreshold,
 unhealthyZoneThreshold: unhealthyZoneThreshold,
 zoneStates: make(map[string]zoneState),
 runTaintManager: runTaintManager,
 useTaintBasedEvictions: useTaintBasedEvictions   runTaintManager,
 //  注冊 enterPartialDisruptionFunc 函數為 ReducedQPSFunc,當 zone state 為 PartialDisruption 時,將 invoke ReducedQPSFunc 來 setLimiterInZone。nc.enterPartialDisruptionFunc = nc.ReducedQPSFunc
 //  注冊 enterFullDisruptionFunc 函數為 HealthyQPSFunc,當 zone state 為 FullDisruption 時,將 invoke HealthyQPSFunc 來 setLimiterInZone。nc.enterFullDisruptionFunc = nc.HealthyQPSFunc
 //  注冊 computeZoneStateFunc 函數為 ComputeZoneState,當 handleDisruption 時,將 invoke ComputeZoneState 來計算集群中 unhealthy node number 及 zone state。nc.computeZoneStateFunc = nc.ComputeZoneState

//  注冊 PodInformer 的 Event Handler:Add,Update,Delete。podInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{  //  對于 Pod Add 和 Update Event,都會去判斷 Node 上 kubelet 的 version,如果 version 低于 1.1.0,則會通過 forcefullyDeletePod 直接調用 apiserver 接口刪除 etcd 中該 Pod object。 //  對于 Pod Add, Update, Delete Event,如果啟動了 TaintManager,則會對比 OldPod 和 newPod 的 Tolerations 信息,如果不相同,則會將該 Pod 的變更信息 Add 到 NoExecuteTaintManager 的 podUpdateQueue 中,交給 Taint Controller 處理。只不過對于 Delete Event,newPod  為 nil。AddFunc: func(obj interface{}) {nc.maybeDeleteTerminatingPod(obj) pod := obj.(*v1.Pod) if nc.taintManager != nil {nc.taintManager.PodUpdated(nil, pod) UpdateFunc: func(prev, obj interface{}) {nc.maybeDeleteTerminatingPod(obj) prevPod := prev.(*v1.Pod) newPod := obj.(*v1.Pod) if nc.taintManager != nil {nc.taintManager.PodUpdated(prevPod, newPod) DeleteFunc: func(obj interface{}) {pod, isPod := obj.(*v1.Pod) // We can get DeletedFinalStateUnknown instead of *v1.Node here and we need to handle that correctly. #34692 if !isPod {deletedState, ok := obj.(cache.DeletedFinalStateUnknown) if !ok {glog.Errorf( Received unexpected object: %v , obj) return pod, ok = deletedState.Obj.(*v1.Pod) if !ok {glog.Errorf( DeletedFinalStateUnknown contained non-Node object: %v , deletedState.Obj) return if nc.taintManager != nil {nc.taintManager.PodUpdated(pod, nil) // returns true if the shared informer s store has synced. nc.podInformerSynced = podInformer.Informer().HasSynced
//  注冊 NodeInformer 的 Event Handler:Add,Update,Delete。nodeEventHandlerFuncs := cache.ResourceEventHandlerFuncs{} if nc.allocateNodeCIDRs { // --allocate-node-cidrs —— Should CIDRs for Pods be allocated and set on the cloud provider。} else { nodeEventHandlerFuncs = cache.ResourceEventHandlerFuncs{  //  對于 Node Add, Update, Delete Event,如果啟動了 TaintManager,則會對比 OldNode 和 newNode 的 Taints 信息,如果不相同,則會將該 Node 的變更信息 Add 到 NoExecuteTaintManager 的 nodeUpdateQueue 中,交給 Taint Controller 處理。只不過對于 Delete Event,newNode  為 nil。AddFunc: func(originalObj interface{}) {obj, err := api.Scheme.DeepCopy(originalObj) if err != nil {utilruntime.HandleError(err) return node := obj.(*v1.Node) if nc.taintManager != nil {nc.taintManager.NodeUpdated(nil, node) UpdateFunc: func(oldNode, newNode interface{}) {node := newNode.(*v1.Node) prevNode := oldNode.(*v1.Node) if nc.taintManager != nil {nc.taintManager.NodeUpdated(prevNode, node) DeleteFunc: func(originalObj interface{}) {obj, err := api.Scheme.DeepCopy(originalObj) if err != nil {utilruntime.HandleError(err) return node, isNode := obj.(*v1.Node) // We can get DeletedFinalStateUnknown instead of *v1.Node here and we need to handle that correctly. #34692 if !isNode {deletedState, ok := obj.(cache.DeletedFinalStateUnknown) if !ok {glog.Errorf( Received unexpected object: %v , obj) return node, ok = deletedState.Obj.(*v1.Node) if !ok {glog.Errorf( DeletedFinalStateUnknown contained non-Node object: %v , deletedState.Obj) return if nc.taintManager != nil {nc.taintManager.NodeUpdated(node, nil) //  注冊 NoExecuteTaintManager 為 taintManager。if nc.runTaintManager {nc.taintManager = NewNoExecuteTaintManager(kubeClient) nodeInformer.Informer().AddEventHandler(nodeEventHandlerFuncs) nc.nodeLister = nodeInformer.Lister() // returns true if the shared informer s nodeStore has synced. nc.nodeInformerSynced = nodeInformer.Informer().HasSynced // returns true if the shared informer s daemonSetStore has synced. nc.daemonSetStore = daemonSetInformer.Lister() nc.daemonSetInformerSynced = daemonSetInformer.Informer().HasSynced return nc, nil

因此,創建 NodeController 實例時,主要進行了如下工作:

maximumGracePeriod – The maximum duration before a pod evicted from a node can be forcefully terminated. 不可配置,代碼中寫死為 5min。

注冊 enterPartialDisruptionFunc 函數為 ReducedQPSFunc,當 zone state 為 PartialDisruption 時,將 invoke ReducedQPSFunc 來 setLimiterInZone。

注冊 enterFullDisruptionFunc 函數為 HealthyQPSFunc,當 zone state 為 FullDisruption 時,將 invoke HealthyQPSFunc 來 setLimiterInZone。

注冊 computeZoneStateFunc 函數為 ComputeZoneState,當 handleDisruption 時,將 invoke ComputeZoneState 來計算集群中 unhealthy node number 及 zone state。

注冊 **PodInformer** 的 Event Handler:Add,Update,Delete。

對于 Pod Add 和 Update Event,都會去判斷 Node 上 kubelet version,如果 version 低于 1.1.0,則會通過 forcefullyDeletePod 直接調用 apiserver 接口刪除 etcd 中該 Pod object。

對于 Pod Add, Update, Delete Event,如果啟動了 TaintManager,則會對比 OldPod 和 newPod 的 Tolerations 信息,如果不相同,則會將該 Pod 的變更信息 Add 到 NoExecuteTaintManager 的 **podUpdateQueue** 中,交給 Taint Controller 處理。只不過對于 Delete Event,newPod 為 nil。

注冊 PodInformerSynced,用來檢查 the shared informer s Podstore 是否已經 synced.

注冊 **NodeInformer** 的 Event Handler:Add,Update,Delete。

對于 Node Add, Update, Delete Event,如果啟動了 TaintManager,則會對比 OldNode 和 newNode 的 Taints 信息,如果不相同,則會將該 Node 的變更信息 Add 到 NoExecuteTaintManager 的 nodeUpdateQueue 中,交給 Taint Controller 處理。只不過對于 Delete Event,newNode 為 nil。

注冊 NoExecuteTaintManager 為 taintManager。

注冊 NodeInformerSynced,用來檢查 the shared informer s NodeStore 是否已經 synced.

注冊 DaemonSetInformerSynced,用來檢查 the shared informer s DaemonSetStore 是否已經 synced.

關于 ZoneState

上面提到 ZoneState,關于 ZoneState 是怎么來的,見如下代碼:

pkg/api/v1/types.go:3277
const (
 // NodeReady means kubelet is healthy and ready to accept pods.
 NodeReady NodeConditionType =  Ready 
 // NodeOutOfDisk means the kubelet will not accept new pods due to insufficient free disk
 // space on the node.
 NodeOutOfDisk NodeConditionType =  OutOfDisk 
 // NodeMemoryPressure means the kubelet is under pressure due to insufficient available memory.
 NodeMemoryPressure NodeConditionType =  MemoryPressure 
 // NodeDiskPressure means the kubelet is under pressure due to insufficient available disk.
 NodeDiskPressure NodeConditionType =  DiskPressure 
 // NodeNetworkUnavailable means that network for the node is not correctly configured.
 NodeNetworkUnavailable NodeConditionType =  NetworkUnavailable 
 // NodeInodePressure means the kubelet is under pressure due to insufficient available inodes.
 NodeInodePressure NodeConditionType =  InodePressure 

// This function is expected to get a slice of NodeReadyConditions for all Nodes in a given zone. // The zone is considered: // - fullyDisrupted if there re no Ready Nodes, // - partiallyDisrupted if at least than nc.unhealthyZoneThreshold percent of Nodes are not Ready, // - normal otherwise func (nc *NodeController) ComputeZoneState(nodeReadyConditions []*v1.NodeCondition) (int, zoneState) { readyNodes := 0 notReadyNodes := 0 for i := range nodeReadyConditions {if nodeReadyConditions[i] != nil   nodeReadyConditions[i].Status == v1.ConditionTrue {readyNodes++} else { notReadyNodes++ switch { case readyNodes == 0   notReadyNodes   0: return notReadyNodes, stateFullDisruption case notReadyNodes   2   float32(notReadyNodes)/float32(notReadyNodes+readyNodes)  = nc.unhealthyZoneThreshold: return notReadyNodes, statePartialDisruption default: return notReadyNodes, stateNormal }

zone state 共分為如下三種類型:

FullDisruption:Ready 狀態的 Nodes number 為 0,并且 NotReady 狀態的 Nodes number 大于 0。

PartialDisruption:NotReady 狀態的 Nodes number 大于 2,并且 notReadyNodes/(notReadyNodes+readyNodes) = nc.unhealthyZoneThreshold, 其中 nc.unhealthyZoneThreshold 通過 –unhealthy-zone-threshold 設置,默認為 0.55。

Normal:除了以上兩種 zone state,其他都屬于 Normal 狀態。

到此,相信大家對“怎么創建 Node Controller”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-16發表,共計11547字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 错那县| 牙克石市| 嵊泗县| 丰台区| 富蕴县| 墨江| 金塔县| 辽阳县| 高淳县| 工布江达县| 雷州市| 荣成市| 翼城县| 宣恩县| 彭泽县| 丁青县| 桐乡市| 玛纳斯县| 漯河市| 攀枝花市| 调兵山市| 璧山县| 秀山| 玛纳斯县| 正定县| 同江市| 将乐县| 洛宁县| 桓台县| 原阳县| 旌德县| 永康市| 左权县| 昔阳县| 大方县| 蒙城县| 开远市| 河南省| 五大连池市| 永嘉县| 孝昌县|