Convert资源版本转换器

Kubernetes允许同一资源的不同版本进行准换,进行转换之前,需要查看资源对象支持的资源组和资源版本:

  1. $ kubectl version
  2. Client Version: version.Info{
  3. Major:"1",
  4. Minor:"16+",
  5. GitVersion:"v1.16.6-beta.0",
  6. GitCommit:"e7f962ba86f4ce7033828210ca3556393c377bcc",
  7. GitTreeState:"clean",
  8. BuildDate:"2020-01-15T08:26:26Z",
  9. GoVersion:"go1.13.5",
  10. Compiler:"gc",
  11. Platform:"darwin/amd64"
  12. }
  13. Server Version: version.Info{
  14. Major:"1",
  15. Minor:"19",
  16. GitVersion:"v1.19.2",
  17. GitCommit:"f5743093fd1c663cb0cbc89748f730662345d44d",
  18. GitTreeState:"clean",
  19. BuildDate:"2020-09-16T13:32:58Z",
  20. GoVersion:"go1.15",
  21. Compiler:"gc",
  22. Platform:"linux/amd64"
  23. }
  24. $ kubectl api-versions | grep autoscaling
  25. autoscaling/v1
  26. autoscaling/v2beta1
  27. autoscaling/v2beta2
  28. $ kubectl api-resources --api-group=autoscaling
  29. NAME SHORTNAMES APIGROUP NAMESPACED KIND
  30. horizontalpodautoscalers hpa autoscaling true HorizontalPodAutoscaler

通过kubectl version、kubectl api-versions、kubectl api-resources查看当前版本Kubernetes集群中的autoscaling资源组下的资源版本,以及Kind。可以发现v1.19.2集群中的autoscaling资源组有三个资源版本,分别为v1/v2beta1/v2beta2。并且autoscaling资源组下拥有HorizontalPodAutoscaler资源对象。
比如将对象HorizontalPodAutoscaler版本的v1转换为v2beta1:

  1. # v1版本的HPA
  2. apiVersion: autoscaling/v1
  3. kind: HorizontalPodAutoscaler
  4. metadata:
  5. labels:
  6. hpa: my-temp-hpa
  7. name: my-temp-hpa
  8. spec:
  9. maxReplicas: 10
  10. minReplicas: 1
  11. scaleTargetRef:
  12. apiVersion: apps/v1
  13. kind: Deployment
  14. name: my-temp
  15. targetCPUUtilizationPercentage: 20

通过一下命令将其转换为v2beta1版本

  1. $ kubectl convert -f hpa_v1_v1beta1.yaml --output-version=autoscaling/v2beta1
  2. kubectl convert is DEPRECATED and will be removed in a future version.
  3. In order to convert, kubectl apply the object to the cluster, then kubectl get at the desired version.
  4. apiVersion: autoscaling/v2beta1
  5. kind: HorizontalPodAutoscaler
  6. metadata:
  7. creationTimestamp: null
  8. labels:
  9. hpa: my-temp-hpa
  10. name: my-temp-hpa
  11. spec:
  12. maxReplicas: 10
  13. metrics:
  14. - resource:
  15. name: cpu
  16. targetAverageUtilization: 20
  17. type: Resource
  18. minReplicas: 1
  19. scaleTargetRef:
  20. apiVersion: apps/v1
  21. kind: Deployment
  22. name: my-temp
  23. status:
  24. conditions: null
  25. currentMetrics: null
  26. currentReplicas: 0
  27. desiredReplicas: 0

为了解决多个版本之间的转换问题,Kubernetes通过内部版本__internal进行多个外部版本之间的转换。

Convert转换器数据结构

Convert转换器数据结构主要存放转换函数(即Conversion Funs)。Convert数据结构如下:
代码路径:vendor/k8s.io/apimachinery/pkg/conversion/convert.go

  1. // Converter knows how to convert one type to another.
  2. type Converter struct {
  3. // Map from the conversion pair to a function which can
  4. // do the conversion.
  5. conversionFuncs ConversionFuncs // 默认的转换函数,一般定义在资源目录下conversion.go中
  6. generatedConversionFuncs ConversionFuncs // 自动生成的转换函数,一般定义在资源目录下zz_generated.conversion.go目录中
  7. // Set of conversions that should be treated as a no-op
  8. ignoredConversions map[typePair]struct{} // 若资源对象注册到此字段,则忽略此资源对象的转换操作
  9. ignoredUntypedConversions map[typePair]struct{}
  10. // nameFunc is called to retrieve the name of a type; this name is used for the
  11. // purpose of deciding whether two types match or not (i.e., will we attempt to
  12. // do a conversion). The default returns the go type name.
  13. // // 在转换过程中获取资源种类的名称,该函数被定义在vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
  14. nameFunc func(t reflect.Type) string
  15. }

Convert转换器数据结构中存放的转换函数(即Conversion Funcs)可以分为两类,分别为默认的转换函数(即ConversionFuncs)字段和自动生成的转换函数(即generatedConversionFuncs)字段。它们都通过ConversionFuncs来管理,代码示例如下:

  1. type ConversionFuncs struct {
  2. untyped map[typePair]ConversionFunc
  3. }
  4. type typePair struct {
  5. source reflect.Type
  6. dest reflect.Type
  7. }
  8. // ConversionFunc converts the object a into the object b, reusing arrays or objects
  9. // or pointers if necessary. It should return an error if the object cannot be converted
  10. // or if some data is invalid. If you do not wish a and b to share fields or nested
  11. // objects, you must copy a before calling this function.
  12. type ConversionFunc func(a, b interface{}, scope Scope) error
  13. // scope contains information about an ongoing conversion.
  14. type scope struct {
  15. converter *Converter
  16. meta *Meta
  17. }

ConversionFunc类型函数(即Type Function)定义了转换函数实现的结构,将资源a转换为资源b。a定义了源资源类型,b定义了目标资源类型。scope定义了多次转换机制(即递归调用转换函数)。

Converter注册转换函数

Converter转换函数需要注册才能在Kubernetes内部使用,Kubernetes支持一下注册函数:
代码路径: vendor/k8s.io/apimachinery/pkg/runtime/scheme.go

  1. // AddIgnoredConversionType identifies a pair of types that should be skipped by
  2. // conversion (because the data inside them is explicitly dropped during
  3. // conversion).
  4. func (s *Scheme) AddIgnoredConversionType(from, to interface{}) error {
  5. return s.converter.RegisterIgnoredConversion(from, to)
  6. }
  7. // AddConversionFunc registers a function that converts between a and b by passing objects of those
  8. // types to the provided function. The function *must* accept objects of a and b - this machinery will not enforce
  9. // any other guarantee.
  10. func (s *Scheme) AddConversionFunc(a, b interface{}, fn conversion.ConversionFunc) error {
  11. return s.converter.RegisterUntypedConversionFunc(a, b, fn)
  12. }
  13. // AddGeneratedConversionFunc registers a function that converts between a and b by passing objects of those
  14. // types to the provided function. The function *must* accept objects of a and b - this machinery will not enforce
  15. // any other guarantee.
  16. func (s *Scheme) AddGeneratedConversionFunc(a, b interface{}, fn conversion.ConversionFunc) error {
  17. return s.converter.RegisterGeneratedUntypedConversionFunc(a, b, fn)
  18. }
  19. // AddFieldLabelConversionFunc adds a conversion function to convert field selectors
  20. // of the given kind from the given version to internal version representation.
  21. func (s *Scheme) AddFieldLabelConversionFunc(gvk schema.GroupVersionKind, conversionFunc FieldLabelConversionFunc) error {
  22. s.fieldLabelConversionFuncs[gvk] = conversionFunc
  23. return nil
  24. }
  • AddIgnoredConversionType:注册忽略的资源类型,不会执行转换操作
  • AddConversionFunc:注册单个ConvertionFunc转换函数
  • AddGeneratedConversionFunc:注册自动生成的转换函数
  • AddFieldLabelConversionFunc:注册字段标签(FieldLabel)的转换函数