1、脚手架工具 Operator的实现方式主要包括OperatorSDK和KubeBuilder,目前KubeBuilder在阿里使用的比较多。
KubeBuilder
OperatorSDK
我们这里主要是用KubeBuilder来进行,其中OperatorSDK其实也是应用了KubeBuilder。
2、创建Operator工程 创建脚手架工程:
1 2 3 4 5 mkdir myapp-operator cd myapp-operator/ go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct kubebuilder init --domain kubenode.kingtest.com
创建脚手架结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 kubebuilder init --domain kubenode.kingtest.com INFO Writing kustomize manifests for you to edit... INFO Writing scaffold for you to edit... INFO Get controller runtime: $ go get sigs.k8s.io/controller-runtime@v0.19.0 go: downloading sigs.k8s.io/controller-runtime v0.19.0 go: downloading k8s.io/apimachinery v0.31.0 go: downloading k8s.io/api v0.31.0 go: downloading k8s.io/client-go v0.31.0 go: downloading k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 go: downloading github.com/go-logr/logr v1.4.2 go: downloading k8s.io/klog/v2 v2.130.1 go: downloading golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc go: downloading github.com/evanphx/json-patch/v5 v5.9.0 go: downloading github.com/prometheus/client_golang v1.19.1 go: downloading gomodules.xyz/jsonpatch/v2 v2.4.0 go: downloading github.com/gogo/protobuf v1.3.2 go: downloading github.com/google/gofuzz v1.2.0 go: downloading sigs.k8s.io/structured-merge-diff/v4 v4.4.1 go: downloading k8s.io/apiextensions-apiserver v0.31.0 go: downloading sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd go: downloading k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 go: downloading github.com/google/uuid v1.6.0 go: downloading github.com/prometheus/client_model v0.6.1 go: downloading github.com/prometheus/common v0.55.0 go: downloading github.com/fsnotify/fsnotify v1.7.0 go: downloading golang.org/x/net v0.26.0 go: downloading gopkg.in/inf.v0 v0.9.1 go: downloading github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da go: downloading github.com/imdario/mergo v0.3.6 go: downloading github.com/spf13/pflag v1.0.5 go: downloading golang.org/x/term v0.21.0 go: downloading github.com/golang/protobuf v1.5.4 go: downloading github.com/google/gnostic-models v0.6.8 go: downloading golang.org/x/time v0.3.0 go: downloading sigs.k8s.io/yaml v1.4.0 go: downloading github.com/beorn7/perks v1.0.1 go: downloading github.com/cespare/xxhash/v2 v2.3.0 go: downloading github.com/prometheus/procfs v0.15.1 go: downloading golang.org/x/sys v0.21.0 go: downloading google.golang.org/protobuf v1.34.2 go: downloading golang.org/x/oauth2 v0.21.0 go: downloading github.com/json-iterator/go v1.1.12 go: downloading gopkg.in/yaml.v2 v2.4.0 go: downloading github.com/fxamacker/cbor/v2 v2.7.0 go: downloading github.com/google/go-cmp v0.6.0 go: downloading gopkg.in/yaml.v3 v3.0.1 go: downloading github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc go: downloading github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 go: downloading github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd go: downloading github.com/modern-go/reflect2 v1.0.2 go: downloading github.com/go-openapi/jsonreference v0.20.2 go: downloading github.com/go-openapi/swag v0.22.4 go: downloading golang.org/x/text v0.16.0 go: downloading github.com/go-openapi/jsonpointer v0.19.6 go: downloading github.com/emicklei/go-restful/v3 v3.11.0 go: downloading github.com/mailru/easyjson v0.7.7 go: downloading github.com/josharian/intern v1.0.0 go: downloading github.com/x448/float16 v0.8.4 go: downloading github.com/pkg/errors v0.9.1 INFO Update dependencies: $ go mod tidy go: downloading github.com/onsi/ginkgo/v2 v2.19.0 go: downloading github.com/stretchr/testify v1.9.0 go: downloading github.com/onsi/gomega v1.33.1 go: downloading github.com/go-logr/zapr v1.3.0 go: downloading go.uber.org/zap v1.26.0 go: downloading k8s.io/apiserver v0.31.0 go: downloading go.uber.org/goleak v1.3.0 go: downloading github.com/evanphx/json-patch v0.5.2 go: downloading gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c go: downloading gopkg.in/evanphx/json-patch.v4 v4.12.0 go: downloading github.com/kr/pretty v0.3.1 go: downloading go.uber.org/multierr v1.11.0 go: downloading github.com/go-task/slim-sprig/v3 v3.0.0 go: downloading golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d go: downloading github.com/google/pprof v0.0.0-20240525223248-4bfdf5a9a2af go: downloading github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 go: downloading github.com/rogpeppe/go-internal v1.12.0 go: downloading github.com/kr/text v0.2.0 go: downloading k8s.io/component-base v0.31.0 go: downloading go.opentelemetry.io/otel v1.28.0 go: downloading go.opentelemetry.io/otel/trace v1.28.0 go: downloading google.golang.org/grpc v1.65.0 go: downloading sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 go: downloading golang.org/x/sync v0.7.0 go: downloading github.com/google/cel-go v0.20.1 go: downloading github.com/blang/semver/v4 v4.0.0 go: downloading go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 go: downloading go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 go: downloading go.opentelemetry.io/otel/sdk v1.28.0 go: downloading google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 go: downloading github.com/felixge/httpsnoop v1.0.4 go: downloading go.opentelemetry.io/otel/metric v1.28.0 go: downloading github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a go: downloading github.com/go-logr/stdr v1.2.2 go: downloading google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 go: downloading github.com/antlr4-go/antlr/v4 v4.13.0 go: downloading google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d go: downloading github.com/spf13/cobra v1.8.1 go: downloading github.com/stoewer/go-strcase v1.2.0 go: downloading github.com/inconshreveable/mousetrap v1.1.0 go: downloading go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 go: downloading github.com/cenkalti/backoff/v4 v4.3.0 go: downloading go.opentelemetry.io/proto/otlp v1.3.1 go: downloading github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 go: downloading github.com/grpc-ecosystem/grpc-gateway v1.16.0 Next: define a resource with: $ kubebuilder create api
本步骤创建了 Go module 工程的模板文件,引入了必要的依赖。 这里先设置了go的代理,不然会无法下载依赖。 第一次新建工程时,会下载一些依赖(go: downloading 。。。) 查看此时的项目结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 . ├── cmd │ └── main.go ├── config │ ├── default │ │ ├── kustomization.yaml │ │ ├── manager_metrics_patch.yaml │ │ └── metrics_service.yaml │ ├── manager │ │ ├── kustomization.yaml │ │ └── manager.yaml │ ├── network-policy │ │ ├── allow-metrics-traffic.yaml │ │ └── kustomization.yaml │ ├── prometheus │ │ ├── kustomization.yaml │ │ └── monitor.yaml │ └── rbac │ ├── kustomization.yaml │ ├── leader_election_role_binding.yaml │ ├── leader_election_role.yaml │ ├── metrics_auth_role_binding.yaml │ ├── metrics_auth_role.yaml │ ├── metrics_reader_role.yaml │ ├── role_binding.yaml │ ├── role.yaml │ └── service_account.yaml ├── Dockerfile ├── go.mod ├── go.sum ├── hack │ └── boilerplate.go.txt ├── Makefile ├── PROJECT ├── README.md └── test ├── e2e │ ├── e2e_suite_test.go │ └── e2e_test.go └── utils └── utils.go 12 directories, 29 files
创建API,生成CRD和Controller:
1 kubebuilder create api --group apps --version v1 --kind Myapp
参数含义:
group参数表示组的概念
version定义版本
kind定义自定义资源类型
以上参数组成 自定义yaml 的 apiVersion和kind
执行kubebuilder create api时直接带上–namespaced=false可以将该对象设计为集群级别(类似node、pv)
创建API结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 kubebuilder create api --group apps --version v1 --kind Myapp INFO Create Resource [y/n] y INFO Create Controller [y/n] y INFO Writing kustomize manifests for you to edit... INFO Writing scaffold for you to edit... INFO api/v1/myapp_types.go INFO api/v1/groupversion_info.go INFO internal/controller/suite_test.go INFO internal/controller/myapp_controller.go INFO internal/controller/myapp_controller_test.go INFO Update dependencies: $ go mod tidy INFO Running make: $ make generate mkdir -p /home/king/workspace/king-devops/operator/myapp-operator/bin Downloading sigs.k8s.io/controller-tools/cmd/controller-gen@v0.16.1 go: downloading sigs.k8s.io/controller-tools v0.16.1 go: downloading github.com/fatih/color v1.17.0 go: downloading golang.org/x/tools v0.24.0 go: downloading github.com/gobuffalo/flect v1.0.2 go: downloading golang.org/x/net v0.28.0 go: downloading github.com/mattn/go-isatty v0.0.20 go: downloading github.com/mattn/go-colorable v0.1.13 go: downloading golang.org/x/sys v0.23.0 go: downloading golang.org/x/sync v0.8.0 go: downloading golang.org/x/mod v0.20.0 go: downloading golang.org/x/text v0.17.0 /home/king/workspace/king-devops/operator/myapp-operator/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
此时的目录结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 . ├── api │ └── v1 │ ├── groupversion_info.go │ ├── myapp_types.go │ └── zz_generated.deepcopy.go ├── bin │ ├── controller-gen -> /home/king/workspace/king-devops/operator/myapp-operator/bin/controller-gen-v0.16.1 │ └── controller-gen-v0.16.1 ├── cmd │ └── main.go ├── config │ ├── crd │ │ ├── kustomization.yaml │ │ └── kustomizeconfig.yaml │ ├── default │ │ ├── kustomization.yaml │ │ ├── manager_metrics_patch.yaml │ │ └── metrics_service.yaml │ ├── manager │ │ ├── kustomization.yaml │ │ └── manager.yaml │ ├── network-policy │ │ ├── allow-metrics-traffic.yaml │ │ └── kustomization.yaml │ ├── prometheus │ │ ├── kustomization.yaml │ │ └── monitor.yaml │ ├── rbac │ │ ├── kustomization.yaml │ │ ├── leader_election_role_binding.yaml │ │ ├── leader_election_role.yaml │ │ ├── metrics_auth_role_binding.yaml │ │ ├── metrics_auth_role.yaml │ │ ├── metrics_reader_role.yaml │ │ ├── myapp_editor_role.yaml │ │ ├── myapp_viewer_role.yaml │ │ ├── role_binding.yaml │ │ ├── role.yaml │ │ └── service_account.yaml │ └── samples │ ├── apps_v1_myapp.yaml │ └── kustomization.yaml ├── Dockerfile ├── go.mod ├── go.sum ├── hack │ └── boilerplate.go.txt ├── internal │ └── controller │ ├── myapp_controller.go │ ├── myapp_controller_test.go │ └── suite_test.go ├── Makefile ├── PROJECT ├── README.md └── test ├── e2e │ ├── e2e_suite_test.go │ └── e2e_test.go └── utils └── utils.go 19 directories, 43 files
如果需要在Nginx CRUD 时进行合法性检查, 可以生成webhook:
1 kubebuilder create webhook --group apps --version v1 --kind Myapp --conversion --defaulting --programmatic-validation
参数含义:
group参数表示组的概念
version定义版本
kind定义自定义资源类型
以上参数组成 自定义yaml 的 apiVersion和kind
defaulting:默认值设置(Defaulting) 的目的是在CRD对象创建或更新时,如果某些字段没有被显式设置值,自动为其填充一个合理的默认值。这对于确保资源实例有一套统一的、预先定义的配置非常有用,可以减少用户的配置负担,并保证资源的一致性。例如,如果你定义了一个监控应用的CRD,可能希望默认开启日志记录功能,除非用户明确关闭它。
programmatic-validation:程序化验证(Programmatic Validation) 则是在CRD对象创建或更新前,对提交的数据进行逻辑验证的机制。与CRD schema提供的静态验证相比,程序化验证可以实现更加复杂的业务逻辑验证。这意味着你可以在webhook服务中编写代码来检查CRD实例的数据是否满足特定的业务规则或约束条件。例如,你可以验证一个资源请求的内存配额是否超过了集群的最大允许值,或者确保引用的其他资源确实存在。
conversion:自动数据迁移:conversion webhook可以在后台自动将CRD的一个版本转换为另一个版本,无需人工干预,从而简化了版本升级过程。
兼容性保障:即使API发生变化,也能确保旧客户端和新客户端都能够正常工作,提高了系统的向后和向前兼容性。
复杂逻辑处理:对于简单的字段添加或删除,Kubernetes的自动转换器可能足够用。但涉及到复杂的数据结构调整或逻辑变换时,就需要自定义conversion webhook来精确控制转换过程。
执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 kubebuilder create webhook --group apps --version v1 --kind Myapp --conversion --defaulting --programmatic-validation INFO Writing kustomize manifests for you to edit... INFO Writing scaffold for you to edit... INFO api/v1/myapp_webhook.go INFO api/v1/myapp_webhook_test.go INFO Webhook server has been set up for you. You need to implement the conversion.Hub and conversion.Convertible interfaces for your CRD types. INFO api/v1/webhook_suite_test.go INFO Update dependencies: $ go mod tidy INFO Running make: $ make generate /home/king/workspace/king-devops/operator/myapp-operator/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..." Next: implement your new Webhook and generate the manifests with: $ make manifests
此时目录结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 . ├── api │ └── v1 │ ├── groupversion_info.go │ ├── myapp_types.go │ ├── myapp_webhook.go │ ├── myapp_webhook_test.go │ ├── webhook_suite_test.go │ └── zz_generated.deepcopy.go ├── bin │ ├── controller-gen -> /home/king/workspace/king-devops/operator/myapp-operator/bin/controller-gen-v0.16.1 │ └── controller-gen-v0.16.1 ├── cmd │ └── main.go ├── config │ ├── certmanager │ │ ├── certificate.yaml │ │ ├── kustomization.yaml │ │ └── kustomizeconfig.yaml │ ├── crd │ │ ├── kustomization.yaml │ │ ├── kustomizeconfig.yaml │ │ └── patches │ │ ├── cainjection_in_myapps.yaml │ │ └── webhook_in_myapps.yaml │ ├── default │ │ ├── kustomization.yaml │ │ ├── manager_metrics_patch.yaml │ │ ├── manager_webhook_patch.yaml │ │ ├── metrics_service.yaml │ │ └── webhookcainjection_patch.yaml │ ├── manager │ │ ├── kustomization.yaml │ │ └── manager.yaml │ ├── network-policy │ │ ├── allow-metrics-traffic.yaml │ │ ├── allow-webhook-traffic.yaml │ │ └── kustomization.yaml │ ├── prometheus │ │ ├── kustomization.yaml │ │ └── monitor.yaml │ ├── rbac │ │ ├── kustomization.yaml │ │ ├── leader_election_role_binding.yaml │ │ ├── leader_election_role.yaml │ │ ├── metrics_auth_role_binding.yaml │ │ ├── metrics_auth_role.yaml │ │ ├── metrics_reader_role.yaml │ │ ├── myapp_editor_role.yaml │ │ ├── myapp_viewer_role.yaml │ │ ├── role_binding.yaml │ │ ├── role.yaml │ │ └── service_account.yaml │ ├── samples │ │ ├── apps_v1_myapp.yaml │ │ └── kustomization.yaml │ └── webhook │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ └── service.yaml ├── Dockerfile ├── go.mod ├── go.sum ├── hack │ └── boilerplate.go.txt ├── internal │ └── controller │ ├── myapp_controller.go │ ├── myapp_controller_test.go │ └── suite_test.go ├── Makefile ├── PROJECT ├── README.md └── test ├── e2e │ ├── e2e_suite_test.go │ └── e2e_test.go └── utils └── utils.go 22 directories, 57 files
最终的工程结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 . ├── api │ └── v1 │ ├── groupversion_info.go │ ├── myapp_types.go │ ├── myapp_webhook.go │ ├── myapp_webhook_test.go │ ├── webhook_suite_test.go │ └── zz_generated.deepcopy.go ├── bin │ ├── controller-gen -> /home/king/workspace/king-devops/operator/myapp-operator/bin/controller-gen-v0.16.1 │ └── controller-gen-v0.16.1 ├── cmd │ └── main.go ├── config │ ├── certmanager │ │ ├── certificate.yaml │ │ ├── kustomization.yaml │ │ └── kustomizeconfig.yaml │ ├── crd │ │ ├── kustomization.yaml │ │ ├── kustomizeconfig.yaml │ │ └── patches │ │ ├── cainjection_in_myapps.yaml │ │ └── webhook_in_myapps.yaml │ ├── default │ │ ├── kustomization.yaml │ │ ├── manager_metrics_patch.yaml │ │ ├── manager_webhook_patch.yaml │ │ ├── metrics_service.yaml │ │ └── webhookcainjection_patch.yaml │ ├── manager │ │ ├── kustomization.yaml │ │ └── manager.yaml │ ├── network-policy │ │ ├── allow-metrics-traffic.yaml │ │ ├── allow-webhook-traffic.yaml │ │ └── kustomization.yaml │ ├── prometheus │ │ ├── kustomization.yaml │ │ └── monitor.yaml │ ├── rbac │ │ ├── kustomization.yaml │ │ ├── leader_election_role_binding.yaml │ │ ├── leader_election_role.yaml │ │ ├── metrics_auth_role_binding.yaml │ │ ├── metrics_auth_role.yaml │ │ ├── metrics_reader_role.yaml │ │ ├── myapp_editor_role.yaml │ │ ├── myapp_viewer_role.yaml │ │ ├── role_binding.yaml │ │ ├── role.yaml │ │ └── service_account.yaml │ ├── samples │ │ ├── apps_v1_myapp.yaml │ │ └── kustomization.yaml │ └── webhook │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ └── service.yaml ├── Dockerfile ├── go.mod ├── go.sum ├── hack │ └── boilerplate.go.txt ├── internal │ └── controller │ ├── myapp_controller.go │ ├── myapp_controller_test.go │ └── suite_test.go ├── Makefile ├── PROJECT ├── README.md └── test ├── e2e │ ├── e2e_suite_test.go │ └── e2e_test.go └── utils └── utils.go 22 directories, 57 files
关键目录及其内容的概述:
Dockerfile: 定义了用于构建Operator容器镜像的Docker配置文件。
Makefile: 包含了一系列预定义的Make任务,用于构建、测试、运行和部署Operator。
PROJECT: 存储项目元数据的文件,Kubebuilder使用它来跟踪项目的状态和配置。
README.md: 项目的主要说明文档,通常包含项目简介、安装指南、开发流程等信息。
api/v1: 定义了自定义资源定义(CRD)的目录,其中包含了资源的Go类型定义及DeepCopy生成文件。
myapp_types.go: 资源类型的定义(myapp_types.go)
myapp_webhook.go: webhook逻辑
zz_generated.deepcopy.go: 深拷贝生成代码
groupversion_info.go: 定义了API组和版本信息。
bin: 存放项目依赖的可执行文件,如controller-gen,用于CRD代码生成。
cmd/main.go: Operator的入口点,负责初始化和运行控制器。
config: 配置目录,包含用于Kubernetes资源部署的各种Kustomize配置。
crd/: 用于CRD资源的Kustomize配置。
default/: 应用默认的RBAC、服务等配置。
manager/: Operator Manager的部署配置。
network-policy/, prometheus/, rbac/, samples/: 分别包含网络策略、Prometheus监控配置、RBAC规则和示例资源的配置。
go.mod, go.sum: Go模块管理文件,记录项目依赖。
hack/boilerplate.go.txt: 用于代码生成的模板文件,保持版权头部一致性。
internal/controller: Operator控制器的核心逻辑所在,包含监控资源(Myapp)的控制器实现。
test: 测试相关目录。
e2e/: 端到端测试代码,验证整个Operator在Kubernetes集群上的行为。
utils/: 测试辅助工具和函数。
3、编写代码 下面主要以Deployment为例,核心逻辑是把自定义CR(Myapp)当做终态,把Deployment当做运行态,通过比对属性的不一致,编写相关的Reconcile逻辑。
一张图解释各种资源和 Controller 的关系:
3.1 定义 CRD 在api/v1/myapp_type.go中定义 Spec 和 Status
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 // MyappSpec defines the desired state of Myapp type MyappSpec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // Important: Run "make" to regenerate code after modifying this file // Foo is an example field of Myapp. Edit myapp_types.go to remove/update Foo string `json:"foo,omitempty"` appsv1.DeploymentSpec `json:",inline"` } // MyappStatus defines the observed state of Myapp type MyappStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster // Important: Run "make" to regenerate code after modifying this file appsv1.DeploymentSpec `json:",inline"` } // +kubebuilder:object:root=true // +kubebuilder:subresource:status // Myapp is the Schema for the myapps API type Myapp struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` Spec MyappSpec `json:"spec,omitempty"` Status MyappStatus `json:"status,omitempty"` }
注意+kubebuilder
并非普通注释,不能随意删除。
3.2 编写Reconcile逻辑 在internal/controller/myapp_controller.go中实现 Reconcile 逻辑
1 2 3 4 5 6 7 8 func (r *MyappReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { logger := log.FromContext(ctx) // TODO(user): your logic here logger.Info("start Reconcile" + req.Name) return ctrl.Result{}, nil }
3.3 修改Webhook 在api/v1/myapp_webhook.go中根据需要进行修改
1 2 3 func (r *Myapp) ValidateCreate() error func (r *Myapp) ValidateUpdate(old runtime.Object) error func (r *Myapp) Default()
3.4 修改main入口 以前的老版本kubebuilder生成的项目,需要在cmd/main.go添加监听的namespace 但是新版本没有这个信息,以下是示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, Metrics: metricsServerOptions, WebhookServer: webhookServer, HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, LeaderElectionID: "6a511ed4.kubenode.kingtest.com", // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily // when the Manager ends. This requires the binary to immediately end when the // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly // speeds up voluntary leader transitions as the new leader don't have to wait // LeaseDuration time first. // // In the default scaffold provided, the program ends immediately after // the manager stops, so would be fine to enable this option. However, // if you are doing or is intended to do any operation such as perform cleanups // after the manager stops then its usage might be unsafe. // LeaderElectionReleaseOnCancel: true,
如果想监听固定的namespace信息,可以在Reconcile内实现。