我们平常用惯了 k8s 提供的 sdk, 却很少了解 k8s 是如何存储我们提交给它的资源配置的;
其实 k8s 充分运用了 etcd 的前缀查询能力, 以前缀对齐匹配的模式存储 / 查询不同类型的 k8s 资源;

Key 的存储

Kubernetes 将所有资源 (如 Pod、Service、Ingress 等) 以 Key-Value 的形式存储在 etcd 中;
除了特殊的 minions、ranges 之外, 其余资源存储的 Key 结构如下:

1
/registry/<资源类型>/<命名空间>/<资源名称>

  • /registry: Kubernetes 资源的根路径;
  • <资源类型>: 资源类型的复数形式, 例如 ingressespodsservicesranges 等;
  • <命名空间>: 资源所属的命名空间 (Namespace), 如果是集群级别的资源 (如 Node), 则省略命名空间部分;
  • <资源名称>: 资源的名称;

特殊场景

  • minions 是 node 信息, Kubernetes 之前节点叫 minion, 没有改过来, 因此依然使用: /registry/minions;
  • ranges 对应 Service 网段以及 NodePort 端口范围:
    1
    2
    3
    > ./etcd_ls.sh /registry/ranges
    /registry/ranges/serviceips
    /registry/ranges/servicenodeports
1
2
3
4
> ./etcd_ls.sh /registry/ranges/servicenodeports | strings
/registry/ranges/servicenodeports
RangeAllocation
30000-32767
1
2
3
4
> ./etcd_ls.sh /registry/ranges/serviceips | strings
/registry/ranges/serviceips
RangeAllocation
10.96.0.0/12

典型示例

假设有一个 Ingress 资源:

  • namespace: alibaba-tao
  • name: tao-acs-m-taobao-com

那么它在 etcd 中的存储 Key 为:

1
/registry/ingresses/alibaba-tao/tao-acs-m-taobao-com

Value 的存储

etcd 中存储的 Value 是资源的 序列化 JSON 或 Protobuf 数据:

  • /registry/apiregistration.k8s.io: 直接存储 JSON 格式;
    • API Registration‌是 Kubernetes 中用于注册和管理自定义资源定义 (Custom Resource Definitions, CRDs) 的一种机制;
  • 其余资源: 默认存储 Protobuf 格式, 以提升性能;

如想改变默认存储格式:

1
--storage-media-type=application/json

参考资料