真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

KubernetesPodGCController怎么配置

本篇內(nèi)容介紹了“Kubernetes PodGC Controller怎么配置”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)建站是一家專(zhuān)注于成都做網(wǎng)站、成都網(wǎng)站制作和德陽(yáng)服務(wù)器托管的網(wǎng)絡(luò)公司,有著豐富的建站經(jīng)驗(yàn)和案例。

PodGC Controller配置

關(guān)于PodGC Controller的相關(guān)配置(kube-controller-manager配置),一共只有兩個(gè):

flagdefault valuecomments
--controllers stringSlice*這里配置需要enable的controlllers列表,podgc當(dāng)然也可以在這里設(shè)置是都要enable or disable,默認(rèn)podgc是在enable列表中的。
--terminated-pod-gc-threshold int3212500Number of terminated pods that can exist before the terminated pod garbage collector starts deleting terminated pods. If <= 0, the terminated pod garbage collector is disabled. (default 12500)

PodGC Controller入口

PodGC Controller是在kube-controller-manager Run的時(shí)候啟動(dòng)的。CMServer Run時(shí)會(huì)invoke StartControllers將預(yù)先注冊(cè)的enabled Controllers遍歷并逐個(gè)啟動(dòng)。

cmd/kube-controller-manager/app/controllermanager.go:180

func Run(s *options.CMServer) error {
   ...
	err := StartControllers(newControllerInitializers(), s, rootClientBuilder, clientBuilder, stop)
	...
}

在newControllerInitializers注冊(cè)了所有一些常規(guī)Controllers及其對(duì)應(yīng)的start方法,為什么說(shuō)這些是常規(guī)的Controllers呢,因?yàn)檫€有一部分Controllers沒(méi)在這里進(jìn)行注冊(cè),比如非常重要的service Controller,node Controller等,我把這些稱(chēng)為非常規(guī)Controllers

func newControllerInitializers() map[string]InitFunc {
	controllers := map[string]InitFunc{}
	controllers["endpoint"] = startEndpointController
	...
	controllers["podgc"] = startPodGCController
	...

	return controllers
}

因此CMServer最終是invoke startPodGCController來(lái)啟動(dòng)PodGC Controller的。

cmd/kube-controller-manager/app/core.go:66

func startPodGCController(ctx ControllerContext) (bool, error) {
	go podgc.NewPodGC(
		ctx.ClientBuilder.ClientOrDie("pod-garbage-collector"),
		ctx.InformerFactory.Core().V1().Pods(),
		int(ctx.Options.TerminatedPodGCThreshold),
	).Run(ctx.Stop)
	return true, nil
}

startPodGCController內(nèi)容很簡(jiǎn)單,啟動(dòng)一個(gè)goruntine協(xié)程,創(chuàng)建PodGC并啟動(dòng)執(zhí)行。

PodGC Controller的創(chuàng)建

我們先來(lái)看看PodGCController的定義。

pkg/controller/podgc/gc_controller.go:44

type PodGCController struct {
	kubeClient clientset.Interface

	podLister       corelisters.PodLister
	podListerSynced cache.InformerSynced

	deletePod              func(namespace, name string) error
	terminatedPodThreshold int
}
  • kubeClient: 用來(lái)跟APIServer通信的client。

  • PodLister: PodLister helps list Pods.

  • podListerSynced: 用來(lái)判斷PodLister是否Has Synced。

  • deletePod: 調(diào)用apiserver刪除對(duì)應(yīng)pod的接口。

  • terminatedPodThreshold: 對(duì)應(yīng)--terminated-pod-gc-threshold的配置,默認(rèn)為12500。

pkg/controller/podgc/gc_controller.go:54

func NewPodGC(kubeClient clientset.Interface, podInformer coreinformers.PodInformer, terminatedPodThreshold int) *PodGCController {
	if kubeClient != nil && kubeClient.Core().RESTClient().GetRateLimiter() != nil {
		metrics.RegisterMetricAndTrackRateLimiterUsage("gc_controller", kubeClient.Core().RESTClient().GetRateLimiter())
	}
	gcc := &PodGCController{
		kubeClient:             kubeClient,
		terminatedPodThreshold: terminatedPodThreshold,
		deletePod: func(namespace, name string) error {
			glog.Infof("PodGC is force deleting Pod: %v:%v", namespace, name)
			return kubeClient.Core().Pods(namespace).Delete(name, metav1.NewDeleteOptions(0))
		},
	}

	gcc.podLister = podInformer.Lister()
	gcc.podListerSynced = podInformer.Informer().HasSynced

	return gcc
}

創(chuàng)建PodGC Controller時(shí)其實(shí)只是把相關(guān)的PodGCController元素進(jìn)行賦值。注意deletePod方法定義時(shí)的參數(shù)metav1.NewDeleteOptions(0),表示立即刪除pod,沒(méi)有g(shù)race period。

PodGC Controller的運(yùn)行

創(chuàng)建完P(guān)odGC Controller后,接下來(lái)就是執(zhí)行Run方法啟動(dòng)執(zhí)行了。

pkg/controller/podgc/gc_controller.go:73

func (gcc *PodGCController) Run(stop <-chan struct{}) {
	if !cache.WaitForCacheSync(stop, gcc.podListerSynced) {
		utilruntime.HandleError(fmt.Errorf("timed out waiting for caches to sync"))
		return
	}

	go wait.Until(gcc.gc, gcCheckPeriod, stop)
	<-stop
}
  • 每100ms都會(huì)去檢查對(duì)應(yīng)的PodLister是否Has Synced,直到Has Synced。

  • 啟動(dòng)goruntine協(xié)程,每執(zhí)行完一次gcc.gc進(jìn)行Pod回收后,等待20s,再次執(zhí)行g(shù)cc.gc,直到收到stop信號(hào)。

pkg/controller/podgc/gc_controller.go:83

func (gcc *PodGCController) gc() {
	pods, err := gcc.podLister.List(labels.Everything())
	if err != nil {
		glog.Errorf("Error while listing all Pods: %v", err)
		return
	}
	if gcc.terminatedPodThreshold > 0 {
		gcc.gcTerminated(pods)
	}
	gcc.gcOrphaned(pods)
	gcc.gcUnscheduledTerminating(pods)
}

gcc.gc是最終的pod回收邏輯:

  • 調(diào)從PodLister中去除所有的pods(不設(shè)置過(guò)濾)

  • 如果terminatedPodThreshold大于0,則調(diào)用gcc.gcTerminated(pods)回收那些超出Threshold的Pods。

  • 調(diào)用gcc.gcOrphaned(pods)回收Orphaned pods。

  • 調(diào)用gcc.gcUnscheduledTerminating(pods)回收UnscheduledTerminating pods。

注意:

  1. gcTerminated和gcOrphaned,gcUnscheduledTerminating這三個(gè)gc都是串行執(zhí)行的。

  2. gcTerminated刪除超出閾值的pods的刪除動(dòng)作是并行的,通過(guò)sync.WaitGroup等待所有對(duì)應(yīng)的pods刪除完成后,gcTerminated才會(huì)結(jié)束返回,才能開(kāi)始后面的gcOrphaned.

  3. gcOrphaned,gcUnscheduledTerminatin,gcUnscheduledTerminatin內(nèi)部都是串行g(shù)c pods的。

回收那些Terminated的pods

func (gcc *PodGCController) gcTerminated(pods []*v1.Pod) {
	terminatedPods := []*v1.Pod{}
	for _, pod := range pods {
		if isPodTerminated(pod) {
			terminatedPods = append(terminatedPods, pod)
		}
	}

	terminatedPodCount := len(terminatedPods)
	sort.Sort(byCreationTimestamp(terminatedPods))

	deleteCount := terminatedPodCount - gcc.terminatedPodThreshold

	if deleteCount > terminatedPodCount {
		deleteCount = terminatedPodCount
	}
	if deleteCount > 0 {
		glog.Infof("garbage collecting %v pods", deleteCount)
	}

	var wait sync.WaitGroup
	for i := 0; i < deleteCount; i++ {
		wait.Add(1)
		go func(namespace string, name string) {
			defer wait.Done()
			if err := gcc.deletePod(namespace, name); err != nil {
				// ignore not founds
				defer utilruntime.HandleError(err)
			}
		}(terminatedPods[i].Namespace, terminatedPods[i].Name)
	}
	wait.Wait()
}
  • 遍歷所有pods,過(guò)濾出所有Terminated Pods(Pod.Status.Phase不為Pending, Running, Unknow的Pods).

  • 計(jì)算terminated pods數(shù)與terminatedPodThreshold的(超出)差值deleteCount。

  • 啟動(dòng)deleteCount數(shù)量的goruntine協(xié)程,并行調(diào)用gcc.deletePod(invoke apiserver's api)方法立刻刪除對(duì)應(yīng)的pod。

回收那些Binded的Nodes已經(jīng)不存在的pods

// gcOrphaned deletes pods that are bound to nodes that don't exist.
func (gcc *PodGCController) gcOrphaned(pods []*v1.Pod) {
	glog.V(4).Infof("GC'ing orphaned")
	// We want to get list of Nodes from the etcd, to make sure that it's as fresh as possible.
	nodes, err := gcc.kubeClient.Core().Nodes().List(metav1.ListOptions{})
	if err != nil {
		return
	}
	nodeNames := sets.NewString()
	for i := range nodes.Items {
		nodeNames.Insert(nodes.Items[i].Name)
	}

	for _, pod := range pods {
		if pod.Spec.NodeName == "" {
			continue
		}
		if nodeNames.Has(pod.Spec.NodeName) {
			continue
		}
		glog.V(2).Infof("Found orphaned Pod %v assigned to the Node %v. Deleting.", pod.Name, pod.Spec.NodeName)
		if err := gcc.deletePod(pod.Namespace, pod.Name); err != nil {
			utilruntime.HandleError(err)
		} else {
			glog.V(0).Infof("Forced deletion of orphaned Pod %s succeeded", pod.Name)
		}
	}
}

gcOrphaned用來(lái)刪除那些bind的node已經(jīng)不存在的pods。

  • 調(diào)用apiserver接口,獲取所有的Nodes。

  • 遍歷所有pods,如果pod bind的NodeName不為空且不包含在剛剛獲取的所有Nodes中,則串行逐個(gè)調(diào)用gcc.deletePod刪除對(duì)應(yīng)的pod。

回收Unscheduled并且Terminating的pods

pkg/controller/podgc/gc_controller.go:167

// gcUnscheduledTerminating deletes pods that are terminating and haven't been scheduled to a particular node.
func (gcc *PodGCController) gcUnscheduledTerminating(pods []*v1.Pod) {
	glog.V(4).Infof("GC'ing unscheduled pods which are terminating.")

	for _, pod := range pods {
		if pod.DeletionTimestamp == nil || len(pod.Spec.NodeName) > 0 {
			continue
		}

		glog.V(2).Infof("Found unscheduled terminating Pod %v not assigned to any Node. Deleting.", pod.Name)
		if err := gcc.deletePod(pod.Namespace, pod.Name); err != nil {
			utilruntime.HandleError(err)
		} else {
			glog.V(0).Infof("Forced deletion of unscheduled terminating Pod %s succeeded", pod.Name)
		}
	}
}

gcUnscheduledTerminating刪除那些terminating并且還沒(méi)調(diào)度到某個(gè)node的pods。

  • 遍歷所有pods,過(guò)濾那些terminating(pod.DeletionTimestamp != nil)并且未調(diào)度成功的(pod.Spec.NodeName為空)的pods。

  • 串行逐個(gè)調(diào)用gcc.deletePod刪除對(duì)應(yīng)的pod。

“Kubernetes PodGC Controller怎么配置”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!


分享文章:KubernetesPodGCController怎么配置
文章轉(zhuǎn)載:http://weahome.cn/article/pdehco.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部