为何能解码Kubernetes etcd中protobuf格式的命名空间却不能解码ConfigMap
解码Kubernetes etcd中ConfigMap protobuf数据的问题说明
操作错误原因
- 未添加
--print-value-only参数:etcdctl get指定-w protobuf输出格式时,默认返回的是etcd的完整RangeResponse protobuf结构,包含响应头、键名、元数据等额外字段,并非直接返回etcd中存储的Kubernetes资源序列化数据。小型资源如Namespace的结构刚好能被protoc --decode_raw兼容识别,但字段更复杂的ConfigMap会直接解析失败。 - 未考虑ConfigMap的压缩存储特性:Kubernetes kube-apiserver默认开启etcd存储压缩功能,ConfigMap属于默认开启压缩的资源类型,当序列化后的资源大小超过阈值时,会被gzip压缩后再写入etcd,压缩后的二进制数据无法直接被protoc解析。
ConfigMap与其他Kubernetes资源的存储差异
Kubernetes针对大体积高频访问的资源设计了单独的压缩策略,默认会对ConfigMap、Secret、ControllerRevision、自定义资源定义(CRD)四类资源触发自动压缩,其他资源如Namespace、Deployment、Node等默认不开启压缩,所以后者可以直接提取后解码。
正确解码步骤
- 仅提取etcd中存储的资源原始值,过滤etcd响应结构的额外内容:
etcdctl get /registry/configmaps/kube-system/coredns -w protobuf --print-value-only > cm_raw.bin
- 校验数据是否为gzip压缩格式,如是先解压:
# 检测格式 file cm_raw.bin # 若输出包含gzip相关标识,执行解压 gzip -d cm_raw.bin -c > cm_uncompressed.bin
- 执行protobuf解码:
# 解码为raw结构 cat cm_uncompressed.bin | protoc --decode_raw # 如需解码为标准ConfigMap结构,可指定Kubernetes官方proto定义 # protoc --decode=k8s.io.api.core.v1.ConfigMap -I <K8s proto文件根目录> cm_uncompressed.bin
内容的提问来源于stack exchange,提问作者Tim Stoop
相关产品推荐
相关产品推荐

