k8s :kube-apiserver RESTful API 实现 - Storage
前言了解 k8s 的同学都知道,kube-apiserver 对外提供 RESTful API 接口提供 查询,监听集群(资源)状态的服务,kube-apiserver 主要就做一件事,就是如何将 RESTful API (CREATE,DELETE,UPDATE,GET .etc)接口调用映射到对后端存储(比如 etcd)的(增删改查)访问,在设计的时候考虑到 k8s 是个快速迭代的开源项目,很多 API 接口(版本)可能在未来版本发生变化,因此如何设计一个扩展性强,耦合度低的架构应该是 Google 那帮货当初主要考虑的问题,所以才导致 kube-apiserver 本来相比 kube-scheduler 和 kube-controller-manager 应该简单的代码设计的巨复杂(个人观点)~ 从 kube-apiserver 收到 RESTful API 请求到从 后端存储中获取(更新 .etc)到数据大概需要经过一下几层(非官方命名),各层之间通过 《接口》 交互(解偶) RESTful API 比如 Storage 和 Storage Backend 之间通过 Storage Backend Interface(参考k8s :kube-apiserver 访问 etcd 后端存储 )交互,Storage 和 RESTful API 之间通过 REST Operation Interface(增删改查 方法的封装)交互 StorageStorage is a generic interface for RESTful storage services. // kubernetes/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go type Storage interface { New() runtime.Object } REST Operation InterfaceStandardStorage is an interface covering the common verbs. Provided for testing whether a resource satisfies the normal storage methods. type StandardStorage interface { Getter Lister GreaterUpdater GracefulDeleter CollectionDeleter Watcher } StandardStorage 聚合了可以对 Storage 施加的操作(或者叫 Verb,动作),RESTful API根据该(子)接口测试 Storage 是否支持相关操作,然后注册相应的 API 接口,比如如果 Storage 支持 Delete 接口,就注册一个 HTTP method 为 DELETE 的方法到相应的资源路径 Storage 实现类kubernetes/pkg/registry/core 目录下包含了各种 Storage 实现类,比如大家耳熟能详的 pod,service,endpoint,configmap,node 等等,各个资源的目录结构很相似,以 pod 为例 kubernetes/pkg/registry/core/pod rest storage storage.go <- Storage 实现 doc.go strategy.go strategy_test.go PodStorage我们以 pod storage 为例来分析 storage 创建,首先是 pod storage 定义 type PodStorage struct { Pod *REST Binding *BindingREST Eviction *EvictionREST Status *StatusREST Log *podrest.LogREST Proxy *podrest.ProxyREST Exec *podrest.ExecREST Attach *podrest.AttachREST PortForward *podrest.PortForwardREST } 这里又冒出一些新的类型 REST,BindingREST .etc,这些 XXXREST 才是"真正"的 Storage,对应具体的 RESTful endpoint // REST implements a RESTStorage for pods type REST struct { *genericregistry.Store proxyTransport http.RoundTripper } // BindingREST implements the REST endpoint for binding pods to nodes when etcd is in use type BindingREST struct { store *genericregistry.Store } XXXREST 类类包含一个 genericregistry.Store 类型的字段,我们在k8s :kube-apiserver 访问 etcd 后端存储中分析过,它用于访问后端存储 PodStorage 通过 NewStorage 方法创建,各个 XXXREST 共享 Store func NewStorage(optsGetter generic.RESTOptionsGetter,...) { 创建 genericregistry.Store store := &genericregistry.Store { ... } ... return PodStorage { Pod: &REST{store,proxyTransport},Binding: &BindingREST{store: store} ... } } Storage 注册Storage 是如何"绑定"到 api 接口呢?这中间还涉及到一些数据结构(类),这里先列出绑定相关的代码: // kubernetes/pkg/registry/core/rest/storage_core.go func (c LegacyRESTStorageProvider) NewLegacyRESTStorage(...) { ... restStorageMap := map[string]rest.Storage { "pods": podStorage.Pod,"pods/attach": podStorage.Attach ... } } 后续再详细分析 总结本文介绍了 kube-apiserver 中 Storage 相关的一些概念,希望对大家阅读 k8s 源代码有所帮助 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |