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

news2024/9/23 3:22:21

一、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 Spec
          type: object        #定义类型
          properties:         #定义对象属性      
            spec:
              type: object
              properties:
                name:               #自定义具体属性的名字
                  type: string
                age:
                  type: integer
  scope: 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: example
  age: 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  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     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.coloradmin.cn/o/1950636.html

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

相关文章

原型图设计指南:从基础到精通

用户体验设计师和原型设计的主要功能 PM、网站开发工程师通过展示产品内容、结构和粗略布局来沟通最初产品设想的重要工具&#xff0c;说明用户将如何与产品互动&#xff0c;而不是视觉设计。在大厂中&#xff0c;岗位分工更加细致明确&#xff0c;大部分原型都是产品经理做的&…

Oracle系统表空间的加解密

实验环境 数据库选择的是orclpdb1&#xff0c;当前系统表空间未加密&#xff1a; SQL> show con_nameCON_NAME ------------------------------ ORCLPDB1SQL> select TABLESPACE_NAME, STATUS, ENCRYPTED from dba_tablespaces;TABLESPACE_NAME STATUS …

【Ubuntu】安装 Snipaste 截图软件

Snipaste 下载安装并使用 Snipastefor more information报错解决方案每次启动软件需要输入的命令如下添加开机自启动 下载 下载地址 安装并使用 Snipaste 进入终端输入命令 # 1、进入到 Snipaste-2.8.9-Beta-x86_64.AppImage 所在目录&#xff08;根据自己的下载目录而定&…

uniapp安卓plus原生选择系统文件

uniapp安卓plus原生选择系统文件 效果&#xff1a; 组件代码&#xff1a; <template xlang"wxml" minapp"mpvue"><view></view> </template> <script>export default {name: file-manager,props: {},data() {return {is…

qt--做一个拷贝文件器

一、项目要求 使用线程完善文件拷贝器的操作 主窗口不能假死主窗口进度条必须能动改写文件大小的单位&#xff08;自适应&#xff09; 1TB1024GB 1GB1024MB 1MB1024KB 1KB1024字节 二、所需技术 1.QFileDialog 文件对话框 QFileDialog也继承了QDialog类&#xff0c;直接使用静态…

Hi-Fix 介绍

一、HIFIX 定义与功能 HIFIX是连接安装在自动检测装置&#xff08;Tester&#xff09;本体内的功能卡(Resource board)和承载被测设备(Device)探针卡&#xff08;Probe card&#xff09;的媒介&#xff0c;将来自检测装置的大量测试信号统一发送到被测设备(Device)。 HiFIX 能…

Java语言程序设计——篇八(1)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; Java常用核心类 主要内容Object: 终极父类toString( )方法equals( )方法getClass( )方法hashCode( )方法clone( )方法finalize( )方法实战演练 …

CentOS6.0安装telnet-server启用telnet服务

CentOS6.0安装telnet-server启用telnet服务 一步到位 fp"/etc/yum.repos.d" ; cp -a ${fp} ${fp}.$(date %0y%0m%0d%0H%0M%0S).bkup echo [base] nameCentOS-$releasever - Base baseurlhttp://mirrors.163.com/centos-vault/6.0/os/$basearch/http://mirrors.a…

使用echo写入多行文字到文件时换行的处理

目标 想使用echo写入如下内容到文件program.c里 #include<stdio.h> int main(){printf("hello!\n"); } 需要处理 1、如何处理行换 2、代码中的换行如何处理 实际例子 创建文件夹 mkdir test cd test chmod 777 . 创建文件写入内容 查看 cat -n program.c…

SLS 数据加工全面升级,集成 SPL 语法

作者&#xff1a;灵圣 数据加工概述 在系统开发、运维过程中&#xff0c;日志是最重要的信息之一&#xff0c;其最大的优点是简单直接。不过在整个日志的生命周期里有一对很难调和的矛盾&#xff1a;输出和采集日志要求尽可能的简单便捷 vs 日志分析时需要数据格式化并能够按…

【SpringBoot】3 项目配置及部署

配置文件配置 将 application.properties 改为 application.yml &#xff0c;写法不一样&#xff0c;本人比较习惯用 yaml 格式。 配置项目名称和项目端口号。 application.yml server:port: 8888 spring:application:name: system配置外置 Servlet 容器 如果要在 Tomcat 容器…

数据结构·AVL树

1. AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果存数据时接近有序&#xff0c;二叉搜索将退化为单支树&#xff0c;此时查找元素效率相当于在顺序表中查找&#xff0c;效率低下。因此两位俄罗斯数学家 G.M.Adelson-Velskii 和E.M.Landis 在1962年发明了一种解…

音视频入门基础:WAV专题(1)——使用FFmpeg命令生成WAV音频文件

在文章《音视频入门基础&#xff1a;PCM专题&#xff08;1&#xff09;——使用FFmpeg命令生成PCM音频文件并播放》中讲述了生成PCM文件的方法。通过FFmpeg命令可以把该PCM文件转为WAV格式的音频文件&#xff1a; ./ffmpeg -ar 44100 -ac 2 -f s16le -acodec pcm_s16le -i aud…

「Ant Design」Antd 中卡片如何完全不展示内容区域、按需展示内容区域、不展示标题

前言 下面是默认的 Antd 卡片&#xff0c;由以下区域组成 处理 Antd 的 Card 展示形式大致有下面三种 卡片完全不展示内容区域 const App () > (<Card title"Default size card" extra{<a href"#">More</a>} style{{ width: 300 }}b…

工厂数字化转型,该如何建设数字孪生车间?

在工业4.0的浪潮下&#xff0c;数字化转型已成为工厂升级的必然趋势&#xff0c;而数字孪生技术的引入则为这一转型注入了强大动力。智汇云舟作为数字孪生行业头部企业和视频孪生技术首倡者&#xff0c;以创新的视角和前沿的技术&#xff0c;为数字工业建设助力&#xff0c;给众…

《昇思25天学习打卡营第2天|张量》

张量其实就是矩阵&#xff0c;在python中主要是使用numpy这个库来操作&#xff0c;然后再mindspore中一般使用tensor对象作为张量的载体 张量如果维度只有二维的话可以简单理解为数据库中的表&#xff0c;但是如果是3维4维主要是在列表中增加列表项比如 【 【1&#xff0c;1】…

C++ //练习 15.28 定义一个存放Quote对象的vector,将Bulk_quote对象传入其中。计算vector中所有元素总的net_price。

C Primer&#xff08;第5版&#xff09; 练习 15.28 练习 15.28 定义一个存放Quote对象的vector&#xff0c;将Bulk_quote对象传入其中。计算vector中所有元素总的net_price。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块&am…

【C++笔试强训】day01

数字统计 思路 用%10取出个位的数字&#xff0c;用/10迭代。 代码 #include <iostream> using namespace std;int main() {int l, r, res 0;cin >> l >> r;for (int i l; i < r; i){int x i;while (x){if (x % 10 2) res;x / 10;}}cout << r…

AttributeError: ‘WandbLogger‘ object has no attribute ‘bbox_interval‘

一、问题描述 跑yolov5时&#xff0c;运行代码出现以下报错 AttributeError: WandbLogger object has no attribute bbox_interval 二、问题原因 可能是版本的问题&#xff0c;需要把wandb关闭 三、解决方法 在路径 \yolov5\utils\loggers 文件夹下的 _init__.py文件中19…

【MySQL】记录MySQL加载数据(LOAD DATA)

MySQL LOAD DATA 一、背景二、模拟生成用户信息三、加载到mysql表3.1、建表语句3.2 加载数据3.3、查看结果 一、背景 现在有个需求是将用户信息存入student.data文件中&#xff0c;在现在load到数据库中 二、模拟生成用户信息 假设用户信息&#xff0c;包含姓名&#xff0c;…