Kubernetes client-go實戰應用
[TOC]
Kubernetes client-go實戰應用
實戰應用
-
官方的一個簡單的Controller示例,可以處理任何CRD資源
The main.go and controller.go contains the sample code to watch for the CRD and do some task accordingly.
採用code-generator 的方式
一個簡單的處理任何CRD資源的示例
client-go手動操作CRD
以前建立和管理CRD的client庫位於:,但是現在client-go已經支援CRD
1,定義types型別
比如定義一個目錄api/types/v1alpha1,裡面是關於types的一些定義檔案;
metav1.ObjectMeta 型別會包含典型的任意的Kubernetes資源的metadata屬性,如name, namespace, labels, annotations。
2,定義DeepCopy深複製方法
被Kubernetes API定義的所有資源物件、型別都需要實現k8s.io/apimachinery/pkg/runtime.Object這個介面定義,這個介面包含兩個方法GetObjectKind() 和 DeepCopyObject():
-
GetObjectKind():
內建的metav1.TypeMeta結構已經實現
-
DeepCopyObject():
需要我們自己去實現這個方法
目的是生成物件,C++中有這樣的用法,名為:深複製,深複製意味著會重新生成物件並複製物件中的所有欄位、地址等資料;淺複製僅僅是物件的引用,並沒有生成新的物件。
需要手動去寫各種欄位域的賦值
3,透過scheme註冊types型別
Scheme定義了序列化和反序列化API物件的方法,用於將group、版本和型別資訊轉換為Go模式和從Go模式轉換為Go模式的型別登錄檔,以及不同版本的Go模式之間的對映。
當和API Server通訊的時候能夠處理新的types型別的話就需要先讓client能夠知道有這個新的types型別存在。
AddToScheme 會利用到反射,因此新定義的types型別的結構體的命名必須要和自定義的Kind的命名(如VirtualService
)保持一致,否則會找不到對應的kind,
var ( SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) AddToScheme = SchemeBuilder.AddToScheme )
AddToScheme: runtime.SchemeBuilder的一個外部方法,當Kubernetes註冊新定義的types型別後,就可以在任何地方呼叫這個方法
4,啟動一個HTTP client
當我們定義好一個新的types型別並且新增了一個register註冊方法到全域性的scheme編譯器後,我們就可以建立一個http client去載入我們的自定義資源了。現在就要用到client-go/rest
這個RESTClient去實現了。一般而言,為了更為安全的方式使用API,優雅的姿勢是打包這些操作到clientset中,透過rest包中的RESTClientFor
方法進行相關的封裝,然後再實現一些普適的interface介面,包含Get、Create、 Delete, Update 、List、Watch等通用介面方法,這個可以參考
5,構建Informer
一般優雅的姿勢去操作Kubernetes的資源並實時做出響應的方案是採用client-go的informer,它的工作模式是:初始時使用List()去載入資源的所有相關例項,然後使用Watch()進行訂閱更新;使用初始物件List列表和從watch訂閱更新到的資料會構建一個本地快取,該快取可以快速訪問任何自定義資源而無需每次都訪問API Server。像Pod、Deployment等資源物件都是採用這種方式。
在k8s.io/client-go/tools/cache
包中提供了一個Informer方法cache.NewInformer
,這個cache.NewInformer
返回兩個引數Store 和Controller:
Controller: 控制 List() 和 Watch() 的呼叫並填充Store
-
Store: 返回從API Server獲取的資源的最新狀態
可以透過這個Store去訪問我們的自定義資源CRDs
code-generator自動程式碼生成操作CRD
程式碼生成相比於前面的手動生成的優勢在於不用手動去寫一些基礎的deepcopy,client,informer,lister
這些方法
code-generation 也是基於client-go,因為client-go 需要實現runtime.Object interface的CustomResources型別 ,這樣就要實現諸如DeepCopy深複製的一系列方法,code-generation 就是實現了比如深複製的程式碼生成器,關於,如下:
deepcopy-gen: 給自定義type型別T建立一個DeepCopy方法
func (t* T) DeepCopy() *T
client-gen: 給自定義資源的APIGroups建立clientsets
informer-gen:透過informers給自定義資源建立一個基礎介面方法去操作自定義資源
lister-gen: 為GET和LIST請求建立一個listers監聽器
informer和lister相當於是controllers,抽象一層controllers去進行操作資源.
實際專案中,需要引入這個工程,然後透過一些指令碼生成。一個簡單的示例是,這個同時也是這篇博文
code-generation-customresources中的示例
也是程式碼生成的,並且有關於自定義資源CRD的一些操作。
1,定義好相關目錄和檔案
-
建立好工程目錄
pkg/apis/{Groupame}/{Version}
,如pkg/apis/networking.istio.io/v1
-
在version目錄下建立檔案
doc.go
types.go : 資源物件的定義
regsiter.go:Scheme和register type
檔案裡面的註釋,格式,都有要求
-
將code-generator專案引入的vendor下
-
建立自動生成指令碼
呼叫
vendor/k8s.io/code-generator/generate-groups.sh
生成
注意點:types不能有interface{} ,否則自動生成的時候會生成出錯,因此其實也不建議透過程式碼自動生成,還是手動去編寫會更好。
type VirtualServiceSpec struct { Hosts []string `json:"hosts"` Gateways []string `json:"gateways"` Http interface{} `json:"http"` } 報錯如下: /v1/zz_generated.deepcopy.go" (107:37: expected ';', found '{' (and 5 more errors)).
2,生成程式碼
然後透過如下命令
generate-groups.sh <generators> <output-package> <apis-package> <groups-versions> ... vendor/k8s.io/code-generator/generate-groups.sh all github.com/openshift-evangelists/crd-code-generation/pkg/client github.com/openshift-evangelists/crd-code-generation/pkg/apis example.com:v1 ... 可以同時指定多個輸出目錄 vendor/k8s.io/code-generator/generate-groups.sh all base-code-example/istio/crd-code-generation-service/pkg/client base-code-example/istio/crd-code-generation-service/pkg/apis "example.com:v1 networking.istio.io:v1" --go-header-file ${SCRIPT_ROOT}/hack/custom-boilerplate.go.txt
可以生成client的所有方法
3,自動生成的優劣
優勢:
減少很大一部分的通用實現,如
deepcopy,client,informer,lister
這些方法,這個相對來說是通用的,各個CRD都要實現一套避免自己編寫出一些不完善或者錯誤的實現
劣勢:
非常嚴格的定義,包括註釋,都要按照要求去實現
type定義的struct,暫時不支援interface型別的轉換,相對來說不方便,需要嚴格知道spec的所有域和欄位的準確型別
istio中client-go的處理
試想一下,istio中的資源、物件都是Kubernetes的CRDs,那麼必然,istio中肯定有處理好Kubernetes CRD的方式,我們知道目前都是採用client-go,那麼istio中必然會有大量的client-go的引用和使用,透過原始碼可以發現確實如此並且都是採用RESTClient,clientset是包含RESTClient的。
在原始碼路徑/Users/meitu/Documents/work_Meitu/goDev/Applications/src/istio.io/istio/pilot/pkg/config/kube/crd
中就是相關CRD的處理,然後/Users/meitu/Documents/work_Meitu/goDev/Applications/src/istio.io/istio/pilot/pkg/config/kube/crd/types.go
是istio中所有一些常用資源的定義如DestinationRule、Gateway、VirtualService等。這樣的話,我們自己要透過client-go去實現後端服務,去開發的話,就可以參考istio原始碼中的一些定義和基本方法,然後結合client-go的一般性處理去實現後端服務程式。
作者:吳德寶AllenWu
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1762/viewspace-2820575/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Kubernetes 實戰——配置應用(ConfigMap、Secret)
- Kubernetes 實戰——發現應用(Service)
- Kubernetes 實戰——升級應用(Deployment)
- Kubernetes 實戰——有狀態應用(StatefulSet)
- kubernetes client-go解析clientGo
- GlusterFS在Kubernetes中的應用實戰(一)
- client-go實戰之五:DiscoveryClientclientGo
- client-go實戰之四:dynamicClientclientGo
- client-go實戰之二:RESTClientclientGoREST
- kubernetes client-go功能介紹clientGo
- Kubernetes的client-go庫介紹clientGo
- Kubernetes: client-go 原始碼剖析(一)clientGo原始碼
- Kubernetes client-go 原始碼分析 - ReflectorclientGo原始碼
- 淺析kubernetes中client-go InformerclientGoORM
- client-go實戰之一:準備工作clientGo
- SpEL應用實戰
- 淺析kubernetes中client-go structure01clientGoStruct
- EggJS 雲原生應用硬核實戰(Kubernetes+Traefik+Helm+Prometheus+Grafana),提供 DemoJSPrometheusGrafana
- eBPF in kubernetes 實戰eBPF
- Kubernetes 部署 Laravel 應用的最佳實踐Laravel
- client-go實戰之六:時隔兩年,重新整理版本繼續實戰clientGo
- Flink Native Kubernetes實戰
- Spring Boot應用在kubernetes的sidecar設計與實戰Spring BootIDE
- client-go實戰之七:準備一個工程管理後續實戰的程式碼clientGo
- Prometheus監控實戰應用Prometheus
- Kubernetes(二) 應用部署
- go語言實戰教程:Redis實戰專案應用GoRedis
- 如何應對Kubernetes的安全挑戰?
- 監聽者模式實戰應用模式
- Spring Boot應用監控實戰Spring Boot
- gRPC應用實戰:(一)簡介RPC
- Docker 命令大全及應用實戰Docker
- Laravel Queues 佇列應用實戰Laravel佇列
- Kubernetes 實戰 —— 02. 開始使用 Kubernetes 和 DockerDocker
- kubernetes實戰篇之dashboard搭建
- LLM應用實戰:當KBQA整合LLM
- SpEL應用實戰|得物技術
- 低程式碼行業應用實戰行業