使用 kubebuilder 创建并部署 k8s-operator
一、准备
本文中的示例运行环境及相关软件版本如下:
- 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 中增加 FirstName
、LastName
和 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"}
使用 kubebuilder 创建并部署 k8s-operator的更多相关文章
- ansible一键部署k8s单机环境
一.虚拟机准备 干净的Centsot7.4.4G内存.2个CPU 最小化安装,最好带虚拟化 二.执行初始化脚本 注意:脚本中配置静态网卡根据实际网卡名称配置,我用的是ens33 可以用 sed -i ...
- 二进制部署k8s
一.二进制部署 k8s集群 1)参考文章 博客: https://blog.qikqiak.com 文章: https://www.qikqiak.com/post/manual-install-hi ...
- 【原】二进制部署 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 ...
- centos7.8 安装部署 k8s 集群
centos7.8 安装部署 k8s 集群 目录 centos7.8 安装部署 k8s 集群 环境说明 Docker 安装 k8s 安装准备工作 Master 节点安装 k8s 版本查看 安装 kub ...
- 在Azure Container Service创建Kubernetes(k8s)群集运行ASP.NET Core跨平台应用程序
引子 在此前的一篇文章中,我介绍了如何在本地docker环境中运行ASP.NET Core跨平台应用程序(http://www.cnblogs.com/chenxizhang/p/7148657.ht ...
- 微服务架构 - 离线部署k8s平台并部署测试实例
一般在公司部署或者真实环境部署k8s平台,很有可能是内网环境,也即意味着是无法连接互联网的环境,这时就需要离线部署k8s平台.在此整理离线部署k8s的步骤,分享给大家,有什么不足之处,欢迎指正. 1. ...
- 部署 k8s Cluster(上)[转]
我们将部署三个节点的 Kubernetes Cluster. k8s-master 是 Master,k8s-node1 和 k8s-node2 是 Node. 所有节点的操作系统均为 Ubuntu ...
- ubuntu18.04使用kubeadm部署k8s单节点
实验目的: 体验kubeadm部署k8s服务,全流程体验! 实验环境: ubuntu18.04 联网在线部署 kubeadm 01.系统检查 节点主机名唯一,建议写入/etc/hosts 禁止swap ...
- Kubeasz部署K8s基础测试环境简介
下面介绍使用Kubeasz部署K8s集群环境. https://github.com/easzlab/kubeasz在需要使用kubeeasz项目安装的k8s时,需要将所有需要它来部署的节点上,都安装 ...
随机推荐
- 阿里P8整理Mysql面试题答案,助你“脱颖而出”,吊打面试官!(建议收藏)
前言 作为一名开发人员,每天英高都在和数据库进行着斗智斗勇,尤其是互联网行业,对MySQL的使用是比较多的.同样的,因为mysql的重要性以及普及性,在面试的时候一定是一个面试的重点或者说常问问题,说 ...
- buid-helper-maven-plugin简单使用
简介 官方文档 https://www.mojohaus.org/build-helper-maven-plugin/index.html 常用的Goals 名称 说明 build-helper:ad ...
- hihoCoder挑战赛1 毁灭者问题
题目链接:http://hihocoder.com/problemset/problem/1034 数据结构题,由于每个魔法单位有着不同的回复速度和上限,所以不能根据吸收时间点进行查询和更新.但是如果 ...
- git clone 命令
感谢原文作者:寻芝彬 原文链接:https://www.jianshu.com/p/c992c799f2dd 描述 拷贝一个 Git 仓库到本地 实例 拷贝一个 Git 仓库到本地,本地目录名称与Gi ...
- python基础篇-爬虫urlparse使用及简单示例
>>> from urllib.parse import urlparse >>> o = urlparse('http://www.cwi.nl:80/%7Egu ...
- 认识Html DOM
1.认识HTML DOM HTML Document Object Model 即:超文本标记语言-文档对象模型 HTML DOM理解为网页的API.它将网页中的各个元素都看作一个个对象,从而使网页中 ...
- Throwable以及错误
/* 异常的体系: ----------| Throwable 所以异常或者错误类的超类 --------------|Error 错误 错误一般是用于jvm或者是硬件引发的问题,所以我们一般不会通过 ...
- IO复习
/* 字节流 输入字节流: ---------| InputStream 所有输入字节流的基类. 抽象类 ------------| FileInputStream 读取文件的输入字节流 ------ ...
- 解决"Uncaught (in promise) Error: Navigation cancelled from "/" to "/login" with a new navigation"报错处理
Uncaught (in promise) Error: Navigation cancelled from "/" to "/login" with a ne ...
- Solution -「CF 1237E」Balanced Binary Search Trees
\(\mathcal{Description}\) Link. 定义棵点权为 \(1\sim n\) 的二叉搜索树 \(T\) 是 好树,当且仅当: 除去最深的所有叶子后,\(T\) 是满的: ...