紫色飛豬的研發之旅(十)-容器平臺工作負載的擴縮容/啓/停/重啓開發

前言

在研發之旅的不斷深入中,愈發感到在接到需求後,畫出實現的邏輯圖是十分必要的。本篇將試圖通過對容器平臺工作負載的擴縮容/啓動/停止/重啓需求來驗證前面一句。

需求分析

本需求可分爲兩大類:

1、擴縮容/啓動/停止 本質是對Pod的副本數的變更操作
2、重啓 本質是對 ReplicaSet的變更操作,不涉及更改Pod副本數

對於第一類還可以細分爲兩類:

1、擴縮容 需要計算該工作負載的請求計算型資源(CPU&MEMORY)的總和,集羣的剩餘計算型資源(CPU&MEMORY),得出可擴容的最大數,然後再進行擴容。應該需要清晰的時,即使無法得出可擴容的最大數,依然不影響進行擴容操作
2、停止/啓動 也就是將副本數縮小爲0和恢復至期望副本數

邏輯圖

根據上述需求分析,可得出一下邏輯圖:

上圖其實不具備過多可道之處,1、生成k8s client 2、查詢集羣節點是否允許調度 3、查工作負載的請求資源 4、查節點的剩餘資源(依賴metrics-server) 5、分別計算出cpu可調度數和memory可調度數,取最小數 6、擴縮容

上圖需要主要重啓時應做到優雅,無中斷

核心代碼

調度:

// 獲取可調度節點
dbNodes, rows := w.nodeDao.FindList(map[string]interface{}{"cluster_name": w.clusterManager.ClusterName, "schedulable": 1})
	if rows == 0 {
		return nil, errors.New("err: There are currently no schedulable nodes in the cluster")
	}
// 獲取工作負載的請求資源
	WorkloadRep , err :=  w.cli.FindOne(namespace,name)
	if err != nil {
		return nil,err
	}
	var useMemValue,useCPUValue,useCPU,useMemory ,totalCPU,totalMem float64
	var schedulerNumber int
	for _, container := range WorkloadRep.Containers {
		useMemValue += tool.CpuAndMem(container.Resources.Requests.Memory().String(), string(container.Resources.Requests.Memory().Format), string(container.Resources.Requests.Memory().Value()))
		useCPUValue += tool.CpuAndMem(container.Resources.Requests.Cpu().String(), string(container.Resources.Requests.Cpu().Format), string(container.Resources.Requests.Cpu().Value()))
	}
// 獲取集羣可調度節點剩餘資源
	for _, dbNode := range dbNodes{
		totalCPU  += dbNode.TotalCPU
		totalMem += dbNode.TotalMemory
		metricsNode, err := w.nodeKubernetes.MetricsNode(w.clusterManager.Metrics,dbNode.NodeName)
		if err == nil {
			useCPU = tool.CPUAndMemStringToFloat64(metricsNode.Usage.Cpu().String())
			useMemory = tool.CPUAndMemStringToFloat64(metricsNode.Usage.Memory().String())
		} else {
			continue
		}
	}
	if useCPU == 0 || useMemory == 0 {
		return nil, errors.New("err: metrics-server error")
	}
// 計算可調度數
	schedulerNumberCpu := (totalCPU * 1000- useCPU ) / useCPUValue
	schedulerNumberMem := (totalMem * 1024 - useMemory  ) / useMemValue
	if schedulerNumberCpu > schedulerNumberMem {
		schedulerNumber = int(schedulerNumberMem)
	} else {
		schedulerNumber = int(schedulerNumberCpu)
	}
	return schedulerNumber, err

重啓

// 生成k8s client
clusterManager, err := buildKubernetesClient(c)
	if err != nil {
		ErrorResponse(c, ecode.KubernetesBuildClientFail, "err :buildKubernetesClient failed")
		return
	}
	namespace := c.Params.ByName("ns")
	kind := c.Params.ByName("kind")
	kind = tool.FirstUpper(kind)
	name := c.Params.ByName("name")
// 更改annotations 重啓時間
	patchdata := map[string]interface{}{
		"spec": map[string]interface{}{
			"template": map[string]interface{}{
				"metadata": map[string]interface{}{
					"annotations": map[string]interface{}{
						"restartTime": time.Now().Format(time.Stamp),
					},
				},
			},
		},
	}
	body , _ := json.Marshal(patchdata)
	if data, err := service.NewWorkloadService(clusterManager, kind).Patch(namespace, name,body); err != nil {
		ErrorResponse(c, ecode.PatchLabelFail, err.Error())
	} else {
		SuccessResponse(c, data)
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章