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 源代碼有所幫助

相關文章
相關標籤/搜索