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 注册的更新事件和删除事件会被触发。