k8s实践之自定义控制器crd编写

本篇文章我们实践用k8s编写一个自定义控制器,文章参考自极客时间张磊老师的课程:深入剖析 Kubernetes。

1.自定义控制器项目

首先我们在 GOPATH 下,创建一个结构如下的项目:

$ tree $GOPATH/src/github.com/qxcheng/k8s-controller-custom-resource
.
├── controller.go
├── crd
│   └── network.yaml
├── example
│   └── example-network.yaml
├── main.go
└── pkg
    └── apis
        └── samplecrd
            ├── register.go
            └── v1
                ├── doc.go
                ├── register.go
                └── types.go

源码请参考: https://github.com/resouer/k8s-controller-custom-resource

注意将其中的相关import路径修改为自己的本地路径。例如:

"github.com/resouer/k8s-controller-custom-resource/pkg/apis/samplecrd"
->
"github.com/qxcheng/k8s-controller-custom-resource/pkg/apis/samplecrd"

2.代码生成

接下来,使用 Kubernetes 提供的代码生成工具,为上面定义的 Network 资源类型自动生成 clientset、informer 和 lister。

# 首先清空main.go controller.go

cd /root/go18/src/github.com/qxcheng/k8s-controller-custom-resource/
go mod init github.com/qxcheng/k8s-controller-custom-resource
go mod tidy
go install k8s.io/code-generator/...@latest

ROOT_PACKAGE="github.com/qxcheng/k8s-controller-custom-resource"
CUSTOM_RESOURCE_NAME="samplecrd"
CUSTOM_RESOURCE_VERSION="v1"
EXEC_DIR=$GOPATH/pkg/mod/k8s.io/code-generator@v0.26.2  # 版本号注意核对

# 脚本需要使用chmod授予执行权限
"${EXEC_DIR}"/generate-groups.sh all "$ROOT_PACKAGE/pkg/client" "$ROOT_PACKAGE/pkg/apis" "$CUSTOM_RESOURCE_NAME:$CUSTOM_RESOURCE_VERSION" --go-header-file "${EXEC_DIR}"/hack/boilerplate.go.txt -v 10

代码生成工作完成之后,我们再查看一下这个项目的目录结构:

$ tree
.
├── controller.go
├── crd
│   └── network.yaml
├── example
│   └── example-network.yaml
├── main.go
└── pkg
    ├── apis
    │   └── samplecrd
    │       ├── register.go
    │       └── v1
    │           ├── doc.go
    │           ├── register.go
    │           ├── types.go
    │           └── zz_generated.deepcopy.go
    └── client
        ├── clientset
        ├── informers
        └── listers

3.编译运行项目

# 将main.go和controller.go恢复。

$ go build -o samplecrd-controller .

$ ./samplecrd-controller -kubeconfig=$HOME/.kube/config -alsologtostderr=true
I0915 12:50:29.051349   27159 controller.go:84] Setting up event handlers
I0915 12:50:29.051615   27159 controller.go:113] Starting Network control loop
I0915 12:50:29.051630   27159 controller.go:116] Waiting for informer caches to sync
E0915 12:50:29.066745   27159 reflector.go:134] github.com/resouer/k8s-controller-custom-resource/pkg/client/informers/externalversions/factory.go:117: Failed to list *v1.Network: the server could not find the requested resource (get networks.samplecrd.k8s.io)
...

在另一个 shell 窗口里执行:

$ kubectl apply -f crd/network.yaml
$ kubectl apply -f example/example-network.yaml

network.yaml如果不可用请参考:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: networks.samplecrd.k8s.io
  annotations:
    "api-approved.kubernetes.io": "https://github.com/kubernetes/kubernetes/pull/78458"
spec:
  group: samplecrd.k8s.io
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        # 校验方法
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                #类型校验
                cidr:
                  type: string
                gateway:
                  type: string
  names:
    kind: Network
    plural: networks
    singular: network
  scope: Namespaced

这时候对example-network.yaml进行更新和删除,可以观察到Informer 注册的更新事件和删除事件会被触发。

posted @ 2023-03-20 14:58  qxcheng  阅读(373)  评论(0编辑  收藏  举报