Kubernetes 實戰 二 CRD 自定義控制器

簡介:

之前介紹過 Kubernetes 實戰 一 CRD 自定義資源
但是CRD只能實現資源的定義,kubernetes operator = crd + controller。 那如何實現自定義的控制呢? 接下來教你10分鐘快速實現自定義controller。(可以合理上網的前提下。。。。)


環境


創建 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.2 添加修改邏輯

// 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)
}

重新執行: make && make install && make run
5s 後vm 被刪除。

好了,到此你已經實現了基礎的控制器是不是很簡單。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章