5.5.2. 使用 Operator SDK 来构建基于 Helm 的 Operator
本流程介绍了使用 Operator SDK 中的工具和库来构建由 Helm Chart 提供技术支持的简单 Nginx Operator 的示例。
最好为每个 Chart 新建一个 Operator。如果要在 Go 中编写一个成熟的 Operator,摆脱基于 Helm 的 Operator,这种做法支持更多具有原生行为的 Kubernetes API(如 oc get Nginx
),也更灵活。
先决条件
- 开发工作站上安装 operator SDK v0.19.4 CLI
-
使用具有
cluster-admin
权限的账户访问基于 Kubernetes 的集群 v1.11.3+(如 OpenShift Container Platform 4.6) -
已安装 OpenShift CLI(
oc
)v4.6+
流程
创建新 Operator 项目。命名空间范围的 Operator 会监视和管理单一命名空间中的资源。命名空间范围的 Operator 因具有高灵活性而常被视为首选。这类 Operator 支持解耦升级、针对故障和监控隔离命名空间以及区别化 API 定义。
要创建基于 Helm 的、全命名空间范围的新
nginx-operator
项目,请使用以下命令:$ operator-sdk new nginx-operator \ --api-version=example.com/v1alpha1 \ --kind=Nginx \ --type=helm
$ cd nginx-operator
这会创建
nginx-operator
项目,专门用于监视 API 版本为example.com/v1apha1
kind 为Nginx
的 Nginx 资源。自定义 Operator 逻辑。
在本例中,
nginx-operator
会针对每个Nginx
自定义资源 (CR) 执行以下协调逻辑:- 如果尚无 Nginx 部署,请创建一个。
- 如果尚无 Nginx 服务,请创建一个。
- 如果被启用且不存在,请创建一个 Nginx ingress。
- 确保部署、服务和可选的 Ingress 符合 Nginx CR 指定的所需配置(如副本数、镜像、服务类型)。
默认情况下,
nginx-operator
会监视Vginx
资源事件,如watches.yaml
文件中所示,并使用指定 Chart 执行 Helm 发行版本:- version: v1alpha1 group: example.com kind: Nginx chart: /opt/helm/helm-charts/nginx
查阅 Nginx Helm Chart。
创建 Helm Operator 项目后,Operator SDK 会创建一个 Helm Chart 示例,其中包含一组模板,用于简单的 Nginx 发行版本。
本例中,针对部署、服务和 Ingress 资源提供了模板,另外还有
NOTES.txt
模板,Helm Chart 开发人员可利用该模板传达有关发型版本的实用信息。如果您对 Helm Charts 还不熟悉,请参阅 Helm Chart 开发者文档。
了解 Nginx CR spec。
Helm 使用名为 values 的概念来自定义 Helm Chart 的默认配置,该 chart 在
values.yaml
文件中定义。通过在 CR spec 中设置所需值来覆盖这些默认值。以副本数量为例:
首先,检查
helm-charts/nginx/values.yaml
文件,会发现 Chart 有一个名为replicaCount
的值,默认设置为1
。要在部署中使用 2 个 Nginx 实例,您的 CR spec 中必须包含replicaCount: 2
。更新
deploy/crds/example.com_v1alpha1_nginx_cr.yaml
文件,如下所示:apiVersion: example.com/v1alpha1 kind: Nginx metadata: name: example-nginx spec: replicaCount: 2
同样,服务端口默认设置为
80
。要改用8080
,请通过添加服务端口覆盖来再次更新deploy/crds/example.com_v1alpha1_nginx_cr.yaml
文件:apiVersion: example.com/v1alpha1 kind: Nginx metadata: name: example-nginx spec: replicaCount: 2 service: port: 8080
Helm Operator 应用整个 spec,将其视为 values 文件内容,与
helm install -f ./overrides.yaml
命令的工作方式类似。
部署 CRD。
在运行 Operator 之前,Kubernetes 需要了解 Operator 将会监视的新自定义资源定义 (CRD)。部署以下 CRD:
$ oc create -f deploy/crds/example_v1alpha1_nginx_crd.yaml
构建并运行 Operator。
有两种方式来构建和运行 Operator:
- 作为 Kubernetes 集群内的一个 pod。
-
作为集群外的 Go 程序,使用
operator-sdk up
命令。
选择以下任一方法:
作为 Kubernetes 集群内的一个 pod 来运行。这是生产环境的首先方法。
构建
nginx-operator
镜像并将其推送至 registry:$ operator-sdk build quay.io/example/nginx-operator:v0.0.1
$ podman push quay.io/example/nginx-operator:v0.0.1
deploy/operator.yaml
文件中会生成 Deployment 清单。本文件中的部署镜像需要从占位符REPLACE_IMAGE
修改为之前构建的镜像。为此,请运行:$ sed -i 's|REPLACE_IMAGE|quay.io/example/nginx-operator:v0.0.1|g' deploy/operator.yaml
部署
nginx-operator
清单:$ oc create -f deploy/service_account.yaml
$ oc create -f deploy/role.yaml
$ oc create -f deploy/role_binding.yaml
$ oc create -f deploy/operator.yaml
验证
nginx-operator
部署是否已启动并正在运行:$ oc get deployment
输出示例
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-operator 1 1 1 1 1m
在集群外运行。这是开发阶段的首选方法,可加快部署和测试的速度。
此外,还务必要确保您的计算机上存在
watches.yaml
文件中引用的 Chart 路径。watches.yaml
文件默认能够与通过operator-sdk build
命令构建的 Operator 镜像一起使用。当使用operator-sdk run --local
命令开发和测试您的 Operator 时,SDK 会在本地文件系统中查找该路径。在该位置创建符号链接,以指向 Helm Chart 的路径:
$ sudo mkdir -p /opt/helm/helm-charts
$ sudo ln -s $PWD/helm-charts/nginx /opt/helm/helm-charts/nginx
要使用
$HOME/.kube/config
中的默认 Kubernetes 配置文件在本地运行 Operator:$ operator-sdk run --local
要使用所提供的 Kubernetes 配置文件在本地运行 Operator:
$ operator-sdk run --local --kubeconfig=<path_to_config>
部署
Nginx
CR。应用之前修改的
Nginx
CR:$ oc apply -f deploy/crds/example.com_v1alpha1_nginx_cr.yaml
确保
nginx-operator
为 CR 创建部署:$ oc get deployment
输出示例
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-nginx-b9phnoz9spckcrua7ihrbkrt1 2 2 2 2 1m
检查 pod,确认已创建两个副本:
$ oc get pods
输出示例
NAME READY STATUS RESTARTS AGE example-nginx-b9phnoz9spckcrua7ihrbkrt1-f8f9c875d-fjcr9 1/1 Running 0 1m example-nginx-b9phnoz9spckcrua7ihrbkrt1-f8f9c875d-ljbzl 1/1 Running 0 1m
检查服务端口是否已设置为
8080
:$ oc get service
输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-nginx-b9phnoz9spckcrua7ihrbkrt1 ClusterIP 10.96.26.3 <none> 8080/TCP 1m
更新
replicaCount
并删除端口。将
spec.replicaCount
字段从2
改为3
,删除spec.service
字段并应用更改:$ cat deploy/crds/example.com_v1alpha1_nginx_cr.yaml
输出示例
apiVersion: "example.com/v1alpha1" kind: "Nginx" metadata: name: "example-nginx" spec: replicaCount: 3
$ oc apply -f deploy/crds/example.com_v1alpha1_nginx_cr.yaml
确认 Operator 已更改部署大小:
$ oc get deployment
输出示例
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE example-nginx-b9phnoz9spckcrua7ihrbkrt1 3 3 3 3 1m
检查服务端口是否已设置为默认值
80
:$ oc get service
输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE example-nginx-b9phnoz9spckcrua7ihrbkrt1 ClusterIP 10.96.26.3 <none> 80/TCP 1m
清理资源:
$ oc delete -f deploy/crds/example.com_v1alpha1_nginx_cr.yaml
$ oc delete -f deploy/operator.yaml
$ oc delete -f deploy/role_binding.yaml
$ oc delete -f deploy/role.yaml
$ oc delete -f deploy/service_account.yaml
$ oc delete -f deploy/crds/example_v1alpha1_nginx_crd.yaml