k8s :kube-apiserver RESTful API 实现 - Storage

xingpingz · · 1536 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

前言

了解 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
||
<REST Operation Interface>
||
Storage
||
<Storage Backend Interface>
||
Sotrage Backend(etcd2,etcd3)

比如 Storage 和 Storage Backend 之间通过 Storage Backend Interface(参考k8s :kube-apiserver 访问 etcd 后端存储 )交互,Storage 和 RESTful API 之间通过 REST Operation Interface(增删改查 方法的封装)交互

Storage

Storage is a generic interface for RESTful storage services.
Resources which are exported to the RESTful API of apiserver need to implement this interface(原文注释,下同)
It is expected that objects may implement any of the below interfaces
所有想通过 RESTful API 暴露出去的资源都必须实现 Storage 接口,Storage 接口是个最小接口(单一职责),资源类可以根据自身情况实现其它各种接口

// kubernetes/staging/src/k8s.io/apiserver/pkg/registry/rest/rest.go
type Storage interface {
    New() runtime.Object
}

REST Operation Interface

StandardStorage is an interface covering the common verbs. Provided for testing whether a resource satisfies the normal storage methods.
Use Storage when passing opaque storage objects
StandardStorage

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 源代码有所帮助


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:xingpingz

查看原文:k8s :kube-apiserver RESTful API 实现 - Storage

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1536 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传