一、准备

本文中的示例运行环境及相关软件版本如下:

  • Kubernetes v1.16.3
  • Go 1.15.6
  • Kubebuilder 3.1.0
  • Docker 20.10.7

安装kubebuilder:

#下载kubebuilder 3.1.0,建议二进制版本:https://github.com/kubernetes-sigs/kubebuilder/releases
#将二进制文件copy到/usr/local/bin下
% chmod +x kubebuilder && mv kubebuilder /usr/local/bin/
#验证
% kubebuilder version

二、创建项目

% mkdir guestbook
% cd guestbook %
% go mod init guestbook //go mod管理包
% kubebuilder init --domain xiaohongshu.org --owner "luxiu"

三、创建API

% kubebuilder create api --group redis  --version v1 --kind RedisCluster
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/rediscluster_types.go
controllers/rediscluster_controller.go
Update dependencies:
$ go mod tidy
Running make:
$ make generate
go: creating new go.mod: module tmp
Downloading sigs.k8s.io/controller-tools/cmd/controller-gen@v0.4.1
go: found sigs.k8s.io/controller-tools/cmd/controller-gen in sigs.k8s.io/controller-tools v0.4.1
/Users/luxiu/Desktop/luxiu/project/kubernetes/crd-test/bin/controller-gen object:headerFile="hack/boilerplate.go.txt" paths="./..."

API 创建完成后,在项目根目录下查看目录结构:

四、安装 CRD

这里安装CRD到指定的k8s集群里,需要修改Makefile里连接k8s配置:

install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl --context cls-j07gq3ud-context-default apply -f -
uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/crd | kubectl --context cls-j07gq3ud-context-default delete -f -
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | kubectl --context cls-j07gq3ud-context-default apply -f -
undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config.
$(KUSTOMIZE) build config/default | kubectl --context cls-j07gq3ud-context-default delete -f -

执行下面命令来安装CRD:

 % make install
/Users/luxiu/Desktop/luxiu/project/kubernetes/crd-test/bin/controller-gen "crd:trivialVersions=true,preserveUnknownFields=false" rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
/Users/luxiu/Desktop/luxiu/project/kubernetes/crd-test/bin/kustomize build config/crd | kubectl --context cls-j07gq3ud-context-default apply -f -
customresourcedefinition.apiextensions.k8s.io/redisclusters.redis.xiaohongshu.org created

五、部署 Controller

在开始部署 controller 之前,我们需要先检查 kubebuilder 自动生成的 YAML 文件。

修改使用 gcr.io 镜像仓库的镜像地址

对于中国大陆用户,可能无法访问 Google 镜像仓库 gcr.io,因此需要修改 config/default/manager_auth_proxy_patch.yaml 文件中的镜像地址,将其中 gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0 修改为quay.io/brancz/kube-rbac-proxy:v0.8.0

有两种方式运行 controller:

  • 本地运行,用于调试
  • 部署到 Kubernetes 上运行,作为生产使用

本地运行 controller

要想在本地运行 controller,只需要执行下面的命令,你将看到 controller 启动和运行时输出:

$ make run

将 Controller 部署到指定 Kubernetes集群

这里有个问题,需要修改Dockerfile中 ,给go 设置proxy代理,这样go mod download时不至于超时连不上:

在 RUN go mod download 这行的上面加如下一行:
ENV GOPROXY="https://goproxy.cn"

构建 controller 的镜像,并推送到公司docker harbor 上,然后在 Kubernetes 上部署 Deployment 资源,如下命令:

$ make docker-build  IMG=docker-reg.devops.xiaohongshu.com/data-infra/rediscluster:v1
$ make docker-push IMG=docker-reg.devops.xiaohongshu.com/data-infra/rediscluster:v1
$ make deploy IMG=docker-reg.devops.xiaohongshu.com/data-infra/rediscluster:v1

在初始化项目时,kubebuilder 会自动根据项目名称创建一个 Namespace,如本文中的guestbook-system ,查看 Deployment 对象和 Pod 资源。

% k8sdev get deployment -n guestbook-system
NAME READY UP-TO-DATE AVAILABLE AGE
guestbook-controller-manager 1/1 1 1 25h
% k8sdev get pod -n guestbook-system
NAME READY STATUS RESTARTS AGE
guestbook-controller-manager-79fd58d674-fvm2m 2/2 Running 0 145m

六、创建 CR

该创建自定义资源对象CR了,如原生中的rc/deployment等对象

% k8sdev apply -f config/samples/redis_v1_rediscluster.yaml
rediscluster.redis.xiaohongshu.org/rediscluster-sample created
% k8sdev get RedisCluster
NAME AGE
rediscluster-sample 38s

至此一个基本的 Operator 框架已经创建完成,但这个 Operator 只是修改了 etcd 中的数据而已,实际上什么事情也没做,因为我们没有在 Operator 中的增加业务逻辑。

七、开发业务逻辑

下面我们将修改 CRD 的数据结构并在 controller 中增加一些日志输出。

修改 CRD

我们将修改api/v1/guestbook_types.go 文件的内容,在 CRD 中增加 FirstNameLastName 和 Status 字段。

// GuestbookSpec defines the desired state of Guestbook
type GuestbookSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file // Foo is an example field of Guestbook. Edit guestbook_types.go to remove/update
FirstName string `json:"firstname"`
LastName string `json:"lastname"`
} // GuestbookStatus defines the observed state of Guestbook
type GuestbookStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
Status string `json:"Status"`
}

修改 Reconcile 函数

Reconcile 函数是 Operator 的核心逻辑,Operator 的业务逻辑都位于 controllers/guestbook_controller.go 文件的 Reconcile 函数中

func (r *GuestbookReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
_ = log.FromContext(ctx) // your logic here
// 获取当前的 CR,并打印
logger := log.FromContext(ctx)
obj := &webappv1.Guestbook{}
if err := r.Get(ctx, req.NamespacedName, obj); err != nil {
logger.Error(err, "Unable to fetch object")
return ctrl.Result{}, nil
} else {
logger.Info("Greeting from Kubebuilder to", obj.Spec.FirstName, obj.Spec.LastName)
} // 初始化 CR 的 Status 为 Running
obj.Status.Status = "Running"
if err := r.Status().Update(ctx, obj); err != nil {
logger.Error(err, "unable to update status")
} return ctrl.Result{}, nil
}

运行测试

  • 安装CRD(同上)
  • 部署controller(同上)
  • 创建CR

修改 config/samples/redis_v1_rediscluster.yaml 文件中的配置

apiVersion: redis.xiaohongshu.org/v1
kind: RedisCluster
metadata:
name: rediscluster-sample
spec:
# Add fields here
firstname: Jimmy
lastname: Song

执行下面命令,创建CR:

$ k8sdev apply -f  config/samples/redis_v1_rediscluster.yaml

查看controller里的运行日志:

% k8sdev get pod  -n guestbook-system
NAME READY STATUS RESTARTS AGE
guestbook-controller-manager-79fd58d674-fvm2m 2/2 Running 0 3h53m % k8sdev logs -f guestbook-controller-manager-79fd58d674-fvm2m -n guestbook-system -c manager
2022-03-08T08:24:04.641Z INFO controller-runtime.manager.controller.guestbook Greeting from Kubebuilder to {"reconciler group": "webapp.my.domain", "reconciler kind": "Guestbook", "name": "guestbook-sample", "namespace": "default", "Jimmy": "Song"}
2022-03-08T08:24:04.651Z INFO controller-runtime.manager.controller.guestbook Greeting from Kubebuilder to {"reconciler group": "webapp.my.domain", "reconciler kind": "Guestbook", "name": "guestbook-sample", "namespace": "default", "Jimmy": "Song"}

参考:部署k8s operator

使用 kubebuilder 创建并部署 k8s-operator的更多相关文章

  1. ansible一键部署k8s单机环境

    一.虚拟机准备 干净的Centsot7.4.4G内存.2个CPU 最小化安装,最好带虚拟化 二.执行初始化脚本 注意:脚本中配置静态网卡根据实际网卡名称配置,我用的是ens33 可以用 sed -i ...

  2. 二进制部署k8s

    一.二进制部署 k8s集群 1)参考文章 博客: https://blog.qikqiak.com 文章: https://www.qikqiak.com/post/manual-install-hi ...

  3. 【原】二进制部署 k8s 1.18.3

    二进制部署 k8s 1.18.3 1.相关前置信息 1.1 版本信息 kube_version: v1.18.3 etcd_version: v3.4.9 flannel: v0.12.0 cored ...

  4. centos7.8 安装部署 k8s 集群

    centos7.8 安装部署 k8s 集群 目录 centos7.8 安装部署 k8s 集群 环境说明 Docker 安装 k8s 安装准备工作 Master 节点安装 k8s 版本查看 安装 kub ...

  5. 在Azure Container Service创建Kubernetes(k8s)群集运行ASP.NET Core跨平台应用程序

    引子 在此前的一篇文章中,我介绍了如何在本地docker环境中运行ASP.NET Core跨平台应用程序(http://www.cnblogs.com/chenxizhang/p/7148657.ht ...

  6. 微服务架构 - 离线部署k8s平台并部署测试实例

    一般在公司部署或者真实环境部署k8s平台,很有可能是内网环境,也即意味着是无法连接互联网的环境,这时就需要离线部署k8s平台.在此整理离线部署k8s的步骤,分享给大家,有什么不足之处,欢迎指正. 1. ...

  7. 部署 k8s Cluster(上)[转]

    我们将部署三个节点的 Kubernetes Cluster. k8s-master 是 Master,k8s-node1 和 k8s-node2 是 Node. 所有节点的操作系统均为 Ubuntu ...

  8. ubuntu18.04使用kubeadm部署k8s单节点

    实验目的: 体验kubeadm部署k8s服务,全流程体验! 实验环境: ubuntu18.04 联网在线部署 kubeadm 01.系统检查 节点主机名唯一,建议写入/etc/hosts 禁止swap ...

  9. Kubeasz部署K8s基础测试环境简介

    下面介绍使用Kubeasz部署K8s集群环境. https://github.com/easzlab/kubeasz在需要使用kubeeasz项目安装的k8s时,需要将所有需要它来部署的节点上,都安装 ...

随机推荐

  1. 使用 TensorFlow 构建机器学习项目中文版·翻译完成

    原文:Building Machine Learning Projects with TensorFlow 协议:CC BY-NC-SA 4.0 不要担心自己的形象,只关心如何实现目标.--<原 ...

  2. html重点标签总结

    一. iframe 的学习 iframe通俗的的理解就是,可以在页面里面嵌套新的页面 它的使用会使页面变卡,一般会有一个固定的尺寸,默认的.他也属于可替换元素行列.我们可以通过CSS来改变尺寸 fra ...

  3. laravel操作Redis排序/删除/列表/随机/Hash/集合等方法全解

    Song • 3563 次浏览 • 0 个回复 • 2017年10月简介 Redis模块负责与Redis数据库交互,并提供Redis的相关API支持: Redis模块提供redis与redis.con ...

  4. js判断变量是否为空字符串、null、undefined

    let _isEmpty = (input) => { return input + '' === 'null' || input + '' === 'undefined' || input.t ...

  5. Python--列表简介

    Python--列表简介 目录 Python--列表简介 一.列表 1. 访问列表元素 2. 索引从0而不是1开始 3. 使用列表中的各个值 二.修改.添加和删除元素 1. 修改列表元素 2. 在列表 ...

  6. LVS调度算法总结

    LVS 调试算法分为两种:静态方法和动态方法. 静态方法 RR:轮询 WRR:加权轮询 SH:源地址哈希,将来自于同一个IP地址的请求始终发往第一次挑中的RS,从而实现会话绑定 DH:目标地址哈希,第 ...

  7. desktopForWin安装

    window环境下搭建appium(win7和win10都试过,能行),这里只说了Android自动化环境.iOS自动化需要MacOS支持. 一.python环境搭建 下载Python 官网下载地址h ...

  8. 通过C#在控制台输出各种图形文字

    这不是要准备公司年会了嘛 每个部门抓壮丁,必须安排至少一个节目 想着上去唱首歌算了,被毙,没有部门特色 妈蛋,唱歌没特色,那隔壁在前线工作的部门要表演个啥,抄表? 冥思苦想之下,给节目加了点部门特色, ...

  9. 框架5--nginx安装部署 下(web服务)

    目录 1.提纲 2.Nginx虚拟主机 3.Nginx日志 4.Nginx访问控制模块 5.Nginx状态监控模块 6.访问连接控制模块 框架5--nginx安装部署 下(web服务) 1.提纲 1. ...

  10. python生成器对象&常见内置函数

    内容概要 异常捕获(补充) for循环本质 生成器 yield 和 return优缺点 笔试题 常用内置函数 内容详细 一.异常捕获补充 try: print(name) except NameErr ...