KubeBuilder 簡明教程
Operator 概述
Operator 是 Kubernetes 的擴展軟件,它利用 定製資源 管理應用及其組件。Operator 遵循 Kubernetes 的理念,特別是在控制器 方面 [^1]
k8s 的是一個高度自動化的系統,其中涵蓋了常見應用程序所需的大部分功能,例如服務發現,負載均衡,HPA 等等,這些功能是由 k8s 自帶的一些控制器實現的,但是需求總是永無止境的,當我們有類似需求但是 k8s 又無法很好的滿足的時候我們就可以使用 Operator 和 Custome Resource(自定義資源)來達到類似的效果。
例如常見的需求就有部署一個數據庫,節點自動化運維,日誌採集組件配置等等
從 Operator 理念的提出到現在已經有了很多工具可以幫助我們快速低成本的開發,其中最常用的就是 CoreOS 開源的 operator-sdk[^3] 和 k8s sig 小組維護的 kubebuilder[^2],我們這個系列選用 kubebuilder。
開始之前我們先了解兩個馬上就會涉及到的核心概念
GV & GVK & GVR
-
GV: Api Group & Version
-
API Group 是相關 API 功能的集合
-
每個 Group 擁有一或多個 Versions
-
GVK: Group Version Kind
-
每個 GV 都包含 N 個 api 類型,稱之爲
Kinds
,不同Version
同一個Kinds
可能不同 -
GVR: Group Version Resource
-
Resource
是Kind
的對象標識,一般來Kind
和Resource
是1:1
的,但是有時候存在1:n
的關係,不過對於 Operator 來說都是1:1
的關係
舉個🌰,我們在 k8s 中的 yaml 文件都有下面這麼兩行,例如上篇文章我們部署的 nginx deployment
apiVersion: apps/v1 # 這個是 GV,G 是 apps,V 是 v1
kind: Deployment # 這個就是 Kind
sepc: # 加上下放的 spec 就是 Resource了
...
根據 GVK K8s 就能找到你到底要創建什麼類型的資源,根據你定義的 Spec 創建好資源之後就成爲了 Resource,也就是 GVR。GVK/GVR 就是 K8s 資源的座標,是我們創建 / 刪除 / 修改 / 讀取資源的基礎 [^4]。
KubeBuilder 簡明教程
安裝
-
訪問官方倉庫下載已經編譯好的二進制文件: Releases · kubernetes-sigs/kubebuilder (github.com)
-
本文編寫的時候 kubebuilder 已經推出了
v3.0.0-rc.0
版本,所以爲了避免剛寫完新版就已經 release 了的尷尬情況,本文直接使用的是 3.0 版本 -
下載好了之後記得將對應文件加入
PATH
當中 -
安裝成功之後使用
kubebuilder version
可以查看安裝的版本信息❯ kubebuilder version Version: main.version{KubeBuilderVersion:"3.0.0-rc.0", KubernetesVendor:"1.19.2", GitCommit:"90fe4124c4c6965c6bfac63339888956952cda90", BuildDate:"2021-04-08T17:36:28Z", GoOs:"linux", GoArch:"amd64"}
項目初始化
先創建一個空文件夾,然後在文件夾內執行下方命令
kubebuilder init --domain lailin.xyz --repo github.com/mohuishou/blog-code/k8s-operator/02-kubebuilder
-
–-domain lailin.xyz
我們的項目的域名 -
--repo xxx
是倉庫地址,同時也是go mode
中的repo
地址
如果你 golang
版本過低或者過高都有可能出現下方的錯誤信息,我這裏是因爲使用的 1.16
版本太高了
2021/04/25 20:47:14 failed to initialize project: unable to run pre-scaffold tasks of "base.go.kubebuilder.io/v3": go version 'go1.16' is incompatible because 'requires 1.13 <= version < 1.16'. You can skip this check using the --skip-go-version-check flag
這種情況下可以添加 --skip-go-version-check
忽略這個錯誤,但是還是建議使用官方推薦的版本
kubebuilder init --domain lailin.xyz --repo github.com/mohuishou/blog-code/k8s-operator/02-kubebuilder --skip-go-version-check
項目目錄
.
├── Dockerfile
├── Makefile # 這裏定義了很多腳本命令,例如運行測試,開始執行等
├── PROJECT # 這裏是 kubebuilder 的一些元數據信息
├── config
│ ├── default # 一些默認配置
│ ├── manager # 部署 crd 所需的 yaml
│ ├── prometheus # 監控指標數據採集配置
│ └── rbac # 部署所需的 rbac 授權 yaml
├── go.mod
├── go.sum
├── hack
│ └── boilerplate.go.txt
└── main.go
創建 api
kubebuilder create api --group apps --version v1 --kind Application
執行之後我們可以發現項目結構發生了一些變化
.
├── api
│ └── v1
│ ├── application_types.go # 這裏是定義 spec 的地方
│ ├── groupversion_info.go # GV 的定義,一般無需修改
│ └── zz_generated.deepcopy.go
├── config
│ ├── crd # 自動生成的 crd 文件,不用修改這裏,只需要修改了 v1 中的 go 文件之後執行 make generate 即可
│ ├── default
│ ├── manager
│ ├── prometheus
│ ├── rbac
│ └── samples # 這裏是 crd 示例文件,可以用來部署到集羣當中
├── controllers
│ ├── application_controller.go # 在這裏實現 controller 的邏輯
│ └── suite_test.go # 這裏寫測試
實現 Controller
定義 CR
// api/v1/application_types.go
// ApplicationSpec defines the desired state of Application
type ApplicationSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Product 該應用所屬的產品
Product string `json:"product,omitempty"`
}
修改之後我們執行一下 make manifests generate
可以發現已經生成了相關的字段,並且代碼中的字段註釋也就是 yaml 文件中的註釋
# config/crd/bases/apps.lailin.xyz_applications.yaml
......
properties:
product:
description: Product 該應用所屬的產品
type: string
......
實現 controller
kubebuilder 已經幫我們實現了 Operator 所需的大部分邏輯,我們只需要在 Reconcile
中實現業務邏輯就行了
// controllers/application_controller.go
func (r *ApplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
_ = r.Log.WithValues("application", req.NamespacedName)
r.Log.Info("app changed", "ns", req.Namespace)
return ctrl.Result{}, nil
}
邏輯修改好之後,我們先執行 make install
安裝 CRD
,然後執行 make run
運行 controller
go run ./main.go
2021-04-25T21:55:55.578+0800 INFO controller-runtime.metrics metrics server is starting to listen {"addr": ":8080"}
2021-04-25T21:55:55.579+0800 INFO setup starting manager
2021-04-25T21:55:55.579+0800 INFO controller-runtime.manager starting metrics server {"path": "/metrics"}
2021-04-25T21:55:55.579+0800 INFO controller-runtime.manager.controller.application Starting EventSource {"reconciler group": "apps.lailin.xyz", "reconciler kind": "Application", "source": "kind source: /, Kind="}
2021-04-25T21:55:55.680+0800 INFO controller-runtime.manager.controller.application Starting Controller {"reconciler group": "apps.lailin.xyz", "reconciler kind": "Application"}
2021-04-25T21:55:55.680+0800 INFO controller-runtime.manager.controller.application Starting workers {"reconciler group": "apps.lailin.xyz", "reconciler kind": "Application", "worker count": 1}
然後我們部署一個測試的 crd kubectl apply -f config/samples/apps_v1_application.yaml
apiVersion: apps.lailin.xyz/v1
kind: Application
metadata:
name: application-sample
spec:
# Add fields here
product: test
然後可以看到之前寫的日誌邏輯已經觸發
2021-04-25T21:57:12.618+0800 INFO controllers.Application app changed {"ns": "default"}
Kubebuilder 註釋
在生成的代碼當中我們可以看到很多 //+kubebuilder:xxx
開頭的註釋,對 Go 比較熟悉的同學應該知道這些註釋是給對應的代碼生成器服務的,在 Go 中有一個比較常用的套路就是利用 go gennerate
生成對應的 go 代碼。
kubebuilder 使用 controller-gen 生成代碼和對應的 yaml 文件,這其中主要包含 CRD 生成、驗證、處理還有 WebHook 的 RBAC 的生成功能,下面我簡單介紹一下,完整版可以看 kubebuilder 的官方文檔
-
CRD 生成
-
//+kubebuilder:subresource:status
開啓 status 子資源,添加這個註釋之後就可以對status
進行更新操作了 -
//+groupName=nodes.lailin.xyz
指定 groupname -
//+kubebuilder:printcolumn
爲kubectl get xxx
添加一列,這個挺有用的 -
......
-
CRD 驗證,利用這個功能,我們只需要添加一些註釋,就給可以完成大部分需要校驗的功能
-
//+kubebuilder:default:=<any>
給字段設置默認值 -
//+kubebuilder:validation:Pattern:=string
使用正則驗證字段 -
......
-
Webhook
-
//+kubebuilder:webhook
用於指定 webhook 如何生成,例如我們可以指定只監聽Update
事件的 webhook -
RBAC 用於生成 rbac 的權限
-
//+kubebuilder:rbac
總結
這篇文章主要講解了 kubebuilder
的安裝使用方式,以及涉及到的一些簡單的概念,項目目錄結構的說明,下一篇文章我們就一起來實現一個真實的 Operator 需求
參考文獻
[^1]: Operator 模式 | Kubernetes: https://kubernetes.io/zh/docs/concepts/extend-kubernetes/operator/
[^2]: kubebuilder 官方文檔, 這個是 master 分支的文檔,待 3.0 發佈後去掉 master 即可: https://master.book.kubebuilder.io/quick-start.html
[^3]: operator-sdk: https://sdk.operatorframework.io/
[^4]: 深入解析 Kubebuilder:讓編寫 CRD 變得更簡單: https://developer.aliyun.com/article/719215
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Y0GwLgz9o2HONkl4FJdlVQ