zoukankan      html  css  js  c++  java
  • CRD自定义控制器

    一、创建自定义CRD

    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      name: crontabs.stable.example.com
    spec:
      group: stable.example.com
      versions:
      - name: v1beta1  
        served: true 
        storage: true 
        schema:  
          openAPIV3Schema:
            description: Define CronTab YAML Spec
            type: object
            properties:
              spec:
                type: object
                properties:
                  cronSpec:
                    type: string
                  image:
                    type: string
                  replicas:
                    type: integer
      scope: Namespaced
      names:
        kind: CronTab
        plural: crontabs
        singular: crontab    
        shortNames:
        - ct
    

    二、初始化项目并且导入包

    1、初始化项目

    $ mkdir -p github.com/cnych/controller-demo && cd github.com/cnych/controller-demo
    # 初始化项目
    $ go mod init github.com/cnych/controller-demo
    go: creating new go.mod: module github.com/cnych/controller-demo
    # 获取依赖
    $ go get k8s.io/apimachinery@v0.17.9
    $ go get -d k8s.io/code-generator@v0.17.9
    $ go get k8s.io/client-go@v0.17.9
    

    2、在当前项目目录建立好自己的 CRD 结构体,然后使用code-generator 生成客户端代码:

    mkdir -p pkg/apis/stable/v1beta1
    

    3、在该文件夹中新建 doc.go 文件,内容如下所示:

    // +k8s:deepcopy-gen=package
    // +groupName=stable.example.com
    
    package v1beta1
    

    4、新建 type.go 文件

    package v1beta1
    
    import (
     metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    )
    
    // +genclient
    // +genclient:noStatus
    // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
    
    // 根据 CRD 定义 CronTab 结构体
    type CronTab struct {
     metav1.TypeMeta `json:",inline"`
     // +optional
     metav1.ObjectMeta `json:"metadata,omitempty"`
     Spec              CronTabSpec `json:"spec"`
    }
    
    // +k8s:deepcopy-gen=false
    
    type CronTabSpec struct {
     CronSpec string `json:"cronSpec"`
     Image    string `json:"image"`
     Replicas int    `json:"replicas"`
    }
    
    // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
    
    // CronTab 资源列表
    type CronTabList struct {
     metav1.TypeMeta `json:",inline"`
    
     // 标准的 list metadata
     // +optional
     metav1.ListMeta `json:"metadata,omitempty"`
    
     Items []CronTab `json:"items"`
    }
    

    5、还需要提供 AddToScheme 与 Resource 两个变量供 client 注册,新建 register.go 文件,内容如下所示

    package v1beta1
    
    import (
     metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
     "k8s.io/apimachinery/pkg/runtime"
     "k8s.io/apimachinery/pkg/runtime/schema"
    )
    
    // GroupName is the group name use in this package
    const GroupName = "stable.example.com"
    // 注册自己的自定义资源
    var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"}
    
    // Resource takes an unqualified resource and returns a Group qualified GroupResource
    func Resource(resource string) schema.GroupResource {
     return SchemeGroupVersion.WithResource(resource).GroupResource()
    }
    
    var (
     // SchemeBuilder initializes a scheme builder
     SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
     // AddToScheme is a global function that registers this API group & version to a scheme
     AddToScheme = SchemeBuilder.AddToScheme
    )
    
    // Adds the list of known types to Scheme.
    func addKnownTypes(scheme *runtime.Scheme) error {
      // 添加 CronTab 与 CronTabList 这两个资源到 scheme
     scheme.AddKnownTypes(SchemeGroupVersion,
      &CronTab{},
      &CronTabList{},
     )
     metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
     return nil
    }
    

    6、最终的项目结构如图

    $ tree .
    .
    ├── go.mod
    ├── go.sum
    └── pkg
        └── apis
            └── stable
                └── v1beta1
                    ├── doc.go
                    ├── register.go
                    └── types.go
    
    4 directories, 5 files
    

    三、生成代码

    1、项目目录下创建目录

    mkdir hack && cd hack
    

    2、创建tools.go文件

    // +build tools
    
    // 建立 tools.go 来依赖 code-generator
    // 因为在没有代码使用 code-generator 时,go module 默认不会为我们依赖此包.
    package tools
    
    import _ "k8s.io/code-generator"
    

    3、创建update-codegen.sh 脚本

    #!/usr/bin/env bash
    
    set -o errexit
    set -o nounset
    set -o pipefail
    
    SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
    CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)}
    
    bash "${CODEGEN_PKG}"/generate-groups.sh "deepcopy,client,informer,lister" 
      github.com/cnych/controller-demo/pkg/client github.com/cnych/controller-demo/pkg/apis 
      stable:v1beta1 
      --output-base "${SCRIPT_ROOT}"/../../.. 
      --go-header-file "${SCRIPT_ROOT}"/hack/boilerplate.go.txt
    
    # To use your own boilerplate text append:
    #   --go-header-file "${SCRIPT_ROOT}"/hack/custom-boilerplate.go.txt
    

    4、创建verify-codegen.sh 脚本

    #!/usr/bin/env bash
    
    set -o errexit
    set -o nounset
    set -o pipefail
    
    SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
    
    DIFFROOT="${SCRIPT_ROOT}/pkg"
    TMP_DIFFROOT="${SCRIPT_ROOT}/_tmp/pkg"
    _tmp="${SCRIPT_ROOT}/_tmp"
    
    cleanup() {
      rm -rf "${_tmp}"
    }
    trap "cleanup" EXIT SIGINT
    
    cleanup
    
    mkdir -p "${TMP_DIFFROOT}"
    cp -a "${DIFFROOT}"/* "${TMP_DIFFROOT}"
    
    "${SCRIPT_ROOT}/hack/update-codegen.sh"
    echo "diffing ${DIFFROOT} against freshly generated codegen"
    ret=0
    diff -Naupr "${DIFFROOT}" "${TMP_DIFFROOT}" || ret=$?
    cp -a "${TMP_DIFFROOT}"/* "${DIFFROOT}"
    if [[ $ret -eq 0 ]]
    then
      echo "${DIFFROOT} up to date."
    else
      echo "${DIFFROOT} is out of date. Please run hack/update-codegen.sh"
      exit 1
    fi
    

    5、为生成的代码文件添加头部内容的 boilerplate.go.txt 文件,内容如下所示

    /*
    Copyright The Kubernetes Authors.
    
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
    
        http://www.apache.org/licenses/LICENSE-2.0
    
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    */
    

    6、接下来就是生成代码了,首先将依赖包放置到 vendor 目录中去

    go mod vendor
    

    7、然后执行脚本生成代码

    $ chmod +x ./hack/update-codegen.sh
    $ ./hack/update-codegen.sh
    Generating deepcopy funcs
    Generating clientset for stable:v1beta1 at github.com/cnych/controller-demo/pkg/client/clientset
    Generating listers for stable:v1beta1 at github.com/cnych/controller-demo/pkg/client/listers
    Generating informers for stable:v1beta1 at github.com/cnych/controller-demo/pkg/client/informers
    

    8、代码生成后,整个项目的 pkg 包变成了下面的样子:

    $ tree pkg
    pkg
    ├── apis
    │   └── stable
    │       └── v1beta1
    │           ├── doc.go
    │           ├── register.go
    │           ├── types.go
    │           └── zz_generated.deepcopy.go
    └── client
        ├── clientset
        │   └── versioned
        │       ├── clientset.go
        │       ├── doc.go
        │       ├── fake
        │       │   ├── clientset_generated.go
        │       │   ├── doc.go
        │       │   └── register.go
        │       ├── scheme
        │       │   ├── doc.go
        │       │   └── register.go
        │       └── typed
        │           └── stable
        │               └── v1beta1
        │                   ├── crontab.go
        │                   ├── doc.go
        │                   ├── fake
        │                   │   ├── doc.go
        │                   │   ├── fake_crontab.go
        │                   │   └── fake_stable_client.go
        │                   ├── generated_expansion.go
        │                   └── stable_client.go
        ├── informers
        │   └── externalversions
        │       ├── factory.go
        │       ├── generic.go
        │       ├── internalinterfaces
        │       │   └── factory_interfaces.go
        │       └── stable
        │           ├── interface.go
        │           └── v1beta1
        │               ├── crontab.go
        │               └── interface.go
        └── listers
            └── stable
                └── v1beta1
                    ├── crontab.go
                    └── expansion_generated.go
    
    20 directories, 26 files
    

     

  • 相关阅读:
    夜空中最亮的星
    让我留在你身边
    反思
    又想起民谣那诗
    初学积性函数
    P1049 装箱问题(01背包)
    set
    紫书 习题 10-4 UVa 1644(素数筛)
    紫书 习题 10-2 UVa 808(建立坐标+找规律)
    紫书 习题 10-1UVa 111040(找规律)
  • 原文地址:https://www.cnblogs.com/wuchangblog/p/14267844.html
Copyright © 2011-2022 走看看