使用 kubebuilder 创建 operator 示例
本文作为 Kubebuilder 教程,将指导您如何使用 kubebuilder 创建一个 Kubernetes Operator。
准备
本文中的示例运行环境及相关软件版本如下:
Kubernetes MiniKube v1.9.2
Kubernetes v1.18.0
Go 1.14
Kubebuilder 2.3.1
kustomize 3.6.1
Docker 19.03.8
使用 Minikube 安装 Kubernetes 集群,Kubernetes 安装好后,检查集群是否可用。
Minikube 的 DNS 解析问题
如果遇到 Kubernetes 集群无法拉取镜像,DNS 解析出现问题,解决方式见 DNS lookup not working when starting minikube with --dns-domain #1674。
使用 minikube ssh 进入 minikube 主机,修改 /etc/systemd/resolved.conf 文件,将其中的 DNS 配置字段修改为 DNS=8.8.8.8,然后执行 sudo systemctl restart systemd-resolved 即可更改 DNS,切勿直接修改 /etc/resolv.conf 文件。
修正 Minikube 的 DNS 配置,请执行下面的命令。
minikube ssh
sudo sed -i 's/#DNS=/DNS=8.8.8.8/g' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved名词解释
在阅读下面的文章前,需要先明确以下两个名词的含义。
CRD:自定义资源定义,Kubernetes 中的资源类型。
CR:Custom Resource,对使用 CRD 创建出来的自定义资源的统称。
安装 kubebuilder
到 kubebuilder 的 GitHub release 页面上下载与您操作系统对应的 kubebuilder 安装包。
MacOS
对于 Mac 系统,将下载好的安装包解压后将其移动到 /usr/local/kubebuilder 目录下,并将 /usr/local/kubebuilder/bin 添加到您的 $PATH 路径下。
创建项目
我们首先将使用自动配置创建一个项目,该项目在创建 CR 时不会触发任何资源生成。
初始化和创建 API
创建的项目路径位于 $GOPATH/jimmysong.io/kubebuilder-example。下文中的操作没有明确说明的话都是在该项目路径下运行。
在项目路径下使用下面的命令初始化项目。
在项目根目录下执行下面的命令创建 API。
API 创建完成后,在项目根目录下查看目录结构。
以上就是自动初始化出来的文件。
安装 CRD
执行下面的命令安装 CRD。
部署 controller
在开始部署 controller 之前,我们需要先检查 kubebuilder 自动生成的 YAML 文件。
修改使用 gcr.io 镜像仓库的镜像地址
对于中国大陆用户,可能无法访问 Google 镜像仓库 gcr.io,因此需要修改 config/default/manager_auth_proxy_patch.yaml 文件中的镜像地址,将其中 gcr.io/kube-rbac-proxy:v0.5.0 修改为 jimmysong/kubebuilder-kube-rbac-proxy:v0.5.0。
有两种方式运行 controller:
本地运行,用于调试
部署到 Kubernetes 上运行,作为生产使用
本地运行 controller
要想在本地运行 controller,只需要执行下面的命令。
你将看到 controller 启动和运行时输出。
将 controller 部署到 Kubernetes
执行下面的命令部署 controller 到 Kubernetes 上,这一步将会在本地构建 controller 的镜像,并推送到 DockerHub 上,然后在 Kubernetes 上部署 Deployment 资源。
在初始化项目时,kubebuilder 会自动根据项目名称创建一个 Namespace,如本文中的 kubebuilder-example-system,查看 Deployment 对象和 Pod 资源。
创建 CR
Kubebuilder 在初始化项目的时候已生成了示例 CR,执行下面的命令部署 CR。
执行下面的命令查看新创建的 CR。
你将看到类似如下的输出。
至此一个基本的 Operator 框架已经创建完成,但这个 Operator 只是修改了 etcd 中的数据而已,实际上什么事情也没做,因为我们没有在 Operator 中的增加业务逻辑。
增加业务逻辑
下面我们将修改 CRD 的数据结构并在 controller 中增加一些日志输出。
修改 CRD
我们将修改上文中使用 kubebuilder 命令生成的默认 CRD 配置,在 CRD 中增加 FirstName、LastName 和 Status 字段。
下面是修改后的 api/v1/guestbook_types.go 文件的内容,对应修改的地方已在代码中注释说明。
上面的代码比原先使用 kubebuilder 生成的默认代码增加了以下内容:
修改 Reconcile 函数
Reconcile 函数是 Operator 的核心逻辑,Operator 的业务逻辑都位于 controllers/guestbook_controller.go 文件的 func (r *GuestbookReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) 函数中。
这段代码的业务逻辑是当发现有 guestbooks.webapp.jimmysong.io 的 CR 变更时,在控制台中输出日志。
运行测试
修改好 Operator 的业务逻辑后,再测试一下新的逻辑是否可以正常运行。
部署 CRD
跟上文的做法一样,执行下面的命令部署 CRD。
运行 controller
跟上文的做法一样,执行下面的命令运行 controller。为了方便起见,我们将在本地运行 controller,当然您也可以将其部署到 Kubernetes 上运行。
保持该窗口在前台运行。
部署 CR
修改 config/samples/webapp_v1_guestbook.yaml 文件中的配置。
将其应用到 Kubernetes。
此时转到上文中运行 controller 的窗口,将在命令行前台中看到如下输出。
从上面的日志中,可以看到这条输出。
这正是在 Reconcile 函数中的输出。
获取当前的 CR
使用下面的命令获取当前的 CR。
将看到如下输出。
我们输出的最后部分:
这正是我们在 CRD 里定义的字段。
删除 CR
使用下面的命令删除 CR。
此时在 controller 的前台输出中可以看到以下内容。
因为该 CR 被删除,因此日志中会提示资源找不到。
更多
本示例仅展示了使用 kubebuilder 创建 Operator 的基本逻辑,步骤为:
初始化项目和 API
安装 CRD
部署 Controller
创建 CR
Operator 的核心逻辑都在 controller 的 Reconcile 函数中,请参考 Awesome Cloud Native 中的 Operator 实现,本书后续将会讨论。
参考
最后更新于