美文网首页kubernets学习kuberne...
从0到1使用kubebuilder创建crd

从0到1使用kubebuilder创建crd

作者: zoux | 来源:发表于2022-09-12 16:15 被阅读0次

    简介

    从0到1,手把手教会如何使用kubebuilder创建crd, 并且定制自己的控制器。

    代码:https://github.com/zoux86/operator-example

    0. 下载kubebuilder

    # download kubebuilder and install locally.
    curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)
    chmod +x kubebuilder && mv kubebuilder /usr/local/bin/
    

    1. 创建目录

    ~/go/src 是我的go src目录

    github.com/zoux86/operator-example是想自定义的crd项目

    // 可以看出来go mod init 指定的字符串就是mod文件里面的module目录
    ~/go/src/github.com/zoux86/operator-example#  go mod init github.com/zoux86/operator-example
    go: creating new go.mod: module github.com/zoux86/operator-example
    
     ~/go/src/github.com/zoux86/operator-example # ls
    go.mod
    
     ~/go/src/github.com/zoux86/operator-example # cat go.mod
    module github.com/zoux86/operator-example   
    
    go 1.18
    

    2. 初始化项目

    执行kubebuilder init这一条命令就行了

     ~/go/src/github.com/zoux86/operator-example # ~/kubebuilder init --domain github.com --license apache2 --owner "zoux86"
    Writing kustomize manifests for you to edit...
    Writing scaffold for you to edit...
    Get controller runtime:
    $ go get sigs.k8s.io/controller-runtime@v0.11.2
    go: downloading sigs.k8s.io/controller-runtime v0.11.2
    go: downloading k8s.io/apimachinery v0.23.5
    go: downloading k8s.io/client-go v0.23.5
    go: downloading k8s.io/utils v0.0.0-20211116205334-6203023598ed
    go: downloading k8s.io/component-base v0.23.5
    go: downloading k8s.io/api v0.23.5
    go: downloading k8s.io/apiextensions-apiserver v0.23.5
    go: downloading sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6
    go: downloading golang.org/x/net v0.0.0-20211209124913-491a49abca63
    go: downloading golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
    Update dependencies:
    $ go mod tidy
    go: downloading github.com/Azure/go-autorest/autorest v0.11.18
    go: downloading github.com/Azure/go-autorest/autorest/adal v0.9.13
    go: downloading github.com/Azure/go-autorest/tracing v0.6.0
    go: downloading github.com/Azure/go-autorest/autorest/mocks v0.4.1
    go: downloading github.com/Azure/go-autorest/autorest/date v0.3.0
    go: downloading github.com/Azure/go-autorest/logger v0.2.1
    go: downloading golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
    Next: define a resource with:
    $ kubebuilder create api
    

    查看文件目录

    k8s apis通常有三个组件Resource, Controller, Manager,它们分别定义/实现在以下的三个package当中:

    • cmd/...:主流程程序Manager入口,负责初始化依赖包、启停Controller。用户通常不需要编辑此包,可以依赖脚手架。通过kubebuilder init自动创建生成。
    • pkg/apis/...:包含API资源的定义。编辑*_types.go文件来修改资源定义。每个资源的定义文件存在于pkg/apis/<api-group-name>/<api-version-name>/<api-kind-name>_types.go中。通过kubebuilder create api自动创建生成。
    • pkg/controller/...:包含Controller的实现。编辑*_controller.go实现Controller。通过kubebuilder create api自动创建生成。
     ~/go/src/github.com/zoux86/operator-example  tree
    .
    ├── Dockerfile
    ├── Makefile
    ├── PROJECT
    ├── README.md
    ├── config
    │   ├── default
    │   │   ├── kustomization.yaml
    │   │   ├── manager_auth_proxy_patch.yaml
    │   │   └── manager_config_patch.yaml
    │   ├── manager
    │   │   ├── controller_manager_config.yaml
    │   │   ├── kustomization.yaml
    │   │   └── manager.yaml
    │   ├── prometheus
    │   │   ├── kustomization.yaml
    │   │   └── monitor.yaml
    │   └── rbac
    │       ├── auth_proxy_client_clusterrole.yaml
    │       ├── auth_proxy_role.yaml
    │       ├── auth_proxy_role_binding.yaml
    │       ├── auth_proxy_service.yaml
    │       ├── kustomization.yaml
    │       ├── leader_election_role.yaml
    │       ├── leader_election_role_binding.yaml
    │       ├── role_binding.yaml
    │       └── service_account.yaml
    ├── go.mod
    ├── go.sum
    ├── hack
    │   └── boilerplate.go.txt
    └── main.go
    

    3. 创建api和controller

    其实从create api 后的输出我们可以看出来:我们修改逻辑后就可以部署了

     ~/go/src/github.com/zoux86/operator-example # ~/kubebuilder create api --group zouxapp --kind PodCount --version v1
    Create Resource [y/n]
    y
    Create Controller [y/n]
    y
    Writing kustomize manifests for you to edit...     // 先修改这2个文件
    Writing scaffold for you to edit...
    api/v1/podcount_types.go
    controllers/podcount_controller.go
    Update dependencies:
    $ go mod tidy                                   
    Running make:
    $ make generate                                     
    mkdir -p /Users/game-netease/go/src/github.com/zoux86/operator-example/bin
    GOBIN=/Users/game-netease/go/src/github.com/zoux86/operator-example/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0
    go: downloading sigs.k8s.io/controller-tools v0.8.0
    go: downloading github.com/spf13/cobra v1.2.1
    go: downloading golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff
    go: downloading github.com/fatih/color v1.12.0
    go: downloading k8s.io/api v0.23.0
    go: downloading k8s.io/apimachinery v0.23.0
    go: downloading github.com/gobuffalo/flect v0.2.3
    go: downloading k8s.io/apiextensions-apiserver v0.23.0
    go: downloading github.com/mattn/go-colorable v0.1.8
    go: downloading github.com/mattn/go-isatty v0.0.12
    go: downloading golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e
    go: downloading golang.org/x/mod v0.4.2
    /Users/game-netease/go/src/github.com/zoux86/operator-example/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."
    Next: implement your new API and generate the manifests (e.g. CRDs,CRs) with:
    $ make manifests
    

    执行create api后,生成以下文件:

    api/v1/groupversion_info.go
    api/v1/podcount_types.go                      // 需要修改这个文件中crd的定义
    api/v1/zz_generated.deepcopy.go
    config/crd/kustomization.yaml
    config/crd/kustomizeconfig.yaml
    config/crd/patches/cainjection_in_podcounts.yaml
    config/crd/patches/webhook_in_podcounts.yaml
    config/rbac/podcount_editor_role.yaml
    config/rbac/podcount_viewer_role.yaml
    config/samples/zouxapp_v1_podcount.yaml
    controllers/podcount_controller.go            // 需要修改这个文件的controller运行逻辑
    controllers/suite_test.go
    go.mod
    main.go
    

    4. 实现自己的crd和控制器逻辑

    根据实际情况而定,这里的控制器逻辑很简单,就是创建同步podCount的spec.count到status里面。

    func (r *PodCountReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
        rlog := log.FromContext(ctx)
        rlog.Info("start to reconciling podCount %s", req.Name)
        podCount := &zouxappv1.PodCount{}
        err := r.Client.Get(ctx, req.NamespacedName, podCount)
        if err != nil {
            rlog.Error(err, fmt.Sprintf("get podcount %s/%s err during reconcile.", req.Namespace, req.Name))
            return ctrl.Result{}, nil
        }
        podCountCopy := podCount.DeepCopy()
        if podCount.Spec.Count <= 0 {
            podCountCopy.Status.Count = 0
        } else {
            podCountCopy.Status.Count = podCount.Spec.Count
        }
    
        err = r.Client.Status().Update(ctx, podCountCopy)
        if err != nil {
            rlog.Error(err, fmt.Sprintf("update crd podcount status error %s/%s  during reconcile.", req.Namespace, req.Name))
        }
        //r.Status().Update(ctx, podCountCopy, metav1.UpdateOptions{})
        // TODO(user): your logic here
    
        return ctrl.Result{}, err
    }
    

    5. make manifests, 创建crd的相关yaml

     ~/go/src/github.com/zoux86/operator-example # make manifests
    /Users/game-netease/go/src/github.com/zoux86/operator-example/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
    

    执行make manifests之后,我们会得到2个文件。

    config/crd/bases/
    config/rbac/role.yaml
    
    
    # cat config/rbac/role.yaml
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      creationTimestamp: null
      name: manager-role
    rules:
    - apiGroups:
      - zouxapp.github.com
      resources:
      - podcounts
      verbs:
      - create
      - delete
      - get
      - list
      - patch
      - update
      - watch
    - apiGroups:
      - zouxapp.github.com
      resources:
      - podcounts/finalizers
      verbs:
      - update
    - apiGroups:
      - zouxapp.github.com
      resources:
      - podcounts/status
      verbs:
      - get
      - patch
      - update
    
    # cat config/crd/bases/zouxapp.github.com_podcounts.yaml
    ---
    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      annotations:
        controller-gen.kubebuilder.io/version: v0.8.0
      creationTimestamp: null
      name: podcounts.zouxapp.github.com
    spec:
      group: zouxapp.github.com
      names:
        kind: PodCount
        listKind: PodCountList
        plural: podcounts
        singular: podcount
      scope: Namespaced
      versions:
      - name: v1
        schema:
          openAPIV3Schema:
            description: PodCount is the Schema for the podcounts API
            properties:
              apiVersion:
                description: 'APIVersion defines the versioned schema of this representation
                  of an object. Servers should convert recognized schemas to the latest
                  internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
                type: string
              kind:
                description: 'Kind is a string value representing the REST resource this
                  object represents. Servers may infer this from the endpoint the client
                  submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
                type: string
              metadata:
                type: object
              spec:
                description: PodCountSpec defines the desired state of PodCount
                properties:
                  count:
                    description: Foo is an example field of PodCount. Edit podcount_types.go
                      to remove/update
                    type: integer
                type: object
              status:
                description: PodCountStatus defines the observed state of PodCount
                properties:
                  count:
                    description: 'INSERT ADDITIONAL STATUS FIELD - define observed state
                      of cluster Important: Run "make" to regenerate code after modifying
                      this file'
                    type: integer
                type: object
            type: object
        served: true
        storage: true
        subresources:
          status: {}
    status:
      acceptedNames:
        kind: ""
        plural: ""
      conditions: []
      storedVersions: []
    

    6. 在集群中部署crd

     ~/go/src/github.com/zoux86/operator-example #kubectl  --kubeconfig=kubeconfig get node create -f config/crd/bases
    customresourcedefinition.apiextensions.k8s.io/podcounts.zouxapp.github.com created
    
     ~/go/src/github.com/zoux86/operator-example # kubectl --kubeconfig=kubeconfig create -f config/samples/zouxapp_v1_podcount.yaml 
    podcount.zouxapp.github.com/podcount-sample created
    

    上集群验证,可以看到创建成功了,但是可以看出来没有status.count,这个因为集群还没部署控制器

    root# kubectl get crd   | grep podc
    podcounts.zouxapp.github.com                            2022-08-25T06:57:09Z
    
    
    root # kubectl get podcounts.zouxapp.github.com
    NAME              AGE
    podcount-sample   11s
    
    root # kubectl get podcounts.zouxapp.github.com -oyaml
    apiVersion: v1
    items:
    - apiVersion: zouxapp.github.com/v1
      kind: PodCount
      metadata:
        creationTimestamp: "2022-08-25T07:01:16Z"
        generation: 1
        name: podcount-sample
        namespace: default
        resourceVersion: "467368378"
        selfLink: /apis/zouxapp.github.com/v1/namespaces/default/podcounts/podcount-sample
        uid: a8b42a4c-1ebd-430a-890f-b0238f4ad125
      spec:
        count: 3
    kind: List
    metadata:
      resourceVersion: ""
      selfLink: ""
    

    7. 部署controller

    之前 CRD 并不会完成任何工作,只是在 ETCD 中创建了一条记录。所以我们需要部署写的controller。

    运行CRD controller

     ~/go/src/github.com/zoux86/operator-example ## go run ./main.go
    I0825 15:35:12.827589   63628 request.go:665] Waited for 1.000074041s due to client-side throttling, not priority and fairness, request: GET:https://xxx/apis/apiextensions.k8s.io/v1?timeout=32s
    1.6614129137223601e+09  INFO    controller-runtime.metrics      Metrics server is starting to listen    {"addr": ":8080"}
    1.6614129137230568e+09  INFO    setup   starting manager
    1.661412913723448e+09   INFO    Starting server {"path": "/metrics", "kind": "metrics", "addr": "[::]:8080"}
    1.661412913723448e+09   INFO    Starting server {"kind": "health probe", "addr": "[::]:8081"}
    1.661412913723506e+09   INFO    controller.podcount     Starting EventSource    {"reconciler group": "zouxapp.github.com", "reconciler kind": "PodCount", "source": "kind source: *v1.PodCount"}
    1.661412913723542e+09   INFO    controller.podcount     Starting Controller     {"reconciler group": "zouxapp.github.com", "reconciler kind": "PodCount"}
    1.661412913825421e+09   INFO    controller.podcount     Starting workers        {"reconciler group": "zouxapp.github.com", "reconciler kind": "PodCount", "worker count": 1}
    I0825 15:35:13.825542   63628 podcount_controller.go:50] start to reconciling podCount podcount-sample
    I0825 15:35:13.868618   63628 podcount_controller.go:50] start to reconciling podCount podcount-sample
    
    

    查看发现生效了

    root# kubectl get podcounts.zouxapp.github.com -oyaml
    apiVersion: v1
    items:
    - apiVersion: zouxapp.github.com/v1
      kind: PodCount
      metadata:
        creationTimestamp: "2022-08-25T07:01:16Z"
        generation: 1
        name: podcount-sample
        namespace: default
        resourceVersion: "467385745"
        selfLink: /apis/zouxapp.github.com/v1/namespaces/default/podcounts/podcount-sample
        uid: a8b42a4c-1ebd-430a-890f-b0238f4ad125
      spec:
        count: 3
      status:
        count: 3
    kind: List
    metadata:
      resourceVersion: ""
      selfLink: ""
    

    相关文章

      网友评论

        本文标题:从0到1使用kubebuilder创建crd

        本文链接:https://www.haomeiwen.com/subject/fidhortx.html