【APIServer】APIServer 资源序列化问题

Posted by Hao Liang's Blog on Sunday, May 15, 2022

1、相关背景

最近在开发 AA(aggregation apiserver) 时,client-go 连接 AA 时出现了序列化报错:

img.png

object xxx does not implement the protobuf marchalling interface and cannot be encoded to a protobuf message

翻源码,发现是一个客户端请求 AA 时,AA 的 Codec 编解码器使用 protobufSerializer 序列化器做序列化时的报错:

// AA 使用的是 kube-apiserver 的 Codec
// staging/src/k8s.io/apimachinery/pkg/runtime/serializer/protobuf/protobuf.go
type errNotMarshalable struct {
	t reflect.Type
}

func (e errNotMarshalable) Error() string {
	return fmt.Sprintf("object %v does not implement the protobuf marshalling interface and cannot be encoded to a protobuf message", e.t)
}

2、Codec 编解码器和 Serializer

  • Serializer:序列化和反序列化器。序列化就是将各种数据结构转换成字符串的过程,方便存储在底层数据库中。反序列化则是将字符串转成数据结构的过程,方便用户获取数据。
  • Codec:编解码器,表示任何数据从 A 格式转换成 B 格式的过程,Serializer 为 Codec 的一种实现。

Codec

Codec 接口:

// staging/src/k8s.io/apimachinery/pkg/runtime/interfaces.go

// Encoder writes objects to a serialized form
type Encoder interface {
    // Encode writes an object to a stream. Implementations may return errors if the versions are
    // incompatible, or if no conversion is defined.
    Encode(obj Object, w io.Writer) error

    Identifier() Identifier
}
// Decoder attempts to load an object from data.
type Decoder interface {
	Decode(data []byte, defaults *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error)
}

// Serializer is the core interface for transforming objects into a serialized format and back.
// Implementations may choose to perform conversion of the object, but no assumptions should be made.
type Serializer interface {
	Encoder
	Decoder
}

// Codec is a Serializer that deals with the details of versioning objects. It offers the same
// interface as Serializer, so this is a marker to consumers that care about the version of the objects
// they receive.
type Codec Serializer

Serializer

jsonSerializer yamlSerializer protobufSerializer

3、client-go 客户端的序列化选项(content-type)

4、kube-apiserver 连接 etcd 客户端的序列化选项(storage-media-type)

5、k8s 资源对象的默认序列化方式