久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

kuberenetes CRD開發方法是什么

166次閱讀
沒有評論

共計 9807 個字符,預計需要花費 25 分鐘才能閱讀完成。

今天丸趣 TV 小編給大家分享一下 kuberenetes CRD 開發方法是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

擴展 kubernetes 兩個最常用最需要掌握的東西:自定義資源 CRD 和 adminsion webhook.

kubernetes 允許用戶自定義自己的資源對象,就如同 deployment statefulset 一樣,這個應用非常廣泛,比如 prometheus opterator 就自定義 Prometheus 對象,再加上一個自定義的 controller 監聽到 kubectl create Prometheus 時就去創建 Pod 組成一個 pormetheus 集群。rook 等等同理。

我需要用 kubernetes 調度虛擬機,所以這里自定義一個 VirtualMachine 類型

kubebuilder

kubebuilder 能幫我們節省大量工作,讓開發 CRD 和 adminsion webhook 變得異常簡單。

安裝

通過源碼安裝:

git clone https://github.com/kubernetes-sigs/kubebuilder
cd kubebuilder
make build
cp bin/kubebuilder $GOPATH/bin

或者下載二進制:

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-beta.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-beta.0_${os}_${arch} /usr/local/kubebuilder
export PATH=$PATH:/usr/local/kubebuilder/bin

還需要裝下 kustomize 這可是個渲染 yaml 的神器,讓 helm 顫抖。

go install sigs.k8s.io/kustomize/v3/cmd/kustomize

使用

注意你得先有個 kubernetes 集群,一步安裝走你

創建 CRD

kubebuilder init --domain sealyun.com --license apache2 --owner  fanux 
kubebuilder create api --group infra --version v1 --kind VirtulMachine

安裝 CRD 并啟動 controller

make install #  安裝 CRD
make run #  啟動 controller

然后我們就可以看到創建的 CRD 了

# kubectl get crd
NAME AGE
virtulmachines.infra.sealyun.com 52m

來創建一個虛擬機:

# kubectl apply -f config/samples/
# kubectl get virtulmachines.infra.sealyun.com 
NAME AGE
virtulmachine-sample 49m

看一眼 yaml 文件:

# cat config/samples/infra_v1_virtulmachine.yaml 
apiVersion: infra.sealyun.com/v1
kind: VirtulMachine
metadata:
 name: virtulmachine-sample
spec:
 # Add fields here
 foo: bar

這里僅僅是把 yaml 存到 etcd 里了,我們 controller 監聽到創建事件時啥事也沒干。

把 controller 部署到集群中

make docker-build docker-push IMG=fanux/infra-controller
make deploy

我是連的遠端的 kubenetes, make docker-build 時 test 過不去,沒有 etcd 的 bin 文件,所以先把 test 關了。

修改 Makefile:

# docker-build: test
docker-build:

Dockerfile 里的 gcr.io/distroless/static:latest 這個鏡像你也可能拉不下來,隨意改改就行,我改成了 golang:1.12.7

也有可能構建時有些代碼拉不下來,啟用一下 go mod vendor 把依賴打包進去

go mod vendor
如果你本地有些代碼拉不下來,可以用 proxy:

export GOPROXY=https://goproxy.io


再改下 Dockerfile, 注釋掉 download:

修改后:

# Build the manager binary
FROM golang:1.12.7 as builder
WORKDIR /go/src/github.com/fanux/sealvm
# Copy the Go Modules manifests
COPY . . 
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o manager main.go
# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
# FROM gcr.io/distroless/static:latest
FROM golang:1.12.7
WORKDIR /
COPY --from=builder /go/src/github.com/fanux/sealvm/manager .
ENTRYPOINT [/manager]

make deploy 時報錯:Error: json: cannot unmarshal string into Go struct field Kustomization.patches of type types.Patch

把 config/default/kustomization.yaml 中的 patches: 改成 patchesStrategicMerge: 即可

kustomize build config/default 這個命令就渲染出了 controller 的 yaml 文件,可以體驗下

看 你的 controller 已經跑起來了:

kubectl get deploy -n sealvm-system
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
sealvm-controller-manager 1 1 1 0 3m
kubectl get svc -n sealvm-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
sealvm-controller-manager-metrics-service ClusterIP 10.98.71.199  none  8443/TCP 4m

開發增加對象數據參數

看下 config/samples 下面的 yaml 文件:

apiVersion: infra.sealyun.com/v1
kind: VirtulMachine
metadata:
 name: virtulmachine-sample
spec:
 # Add fields here
 foo: bar

這里參數里有 foo:bar,那我們來加個虛擬 CPU,內存信息:

直接 api/v1/virtulmachine_types.go 即可

// VirtulMachineSpec defines the desired state of VirtulMachine
//  在這里加信息
type VirtulMachineSpec struct {
 // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
 // Important: Run  make  to regenerate code after modifying this file
 CPU string `json: cpu ` //  這是我增加的
 Memory string `json: memory `
// VirtulMachineStatus defines the observed state of VirtulMachine
//  在這里加狀態信息,比如虛擬機是啟動狀態,停止狀態啥的
type VirtulMachineStatus struct {
 // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
 // Important: Run  make  to regenerate code after modifying this file
}

然后 make 一下:

make   make install   make run

這時再去渲染一下 controller 的 yaml 就會發現 CRD 中已經帶上 CPU 和內存信息了:

kustomize build config/default

properties:
 cpu:
 description:  INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
 Important: Run  make  to regenerate code after modifying this file 
 type: string
 memory:
 type: string

修改一下 yaml:

apiVersion: infra.sealyun.com/v1
kind: VirtulMachine
metadata:
 name: virtulmachine-sample
spec:
 cpu:  1 
 memory:  2G
# kubectl apply -f config/samples 
virtulmachine.infra.sealyun.com  virtulmachine-sample  configured
# kubectl get virtulmachines.infra.sealyun.com virtulmachine-sample -o yaml 
apiVersion: infra.sealyun.com/v1
kind: VirtulMachine
metadata:
 annotations:
 kubectl.kubernetes.io/last-applied-configuration: |
 {apiVersion : infra.sealyun.com/v1 , kind : VirtulMachine , metadata :{ annotations :{}, name : virtulmachine-sample , namespace : default }, spec :{cpu : 1 , memory : 2G}}
 creationTimestamp: 2019-07-26T08:47:34Z
 generation: 2
 name: virtulmachine-sample
 namespace: default
 resourceVersion:  14811698 
 selfLink: /apis/infra.sealyun.com/v1/namespaces/default/virtulmachines/virtulmachine-sample
 uid: 030e2b9a-af82-11e9-b63e-5254bc16e436
spec: #  新的 CRD 已生效
 cpu:  1 
 memory: 2G

Status 同理,就不再贅述了,比如我把 status 里加一個 Create, 表示 controller 要去創建虛擬機了 (主要一些控制層面的邏輯),創建完了把狀態改成 Running

Reconcile 唯一需要實現的接口

controller 把輪訓與事件監聽都封裝在這一個接口里了. 你不需要關心怎么事件監聽的.

獲取虛擬機信息

func (r *VirtulMachineReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {ctx = context.Background()
 _ = r.Log.WithValues(virtulmachine , req.NamespacedName)
 vm :=  v1.VirtulMachine{}
 if err := r.Get(ctx, req.NamespacedName, vm); err != nil { #  獲取 VM 信息
 log.Error(err,  unable to fetch vm)
 } else { fmt.Println(vm.Spec.CPU, vm.Spec.Memory) #  打印 CPU 內存信息
 return ctrl.Result{}, nil}

make make install make run 這個時候去創建一個虛擬機 kubectl apply -f config/samples, 日志里就會輸出 CPU 內存了. List 接口同理,我就不贅述了

r.List(ctx,  vms, client.InNamespace(req.Namespace), client.MatchingField(vmkey, req.Name))

更新狀態

在 status 結構體中加入狀態字段:

type VirtulMachineStatus struct {Status string `json: status `}

controller 里去更新狀態:

vm.Status.Status =  Running 
if err := r.Status().Update(ctx, vm); err != nil {log.Error(err,  unable to update vm status)
}

如果出現:the server could not find the requested resource 這個錯誤,那么在 CRD 結構體上需要加個注釋 // +kubebuilder:subresource:status:

// +kubebuilder:subresource:status
// +kubebuilder:object:root=true
type VirtulMachine struct {
 metav1.TypeMeta `json: ,inline `
 metav1.ObjectMeta `json: metadata,omitempty `
 Spec VirtulMachineSpec `json: spec,omitempty `
 Status VirtulMachineStatus `json: status,omitempty `
}

這樣就好了

編譯啟動后再去 apply 發現狀態已經變成 running:

# kubectl get virtulmachines.infra.sealyun.com virtulmachine-sample -o yaml
status:
 status: Running

刪除

time.Sleep(time.Second * 10)
if err := r.Delete(ctx, vm); err != nil {log.Error(err,  unable to delete vm  ,  vm , vm)
}

10s 之后我們將 GET 不到

刪除回收器 Finalizers

如果不使用 Finalizers,kubectl delete 時直接就刪了 etcd 數據,controller 再想去拿 CRD 時已經拿不到了:

ERRO[0029] VirtulMachine.infra.sealyun.com  virtulmachine-sample  not foundunable to fetch vm source= virtulmachine_controller.go:48

所以在創建時我們需要給 CRD 加上 Finalizer:

vm.ObjectMeta.Finalizers = append(vm.ObjectMeta.Finalizers,  virtulmachine.infra.sealyun.com)

然后刪除時就只會給 CRD 打上一個刪除時間戳,供我們做后續處理, 處理完了我們刪除掉 Finalizers:

 如果  DeleteionTimestamp 不存在
  如果沒有 Finalizers
  加上 Finalizers, 并更新 CRD
要不然,說明是要被刪除的
  如果存在 Finalizers,刪除 Finalizers, 并更新 CRD

看個完整的代碼示例:

if cronJob.ObjectMeta.DeletionTimestamp.IsZero() { if !containsString(cronJob.ObjectMeta.Finalizers, myFinalizerName) { cronJob.ObjectMeta.Finalizers = append(cronJob.ObjectMeta.Finalizers, myFinalizerName)
 if err := r.Update(context.Background(), cronJob); err != nil { return ctrl.Result{}, err
 }
 }
 } else { if containsString(cronJob.ObjectMeta.Finalizers, myFinalizerName) { if err := r.deleteExternalResources(cronJob); err != nil { return ctrl.Result{}, err
 }
 cronJob.ObjectMeta.Finalizers = removeString(cronJob.ObjectMeta.Finalizers, myFinalizerName)
 if err := r.Update(context.Background(), cronJob); err != nil { return ctrl.Result{}, err
 }
 }
 }

webhook

kuberentes 有三種 webhook,admission webhook, authorization webhook and CRD conversion webhook.

這里比如我們要給 CRD 設置一些默認值,又或者是用戶創建時少填了一些參數,那么我們得禁止創建等等這些事。

使用 webhook 也非常的簡單,只需給定義的結構體實現 Defaulter 和 Validator 接口即可.

其它接口

Reconcile 結構體聚合了 Client 接口,所以 client 的所有方法都是可以直接調用,大部分是對 CRD object 的相關操作

type Client interface {
 Reader
 Writer
 StatusClient
}
// Reader knows how to read and list Kubernetes objects.
type Reader interface {
 // Get retrieves an obj for the given object key from the Kubernetes Cluster.
 // obj must be a struct pointer so that obj can be updated with the response
 // returned by the Server.
 Get(ctx context.Context, key ObjectKey, obj runtime.Object) error
 // List retrieves list of objects for a given namespace and list options. On a
 // successful call, Items field in the list will be populated with the
 // result returned from the server.
 List(ctx context.Context, list runtime.Object, opts ...ListOptionFunc) error
// Writer knows how to create, delete, and update Kubernetes objects.
type Writer interface {
 // Create saves the object obj in the Kubernetes cluster.
 Create(ctx context.Context, obj runtime.Object, opts ...CreateOptionFunc) error
 // Delete deletes the given obj from Kubernetes cluster.
 Delete(ctx context.Context, obj runtime.Object, opts ...DeleteOptionFunc) error
 // Update updates the given obj in the Kubernetes cluster. obj must be a
 // struct pointer so that obj can be updated with the content returned by the Server.
 Update(ctx context.Context, obj runtime.Object, opts ...UpdateOptionFunc) error
 // Patch patches the given obj in the Kubernetes cluster. obj must be a
 // struct pointer so that obj can be updated with the content returned by the Server.
 Patch(ctx context.Context, obj runtime.Object, patch Patch, opts ...PatchOptionFunc) error
// StatusClient knows how to create a client which can update status subresource
// for kubernetes objects.
type StatusClient interface {Status() StatusWriter
}

以上就是“kuberenetes CRD 開發方法是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,丸趣 TV 小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注丸趣 TV 行業資訊頻道。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-04發表,共計9807字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 资兴市| 同心县| 大姚县| 贵阳市| 平原县| 莎车县| 克东县| 东至县| 榕江县| 子洲县| 麻江县| 洞口县| 汤阴县| 营口市| 社会| 旌德县| 林甸县| 定西市| 东莞市| 南靖县| 大化| 普宁市| 旬阳县| 阿荣旗| 长寿区| 乐亭县| 衡山县| 大兴区| 信丰县| 阳江市| 镇安县| 大埔区| 定襄县| 慈溪市| 盐亭县| 姚安县| 郧西县| 新野县| 上虞市| 盐津县| 陇川县|