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://xiahunao.cn/news/3269701.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

RAG优化技巧 | 7大挑战与解決方式 | 提高你的LLM: 下篇

RAG优化技巧 | 7大挑战与解决方式 | 提高你的LLM&#xff1a;下篇 在当今快速发展的人工智能领域&#xff0c;大型语言模型&#xff08;LLM&#xff09;已经成为无处不在的技术&#xff0c;它们不仅改变了我们与机器交流的方式&#xff0c;还在各行各业中发挥着革命性的影响。…

实时多模态大模型

1、GPT4o 不开源 2、Moshi 开源模型来自法国一个仅有 8 人的非营利性 AI 研究机构 ——Kyutai&#xff0c;模型名为 Moshi&#xff0c;具备听、说、看的多模态功能。图灵奖得主 Yann LeCun 转发说道&#xff1a;「Moshi 能听懂带有法国口音的英语。」据悉&#xff0c;该团队开…

C++序列化Cereal库的使用

目录 一、什么是序列化二、Cereal序列化库三、下载与编译四、使用 一、什么是序列化 序列化在编程中有以下几个重要的原因&#xff1a; 数据存储&#xff1a;将数据对象序列化为一种持久化的格式&#xff0c;可以将其存储在文件、数据库或其他存储介质中。这样可以在程序的不同…

视觉SLAM第二讲

SLAM分为定位和建图两个问题。 定位问题 定位问题是通过传感器观测数据直接或间接求解位置和姿态。 通常可以分为两类&#xff1a;基于已知地图的定位和基于未知地图的定位。 基于已知地图的定位 利用预先构建的地图&#xff0c;结合传感器数据进行全局定位。SLAM中的全局…

HDU1056——HangOver,HDU1057——A New Growth Industry,HDU1058——Humble Numbers

目录 HDU1056——HangOver 题目描述 运行代码 代码思路 HDU1057——A New Growth Industry 题目描述 运行代码 代码思路 HDU1058——Humble Numbers 题目描述 运行代码 代码思路 HDU1056——HangOver 题目描述 Problem - 1056 运行代码 #include <iostream&…

html+css+js 实现马赛克背景按钮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽效果&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文…

报错Found dtype Long but expected Float解决办法

Found dtype Long but expected Float错误通常发生在尝试将一个数据类型为Long的张量传递给一个期望数据类型为Float的函数或操作时。 在PyTorch中&#xff0c;Long和Float是两种常见的数据类型&#xff0c;分别对应于64位整数和32位浮点数。某些函数或操作可能只接受特定数据…

详细分析 Bladex中的swagger-resources资源未授权访问的解决方法

目录 1. 问题所示2. 原理分析2.1 RouterFunctionConfiguration 类2.2 SwaggerResourceHandler 类3. 解决方法3.1 网关过滤3.2 去除配置3.3 代码修改4. 彩蛋1. 问题所示 从而也导致资源接口文件泄露 https://xxx/swagger-resources 或者 ip:端口号/swagger-resources 2. 原理分…

数据仓库设计与数据建模初探

一、为什么需要引入数据仓库 数据仓库本质上是一种数据库&#xff0c;但它有一些特定的特性和用途&#xff0c;使其与传统的关系数据库有所不同。 需要分析的数据量较大&#xff08;单批 GiB&#xff09;&#xff0c;此时事务性数据库分析性能堪忧&#xff0c;需要通过建立索…

空调压力传感器

空调压力传感器是自动空调控制系统的一个传感器元件&#xff0c;其作用是防止制冷系统在极限制冷剂管路的压力下工作&#xff0c;并帮助控制发动机冷却风扇的转速。压力传感器安装在发动机舱内空调高压管路上。 该传感器向发动机ECM或空调控制单元输出压力信号&#xff0c;当检…

自学网络安全,从小白到大神的破茧之路!

在当今数字化高速发展的时代&#xff0c;网络安全已经成为了至关重要的领域。无论是个人的隐私保护&#xff0c;还是企业、国家的关键信息资产维护&#xff0c;都离不开网络安全的有力保障。出于对这一领域的浓厚兴趣以及对未来职业发展的清晰规划&#xff0c;我毅然决然地踏上…

【计算机网络】TCP负载均衡实验

一&#xff1a;实验目的 1&#xff1a;了解TCP负载均衡的配置。 2&#xff1a;学会使用NAT技术处理和外部网络的连接。 二&#xff1a;实验仪器设备及软件 硬件&#xff1a;RCMS交换机、网线、内网网卡接口、Windows 2019操作系统的计算机等。具体为&#xff1a;二层交换机1…

Python数据分析案例55——基于LSTM结构自编码器的多变量时间序列异常值监测

案例背景 时间序列的异常值检测是方兴未艾的话题。比如很多单变量的&#xff0c;一条风速&#xff0c;一条用电量这种做时间序列异常值检测&#xff0c;想查看一下哪个时间点的用电量异常。 多变量时间序列由不同变量随时间变化的序列组成&#xff0c;这些时间序列在实际应用…

LivePortrait优化版,表情迁移,数字人,视频驱动视频v2v(WIN,MAC)

大家好&#xff0c;今天给大家分享一个由快手、中国科学技术大学和复旦大学联合团队开发的表情迁移项目——LivePortrait。老规矩&#xff0c;整合包也已经准备OK了。&#xff08;MAC用户不要担心&#xff01;这次有有有有MAC的哦&#xff01;&#xff09; 只需要上传一段参考视…

Godot入门 04平台设计

新建创景&#xff0c;添加AnimatableBody2D节点。 添加Sprite2D节点 拖动图片 剪裁图片&#xff0c;吸附模式&#xff1a;像素吸附 添加CollisionShape2D&#xff0c;设置实际形状为矩形 重命名AnimatableBody2D节点为Platform&#xff0c;保存场景&#xff0c;拖动platform场景…

20 B端产品的数据分析

数据分析的价值 数据衡量业务&#xff1a;通过管理数据报表&#xff0c;可以快速衡量业务发展状态。 数据洞察业务&#xff1a;通过数据分析&#xff0c;可以找到业务发展的机遇。 数据驱动指导业务&#xff1a;基于数据&#xff0c;驱动业务决策&#xff0c;数据支撑决策。 …

Django5之视图装饰器

本节主要介绍Django框架视图层中装饰器的内容。视图装饰器用来对视图函数进行相关的控制操作&#xff0c;实现了对各种HTTP特性的支持功能。 4.5.1 允许HTTP方法 在Django框架中&#xff0c;位于django.views.decorators.http模块的装饰器被用来限制可以访问该视图的HTTP请求…

RICHTEK立锜科技静态耗电的nanoPower Buck转换器RT5713/RT5714

RT5713/14 是静态耗电只有 360nA 的高效同步 Buck 转换器&#xff0c;即使负载电流低达 10mA 时也能保持其很高的转换效率。其输入电压范围为 2.2V~5.5V&#xff0c;输出电压为两档可选&#xff0c;通过电压选择引脚 VSEL 即可进行设定&#xff0c;负载能力可达 0.5A/1A。 它采…

字符串格式化(不造轮子)

jdk提供的字符串格式化工具类String.format、MessageFormat使用的占位符不够直观&#xff0c;除了使用重量级的模板引擎外&#xff0c;寻求一种轻量级的方式 Apache StringSubstitutor commons-text包下的org.apache.commons.text.StringSubstitutor类 <dependency><…

如何知道一个字段在selenium中是否可编辑?

这篇文章将检查我们如何使用Java检查selenium webdriver中的字段是否可编辑。 我们如何知道我们是否可以编辑字段&#xff1f;“readonly”属性控制字段的可编辑性。如果元素上存在“readonly”属性&#xff0c;则无法编辑或操作该元素或字段。 因此&#xff0c;如果我们找到一…