对于自定义资源,需要编写对应的 custom controller( 亦即 operator)来进行对应的资源控制。本文主要记录我的操作过程
详细的教程也可以参考官方教程: github.com/kubernetes/…
1. 下载code-generatorrepo
下载code-generatorrepo, 切换到对应的分支,分支选择建议与你的k8s版本匹配,我的版本是1.23.4,对应的code-generator版本为0.23.3
git clone https://github.com/kubernetes/code-generator
git checkout v0.23.3
或者
git checkout kubernetes-1.23.4
2. 编译项目, 生成对应的gen文件
报错:
go install code-generator/cmd/{client-gen,lister-gen,informer-gen,deepcopy-gen}
package code-generator/cmd/client-gen is not in GOROOT (/usr/local/Cellar/go/1.18.2/libexec/src/code-generator/cmd/client-gen)
package code-generator/cmd/lister-gen is not in GOROOT (/usr/local/Cellar/go/1.18.2/libexec/src/code-generator/cmd/lister-gen)
package code-generator/cmd/informer-gen is not in GOROOT (/usr/local/Cellar/go/1.18.2/libexec/src/code-generator/cmd/informer-gen)
package code-generator/cmd/deepcopy-gen is not in GOROOT (/usr/local/Cellar/go/1.18.2/libexec/src/code-generator/cmd/deepcopy-gen)
这一步也可以不执行,在后续调用
generate-group.sh时自动安装
由于我的repo不在gopath下,替换为使用绝对路径
go install ./cmd/{client-gen,lister-gen,informer-gen,deepcopy-gen}
生成结束后,可以在$(go env GOPATH)/bin/目录下看到刚刚的编译成果物,例如我刚刚就编译生成了:
➜ bin ls -alht
total 711792
drwxr-xr-x 29 admin staff 928B 5 14 17:23 .
-rwxr-xr-x 1 admin staff 8.7M 5 14 17:23 client-gen
-rwxr-xr-x 1 admin staff 8.5M 5 14 17:23 informer-gen
-rwxr-xr-x 1 admin staff 8.4M 5 14 17:23 lister-gen
-rwxr-xr-x 1 admin staff 8.1M 5 14 17:23 deepcopy-gen
上一个步骤中生成的bin文件一般不会直接调用,而是通过code-generator中的脚本generate-groups进行调用。
这个脚本的作用是用于生成crd所需的项目代码
3. 编写初始化文件
可以参考官方给的sample进行改写, kubernetes/sample-controller: Repository for sample controller. Complements sample-apiserver (github.com)
或者直接在Kubernetes仓库的如下目录中:vendor/k8s.io/sample-controller 、staging/src/k8s.io/sample-apiserver。
4. 初始化步骤
├── pkg
│ └── apis
│ └── crd.example.com // group
│ └── v1 // version
│ ├── doc.go
│ ├── register.go
│ └── types.go
目录层级为pkg/{group}/{version}/, 需要自己创建的文件为doc.go/redister.go/types.go
下载依赖: go get -d k8s.io/sample-controller
5. 改写文件
- doc.go:
//+k8s:deepcopy-gen=package
//+groupName=crd.example.com
-
types.go: 直接copy
-
register: 拷贝后进行修改
- 修正:SchemeGroupVersion 的Group和Version
varSchemeGroupVersion=schema.GroupVersion{Group:"crd.example.com",Version:"v1"}
- addKnownTypes: Foo和FooList因为没有zz_generated.deepcopy.go文件,所以会存在告警,后续生成后就好了
6.生成deepcopy及其他文件
使用脚本生成文件
➜ code-generator git:(fb849a7) ✗ /Users/admin/work/k8s/demo/CRD/code-generator/code-generator/generate-groups.sh all github.com/jijunhua/k8s-demo/operator-crd/pkg/generated github.com/jijunhua/k8s-demo/operator-crd/pkg/apis crd.example.com:v1 --go-header-file=/Users/admin/work/k8s/demo/CRD/code-generator/code-generator/hack/boilerplate.go.txt
Generating deepcopy funcs
Generating clientset for crd.example.com:v1 at github.com/jijunhua/k8s-demo/operator-crd/generated/clientset
Generating listers for crd.example.com:v1 at github.com/jijunhua/k8s-demo/operator-crd/generated/listers
Generating informers for crd.example.com:v1 at github.com/jijunhua/k8s-demo/operator-crd/generated/informers
这个时候代码生成在 ${GOPATH}/github.com/jijunhua/k8s-demo/operator-crd/generated下
如果需要生成到指定目录,使用--output-base指定到你的src层级目录
生成完成后, 刚刚的Foo报错就没了
7. 写一个operator demo
package main
import (
"context"
"log"
clientset "github.com/jijunhua/k8s-demo/operator-crd/pkg/generated/clientset/versioned"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/clientcmd"
)
func main() {
config, err := clientcmd.BuildConfigFromFlags("", clientcmd.RecommendedHomeFile)
if err != nil {
klog.Fatalln(err)
return
}
client, err := clientset.NewForConfig(config)
if err != nil {
klog.Fatalln(err)
return
}
list, err := client.CrdV1().Foos("default").List(context.TODO(), metav1.ListOptions{})
if err != nil {
klog.Fatalln(err)
return
}
for _, foo := range list.Items {
klog.Infof("%+v", foo.Name)
}
}
8. 注册foo crd + 运行
如果尚未注册过foo这个crd,会报错:
2022/05/15 14:53:21 the server could not find the requested resource (get foos.crd.example.com)
有关foo这个crd的定义,可以在sample-controller项目中找到。复制并修改对应的group 及version后,应用一下
# create a CustomResourceDefinition
kubectl create -f artifacts/examples/crd-status-subresource.yaml
# create a custom resource of type Foo
kubectl create -f artifacts/examples/example-foo.yaml
运行结果
I0515 16:44:48.170289 21692 main.go:34] example-foo
其他:
后续应该还有controller的编写,这里不详细描述。 controller及新项目的构建可以完成参考:github.com/kubernetes/… 进行修改实现。
code-generator中提供了一个更详细的参考实例,Kubernetes Deep Dive: Code Generation for CustomResources (redhat.com)