k8s :kube-apiserver 啟動流程 - 2

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

前言

文章字數一多,線上編輯不方便,本文是 k8s:kube-apiserver 啟動流程的第2部分
傳送門:k8s :kube-apiserver 啟動流程 - 1

回顧

上回講到 Run 方法:

// kubernetes/cmd/kube-apiserver/app.server.gofunc Run(runOptions *options.ServerRunOptions, stopCh <-chan struct{}) error {    ...    server, err := CreateServerChain(runOptions, stopCh)    if err != nil {        return err    }    return server.PrepareRun().Run(stopCh)}

目前系統中有以下 api server:

  • CustomResourceDefinitions
  • Master
  • APIAggregator

每個 api server 都對應一個 Config(配置)

  • apiextensionsapiserver.Config
  • master.Config
  • aggregatorapiserver.Config

CreateServerChain 的任務就是根據 ServerRunOptions 建立 XXXConfig,然後再用 XXXConfig 建立 api server,各個 api server 通過 GenericAPIServer 的 delegationTarget 欄位組成《責任鏈》
以 Master api server 建立為例:

func CreateServerChain(runOptions *options.ServerRunOptions, stopCh <-chan struct{})(*genericapiserver.GenericAPIServer, error) {    ...    kubeAPIServerConfig, ... := CreateKubeAPIServerConfig(...)    ...    kubeAPIServer, err := CreateKubeAPIServer(kubeAPIServerConfig,         apiExtensionsServer.GenericAPIServer, sharedInformers, versionedInformers)    ...} 

下面將簡要介紹 Master api server 的建立過程,主要分析 kube-apiserver 是如何將 資來源物件(Node,Pod,Service 等)綁定到具體的 RESTful API,使得用戶端可以通過 RESTful API 操作資來源物件

如果是你會怎麼做?

在大概看了一些原始碼之後,我不禁問自己:如果是你來設計代碼架構,你會怎麼做?
例如給定一個實體 Student(Java 虛擬碼,下同),持久化在 etcd 裡

public class Student {    public int id;    public String name;    public String phone;}

如何提供 RESTful api 介面提供對 Student 的 CRUD 操作? 設計代碼架構使之適應所有的實體

api 介面樣本:

增加(假定參數都通過 url 傳遞)

PUT /user?id=xxx&name=yyy&phone=zzz

刪除

DELETE /user?id=xxx

修改

POST /user?id=xxx&name=yyy

查詢

GET /user?id=xxx

我們分幾步來考慮,首先考慮持久化,為了支援不同的持久化架構,或者即時我們就使用一種持久化架構也需要考慮架構版本匹配問題,這就需要將對持久化架構的基本操作進行抽象,抽取出介面 Backend

public interface Backend {    String get(String key);    void set(String key, String value);}

然後我們有具體的實作類別 EtcdBackend, ConsulBackend 以及 工廠類 BackendFactory

public class EtcdBackend implements Backend {    public String get(String key) { ... }    public void set(String key, String value) { ... }}public class ConsulBackend implements Backend {    public String get(String key) { ... }    public void set(String key, String value) { ... }}public class BackendFactory {    Backend get(String name) { ... }}

Backend 搞定了,現在我們需要一個 DAO(Data access object)來訪問它

public class UserDao {    private Backend backend;    // CRUD 方法    ...}

我們注意到會有很多實體,他們都需要使用 Backend 介面訪問後端儲存,所以可以搞個基類 AbstractDao,將 backedn 欄位移到基類裡頭

pubic class AbstractDao {    private Backend backend;}public class User extends AbstractDao {    // CRUD 方法    ...}

進一步觀察,其實各個 DAO 的 CRUD 方法也有很多重複的(模版)代碼,比如如果我們能夠封裝以下變化點:

  • 產生後端儲存需要的key
  • 序列化和還原序列化對象

DAO 中的 CRUD 方法可以進一步抽取到 AbstractDao 中,那些實在需要子類特例化的方法,可以通過《模版方法》模式來實現

public class AbstractDao {    private Backend backend;    // CRUD 方法    ...}public class UserDao extends AbstractDao {    // Template 方法    ...}

我們現在離最後的完工又近了一步,還剩一個問題,就是如何將 url 和 DAO 對應起來,這是一個映射問題,可以使用 map 來保持 url 對應的 DAO

map.put("/user", userDao)

以上只是一個簡單的推導,k8s 的時候比這個 demo 複雜的多,考慮到各種解耦和擴充性,下回將正式介紹 k8s 的實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.