一、需求分析
- 在使用client-go创建应用的时候,需要用到资源分配,且需要对资源进行切分,并自动适配单位
- 对于BinarySI,例如1Gi/2 = 512Mi
- 对于DecimalSI,例如100m/10 = 10m, 1/10 = 100m, 100/10 = 10
二、代码实现
- 代码比较简单,但我自认为对于这个功能的实现还算全面
- 如果直接利用resouce包的ParseQuantity结构体进行资源划分,会存在一些问题
- 如BinarySI和DecimalSI的处理方法不一致,所以需要先判断Format
- 在对1Gi,1Mi等资源分割时,无法适配单位,所以通过计算byte,再利用switch进行单位适配
- k8s资源需要使用整数,故将匹配单位转换为其对应的下一级单位,减少精度损失
- 代码如下
import (
"errors"
"fmt"
"k8s.io/apimachinery/pkg/api/resource"
)
// SplitRSC 将资源除以n,用作request
func SplitRSC(rsc string, n int) (string, error) {
quantity, err := resource.ParseQuantity(rsc)
if err != nil {
return "", errors.New("failed to parse resource quantity: " + err.Error())
}
// 获取该资源的数量单位
unit := quantity.Format
// 如果是十进制,即cpu的单位
if unit == resource.DecimalSI {
quantity.SetMilli(quantity.MilliValue() / int64(n))
return quantity.String(), nil
} else {
// 将该资源的数量转化为字节数
bytes := quantity.Value()
// 将字节数除以n
bytesPerPart := bytes / int64(n)
// 将结果转换为适当的单位
var result string
switch {
case bytesPerPart >= 1<<60:
// 保留到整数位,故将单位转换到下一级单位,
result = fmt.Sprintf("%.0fPi", float64(bytesPerPart)/(1<<50))
case bytesPerPart >= 1<<50:
result = fmt.Sprintf("%.0fTi", float64(bytesPerPart)/(1<<40))
case bytesPerPart >= 1<<40:
result = fmt.Sprintf("%.0fGi", float64(bytesPerPart)/(1<<30))
case bytesPerPart >= 1<<30:
result = fmt.Sprintf("%.0fMi", float64(bytesPerPart)/(1<<20))
case bytesPerPart >= 1<<20:
result = fmt.Sprintf("%.0fKi", float64(bytesPerPart)/(1<<10))
default:
quantity.Set(bytesPerPart)
result = quantity.String()
}
return result, nil
}
}
三、项目地址
Kube-CC:基于K8S的轻量化大数据课程实验教学平台构建