kubebuilder用來自定義k8s 資源類型,例如GuestBook類型(和deployment、ingress等資源類似),用只需要簡單的命令,和框架化的代碼填充即可完成自定資源的定義。kubebuilder還可以控制該資源類型的創建、刪除等操作的腳手架工程。這里的控制不是指用戶使用kubectl create/delete來控制資源創建和刪除的意思,而是用來動態顯示資源狀態的。例如deployment資源類型,如果是多副本的話,就需要創建多個副本,並感知目前創建了幾個副本。如果某個副本異常退出還需要創建新的副本來頂替上。同樣,如果副本數被用戶調小,則需要刪除一些副本。首先,上一張kubebuilder的架構圖:
從上圖可以看出controller是Kubernetes和任何其他operator的核心。控制器的任務是確保任何給定對象的實際狀態(包括集群狀態和可能的外部狀態,如Kubelet的運行容器或雲提供商的負載平衡器)與對象中的期望狀態相匹配。每個控制器關注一個根類型,但可能與其他類型交互。這個過程稱之為reconciling. 在控制器運行時中,為特定類型實現協調的邏輯稱為Reconciler.在xxx_controller.go文件中,我們可以看到Reconcile函數,你可以在里面添加客制化代碼。
webhook是修改請求和驗證請求的,如果通過不了驗證一般情況下報錯返回。
kubebuilder安裝
到https://github.com/kubernetes-sigs/kubebuilder/releases 頁面下載合適的release二進制kubebuilder版本
chmod +x kubebuilder && mv kubebuilder /usr/local/bin/
創建API
下面以創建一個myingress資源為例,這個工程的工作目錄為/root/share/hello/src/github.com/world
mkdir /root/share/hello/src/github.com/world -p
export GOPATH=/root/share/hello/
export GOPROXY=https://goproxy.cn
cd /root/share/hello/src/github.com/world
kubebuilder init --domain my.domain //這一步可能要等一會
// 默認namespaced為true
kubebuilder create api --group net --version v1 --kind MyIngress
// 如果需要修改namespace為cluster,可以使用下面的命令強制更新DpvsIngress API 定義
kubebuilder create api --group net --version v1 --kind MyIngress --namespaced=false --force
這是去api目錄下找到xxx_types.go文件,添加客制化屬性。
添加客制化定義
一般在xxx_types.go 中的添加一些spec屬性,舉例如下所示:
type WorldSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Foo is an example field of DpvsIngress. Edit world_types.go to remove/update
Foo string `json:"foo,omitempty"`
Selector *metav1.LabelSelector `json:"selector,omitempty"`
Servers []Servers `json:"servers"`
}
type Servers struct {
Servers []VIPInfo `json:"vipInfo,omitempty"`
}
type VIPInfo struct {
VIP string `json:"vip"`
Database Databaseinfo `json:"database"`
}
type Databaseinfo struct {
name string `json:"name "`
ip string `json:"ip "`
}
然后執行以下命令:
make manifests
make install #期間報錯少了什么組件就安裝什么組件
make run
這個步驟報錯及解決方法如下:
(1) "invalid configuration: no configuration has been provided, try setting KUBERNETES_MASTER environment variable"
可以通過export KUBECONFIG=/xxx/xxx設置kubeconfig文件來解決,但是當修改了api/v1下面的代碼需要重新make時,可能需要unset該變量否則無法make install
(2)"metrics server failed to listen. You may want to disable the metrics server or use another port if it is due to conflicts {"error": "error listening on :8080: listen tcp :8080: bind: address already in use"}"
修改當前目錄下的main.go 中 flag.StringVar(&metricsAddr, "metrics-bind-address", ":8090", "The address the metric endpoint binds to.") 語句的監聽端口為本機未占用端口
然后這個main函數就運行起來了,看了似乎是個daemon程序。
修改后再次執行make install,會在config/crd/bases/目錄下生成資源類型YAML文件,並自動更新該資源類型。然后使用如下yaml文件創建一個資源實例:
apiVersion: my.domain/v1
kind: World
metadata:
name: world-sample
spec:
# TODO(user): Add fields here
selector:
matchLabels:
tag: abc
servers:
- vipInfo:
- vip: "172.0.0.254"
database:
name: "zone1"
ip: "192.168.1.1"
- vipInfo:
- vip: "172.0.0.253"
database:
name: "zone2"
ip: "192.168.1.2"
自定義資源類似的刪除
刪除自定義資源類型前,先把資源實例刪掉。然后再用yaml資源定義文件刪除資源類型,如果找不到資源類型文件則可以直接到etcd搜索關鍵字再刪除。
另外,利用kubebuilder生成的CRD YAML創建客制化資源時,有時不會馬上生效,可以等一會就可以創建該資源實例了。