主流operator开发框架的包括operator framework sdk和kubebuilder,前者是redhat开源并维护的一套工具,支持使用go、ansible、helm进行operator开发(其中只有go可以开发到能力级别5的operator,其他两种则不行);而kubebuilder则是kubernetes官方的一个sig(特别兴趣小组)维护的operator开发工具。目前基于operator framework sdk和go进行operator开发时,operator sdk底层使用的也是kubebuilder,所以这里我们就直接使用kubebuilder来开发operator。
Windows下编译安装kubebuilder
kuberbuilder没有直接的Windows版本,所以需要下载源码,编译后使用
可能会clone不下来,直接下下来打开。
原始的go.mod用的是1.19,改成1.8试试
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/kubebuilder-master
$ make build
fatal: not a git repository (or any of the parent directories): .git
fatal: not a git repository (or any of the parent directories): .git
go build -ldflags " -X main.kubeBuilderVersion= -X main.goos=windows -X main.goarch=amd64 -X main.gitCommit= -X main.buildDate=2022-12-04T02:24:32Z " -o bin/kubebuilder ./cmd
build成功了,文件放在bin下了
要把编译后的二进制文件放到Git目录下:C:\Program Files\Git\usr\bin
拷贝过去后进行验证,出现下面这样表示成功
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/kubebuilder-master
$ kubebuilder -v
time="2022-12-04T10:30:29+08:00" level=error msg="could not get plugins root: Host not supported: windows"
time="2022-12-04T10:30:29+08:00" level=error msg="Host not supported: windows"
CLI tool for building Kubernetes extensions and tools.
Usage:
kubebuilder [flags]
kubebuilder [command]
Examples:
The first step is to initialize your project:
kubebuilder init [--plugins=<PLUGIN KEYS> [--project-version=<PROJECT VERSION>]]
<PLUGIN KEYS> is a comma-separated list of plugin keys from the following table
and <PROJECT VERSION> a supported project version for these plugins.
Plugin keys | Supported project versions
------------------------------------------+----------------------------
base.go.kubebuilder.io/v3 | 3
base.go.kubebuilder.io/v4-alpha | 3
declarative.go.kubebuilder.io/v1 | 2, 3
deploy-image.go.kubebuilder.io/v1-alpha | 3
go.kubebuilder.io/v2 | 2, 3
go.kubebuilder.io/v3 | 3
go.kubebuilder.io/v4-alpha | 3
grafana.kubebuilder.io/v1-alpha | 3
kustomize.common.kubebuilder.io/v1 | 3
kustomize.common.kubebuilder.io/v2-alpha | 3
For more specific help for the init command of a certain plugins and project version
configuration please run:
kubebuilder init --help --plugins=<PLUGIN KEYS> [--project-version=<PROJECT VERSION>]
Default plugin keys: "go.kubebuilder.io/v3"
Default project version: "3"
Available Commands:
completion Load completions for the specified shell
create Scaffold a Kubernetes API or webhook
edit Update the project configuration
help Help about any command
init Initialize a new project
version Print the kubebuilder version
Flags:
-h, --help help for kubebuilder
--plugins strings plugin keys to be used for this subcommand execution
--project-version string project version (default "3")
Additional help topics:
kubebuilder alpha Alpha-stage subcommands
Use "kubebuilder [command] --help" for more information about a command.
通过kubebuilder创建一个operator项目
使用kuberbuilder初始化新项目,该命令将下载 controller-runtime 二进制文件,并为我们准备好项目。
zengz@DESKTOP-Q3MJC4 MINGW64 /f/go/project/0-shizhanxiangmu/myk8sOperator
$ kubebuilder init myk8soperator --domain="wendao" --project-name="myk8soperator" --repo="gitee.com/wendao365/myk8soperator" --skip-go-version-check
time="2022-12-04T10:59:52+08:00" level=error msg="could not get plugins root: Host not supported: windows"
time="2022-12-04T10:59:52+08:00" level=error msg="Host not supported: windows"
time="2022-12-04T10:59:52+08:00" level=warning msg="the platform of this environment (windows/amd64) is not suppported by kustomize v3 (v3.8.7) which is used in this scaffold. You will
be unable to download a binary for the kustomize version supported and used by this plugin. The currently supported platforms are: [\"linux/amd64\" \"linux/arm64\" \"darwin/amd64\"]"
Writing kustomize manifests for you to edit...
Writing scaffold for you to edit...
Get controller runtime:
$ go get sigs.k8s.io/controller-runtime@v0.13.1
go: downloading sigs.k8s.io/controller-runtime v0.13.1
go: downloading k8s.io/apimachinery v0.25.0
go: downloading k8s.io/client-go v0.25.0
go: downloading k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed
go: downloading github.com/prometheus/client_golang v1.12.2
go: downloading k8s.io/klog/v2 v2.70.1
go: downloading k8s.io/component-base v0.25.0
go: downloading sigs.k8s.io/structured-merge-diff/v4 v4.2.3
go: downloading golang.org/x/time v0.0.0-20220609170525-579cf78fd858
go: downloading github.com/evanphx/json-patch/v5 v5.6.0
go: downloading k8s.io/api v0.25.0
go: downloading gomodules.xyz/jsonpatch/v2 v2.2.0
go: downloading k8s.io/apiextensions-apiserver v0.25.0
go: downloading sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2
go: downloading github.com/google/gnostic v0.5.7-v3refs
go: downloading k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1
go: downloading golang.org/x/net v0.0.0-20220722155237-a158d28d115b
go: downloading github.com/prometheus/procfs v0.7.3
go: downloading github.com/fsnotify/fsnotify v1.5.4
Update dependencies:
$ go mod tidy
go: go.mod file indicates go 1.19, but maximum version supported by tidy is 1.18
Error: failed to initialize project: unable to run post-scaffold tasks of "base.go.kubebuilder.io/v3": exit status 1
Usage:
kubebuilder init [flags]
Examples:
# Initialize a new project with your domain and name in copyright
kubebuilder init --plugins go/v3 --domain example.org --owner "Your name"
# Initialize a new project defining a specific project version
kubebuilder init --plugins go/v3 --project-version 3
Flags:
--component-config create a versioned ComponentConfig file, may be 'true' or 'false'
--domain string domain for groups (default "my.domain")
--fetch-deps ensure dependencies are downloaded (default true)
-h, --help help for init
--license string license to use to boilerplate, may be one of 'apache2', 'none' (default "apache2")
--owner string owner to add to the copyright
--project-name string name of this project
--project-version string project version (default "3")
--repo string name to use for go module (e.g., github.com/user/repo), defaults to the go package of the current working directory.
--skip-go-version-check if specified, skip checking the Go version
Global Flags:
--plugins strings plugin keys to be used for this subcommand execution
2022/12/04 11:00:17 failed to initialize project: unable to run post-scaffold tasks of "base.go.kubebuilder.io/v3": exit status 1
Operator 最重要的组成部分:
- main.go 是项目入口,负责设置并运行管理器。
- config/包含在 Kubernetes 中部署 Operator 的 manifest。
- Dockerfile 是用于构建管理器镜像的容器文件。
make kustomize
kustomize 是一个通过 kustomization 文件定制 kubernetes 对象的工具,它可以通过一些资源生成一些新的资源,也可以定制不同的资源的集合。
一个比较典型的场景是我们有一个应用,在不同的环境例如生产环境和测试环境,它的 yaml 配置绝大部分都是相同的,只有个别的字段不同,这时候就可以利用 kustomize 来解决,kustomize 也比较适合用于 gitops 工作流。
简单理解,kustomize识别kustomization.yaml文件,并按照kustomization.yaml中的指示做事,并且kustomization.yaml中可以继续套用kustomization.yaml。
把kustomize工具拉下来,生成yaml文件
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/myk8sOperator (master)
$ make kustomize
mkdir -p /f/go/project/0-shizhanxiangmu/myk8sOperator/bin
test -s /f/go/project/0-shizhanxiangmu/myk8sOperator/bin/kustomize || { curl -Ss "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash -
s -- 3.8.7 /f/go/project/0-shizhanxiangmu/myk8sOperator/bin; }
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
kustomize失败,没有建立安全连接
要手动把这个文件弄下来,根据Makefile中的指令来执行
{ curl -Ss "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash - s -- 3.8.7 /f/go/project/0-shizhanxiangmu/myk8sOperator/bin; }
kubebuilder create api
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/myk8sOperator (master)
$ kubebuilder create api --group traefik --version v1 --kind Service
time="2022-12-04T11:21:49+08:00" level=error msg="could not get plugins root: Host not supported: windows"
time="2022-12-04T11:21:49+08:00" level=error msg="Host not supported: windows"
Create Resource [y/n]
y
Create Controller [y/n]
y
Writing kustomize manifests for you to edit...
Writing scaffold for you to edit...
api\v1\service_types.go
controllers\service_controller.go
Update dependencies:
$ go mod tidy
Running make:
$ make generate
Error: failed to create API: unable to run post-scaffold tasks of "base.go.kubebuilder.io/v3": exec: "make": executable file not found in %PATH%
Usage:
kubebuilder create api [flags]
Examples:
# Create a frigates API with Group: ship, Version: v1beta1 and Kind: Frigate
kubebuilder create api --group ship --version v1beta1 --kind Frigate
# Edit the API Scheme
nano api/v1beta1/frigate_types.go
# Edit the Controller
nano controllers/frigate/frigate_controller.go
# Edit the Controller Test
nano controllers/frigate/frigate_controller_test.go
# Generate the manifests
make manifests
# Install CRDs into the Kubernetes cluster using kubectl apply
make install
# Regenerate code and run against the Kubernetes cluster configured by ~/.kube/config
make run
Flags:
--controller if set, generate the controller without prompting the user (default true)
--force attempt to create resource even if it already exists
--group string resource Group
-h, --help help for api
--kind string resource Kind
--make make generate if true, run make generate after generating files (default true)
--namespaced resource is namespaced (default true)
--plural string resource irregular plural form
--resource if set, generate the resource without prompting the user (default true)
--version string resource Version
Global Flags:
--plugins strings plugin keys to be used for this subcommand execution
2022/12/04 11:22:00 failed to create API: unable to run post-scaffold tasks of "base.go.kubebuilder.io/v3": exec: "make": executable file not found in %PATH%
crd开发
make manifests
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/myk8sOperator (master)
$ make manifests
mkdir -p /f/go/project/0-shizhanxiangmu/myk8sOperator/bin
test -s /f/go/project/0-shizhanxiangmu/myk8sOperator/bin/controller-gen && /f/go/project/0-shizhanxiangmu/myk8sOperator/bin/controller-gen --version | grep -q v0.10.0 || \
GOBIN=/f/go/project/0-shizhanxiangmu/myk8sOperator/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.10.0
go: downloading sigs.k8s.io/controller-tools v0.10.0
go: downloading github.com/fatih/color v1.12.0
go: downloading github.com/gobuffalo/flect v0.2.5
go: downloading github.com/mattn/go-colorable v0.1.8
/f/go/project/0-shizhanxiangmu/myk8sOperator/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
make generate
直接下载kustuomize文件放在bin下,执行make generate生成了对应文件
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/myk8sOperator (master)
$ make generate
mkdir -p /f/go/project/0-shizhanxiangmu/myk8sOperator/bin
test -s /f/go/project/0-shizhanxiangmu/myk8sOperator/bin/controller-gen && /f/go/project/0-shizhanxiangmu/myk8sOperator/bin/controller-gen --version | grep -q v0.10.0 || \
GOBIN=/f/go/project/0-shizhanxiangmu/myk8sOperator/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.10.0
/f/go/project/0-shizhanxiangmu/myk8sOperator/bin/controller-gen object:headerFile="hack\\boilerplate.go.txt" paths="./..."
连接kubernetes集群并安装crd
连接腾讯云的kubernetes集群,查看它本身的crd
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/mykubeoper (master)
$ kubectl.exe get crd
NAME CREATED AT
loadbalancerresources.networking.tke.cloud.tencent.com 2022-12-13T02:51:32Z
tkeserviceconfigs.cloud.tencent.com 2022-12-13T02:51:27Z
volumesnapshotclasses.snapshot.storage.k8s.io 2022-12-13T02:53:01Z
volumesnapshotcontents.snapshot.storage.k8s.io 2022-12-13T02:53:01Z
volumesnapshots.snapshot.storage.k8s.io 2022-12-13T02:53:01Z
make install 安装crd
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/mykubeoper (master)
$ make install
mkdir -p /f/go/project/0-shizhanxiangmu/mykubeoper/bin
test -s /f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen && /f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen --version | grep -q v0.8.0 || \
GOBIN=/f/go/project/0-shizhanxiangmu/mykubeoper/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0
/f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
/f/go/project/0-shizhanxiangmu/mykubeoper/bin/kustomize version is not expected v3.8.7. Removing it before installing.
test -s /f/go/project/0-shizhanxiangmu/mykubeoper/bin/kustomize || { curl -Ss "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash -s -
- 3.8.7 /f/go/project/0-shizhanxiangmu/mykubeoper/bin; }
{Version:kustomize/v3.8.7 GitCommit:ad092cc7a91c07fdf63a2e4b7f13fa588a39af4f BuildDate:2020-11-11T23:14:14Z GoOs:windows GoArch:amd64}
kustomize installed to /f/go/project/0-shizhanxiangmu/mykubeoper/bin/kustomize
/f/go/project/0-shizhanxiangmu/mykubeoper/bin/kustomize build config/crd | kubectl apply -f -
customresourcedefinition.apiextensions.k8s.io/services.traefik.wendao created
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/mykubeoper (master)
$ kubectl.exe get crd -o wide
NAME CREATED AT
loadbalancerresources.networking.tke.cloud.tencent.com 2022-12-13T02:51:32Z
services.traefik.wendao 2022-12-13T04:32:15Z
tkeserviceconfigs.cloud.tencent.com 2022-12-13T02:51:27Z
volumesnapshotclasses.snapshot.storage.k8s.io 2022-12-13T02:53:01Z
volumesnapshotcontents.snapshot.storage.k8s.io 2022-12-13T02:53:01Z
volumesnapshots.snapshot.storage.k8s.io 2022-12-13T02:53:01Z
验证crd
用一个样例文件来测试,在生成的样例文件处修改
config/samples/traefik_v1_service.yaml
apiVersion: traefik.wendao/v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: service
app.kubernetes.io/instance: service-sample
app.kubernetes.io/part-of: myk8soper
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/created-by: myk8soper
name: service-sample
spec:
# TODO(user): Add fields here
entrypoint: "http"
url: "10.10.10.10:8080"
创建crd并查看
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/mykubeoper (master)
$ kubectl.exe apply -f ./config/samples/traefik_v1_service.yaml
service.traefik.wendao/service-sample created
类型就是根据crd的名称来看
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/mykubeoper (master)
$ kubectl.exe get services.traefik.wendao -o wide
NAME AGE
service-sample 91s
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/mykubeoper (master)
$ kubectl.exe describe services.traefik.wendao service-sample
Name: service-sample
Namespace: default
Labels: app.kubernetes.io/created-by=myk8soper
app.kubernetes.io/instance=service-sample
app.kubernetes.io/managed-by=kustomize
app.kubernetes.io/name=service
app.kubernetes.io/part-of=myk8soper
Annotations: <none>
API Version: traefik.wendao/v1
Kind: Service
Metadata:
Creation Timestamp: 2022-12-13T06:52:56Z
Generation: 1
Managed Fields:
API Version: traefik.wendao/v1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:labels:
.:
f:app.kubernetes.io/created-by:
f:app.kubernetes.io/instance:
f:app.kubernetes.io/managed-by:
f:app.kubernetes.io/name:
f:app.kubernetes.io/part-of:
f:spec:
.:
f:entrypoint:
f:url:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2022-12-13T06:52:56Z
Resource Version: 14887488948
Self Link: /apis/traefik.wendao/v1/namespaces/default/services/service-sample
UID: dc3a4194-b25c-4850-a8ac-75ab72f29773
Spec:
Entrypoint: http
URL: 10.10.10.10:8080
Events: <none>
编写operator的controller
api/v1/service_types.go—修改一下ServiceStatus,增加一个字段
type ServiceStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
// 是否已经成功同步
IsSync bool `json:"is_sysnc"`
// 如果同步给Traefik失败,则记录使用原因
FailedMessage string `json:"failed_message"`
// 触发同步的时间
UpdateTime int64 `json:"update_time"`
}
再次执行make manifests,生成新的yaml文件
执行make generate,生成新的go文件
删除原来的crd,用make uninstall
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/mykubeoper (master)
$ make uninstall
mkdir -p /f/go/project/0-shizhanxiangmu/mykubeoper/bin
test -s /f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen && /f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen --version | grep -q v0.8.0 || \
GOBIN=/f/go/project/0-shizhanxiangmu/mykubeoper/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0
/f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
test -s /f/go/project/0-shizhanxiangmu/mykubeoper/bin/kustomize || { curl -Ss "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash -s -
- 3.8.7 /f/go/project/0-shizhanxiangmu/mykubeoper/bin; }
/f/go/project/0-shizhanxiangmu/mykubeoper/bin/kustomize build config/crd | kubectl delete --ignore-not-found=false -f -
安装新的crd,make install
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/mykubeoper (master)
$ make install
mkdir -p /f/go/project/0-shizhanxiangmu/mykubeoper/bin
test -s /f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen && /f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen --version | grep -q v0.8.0 || \
GOBIN=/f/go/project/0-shizhanxiangmu/mykubeoper/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0
/f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
test -s /f/go/project/0-shizhanxiangmu/mykubeoper/bin/kustomize || { curl -Ss "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash -s -
- 3.8.7 /f/go/project/0-shizhanxiangmu/mykubeoper/bin; }
/f/go/project/0-shizhanxiangmu/mykubeoper/bin/kustomize build config/crd | kubectl apply -f -
customresourcedefinition.apiextensions.k8s.io/services.traefik.wendao created
Crontroller 业务逻辑编写
Reconcile 函数是 Operator 的核心逻辑, 位于 controllers/traefikservice_controller.go 文件中, 我们修改他,添加我们的业务逻辑
// ServiceReconciler reconciles a Service object
type ServiceReconciler struct {
client.Client
Scheme *runtime.Scheme
}
//+kubebuilder:rbac:groups=traefik.magedu.go8,resources=services,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=traefik.magedu.go8,resources=services/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=traefik.magedu.go8,resources=services/finalizers,verbs=update
// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
// TODO(user): Modify the Reconcile function to compare the state specified by
// the Service object against the actual cluster state, and then
// perform operations to make the cluster state reflect the state specified by
// the user.
//
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.13.1/pkg/reconcile
func (r *ServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
l := log.FromContext(ctx)
// TODO(user): your logic here
l.Info("start ...")
// 1. 获取对象(用户期望的状态)
obj := &traefikv1.Service{}
if err := r.Get(ctx, req.NamespacedName, obj); err != nil {
// 记录下保存信息
l.Error(err, fmt.Sprintf("get object %s failed", req.NamespacedName))
return ctrl.Result{}, nil
}
// 打印下对象
l.Info("get an object",
"name", req.NamespacedName,
"entrypoint", obj.Spec.EntryPoint,
"url", obj.Spec.URL,
)
// 2. 判断对象的状态
if obj.Status.IsSync {
// 已经同步, 无需做状态处理
l.Info("object has synced", "name", req.NamespacedName)
return ctrl.Result{}, nil
}
// 3. 操作对象 让其变成期望的状态(这里不写操作Traefik的业务路径)
l.Info("sync to traefik success")
// 4. 操作成功后,修改对象的状态, 变成期望状态
obj.Status.IsSync = true
obj.Status.UpdateTime = time.Now().Unix()
// 5. 对象状态同步到API Server, 需要Status() 才能修改到资源的状态
if err := r.Client.Status().Update(ctx, obj); err != nil {
l.Error(err, "update k8s object error")
}
return ctrl.Result{}, nil
}
// SetupWithManager sets up the controller with the Manager.
func (r *ServiceReconciler) SetupWithManager(mgr ctrl.Manager) error {
// 编写对应的Resoruce Controller 扩展对象
// For(&appsv1.Deployment{}) 编写Deployment的Controller
return ctrl.NewControllerManagedBy(mgr).
For(&traefikv1.Service{}).
Complete(r)
}
crd+controller调试
本地启动controller
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/mykubeoper (master)
$ make run
mkdir -p /f/go/project/0-shizhanxiangmu/mykubeoper/bin
test -s /f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen && /f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen --version | grep -q v0.8.0 || \
GOBIN=/f/go/project/0-shizhanxiangmu/mykubeoper/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0
/f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
/f/go/project/0-shizhanxiangmu/mykubeoper/bin/controller-gen object:headerFile="hack\\boilerplate.go.txt" paths="./..."
go fmt ./...
go vet ./...
go run ./main.go
1.6709186203836606e+09 INFO controller-runtime.metrics Metrics server is starting to listen {"addr": ":8080"}
1.6709186203852835e+09 INFO setup starting manager
1.6709186203858254e+09 INFO Starting server {"path": "/metrics", "kind": "metrics", "addr": "[::]:8080"}
1.6709186203858254e+09 INFO Starting server {"kind": "health probe", "addr": "[::]:8081"}
1.6709186203858254e+09 INFO Starting EventSource {"controller": "service", "controllerGroup": "traefik.wendao", "controllerKind": "Service", "source": "kind source: *v1.Service"
}
1.6709186203863542e+09 INFO Starting Controller {"controller": "service", "controllerGroup": "traefik.wendao", "controllerKind": "Service"}
1.670918620488402e+09 INFO Starting workers {"controller": "service", "controllerGroup": "traefik.wendao", "controllerKind": "Service", "worker
运行crd
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/0-shizhanxiangmu/mykubeoper (master)
$ kubectl.exe apply -f config/samples/traefik_v1_service.yaml
service.traefik.wendao/service-sample created
运行operator
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/1-ProjectBatch/go8-day18/projects/k8soperator
$ make run
mkdir -p /f/go/project/1-ProjectBatch/go8-day18/projects/k8soperator/bin
test -s /f/go/project/1-ProjectBatch/go8-day18/projects/k8soperator/bin/controller-gen && /f/go/project/1-ProjectBatch/go8-day18/projects/k8soperator/bin/controller-gen --version | gre
p -q v0.8.0 || \
GOBIN=/f/go/project/1-ProjectBatch/go8-day18/projects/k8soperator/bin go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0
/f/go/project/1-ProjectBatch/go8-day18/projects/k8soperator/bin/controller-gen rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
/f/go/project/1-ProjectBatch/go8-day18/projects/k8soperator/bin/controller-gen object:headerFile="hack\\boilerplate.go.txt" paths="./..."
go fmt ./...
go vet ./...
go run ./main.go
1.6709229158465655e+09 INFO controller-runtime.metrics Metrics server is starting to listen {"addr": ":8080"}
1.6709229158485708e+09 INFO setup starting manager
1.6709229158495705e+09 INFO Starting server {"path": "/metrics", "kind": "metrics", "addr": "[::]:8080"}
1.670922915850569e+09 INFO Starting EventSource {"controller": "service", "controllerGroup": "traefik.magedu.go8", "controllerKind": "Service", "source": "kind source: *v1.Serv
ice"}
1.670922915851587e+09 INFO Starting Controller {"controller": "service", "controllerGroup": "traefik.magedu.go8", "controllerKind": "Service"}
1.6709229158495705e+09 INFO Starting server {"kind": "health probe", "addr": "[::]:8081"}
1.6709229159595575e+09 INFO Starting workers {"controller": "service", "controllerGroup": "traefik.magedu.go8", "controllerKind": "Service", "worker count": 1}
1.6709229538365262e+09 INFO start ... {"controller": "service", "controllerGroup": "traefik.magedu.go8", "controllerKind": "Service", "Service": {"name":"service-sample","nam
espace":"default"}, "namespace": "default", "name": "service-sample", "reconcileID": "651d5b0a-e81e-4d8f-b2c5-860df52443c3"}
1.6709229538365262e+09 INFO get an object {"controller": "service", "controllerGroup": "traefik.magedu.go8", "controllerKind": "Service", "Service": {"name":"service-sample","nam
espace":"default"}, "namespace": "default", "name": "service-sample", "reconcileID": "651d5b0a-e81e-4d8f-b2c5-860df52443c3", "name": {"namespace": "default", "name": "service-sample"},
"entrypoint": "http", "url": "10.10.10.10:8080"}
1.6709229538371012e+09 INFO sync to traefik success {"controller": "service", "controllerGroup": "traefik.magedu.go8", "controllerKind": "Service", "Service": {"name":"service-samp
le","namespace":"default"}, "namespace": "default", "name": "service-sample", "reconcileID": "651d5b0a-e81e-4d8f-b2c5-860df52443c3"}
1.6709229538627574e+09 INFO start ... {"controller": "service", "controllerGroup": "traefik.magedu.go8", "controllerKind": "Service", "Service": {"name":"service-sample","nam
espace":"default"}, "namespace": "default", "name": "service-sample", "reconcileID": "390d5a30-762a-4e25-899a-d4497aa668db"}
1.6709229538642845e+09 INFO get an object {"controller": "service", "controllerGroup": "traefik.magedu.go8", "controllerKind": "Service", "Service": {"name":"service-sample","nam
espace":"default"}, "namespace": "default", "name": "service-sample", "reconcileID": "390d5a30-762a-4e25-899a-d4497aa668db", "name": {"namespace": "default", "name": "service-sample"},
"entrypoint": "http", "url": "10.10.10.10:8080"}
1.6709229538652847e+09 INFO object has synced {"controller": "service", "controllerGroup": "traefik.magedu.go8", "controllerKind": "Service", "Service": {"name":"service-samp
le","namespace":"default"}, "namespace": "default", "name": "service-sample", "reconcileID": "390d5a30-762a-4e25-899a-d4497aa668db", "name": {"namespace": "default", "name": "service-s
ample"}}
运行效果检查
zengz@DESKTOP-Q3MJC54 MINGW64 /f/go/project/1-ProjectBatch/go8-day18/projects/k8soperator
$ kubectl.exe describe services.traefik.magedu.go8 service-sample
Name: service-sample
Namespace: default
Labels: app.kubernetes.io/created-by=k8soperator
app.kubernetes.io/instance=service-sample
app.kubernetes.io/managed-by=kustomize
app.kubernetes.io/name=service
app.kubernetes.io/part-of=k8soperator
Annotations: <none>
API Version: traefik.magedu.go8/v1
Kind: Service
Metadata:
Creation Timestamp: 2022-12-13T09:15:54Z
Generation: 1
Managed Fields:
API Version: traefik.magedu.go8/v1
Fields Type: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.:
f:kubectl.kubernetes.io/last-applied-configuration:
f:labels:
.:
f:app.kubernetes.io/created-by:
f:app.kubernetes.io/instance:
f:app.kubernetes.io/managed-by:
f:app.kubernetes.io/name:
f:app.kubernetes.io/part-of:
f:spec:
.:
f:entrypoint:
f:url:
Manager: kubectl-client-side-apply
Operation: Update
Time: 2022-12-13T09:15:54Z
API Version: traefik.magedu.go8/v1
Fields Type: FieldsV1
fieldsV1:
f:status:
.:
f:failed_message:
f:is_sysnc:
f:update_time:
Manager: main.exe
Operation: Update
Subresource: status
Time: 2022-12-13T09:15:54Z
Resource Version: 14895379840
Self Link: /apis/traefik.magedu.go8/v1/namespaces/default/services/service-sample
UID: 3095b5ef-20b7-4fc7-b04d-f7404d89de7c
Spec:
Entrypoint: http
URL: 10.10.10.10:8080
Status:
failed_message:
is_sysnc: true
update_time: 1670922953
Events: <none>
评论区