簡介:
之前介紹過
Kubernetes 實戰 一 CRD 自定義資源。
但是CRD隻能實作資源的定義,kubernetes operator = crd + controller。 那如何實作自定義的控制呢? 接下來教你10分鐘快速實作自定義controller。(可以合理上網的前提下。。。。)
環境
- mac os 10.13.6
- kubernetes 1.14.0 --> Centos 7 快速搭建kubernetes 叢集
- kubebuilder 2.0.0-alpha.4
- kustomize 3.1.0
- golang 1.12.7
建立 operator 操作步驟
0. 寫在前面
接下來的來的過程有一些小坑,很多步驟都需要翻牆、希望能夠合理的翻牆 否則不用多說了吧 。。。。。
建議使用我的
github代碼,熟悉流程後在自行搭建,可以直接跳過 2、3 兩個步驟。第8步 就是編譯鏡像然後通過yml部署到kubernetes叢集 不想嘗試的可以跳過。
代碼下載下傳:
git clone https://github.com/xiliangMa/vm-crd.git
1. kubebuilder 安裝
kubebuilder 基于 client go 能幫我們節省大量工作,讓開發CRD和adminsion webhook變得異常簡單。go 語言開發的首選,如果你是 java 開發的話可以使用 Fabric8
二進制安裝:
os=$(go env GOOS)
arch=$(go env GOARCH)
# download kubebuilder and extract it to tmp
curl -sL https://go.kubebuilder.io/dl/2.0.0-rc.0/${os}/${arch} | tar -xz -C /tmp/
# move to a long-term location and put it on your path
# (you'll need to set the KUBEBUILDER_ASSETS env var if you put it somewhere else)
sudo mv /tmp/kubebuilder_2.0.0-rc.0_${os}_${arch} /usr/local/kubebuilder
export PATH=$PATH:/usr/local/kubebuilder/bin
2. kustomize 安裝
go install sigs.k8s.io/kustomize/v3/cmd/kustomize
3. 建立 operator project
需要翻牆。。。。
kubebuilder init --domain xiliangma.com --license apache2 --owner "xiliangMa"
4. 建立 api
kubebuilder create api --group mscloud --version v1 --kind VM
5. 部署 CRD 到叢集
部署 crd:
make install
檢視 crd:
crd git:(master) kubectl get crd | grep vm
vms.mscloud.xiliangam.com 2019-08-19T08:00:31Z
6. 本地啟動 controller
crd git:(master) make run
go get sigs.k8s.io/controller-tools/cmd/[email protected]
/Users/maxiliang/go/bin/controller-gen object:headerFile=./hack/boilerplate.go.txt paths=./api/...
go fmt ./...
go vet ./...
go run ./main.go
2019-08-19T16:44:26.614+0800 INFO controller-runtime.controller Starting EventSource {"controller": "vm", "source": "kind source: /, Kind="}
2019-08-19T16:44:26.615+0800 INFO setup starting manager
2019-08-19T16:44:26.718+0800 INFO controller-runtime.controller Starting Controller {"controller": "vm"}
2019-08-19T16:44:26.819+0800 INFO controller-runtime.controller Starting workers {"controller": "vm", "worker count": 1}
Get vm spec info success, vm1 Centos 7.2 1 1024 true
2019-08-19T16:44:26.827+0800 DEBUG controller-runtime.controller Successfully Reconciled {"controller": "vm", "request": "default/vm-sample2"}
Get vm spec info success, vm1 Centos 7.2 1 1024 true
2019-08-19T16:44:26.834+0800 DEBUG controller-runtime.controller Successfully Reconciled {"controller": "vm", "request": "default/vm-sample2"}
7. 建立 vm
建立:
kubectl apply -f config/samples/mscloud_v1_vm.yaml
檢視:
crd git:(master) kubectl get vm
NAME AGE
vm-sample2 35m
8. build 鏡像部署
需要翻牆。。。。此步驟可以不做,本地啟動controller 也可以
make docker-build docker-push IMG=xiliangma/vmcontroller
make deploy
好了已經成功釋出controller 到叢集了。好了 到這裡是不是就完事了,散夥回家。。。
crd git:(master) docker images | grep xiliangma/vmcontroller
xiliangma/vmcontroller latest a1d7fa46abbf 8 days ago 815MB
哈哈 接下來才是自定義controller部分,很簡單其實就是對 vm 資源的增删改查。。。。
自定義 controller 開發
下面可以看到spec中隻有foo 屬性,那如何像 deployment 一樣實作多參數配置呢?請看下面的操作步驟。
crd git:(master) cat config/samples/mscloud_v1_vm.yaml
apiVersion: mscloud.xiliangam.com/v1
kind: VM
metadata:
name: vm-sample
spec:
# Add fields here
foo: bar
1. 自定義 vm
- 1.1 修改 VMSpec
- 1.2 建立 vm
- 1.3 添加控制邏輯
1.1 修改 VMSpec 添加屬性
添加 Name 、 類型、HA 等。。
type VMSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// xiliangma test vm crd controller
Name string `json:"name"`
Type string `json:"type"`
CPU int `json:"cpu"`
Memory int `json:"memory"`
HA bool `json:"ha"`
}
1.3 建立 vm
mscloud_v2_vm.yaml:
apiVersion: mscloud.xiliangam.com/v1
kind: VM
metadata:
name: vm-sample2
spec:
# Add fields here
foo: bar
name: "vm1"
type: "Centos 7.2"
cpu: 1
memory: 1024
ha: true
kubectl apply -f config/samples/mscloud_v2_vm.yaml
好了添加的屬性已經成功配置:
crd git:(master) kubectl describe vms
Name: vm-sample2
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"mscloud.xiliangam.com/v1","kind":"VM","metadata":{"annotations":{},"name":"vm-sample2","namespace":"default"},"spec":{"cpu"...
API Version: mscloud.xiliangam.com/v1
Kind: VM
Metadata:
Creation Timestamp: 2019-08-19T08:40:59Z
Generation: 1
Resource Version: 261536
Self Link: /apis/mscloud.xiliangam.com/v1/namespaces/default/vms/vm-sample2
UID: 11803e5e-c25d-11e9-970d-025000000001
--------- 成功添加vm 屬性
Spec:
Cpu: 1
Foo: bar
Ha: true
Memory: 1024
Name: vm1
Type: Centos 7.2
Events: <none>
1.4 添加擷取邏輯
通過 kubebuilder 初始化的項目結構比較簡單,控制邏輯都在controller 裡實即可。
Reconcile 裡添加擷取邏輯:
ctx := context.Background()
log := r.Log.WithValues("vm", req.NamespacedName)
// 1. xiliangma 擷取vm 資訊
var vm mscloudv1.VM
if err := r.Get(ctx, req.NamespacedName, &vm); err != nil {
log.Error(err, "unable to get vm")
} else {
fmt.Println("Get vm spec info success, ", vm.Spec.Name, vm.Spec.Type, vm.Spec.CPU, vm.Spec.Memory, vm.Spec.HA)
}
測試 make && make install && make run 日志中能看到列印出的資訊
2. 更新
- 2.1 修改 VMStatus
-
2.2 添加修改邏輯
1.2 修改 VMStatus
添加 UpdateLastTime 、 Status
type VMStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
// xiliangma test vm crd controller
UpdateLastTime metav1.Time `json:"update_last_time"`
Status string `json:"status"`
}
// 2. 更新虛拟機狀态
vm.Status.UpdateLastTime = metav1.Now()
vm.Status.Status = "Running"
if err := r.Status().Update(ctx, &vm); err != nil {
log.Error(err, "not update vm status.")
}
重新執行: make && make install && make run
如果出現:the server could not find the requested resource 這個錯誤,那麼在CRD結構體上需要加個注釋 // +kubebuilder:subresource:status
// +kubebuilder:subresource:status
// +kubebuilder:object:root=true
// VM is the Schema for the vms API
type VM struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec VMSpec `json:"spec,omitempty"`
Status VMStatus `json:"status,omitempty"`
}
看到下面結果 修改成功:
crd git:(master) kubectl describe vms
Name: vm-sample2
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"mscloud.xiliangam.com/v1","kind":"VM","metadata":{"annotations":{},"name":"vm-sample2","namespace":"default"},"spec":{"cpu"...
API Version: mscloud.xiliangam.com/v1
Kind: VM
Metadata:
Creation Timestamp: 2019-08-19T08:40:59Z
Generation: 1
Resource Version: 261536
Self Link: /apis/mscloud.xiliangam.com/v1/namespaces/default/vms/vm-sample2
UID: 11803e5e-c25d-11e9-970d-025000000001
Spec:
Cpu: 1
Foo: bar
Ha: true
Memory: 1024
Name: vm1
Type: Centos 7.2
Status:
---- 修改成功
Status: Running
Update Last Time: 2019-08-19T08:44:26Z
Events: <none>
3. 删除 vm
添加删除邏輯:
// 3. 删除虛拟機
time.Sleep(time.Second * 5)
if err := r.Delete(ctx, &vm); err != nil {
log.Error(err, "unable to delete vm ", "vm", vm)
}
5s 後vm 被删除。
好了,到此你已經實作了基礎的控制器是不是很簡單。