Kubernetes的client-go庫介紹

[TOC]html

Kubernetes的client-go庫介紹

client-go的做用

github上client-go官方項目工程node

基本介紹

Kubernetes官方從2016年8月份開始,將Kubernetes資源操做相關的核心源碼抽取出來,獨立出來一個項目Client-go,做爲官方提供的Go client。Kubernetes的部分代碼也是基於這個client實現的,因此對這個client的質量、性能等方面仍是很是有信心的。git

client-go是一個調用kubernetes集羣資源對象API的客戶端,即經過client-go實現對kubernetes集羣中資源對象(包括deployment、service、ingress、replicaSet、pod、namespace、node等)的增刪改查等操做。大部分對kubernetes進行前置API封裝的二次開發都經過client-go這個第三方包來實現。github

源碼簡介

主要package

主要的幾個package包的功能說明:api

  • kubernetes: 訪問 Kubernetes API的一系列的clientset
  • discovery:經過Kubernetes API 進行服務發現
  • dynamic:對任意Kubernetes對象執行通用操做的動態client
  • transport:啓動鏈接和鑑權auth
  • tools/cache:controllers控制器

Client結構

  • RESTClient:RESTClient是最基礎的,至關於的底層基礎結構,能夠直接經過 是RESTClient提供的RESTful方法如Get(),Put(),Post(),Delete()進行交互緩存

    • 同時支持Json 和 protobuf
    • 支持全部原生資源和CRDs
    • 可是,通常而言,爲了更爲優雅的處理,須要進一步封裝,經過Clientset封裝RESTClient,而後再對外提供接口和服務
  • Clientset:Clientset是調用Kubernetes資源對象最經常使用的client,能夠操做全部的資源對象,包含RESTClient。須要指定Group、指定Version,而後根據Resource獲取安全

    • 優雅的姿式是利用一個controller對象,再加上Informer
  • DynamicClient:Dynamic client 是一種動態的 client,它能處理 kubernetes 全部的資源。不一樣於 clientset,dynamic client 返回的對象是一個 map[string]interface{},若是一個 controller 中須要控制全部的 API,可使用dynamic client,目前它在 garbage collector 和 namespace controller中被使用。bash

    • 只支持JSON

RESTClient

RESTClient 封裝了指定資源URL的通用Kubernetes API的訪問姿式微信

Clientset

/Users/meitu/Documents/work_Meitu/goDev/Applications/src/k8s.io/client-go/kubernetes/clientset.gosession

Clientset 是一系列的clients的group組合,注意每一個group在一個Clientset中只包含一個版本。

Clientset包含了appsV一、coreV1,這中間包含了RESTClient,所以Clientset是基於RESTClient的。

dynamic client

dynamic client針對的是全部資源,可是隻支持Json;

主要源碼路徑在:/Users/meitu/Documents/work_Meitu/goDev/Applications/src/k8s.io/client-go/dynamic

type ResourceInterface interface {
	Create(obj *unstructured.Unstructured, options metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error)
	Update(obj *unstructured.Unstructured, options metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error)
	UpdateStatus(obj *unstructured.Unstructured, options metav1.UpdateOptions) (*unstructured.Unstructured, error)
	Delete(name string, options *metav1.DeleteOptions, subresources ...string) error
	DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error
	Get(name string, options metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error)
	List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error)
	Watch(opts metav1.ListOptions) (watch.Interface, error)
	Patch(name string, pt types.PatchType, data []byte, options metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, error)
}
複製代碼

Informer

Client-go包中一個相對較爲高端的設計在於Informer的設計,咱們知道咱們能夠直接經過Kubernetes API交互,可是考慮一點就是交互的形式,Informer設計爲List/Watch的方式。Informer在初始化的時先經過List去從Kubernetes API中取出資源的所有object對象,並同時緩存,而後後面經過Watch的機制去監控資源,這樣的話,經過Informer及其緩存,咱們就能夠直接和Informer交互而不是每次都和Kubernetes API交互。

Informer另一塊內容在於提供了事件handler機制,並會觸發回調,這樣上層應用如Controller就能夠基於回調處理具體業務邏輯。由於Informer經過List、Watch機制能夠監控到全部資源的全部事件,所以只要給Informer添加ResourceEventHandler 實例的回調函數實例取實現OnAdd(obj interface{}) OnUpdate(oldObj, newObj interface{}) 和 OnDelete(obj interface{})這三個方法,就能夠處理好資源的建立、更新和刪除操做

Kubernetes中都是各類controller的實現,各類controller都會用到Informer。

對象資源的操做接口

默認的每一種資源對象都有一個interface,封裝了對象的CURD方法和list/watch方法

如 Deployment(/文件路徑Users/meitu/Documents/work_Meitu/goDev/Applications/src/k8s.io/client-go/kubernetes/typed/apps/v1/deployment.go):

type DeploymentInterface interface {
	Create(*v1.Deployment) (*v1.Deployment, error)
	Update(*v1.Deployment) (*v1.Deployment, error)
	UpdateStatus(*v1.Deployment) (*v1.Deployment, error)
	Delete(name string, options *metav1.DeleteOptions) error
	DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error
	Get(name string, options metav1.GetOptions) (*v1.Deployment, error)
	List(opts metav1.ListOptions) (*v1.DeploymentList, error)
	Watch(opts metav1.ListOptions) (watch.Interface, error)
	Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Deployment, err error)
	DeploymentExpansion
}

複製代碼

如Service(文件路徑/Users/meitu/Documents/work_Meitu/goDev/Applications/src/k8s.io/client-go/kubernetes/typed/core/v1/service.go)

// ServiceInterface has methods to work with Service resources.
type ServiceInterface interface {
	Create(*v1.Service) (*v1.Service, error)
	Update(*v1.Service) (*v1.Service, error)
	UpdateStatus(*v1.Service) (*v1.Service, error)
	Delete(name string, options *metav1.DeleteOptions) error
	Get(name string, options metav1.GetOptions) (*v1.Service, error)
	List(opts metav1.ListOptions) (*v1.ServiceList, error)
	Watch(opts metav1.ListOptions) (watch.Interface, error)
	Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1.Service, err error)
	ServiceExpansion
}

複製代碼

這也就是說明,在Kubernetes中,全部對象資源的操做方式都是統一的,有個interface當作虛基類,包含資源的全部操做方法,而後各個子類繼承而後實現它們,子類中的實現定義會針對不一樣的資源有不一樣詮釋

client-go中的設計思想

client-go 和 controller的架構設計

github上關於client-go的設計有一副概覽圖以下:

evernotecid://5FE43ADA-E2E0-493A-9B2A-64DC8D9CB22F/appyinxiangcom/4068038/ENNote/p2171?hash=6cfd2f55a147ce7733d84bbacda91850

主要是兩大塊:

  • client-go組件自己
  • controller上層控制器

上圖相對較爲複雜,有不少細節,我本身結合源碼的理解以下:

evernotecid://5FE43ADA-E2E0-493A-9B2A-64DC8D9CB22F/appyinxiangcom/4068038/ENResource/p8319

client-go組件

  • Reflector:經過Kubernetes API監控Kubernetes的資源類型

    • 採用List、Watch機制
    • 能夠Watch任何資源包括CRD
    • 添加object對象到FIFO隊列,而後Informer會從隊列裏面取數據
  • Informer:controller機制的基礎

    • 循環處理object對象
      • 從Reflector取出數據,而後將數據給到Indexer去緩存
    • 提供對象事件的handler接口
  • Indexer:提供object對象的索引,是線程安全的,緩存對象信息

controller組件

  • Informer reference: controller須要建立合適的Informer才能經過Informer reference操做資源對象

  • Indexer reference: controller建立Indexer reference而後去利用索引作相關處理

  • Resource Event Handlers:Informer會回調這些handlers

  • Work queue: Resource Event Handlers被回調後將key寫到工做隊列

    • 這裏的key至關於事件通知,後面根據取出事件後,作後續的處理
  • Process Item:從工做隊列中取出key後進行後續處理,具體處理能夠經過Indexer reference

  • controller能夠直接建立上述兩個引用對象去處理,也能夠採用工廠模式,官方都有相關示例

參考

Accessing Kubernetes CRDs from the client-go package

client-go under the hood

Kubernetes Deep Dive: Code Generation for CustomResources

kubernetes client-go

Kubernetes Informer 詳解

如何用 client-go 拓展 Kubernetes 的 API

Using Kubernetes API from Go

【"歡迎關注個人微信公衆號:Linux 服務端系統研發,後面會大力經過微信公衆號發送優質文章"】

個人微信公衆號
相關文章
相關標籤/搜索