1、相关背景
最近在开发 AA(aggregation apiserver) 时,client-go 连接 AA 时出现了序列化报错:
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