API资源对象CRD、认识Operator-理论知识和认识Operator-初次上手(2024-07-17)

一、API资源对象CRD

Kubernetes 自定义资源定义(Custom Resource Definition,简称 CRD)是一种强大的 Kubernetes API 扩展机制,允许你定义和创建自己的资源类型,以满足您的应用程序或基础设施需求。

CRD 的核心思想是通过声明式的 API 来扩展 Kubernetes 的功能。你可以定义自己的资源结构,然后像操作 Kubernetes 内建资源一样操作这些自定义资源。这意味着您可以使用熟悉的Kubernetes工具如kubectl或Kubernetes控制器与管理您的自定义资源进行交互

CRD提供了一种扩展Kubernetes平台以适应特定要求的方式,并能够构建自定义的运算符或控制器来自动化管理自定义资源。运算符可以监视自定义资源的更改并相应地采取操作,例如提供额外的资源、扩展或执行自定义操作。CRD已成为扩展Kubernetes的流行机制,在Kubernetes生态系统中的各种项目和框架中广泛使用,如Prometheus、Istio和Knative

示例:

[root@aminglinux01 ~]# cat crd-example.yaml 
apiVersion: apiextensions.k8s.io/v1      #指定所使用的 CRD API 的版本,此示例使用了apiextensions.k8s.io/v1 版本。
kind: CustomResourceDefinition           #定义资源类型为 CustomResourceDefinition。
metadata:             #定义元数据,其中 name 字段指定了 CRD 的名称myresources.example.com。name: myresources.example.com        ###name必须包含group字段
spec:                 #定义了 CRD 的规范。group: example.com           #指定 CRD 所属的 API 组,此示例中为 example.com。versions:                    #定义 CRD 的版本列表。- name: v1                 #指定版本的名称,此示例中为 v1。served: true             #指定此版本是否由 API 服务器提供服务,设为 true 表示提供服务。storage: truestorage:   #指定此版本是否持久化存储数据,设为 true 表示持久化
存储。schema:openAPIV3Schema:      #指定自定义资源的 OpenAPI v3 架构定义description: Define CronTab YAML Spectype: object        #定义类型properties:         #定义对象属性      spec:type: objectproperties:name:               #自定义具体属性的名字type: stringage:type: integerscope: Namespaced                 #指定资源的作用域,此示例中为 Namespaced,表示资源
在命名空间级别进行管理。names:                            #定义了资源的名称相关信息。plural: myresources             #指定资源的复数形式名称,此示例中为 myresources。singular: myresource            #指定资源的单数形式名称,此示例中为 myresource。kind: MyResource                #指定资源的类型名称,此示例中为 MyResource。shortNames:                     #指定资源的缩略名称列表,此示例中只包含一个缩
略名称 mr。- mr
[root@aminglinux01 ~]# 

说明:
和我们定义普通的资源对象比较类似,这里可以随意定义一个自定义的资源对象,但是在创建资源的时候,肯定不是任由我们随意去编写YAML 文件的,当我们把上面的 CRD 文件提交给 Kubernetes 之后,Kubernetes 会对我们提交的声明文件进行校验,从定义可以看出 CRD是基于 OpenAPI v3 schem 进行规范的。

  • apiVersion:指定所使用的 CRD API 的版本,此示例使用了apiextensions.k8s.io/v1 版本。
  • kind:定义资源类型为 CustomResourceDefinition。
  • metadata:定义元数据,其中 name 字段指定了 CRD 的名称为myresources.example.com。name中必须包含group字段。
  • spec:定义了 CRD 的规范。
  • group:指定 CRD 所属的 API 组,此示例中为 example.com。
  • versions:定义 CRD 的版本列表。
  • name:指定版本的名称,此示例中为 v1。
  • served:指定此版本是否由 API 服务器提供服务,设为 true 表示提供服务。
  • storage:指定此版本是否持久化存储数据,设为 true 表示持久化存储。
  • openAPIV3Schema: 指定自定义资源的 OpenAPI v3 架构定义
  • type:定义类型
  • properties:定义对象属性
  • name/age:自定义具体属性的名字
  • scope:指定资源的作用域,此示例中为 Namespaced,表示资源在命名空间级别进行管理。
  • names:定义了资源的名称相关信息。
  • plural:指定资源的复数形式名称,此示例中为 myresources。
  • singular:指定资源的单数形式名称,此示例中为 myresource。
  • kind:指定资源的类型名称,此示例中为 MyResource。
  • shortNames:指定资源的缩略名称列表,此示例中只包含一个缩略名称 mr。

应用

kubectl apply -f crd-example.yaml

[root@aminglinux01 ~]# kubectl apply -f crd-example.yaml
customresourcedefinition.apiextensions.k8s.io/myresources.example.com created
[root@aminglinux01 ~]# 

查看crd

kubectl get crd

[root@aminglinux01 ~]# kubectl get crd
NAME                                                  CREATED AT
bgpconfigurations.crd.projectcalico.org               2024-07-08T13:28:18Z
bgppeers.crd.projectcalico.org                        2024-07-08T13:28:18Z
blockaffinities.crd.projectcalico.org                 2024-07-08T13:28:18Z
caliconodestatuses.crd.projectcalico.org              2024-07-08T13:28:18Z
clusterinformations.crd.projectcalico.org             2024-07-08T13:28:18Z
felixconfigurations.crd.projectcalico.org             2024-07-08T13:28:18Z
globalconfigurations.k8s.nginx.org                    2024-07-14T20:10:00Z
globalnetworkpolicies.crd.projectcalico.org           2024-07-08T13:28:18Z
globalnetworksets.crd.projectcalico.org               2024-07-08T13:28:18Z
hostendpoints.crd.projectcalico.org                   2024-07-08T13:28:18Z
ipamblocks.crd.projectcalico.org                      2024-07-08T13:28:18Z
ipamconfigs.crd.projectcalico.org                     2024-07-08T13:28:18Z
ipamhandles.crd.projectcalico.org                     2024-07-08T13:28:18Z
ippools.crd.projectcalico.org                         2024-07-08T13:28:18Z
ipreservations.crd.projectcalico.org                  2024-07-08T13:28:18Z
kubecontrollersconfigurations.crd.projectcalico.org   2024-07-08T13:28:18Z
myresources.example.com                               2024-07-17T18:06:32Z
networkpolicies.crd.projectcalico.org                 2024-07-08T13:28:18Z
networksets.crd.projectcalico.org                     2024-07-08T13:28:18Z
policies.k8s.nginx.org                                2024-07-14T20:10:00Z
transportservers.k8s.nginx.org                        2024-07-14T20:10:00Z
virtualserverroutes.k8s.nginx.org                     2024-07-14T20:10:00Z
virtualservers.k8s.nginx.org                          2024-07-14T20:10:00Z
[root@aminglinux01 ~]# 

一旦创建完自定义的CRD,那么就会生成一个自定义的API

/apis/example.com/v1/namespaces/*/myresources/...

创建自定义资源实例,基于前面CRD定义的资源

[root@aminglinux01 ~]# cat myresource-instance.yaml 
apiVersion: example.com/v1
kind: MyResource ##和上面CRD里相对应
metadata:name: myresource-instance
spec: ##以下两个key必须在CRD中有过定义name: exampleage: 25
[root@aminglinux01 ~]# 

kubectl apply -f myresource-instance.yaml

[root@aminglinux01 ~]# kubectl apply -f myresource-instance.yaml
myresource.example.com/myresource-instance created
[root@aminglinux01 ~]# 

查看MyResource

kubectl get MyResource #或者用短名称
kubectl get mr

[root@aminglinux01 ~]# kubectl get MyResource
NAME                  AGE
myresource-instance   51s
[root@aminglinux01 ~]# kubectl get mr
NAME                  AGE
myresource-instance   59s
[root@aminglinux01 ~]# 

以上定义的CRD,仅仅是写入到了etcd中,并没有其它用处,要想让它有进一步作用,还得去定义Controller而Controller更多的是开发范畴的事情,咱们暂时先不涉及。

二、认识Operator

1.Operator理论知识

1)Operator是什么
你可以理解成Operator就是CRD+自定义Controller的实践应用。

Kubernetes Operator由CoreOS公司开发,它是一种自定义控制器,它扩展了 Kubernetes API 的功能,用于管理和自动化应用程序、服务或资源的生命周期。Operator 可以将复杂的操作封装到 Kubernetes中,以便在集群中创建、配置、部署和管理特定类型的应用程序或服务。


Operator 的核心思想是将应用程序的专业知识嵌入到自定义控制器中,以便控制器能够理解和管理特定类型的应用程序。这样一来,Operator 可以根据自定义资源的规范和状态,自动执行与应用程序相关的任务,如创建、更新、伸缩、备份和恢复等。Operator 还可以响应集群事件,自动修复故障和应用程序状态的健康性。


通过使用 Operator,开发人员和管理员可以更轻松地在 Kubernetes上管理复杂的应用程序和服务,减少手动操作的工作量,提高可靠性和可重复性。同时,Operator 的开放性设计使得可以创建适用于各种不同类型应用程序的自定义操作符,从数据库、消息队列到机器学习模型
等各种类型的应用程序都可以通过 Operator 进行管理。
2)Operator用来做什么
使用 Operator 有很多理由。通常情况下,要么是开发团队为他们的产品创建 Operator,要么是 DevOps 团队希望对第三方软件管理进行自动化。无论哪种方式,都应该从确定 Operator 应该负责哪些东西开始。


最基本的 Operator 用于部署,使用 kubectl apply 就可以创建一个用于响应 API 资源的数据库,但这比内置的 Kubernetes 资源(如StatefulSets 或 Deployments)好不了多少。复杂的 Operator 将提供更大的价值。如果你想要对数据库进行伸缩该怎么办?


如果是 StatefulSet,你可以执行 kubectl scale statefulset my-db --replicas 3,这样就可以得到 3 个实例。但如果这些实例需要不同的配置呢?是否需要指定一个实例为主实例,其他实例为副本?如果在添加新副本之前需要执行设置步骤,那该怎么办?在这种情况下,可以使用Operator。


更高级的 Operator 可以处理其他一些特性,如响应负载的自动伸缩、备份和恢复、与 Prometheus 等度量系统的集成,甚至可以进行故障检测和自动调优。任何具有传统“运行手册”文档的操作都可以被自动化、测试和依赖,并自动做出响应。


被管理的系统甚至不需要部署在 Kubernetes 上也能从 Operator 中获益。例如,主要的云服务提供商(如 Amazon Web Services、微软Azure 和谷歌云)提供 Kubenretes Operator 来管理其他云资源,如对象存储。用户可以通过配置 Kubernetes 应用程序的方式来配置云资源。运维团队可能对其他资源也采取同样的方法,使用 Operator 来管理任何东西——从第三方软件服务到硬件。
下面总结了一些常见的场景:

  • 按需部署一个应用程序,并自动配置,比如Prometheus
  • 需要备份和恢复应用程序的状态,如MySQL数据库
  • 处理应用程序代码的升级以及相关更改,例如数据库架构或额外的配置设置
  • 发布一个服务,要让不支持Kubernetes API的应用程序能够发现
  • 模拟整个或部分集群中的故障以测试其弹性
  • 在没有内部成员选举程序的情况下为分布式应用程序选择领导者

2.Operator初次上手

说明:需要大家有一点go的开发能力

目前主流的Operator开发框架有两个:kubebuilder和Operator-sdk,两者实际上并没有本质的区别,它们的核心都是使用官方的 controllertools和 controller-runtime。不过细节上稍有不同,比如
kubebuilder 有着更为完善的测试与部署以及代码生成的脚手架等;而operator-sdk 对 ansible operator 这类上层操作的支持更好一些。下面基于kubebuilder,讲解如何开发Operator。

环境准备

Kubebuilder工作依赖go环境,所以需要安装go,理应单独拿一台机器来安装Kubebuilder,但我们为了节省资源,就拿aminglinux03来安

1)安装go

Rocky8使用yum安装

yum install -y golang.x86_64

检测版本

go version

[root@aminglinux03 ~]# go version
go version go1.21.11 (Red Hat 1.21.11-1.module+el8.10.0+1831+fc70fba6) linux/amd64
[root@aminglinux03 ~]# 

设置代理

go env -w GOPROXY=https://goproxy.cn,direct

2)安装docker

开发过程中会用到docker环境,由于我们部署k8s时,安装过containerd,当时配置过yum仓库,所以可以直接通过yum来安装docker

yum install -y docker-ce

启动服务

systemctl start docker

3)安装kubectl 以及配置直接访问k8s集群
由于是aminglinux03,已经安装过kubectl,如果没有安装请参考部署k8s集群的步骤来安装。而默认aminglinux03是无法直接访问k8s集群的,需要将aminglinux01下面的/root/.kube目录拷贝到aminglinux03才可以

##以下操作在aminglinux01上操作
scp -r /root/.kube aminglinux03:/root/

测试

##在aminglinux03上执行
kubectl get node

[root@aminglinux03 ~]# kubectl get node
NAME           STATUS   ROLES           AGE   VERSION
aminglinux01   Ready    control-plane   13d   v1.26.2
aminglinux02   Ready    <none>          13d   v1.26.2
aminglinux03   Ready    <none>          13d   v1.26.2
[root@aminglinux03 ~]# 

4)安装kubebuilder

curl -k -L -o kubebuilder https://github.com/kubernetes-sigs/kubebuilder/releases/download/v4.1.0/kubebuilder_linux_amd64
chmod +x kubebuilder && mv kubebuilder /usr/local/bin/

[root@aminglinux03 ~]# curl -k -L -o kubebuilder https://github.com/kubernetes-sigs/kubebuilder/releases/download/v4.1.0/kubebuilder_linux_amd64% Total    % Received % Xferd  Average Speed   Time    Time     Time  CurrentDload  Upload   Total   Spent    Left  Speed0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 13.5M  100 13.5M    0     0   136k      0  0:01:42  0:01:42 --:--:--  112k
[root@aminglinux03 ~]# chmod +x kubebuilder && mv kubebuilder /usr/local/bin/

测试

kubebuilder version

[root@aminglinux03 ~]# kubebuilder version
Version: main.version{KubeBuilderVersion:"3.15.0", KubernetesVendor:"1.27.1", GitCommit:"c01af8fb2cf7c8e11b06b6b491f7974fc1232d1a", BuildDate:"2024-05-15T10:16:58Z", GoOs:"linux", GoArch:"amd64"}
[root@aminglinux03 ~]# 

 创建Helloworld项目

1)初始化项目

export GOPATH=`go env GOPATH`
mkdir -p $GOPATH/src/helloworld
cd $GOPATH/src/helloworld
kubebuilder init --domain aminglinux.com

[root@aminglinux03 helloworld]# kubebuilder init --domain aminglinux.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.17.3 
go: downloading sigs.k8s.io/controller-runtime v0.17.3
go: downloading k8s.io/apimachinery v0.29.2
go: downloading k8s.io/client-go v0.29.2
go: downloading k8s.io/utils v0.0.0-20230726121419-3b25d923346b
go: downloading github.com/go-logr/logr v1.4.1
go: downloading k8s.io/api v0.29.2
go: downloading k8s.io/klog/v2 v2.110.1
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/component-base v0.29.2
go: downloading golang.org/x/net v0.19.0
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.15.0
go: downloading github.com/evanphx/json-patch/v5 v5.8.0
go: downloading github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
go: downloading github.com/evanphx/json-patch v4.12.0+incompatible
go: downloading golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
go: downloading github.com/prometheus/client_golang v1.18.0
go: downloading gomodules.xyz/jsonpatch/v2 v2.4.0
go: downloading k8s.io/apiextensions-apiserver v0.29.2
go: downloading gopkg.in/inf.v0 v0.9.1
go: downloading sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd
go: downloading github.com/json-iterator/go v1.1.12
go: downloading gopkg.in/yaml.v2 v2.4.0
go: downloading sigs.k8s.io/yaml v1.4.0
go: downloading golang.org/x/oauth2 v0.12.0
go: downloading golang.org/x/time v0.3.0
go: downloading k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00
go: downloading github.com/google/gnostic-models v0.6.8
go: downloading github.com/golang/protobuf v1.5.3
go: downloading golang.org/x/sys v0.16.0
go: downloading github.com/google/go-cmp v0.6.0
go: downloading github.com/google/uuid v1.3.0
go: downloading github.com/fsnotify/fsnotify v1.7.0
go: downloading github.com/prometheus/client_model v0.5.0
go: downloading github.com/prometheus/common v0.45.0
go: downloading github.com/pkg/errors v0.9.1
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/davecgh/go-spew v1.1.1
go: downloading golang.org/x/text v0.14.0
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading github.com/go-openapi/jsonreference v0.20.2
go: downloading github.com/go-openapi/swag v0.22.3
go: downloading google.golang.org/protobuf v1.31.0
go: downloading github.com/beorn7/perks v1.0.1
go: downloading github.com/cespare/xxhash/v2 v2.2.0
go: downloading github.com/prometheus/procfs v0.12.0
go: downloading github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0
go: downloading google.golang.org/appengine v1.6.7
go: downloading github.com/go-openapi/jsonpointer v0.19.6
go: downloading github.com/mailru/easyjson v0.7.7
go: downloading github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
go: downloading github.com/josharian/intern v1.0.0
go: downloading github.com/emicklei/go-restful/v3 v3.11.0
INFO Update dependencies:
$ go mod tidy           
go: downloading github.com/onsi/ginkgo/v2 v2.14.0
go: downloading github.com/onsi/gomega v1.30.0
go: downloading github.com/stretchr/testify v1.8.4
go: downloading github.com/go-logr/zapr v1.3.0
go: downloading go.uber.org/zap v1.26.0
go: downloading github.com/pmezard/go-difflib v1.0.0
go: downloading go.uber.org/goleak v1.3.0
go: downloading go.uber.org/multierr v1.11.0
go: downloading gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
go: downloading github.com/kr/pretty v0.3.1
go: downloading github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572
go: downloading golang.org/x/tools v0.16.1
go: downloading github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1
go: downloading github.com/kr/text v0.2.0
go: downloading github.com/rogpeppe/go-internal v1.10.0
Next: define a resource with:
$ kubebuilder create api
[root@aminglinux03 helloworld]# 

初始化完成后,目录结构是:

├── cmd
│ └── main.go
├── config
│ ├── default
│ │ ├── kustomization.yaml
│ │ ├── manager_auth_proxy_patch.yaml
│ │ └── manager_config_patch.yaml
│ ├── manager
│ │ ├── kustomization.yaml
│ │ └── manager.yaml
│ ├── prometheus
│ │ ├── kustomization.yaml
│ │ └── monitor.yaml
│ └── rbac
│ ├── auth_proxy_client_clusterrole.yaml
│ ├── auth_proxy_role_binding.yaml
│ ├── auth_proxy_role.yaml
│ ├── auth_proxy_service.yaml
│ ├── kustomization.yaml
│ ├── leader_election_role_binding.yaml
│ ├── leader_election_role.yaml
│ ├── role_binding.yaml
│ └── service_account.yaml
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│ └── boilerplate.go.txt
├── Makefile
├── PROJECT
└── README.md

2)创建API(CRD + Controller)

先安装make,如果没有make会出问题

yum install -y make

创建API

kubebuilder create api --group webapp --version v1 --kind Guestbook ##打两次y
Create Resource [y/n]
y
reate Controller [y/n]
y

[root@aminglinux03 helloworld]# kubebuilder create api --group webapp --version v1 --kind Guestbook 
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/guestbook_types.go                    
INFO api/v1/groupversion_info.go                  
INFO internal/controller/suite_test.go            
INFO internal/controller/guestbook_controller.go  
INFO internal/controller/guestbook_controller_test.go 
INFO Update dependencies:
$ go mod tidy           
INFO Running make:
$ make generate                
mkdir -p /root/go/src/helloworld/bin
Downloading sigs.k8s.io/controller-tools/cmd/controller-gen@v0.14.0
go: downloading sigs.k8s.io/controller-tools v0.14.0
go: downloading github.com/spf13/cobra v1.8.0
go: downloading github.com/gobuffalo/flect v1.0.2
go: downloading k8s.io/apiextensions-apiserver v0.29.0
go: downloading k8s.io/apimachinery v0.29.0
go: downloading github.com/fatih/color v1.16.0
go: downloading k8s.io/api v0.29.0
go: downloading github.com/mattn/go-colorable v0.1.13
go: downloading github.com/mattn/go-isatty v0.0.20
go: downloading golang.org/x/mod v0.14.0
go: downloading github.com/go-logr/logr v1.3.0
go: downloading golang.org/x/sys v0.15.0
/root/go/src/helloworld/bin/controller-gen-v0.14.0 object:headerFile="hack/boilerplate.go.txt" paths="./..."
Next: implement your new API and generate the manifests (e.g. CRDs,CRs) with:
$ make manifests
[root@aminglinux03 helloworld]# 

3)构建和部署CRD

make install

[root@aminglinux03 helloworld]# make install
/root/go/src/helloworld/bin/controller-gen-v0.14.0 rbac:roleName=manager-role crd webhook paths="./..." output:crd:artifacts:config=config/crd/bases
Downloading sigs.k8s.io/kustomize/kustomize/v5@v5.3.0
go: downloading sigs.k8s.io/kustomize/kustomize/v5 v5.3.0
go: downloading github.com/spf13/cobra v1.7.0
go: downloading sigs.k8s.io/kustomize/api v0.16.0
go: downloading sigs.k8s.io/kustomize/cmd/config v0.13.0
go: downloading sigs.k8s.io/kustomize/kyaml v0.16.0
go: downloading golang.org/x/text v0.13.0
go: downloading golang.org/x/exp v0.0.0-20231006140011-7918f672742d
go: downloading github.com/go-errors/errors v1.4.2
go: downloading k8s.io/kube-openapi v0.0.0-20230601164746-7562a1006961
go: downloading github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00
go: downloading github.com/xlab/treeprint v1.2.0
go: downloading github.com/imdario/mergo v0.3.13
go: downloading gopkg.in/evanphx/json-patch.v5 v5.6.0
go: downloading google.golang.org/protobuf v1.30.0
go: downloading github.com/google/go-cmp v0.5.9
go: downloading github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
go: downloading go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5
/root/go/src/helloworld/bin/kustomize-v5.3.0 build config/crd | kubectl apply -f -
customresourcedefinition.apiextensions.k8s.io/guestbooks.webapp.aminglinux.com created
[root@aminglinux03 helloworld]# 

这个过程会将CRD部署到k8s集群里
我们可以查看CRD

kubectl get crd |grep aminglinux.com

[root@aminglinux03 helloworld]# kubectl get crd |grep aminglinux.com
guestbooks.webapp.aminglinux.com                      2024-07-18T20:03:28Z
[root@aminglinux03 helloworld]# 

我们可以通过下面命令查看该CRD对应的yaml

$GOPATH/src/helloworld/bin/kustomize build config/crd

4)编辑Controller对应的源码,并编译

如果是生产环境,此时就要去编辑Controller对应的go程序啦,由于我们是体验过程,所以只做简单改动源码文件路径为:
$GOPATH/src/helloworld/internal/controller/guestbook_controller.go

[root@aminglinux03 controller]# ls
guestbook_controller.go  guestbook_controller_test.go  suite_test.go
[root@aminglinux03 controller]# pwd
/root/go/src/helloworld/internal/controller
[root@aminglinux03 controller]# 

vi $GOPATH/src/helloworld/internal/controller/guestbook_controller.go
改动1:
增加一个依赖包fmt

改动2:
找到// : your logic here,在下面增加一行代码,用来打印堆栈信息

fmt.Println("Helloworld.")

改完后,执行

make run

这样就可以将该Controller运行起来了。会显示如下信息

test -s /root/go/src/helloworld/bin/controller-gen &&
/root/go/src/helloworld/bin/controller-gen --version | grep -q
v0.11.3 || \
GOBIN=/root/go/src/helloworld/bin go install
sigs.k8s.io/controller-tools/cmd/controller-gen@v0.11.3
/root/go/src/helloworld/bin/controller-gen rbac:roleName=managerrole
crd webhook paths="./..."
output:crd:artifacts:config=config/crd/bases
/root/go/src/helloworld/bin/controller-gen
object:headerFile="hack/boilerplate.go.txt" paths="./..."
go fmt ./...
go vet ./...
go run ./cmd/main.go
2023-06-07T17:11:37+08:00 INFO controllerruntime.
metrics Metrics server is starting to
listen {"addr": ":8080"}
2023-06-07T17:11:37+08:00 INFO setup starting manager
2023-06-07T17:11:37+08:00 INFO Starting server {"path":
"/metrics", "kind": "metrics", "addr": "[::]:8080"}
2023-06-07T17:11:37+08:00 INFO Starting server {"kind":
"health probe", "addr": "[::]:8081"}
2023-06-07T17:11:37+08:00 INFO Starting
EventSource {"controller": "guestbook", "controllerGroup":
"webapp.aminglinux.com", "controllerKind": "Guestbook", "source":
"kind source: *v1.Guestbook"}
2023-06-07T17:11:37+08:00 INFO Starting
Controller {"controller": "guestbook", "controllerGroup":
"webapp.aminglinux.com", "controllerKind": "Guestbook"}
2023-06-07T17:11:38+08:00 INFO Starting
workers {"controller": "guestbook", "controllerGroup":
"webapp.aminglinux.com", "controllerKind": "Guestbook", "worker
count": 1}

说明:
不要按ctrc c中断,此时需要我们到k8s那边去

5)到k8s创建Guestbook资源的实例
现在kubernetes已经部署了Guestbook类型的CRD,而且对应的controller也已正在运行中,可以尝试创建Guestbook类型的实例了(相当于有了pod的定义后,才可以创建pod);

kubebuilder已经自动创建了一个类型的部署文件:
$GOPATH/src/helloworld/config/samples/webapp_v1_guestbook.yaml,内容如下,很简单,接下来咱们就用这个文件来创建Guestbook实例:

cat > guestbook.yaml <<EOF
apiVersion: webapp.aminglinux.com/v1
kind: Guestbook
metadata:
  labels:
    app.kubernetes.io/name: guestbook
    app.kubernetes.io/instance: guestbook-sample
    app.kubernetes.io/part-of: helloworld
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/created-by: helloworld
  name: guestbook-sample
spec:
  # TODO(user): Add fields here
  foo: bar
EOF

应用此yaml

kubectl apply -f guestbook.yaml

回到aminglinux03的终端,可以看到多了一行输出

6)将Controller制作成镜像,并上传到远程仓库
首先需要有一个私有镜像仓库,用来存储编译好的镜像。如果有harbor直接使用harbor最好,如果没有,就是用docker的镜像仓库hub.docker.com,假设你已经有账号了。在编译镜像之前还需要登录到docker的镜像仓库

docker login https://hub.docker.com

我在这里使用的是harbor

docker login https://harbor.yuankeedu.com

给Dockerfile里增加GOPROXY设置
vi Dockerfile #在go mod download上面增加一行

RUN go env -w GOPROXY=https://goproxy.cn

Harbor这里,我已经创建项目aming,然后编译镜像

make docker-build docker-push
IMG=harbor.yuankeedu.com/aming/guestbook:v1

如果编译不过去,那就是网络问题,下载镜像有问题,此时就要做一个代理

按如下方法做代理

mkdir -p /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/proxy.conf
<<EOF
[Service]
Environment="HTTP_PROXY=http://t.lishiming.net:38089/"
Environment="HTTPS_PROXY=http://t.lishiming.net:38089/"
Environment="NO_PROXY=localhost,127.0.0.1,.yuankeedu.com"
EOF
##注意,上面的地址要换成你自己的,这个代理是我自己设置的,如
果你没有自己的代理,可以用我这个,但不保证一直能使用
systemclt daemon-reload
systemctl restart docerk

harbor那边已经成功上传镜像

7)在k8s里部署该镜像
部署之前,需要把之前设置的代理取消,否则会出错

unset http_proxy
unset https_proxy

修改kube-rbac-proxy镜像地址,因为自带的镜像下载不到

sed -i 's/gcr.io/gcr.lank8s.cn/'
./config/default/manager_auth_proxy_patch.yaml

将harbor项目改为公开,方便下载

在三个k8s node上手动将镜像下载下来

ctr -n k8s.io i pull
harbor.yuankeedu.com/aming/guestbook:v1

部署,这是在aminglinux03上执行的,当前目录还是在
$GOPATH/src/helloworld

make deploy IMG=harbor.yuankeedu.com/aming/guestbook:v1

查看pod

kubectl get po -n helloworld-system

此时,我们再次到k8s里去apply guestbook.yaml

kubectl delete -f guestbook.yaml
kubectl apply -f guestbook.yaml

再去查看helloworld-controller-manager-694854949d-wjkk5的log

kubectl -n helloworld-system logs helloworldcontroller-
manager-694854949d-wjkk5

就能看到最后面的 Helloworld 输出了。

8)清理
到aminglinux03,进入到$GOPATH/src/helloworld,执行

make uninstall

注意,它清理的是CRD资源,Controller并不会清理,要想删除
Controller,直接删除对应ns即可

kubectl delete ns helloworld-system

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/50817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 2766题: 重新放置石块(原创)

【题目描述】 给你一个下标从 0 开始的整数数组 nums &#xff0c;表示一些石块的初始位置。再给你两个长度 相等 下标从 0 开始的整数数组 moveFrom 和 moveTo 。 在 moveFrom.length 次操作内&#xff0c;你可以改变石块的位置。在第 i 次操作中&#xff0c;你将位置在 moveF…

基于Pytorch框架的深度学习densenet121神经网络鸟类行为识别分类系统源码

第一步&#xff1a;准备数据 5种鸟类行为数据&#xff1a;self.class_indict ["bowing_status", "grooming", "headdown", "vigilance_status", "walking"] &#xff0c;总共有23790张图片&#xff0c;每个文件夹单独放一…

从零搭建pytorch模型教程(八)实践部分(二)目标检测数据集格式转换

前言 图像目标检测领域有一个非常著名的数据集叫做COCO&#xff0c;基本上现在在目标检测领域发论文&#xff0c;COCO是不可能绕过的Benchmark。因此许多的开源目标检测算法框架都会支持解析COCO数据集格式。通过将其他数据集格式转换成COCO格式可以无痛的使用这些开源框架来训…

【计算机网络】静态路由实验

一&#xff1a;实验目的 1&#xff1a;掌握通过静态路由方法实现网络的连通性。 二&#xff1a;实验仪器设备及软件 硬件&#xff1a;RCMS-C服务器、网线、Windows 2019/2003操作系统的计算机等。 软件&#xff1a;记事本、WireShark、Chrome浏览器等。 三&#xff1a;实验方…

《分析模式:可重用对象模型》学习笔记之四:企业财务分析中的观察和测量02

这个模型基本解决问题&#xff0c;可以方便定义层次&#xff0c;以及反映了三个不同的维数元素&#xff0c;也反映了企业部门单元和维数元素的关系&#xff0c;但是很快可以看到&#xff0c;在这里&#xff0c;维数被局限在三个&#xff1a;也就是说&#xff0c;如果维数需要改…

静止轨道卫星大气校正(Atmospheric Correction)和BRDF校正

文章内容仅用于自己知识学习和分享&#xff0c;如有侵权&#xff0c;还请联系并删除 &#xff1a;&#xff09; 目的&#xff1a; TOA reflectance 转为 surface refletance。 主要包含两步&#xff1a; 1&#xff09;大气校正&#xff1b; 2&#xff09;BRDF校正 进度&#x…

抖音矩阵管理系统开发:全面解析与推荐

在数字时代&#xff0c;短视频平台如抖音已经成为人们生活中不可或缺的一部分。随着内容创作者数量的激增&#xff0c;如何高效地管理多个抖音账号&#xff0c;实现内容矩阵化运营&#xff0c;成为了众多创作者关注的焦点。今天&#xff0c;我们就来全面解析抖音矩阵管理系统的…

Java_如何在IDEA中使用Git

注意&#xff1a;进行操作前首先要确保已经下载git&#xff0c;在IDEA中可以下载git&#xff0c;但是速度很慢&#xff0c;可以挂梯子下载。 导入git仓库代码 第一次导入&#xff1a; 首先得到要加载的git仓库的url&#xff1a; 在git仓库中点击 “克隆/下载” 按钮&#xf…

SpringBoot教程(十七) | SpringBoot集成swagger

SpringBoot教程&#xff08;十七&#xff09; | SpringBoot集成swagger 一、Swagger的简述二、SpringBoot集成swagger21. 引入依赖2. 新建SwaggerConfig配置类当 SpringBoot为2.6.x及以上时 需要注意 3.配置Swagger开关4. 给Controller 添加注解&#xff08;正式使用&#xff0…

PCIe 以太网芯片 RTL8125B 的 spec 和 Linux driver 分析备忘

1,下载 RTL8125B driver 下载页&#xff1a; https://www.realtek.com/Download/List?cate_id584 2,RTL8125B datasheet下载 下载页&#xff1a; https://file.elecfans.com/web2/M00/44/D8/poYBAGKHVriAHnfWADAT6T6hjVk715.pdf3, 编译driver 解压&#xff1a; $ tar xj…

鸿蒙OpenHarmony Native API【drawing_color.h与drawing_font_collection.h】 头文件

drawing_color.h Overview Related Modules: [Drawing] Description: 文件中定义了与颜色相关的功能函数 Since: 8 Version: 1.0 Summary Functions FunctionDescription[OH_Drawing_ColorSetArgb] (uint32_t alpha, uint32_t red, uint32_t green, uint32_t blue)u…

机器学习第四十九周周报 GT

文章目录 week49 GY摘要Abstract1. 题目2. Abstract3. 网络结构3.1 graphon3.2 框架概览 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过程4.3.1 有效性4.3.2 可转移性4.3.3 消融研究4.3.4 运行时间 5. 结论6.代码复现小结参考文献 week49 GY 摘要 本周阅读了题为Fine-tun…

几个小创新模型,Transformer与SVM、LSTM、BiLSTM、Adaboost的结合,MATLAB分类全家桶再更新!...

截止到本期MATLAB机器学习分类全家桶&#xff0c;一共发了5篇&#xff0c;参考文章如下&#xff1a; 1.机器学习分类全家桶&#xff0c;模式识别&#xff0c;故障诊断的看这一篇绝对够了&#xff01;MATLAB代码 2. 再更新&#xff0c;机器学习分类全家桶&#xff0c;模式识别&a…

【四】jdk8基于m2芯片arm架构Ubuntu24虚拟机下载与安装

文章目录 1. 安装版本2. 开始安装3. 集群安装 1. 安装版本 如无特别说明&#xff0c;本文均在root权限下安装。进入oracle官网&#xff1a;https://www.oracle.com/java/technologies/downloads/找到最下面Java SE 看到java 8&#xff0c;下载使用 ARM64 Compressed Archive版…

vue3+vite纯前端实现自动触发浏览器刷新更新版本内容,并在打包时生成版本号文件

前言 在前端项目中&#xff0c;有时候为了实现自动触发浏览器刷新并更新版本内容&#xff0c;可以采取一系列巧妙的措施。我的项目中是需要在打包时候生成一个version.js文件&#xff0c;用当前打包时间作为版本的唯一标识&#xff0c;然后打包发版 &#xff0c;从实现对版本更…

五大设备制造商的 200 多种机型的安全启动功能完全失效

2012 年&#xff0c;一个由硬件和软件制造商组成的行业联盟采用了安全启动技术&#xff0c;以防范长期存在的安全威胁。这种威胁是恶意软件的幽灵&#xff0c;它可以感染 BIOS&#xff0c;即每次计算机启动时加载操作系统的固件。从那里&#xff0c;它可以保持不受检测和删除&a…

从零开始学Java(超详细韩顺平老师笔记梳理)08——面向对象编程中级(上)IDEA常用快捷键、包、封装、继承

文章目录 前言一、IDEA使用常用快捷键模板/自定义模板 二、包package1. 基本介绍2. 包的命名规范3. 常用的包和如何引入4. 注意事项和细节 三、访问修饰符&#xff08;四类&#xff09;四、封装Encapsulation&#xff08;重点&#xff09;1. 封装介绍2. 封装步骤3. 快速入门4. …

SpringCloud Nacos的配置与使用

Spring Cloud Nacos的配置与使用 文章目录 Spring Cloud Nacos的配置与使用1. 简单介绍2. 环境搭建3. 服务注册/服务发现4. Nacos 负载均衡4.1 服务下线4.2 权重配置4.3 同集群优先访问 5. Nacos 健康检查5.1 两种健康检查机制5.2 服务实例类型 6.Nacos 环境隔离6.1 创建namesp…

【MySQL进阶之路 | 高级篇】表级锁之S锁,X锁,意向锁

1. 从数据操作的粒度划分&#xff1a;表级锁&#xff0c;页级锁&#xff0c;行锁 为了尽可能提高数据库的并发度&#xff0c;每次锁定的数据范围越小越好&#xff0c;理论上每次只锁定当前操作的数据的方案会得到最大的并发度&#xff0c;但是管理锁是很耗资源的事情&#xff…

驾驭代码的无形疆界:动态内存管理揭秘

目录 1.:为什么要有动态内存分配 2.malloc和free 2.1:malloc 2.2:free 3.calloc和realloc 3.1:calloc 3.1.1:代码1(malloc) 3.1.2:代码2(calloc) 3.2:realloc 3.2.1:原地扩容 3.2.2:异地扩容 3.2.3:代码1(原地扩容) 3.2.3:代码2(异地扩容) 4:常见的动态内存的错误…