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 应该简单的代码设计的巨复杂(我的观点)~node

从 kube-apiserver 收到 RESTful API 请求到从 后端存储中获取(更新 .etc)到数据大概须要通过一下几层(非官方命名),各层之间经过 《接口》 交互(解偶)segmentfault

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(增删改查 方法的封装)交互api

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 的方法到相应的资源路径ide

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 定义this

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

相关文章
相关标签/搜索