$ mkdir -p $HOME/projects/nginx-operator
Operator 开发人员可以利用 Operator SDK 中的 Helm 支持来构建一个用于 Nginx 的示例基于 Helm 的 Operator 并管理其生命周期。本教程将逐步介绍以下过程
创建 Nginx 部署
确保部署大小与 Nginx
自定义资源 (CR) 规范中指定的大小相同
使用状态写入器更新 Nginx
CR 状态,其中包含 nginx
Pod 的名称
Red Hat 支持的 Operator SDK CLI 工具版本(包括与 Operator 项目相关的脚手架和测试工具)已弃用,并计划在未来的 OpenShift Dedicated 版本中删除。Red Hat 将在此版本的生命周期内为该功能提供错误修复和支持,但此功能将不再接收增强功能,并将从未来的 OpenShift Dedicated 版本中删除。 不建议使用 Red Hat 支持的 Operator SDK 版本创建新的 Operator 项目。拥有现有 Operator 项目的 Operator 作者可以使用 OpenShift Dedicated 发布的 Operator SDK CLI 工具版本来维护其项目并创建针对较新版本的 OpenShift Dedicated 的 Operator 版本。 以下与 Operator 项目相关的基础镜像 *未* 弃用。这些基础镜像的运行时功能和配置 API 仍然支持错误修复和解决 CVE。
有关不受支持的社区维护的 Operator SDK 版本的信息,请参阅 Operator SDK (Operator Framework)。 |
此过程是使用 Operator Framework 的两个核心组件完成的
operator-sdk
CLI 工具和 controller-runtime
库 API
在集群上安装、升级和基于角色的访问控制 (RBAC) Operator
本教程比 OpenShift Container Platform 文档中的 基于 Helm 的 Operator 的 Operator SDK 入门 更详细。 |
已安装 Operator SDK CLI
已安装 OpenShift CLI (oc
)
使用具有 dedicated-admin
权限的帐户通过 oc
登录到 OpenShift Dedicated 集群
要允许集群拉取镜像,您推送镜像的仓库必须设置为公共仓库,或者您必须配置镜像拉取密钥
使用 Operator SDK CLI 创建一个名为 nginx-operator
的项目。
为项目创建一个目录
$ mkdir -p $HOME/projects/nginx-operator
更改到该目录
$ cd $HOME/projects/nginx-operator
使用 helm
插件运行 operator-sdk init
命令来初始化项目
$ operator-sdk init \
--plugins=helm \
--domain=example.com \
--group=demo \
--version=v1 \
--kind=Nginx
默认情况下, |
init
命令专门为监视 API 版本为 example.com/v1
且类型为 Nginx
的资源创建 nginx-operator
项目。
对于基于 Helm 的项目,init
命令会根据图表默认清单将要部署的资源,在 config/rbac/role.yaml
文件中生成 RBAC 规则。请验证此文件中生成的规则是否满足 Operator 的权限要求。
您可以使用现有的图表(来自本地文件系统或远程图表存储库),而不是使用样板 Helm 图表创建项目,方法是使用以下标志:
--helm-chart
--helm-chart-repo
--helm-chart-version
如果指定了 --helm-chart
标志,则 --group
、--version
和 --kind
标志将成为可选。如果未设置,则使用以下默认值:
标志 | 值 |
---|---|
|
|
|
|
|
|
|
从指定的图表中推断 |
如果 --helm-chart
标志指定了本地图表存档(例如 example-chart-1.2.0.tgz
)或目录,则会验证并解压缩或将图表复制到项目中。否则,Operator SDK 将尝试从远程存储库获取图表。
如果 --helm-chart-repo
标志未指定自定义存储库 URL,则支持以下图表引用格式:
格式 | 描述 |
---|---|
|
从名为 |
|
从指定的 URL 获取 Helm 图表存档。 |
如果 --helm-chart-repo
指定了自定义存储库 URL,则支持以下图表引用格式:
格式 | 描述 |
---|---|
|
在 |
如果未设置 --helm-chart-version
标志,则 Operator SDK 将获取 Helm 图表的最新可用版本。否则,它将获取指定的版本。当使用 --helm-chart
标志指定的图表引用特定版本时(例如,它是本地路径或 URL 时),不会使用可选的 --helm-chart-version
标志。
更多详细信息和示例,请运行:
$ operator-sdk init --plugins helm --help
operator-sdk init
命令生成的多个文件包括一个 Kubebuilder PROJECT
文件。从项目根目录运行的后续 operator-sdk
命令以及 help
输出将读取此文件,并知道项目类型为 Helm。例如:
domain: example.com
layout:
- helm.sdk.operatorframework.io/v1
plugins:
manifests.sdk.operatorframework.io/v2: {}
scorecard.sdk.operatorframework.io/v2: {}
sdk.x-openshift.io/v1: {}
projectName: nginx-operator
resources:
- api:
crdVersion: v1
namespaced: true
domain: example.com
group: demo
kind: Nginx
version: v1
version: "3"
对于此示例,nginx-operator
项目将为每个 Nginx
自定义资源 (CR) 执行以下协调逻辑:
如果不存在,则创建 Nginx 部署。
如果不存在,则创建 Nginx 服务。
如果启用了 Nginx 入口并且不存在,则创建它。
确保部署、服务和可选的入口与 Nginx
CR 中指定的所需配置匹配,例如副本数量、镜像和服务类型。
默认情况下,nginx-operator
项目监视 watches.yaml
文件中显示的 Nginx
资源事件,并使用指定的图表执行 Helm 发布。
# Use the 'create api' subcommand to add watches to this file.
- group: demo
version: v1
kind: Nginx
chart: helm-charts/nginx
# +kubebuilder:scaffold:watch
创建 Helm Operator 项目时,Operator SDK 会创建一个示例 Helm 图表,其中包含用于简单 Nginx 发布的一组模板。
对于此示例,提供了用于部署、服务和入口资源的模板,以及 NOTES.txt
模板,Helm 图表开发者使用它来传达关于发布的有用信息。
如果您还不熟悉 Helm 图表,请查看 Helm 开发者文档。
Helm 使用名为 values 的概念来提供对 Helm 图表默认值的自定义,这些默认值在 values.yaml
文件中定义。
您可以通过在自定义资源 (CR) 规范中设置所需的值来覆盖这些默认值。您可以使用副本数量作为示例。
helm-charts/nginx/values.yaml
文件中有一个名为 replicaCount
的值,默认为 1
。要在您的部署中拥有两个 Nginx 实例,您的 CR 规范必须包含 replicaCount: 2
。
编辑 config/samples/demo_v1_nginx.yaml
文件以设置 replicaCount: 2
apiVersion: demo.example.com/v1
kind: Nginx
metadata:
name: nginx-sample
...
spec:
...
replicaCount: 2
同样,默认服务端口设置为 80
。要使用 8080
,请编辑 config/samples/demo_v1_nginx.yaml
文件以设置 spec.port: 8080
,这将添加服务端口覆盖。
apiVersion: demo.example.com/v1
kind: Nginx
metadata:
name: nginx-sample
spec:
replicaCount: 2
service:
port: 8080
Helm Operator 将应用整个规范,就好像它是 values 文件的内容一样,就像 helm install -f ./overrides.yaml
命令一样。
Operator 作者可以开发支持网络代理的 Operator。具有 dedicated-admin
角色的管理员可以为 Operator Lifecycle Manager (OLM) 处理的环境变量配置代理支持。要支持代理集群,您的 Operator 必须检查环境中是否存在以下标准代理变量,并将这些值传递给操作数:
HTTP_PROXY
HTTPS_PROXY
NO_PROXY
本教程使用 |
启用了集群范围出站代理的集群。
编辑 watches.yaml
文件,通过添加 overrideValues
字段来包含基于环境变量的覆盖。
...
- group: demo.example.com
version: v1alpha1
kind: Nginx
chart: helm-charts/nginx
overrideValues:
proxy.http: $HTTP_PROXY
...
在 helm-charts/nginx/values.yaml
文件中添加 proxy.http
值。
...
proxy:
http: ""
https: ""
no_proxy: ""
为了确保图表模板支持使用变量,请编辑 helm-charts/nginx/templates/deployment.yaml
文件中的图表模板,使其包含以下内容:
containers:
- name: {{ .Chart.Name }}
securityContext:
- toYaml {{ .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: http_proxy
value: "{{ .Values.proxy.http }}"
通过将以下内容添加到 config/manager/manager.yaml
文件中,在 Operator 部署上设置环境变量:
containers:
- args:
- --leader-elect
- --leader-election-id=ansible-proxy-demo
image: controller:latest
name: manager
env:
- name: "HTTP_PROXY"
value: "http_proxy_test"
要构建和运行您的 Operator,请使用 Operator SDK CLI 打包您的 Operator,然后使用 Operator Lifecycle Manager (OLM) 部署到集群。
如果您希望在 OpenShift Container Platform 集群而不是 OpenShift Dedicated 集群上部署您的 Operator,则可以使用两种额外的部署选项:
|
在集群外部本地运行(OpenShift Container Platform 文档)
在集群上作为部署运行(OpenShift Container Platform 文档)
Operator 包格式是 Operator SDK 和 Operator Lifecycle Manager (OLM) 的默认打包方法。您可以使用 Operator SDK 将您的 Operator 项目构建并推送为包镜像,从而使其准备好用于 OLM。
在开发工作站上安装 Operator SDK CLI
已安装 OpenShift CLI (oc
) v+
使用 Operator SDK 初始化 Operator 项目
在您的 Operator 项目目录中运行以下 make
命令以构建和推送您的 Operator 镜像。修改以下步骤中的 IMG
参数以引用您有权访问的存储库。您可以在 Quay.io 等存储库站点获取用于存储容器的帐户。
构建镜像
$ make docker-build IMG=<registry>/<user>/<operator_image_name>:<tag>
SDK 为 Operator 生成的 Dockerfile 明确引用了 |
将镜像推送到存储库
$ make docker-push IMG=<registry>/<user>/<operator_image_name>:<tag>
通过运行 make bundle
命令创建您的 Operator 包清单,该命令将调用多个命令,包括 Operator SDK 的 generate bundle
和 bundle validate
子命令
$ make bundle IMG=<registry>/<user>/<operator_image_name>:<tag>
Operator 的包清单描述了如何显示、创建和管理应用程序。make bundle
命令在您的 Operator 项目中创建以下文件和目录
名为 bundle/manifests
的包清单目录,其中包含一个 ClusterServiceVersion
对象
名为 bundle/metadata
的包元数据目录
config/crd
目录中的所有自定义资源定义 (CRD)
Dockerfile bundle.Dockerfile
然后,这些文件将使用 operator-sdk bundle validate
自动验证,以确保磁盘上的包表示正确。
通过运行以下命令构建和推送您的包镜像。OLM 使用索引镜像来使用 Operator 包,该镜像引用一个或多个包镜像。
构建包镜像。使用注册表、用户命名空间和您打算推送镜像的镜像标签的详细信息设置 BUNDLE_IMG
$ make bundle-build BUNDLE_IMG=<registry>/<user>/<bundle_image_name>:<tag>
推送包镜像
$ docker push <registry>/<user>/<bundle_image_name>:<tag>
Operator Lifecycle Manager (OLM) 帮助您在 Kubernetes 集群上安装、更新和管理 Operator 及其关联服务的生命周期。OLM 在 OpenShift Dedicated 上默认安装,并作为 Kubernetes 扩展运行,因此您可以使用 Web 控制台和 OpenShift CLI (oc
) 执行所有 Operator 生命周期管理功能,无需任何其他工具。
Operator 包格式是 Operator SDK 和 OLM 的默认打包方法。您可以使用 Operator SDK 快速在 OLM 上运行包镜像,以确保其正常运行。
在开发工作站上安装 Operator SDK CLI
已构建并推送到注册表的 Operator 包镜像
在基于 Kubernetes 的集群上安装 OLM(如果您使用 apiextensions.k8s.io/v1
CRD,例如 OpenShift Dedicated,则版本为 1.16.0 或更高版本)
使用具有 dedicated-admin
权限的帐户使用 oc
登录到集群
输入以下命令在集群上运行 Operator
$ operator-sdk run bundle \(1)
-n <namespace> \(2)
<registry>/<user>/<bundle_image_name>:<tag> (3)
1 | run bundle 命令创建一个有效的基于文件的目录,并使用 OLM 在您的集群上安装 Operator 包。 |
2 | 可选:默认情况下,该命令会在您 ~/.kube/config 文件中当前活动的项目中安装 Operator。您可以添加 -n 标志来设置安装的不同命名空间范围。 |
3 | 如果您没有指定镜像,则该命令将使用 quay.io/operator-framework/opm:latest 作为默认索引镜像。如果您指定镜像,则该命令将使用包镜像本身作为索引镜像。 |
从 OpenShift Dedicated 4.11 开始, |
此命令执行以下操作
创建一个引用您的包镜像的索引镜像。索引镜像是不透明且短暂的,但准确地反映了如何在生产环境中将包添加到目录。
创建一个指向您的新索引镜像的目录源,这使 OperatorHub 能够发现您的 Operator。
通过创建 OperatorGroup
、Subscription
、InstallPlan
和所有其他必需的资源(包括 RBAC)来将您的 Operator 部署到您的集群。
安装 Operator 后,您可以通过创建现在由 Operator 在集群上提供的自定义资源 (CR) 来测试它。
在集群上安装的示例 Nginx Operator,它提供 Nginx
CR
切换到安装 Operator 的命名空间。例如,如果您使用 make deploy
命令部署了 Operator
$ oc project nginx-operator-system
编辑 config/samples/demo_v1_nginx.yaml
中的示例 Nginx
CR 清单以包含以下规范
apiVersion: demo.example.com/v1
kind: Nginx
metadata:
name: nginx-sample
...
spec:
...
replicaCount: 3
Nginx 服务帐户需要特权访问才能在 OpenShift Dedicated 中运行。为 nginx-sample
pod 的服务帐户添加以下安全上下文约束 (SCC)
$ oc adm policy add-scc-to-user \
anyuid system:serviceaccount:nginx-operator-system:nginx-sample
创建 CR
$ oc apply -f config/samples/demo_v1_nginx.yaml
确保 Nginx
Operator 使用正确的规模为示例 CR 创建部署
$ oc get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-operator-controller-manager 1/1 1 1 8m
nginx-sample 3/3 3 3 1m
检查 Pod 和 CR 状态以确认状态已更新为 Nginx Pod 名称。
检查 Pod
$ oc get pods
NAME READY STATUS RESTARTS AGE
nginx-sample-6fd7c98d8-7dqdr 1/1 Running 0 1m
nginx-sample-6fd7c98d8-g5k7v 1/1 Running 0 1m
nginx-sample-6fd7c98d8-m7vn7 1/1 Running 0 1m
检查 CR 状态
$ oc get nginx/nginx-sample -o yaml
apiVersion: demo.example.com/v1
kind: Nginx
metadata:
...
name: nginx-sample
...
spec:
replicaCount: 3
status:
nodes:
- nginx-sample-6fd7c98d8-7dqdr
- nginx-sample-6fd7c98d8-g5k7v
- nginx-sample-6fd7c98d8-m7vn7
更新部署规模。
更新 config/samples/demo_v1_nginx.yaml
文件,将 Nginx
CR 中的 spec.size
字段从 3
更改为 5
$ oc patch nginx nginx-sample \
-p '{"spec":{"replicaCount": 5}}' \
--type=merge
确认 Operator 更改了部署规模
$ oc get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-operator-controller-manager 1/1 1 1 10m
nginx-sample 5/5 5 5 3m
通过运行以下命令删除 CR
$ oc delete -f config/samples/demo_v1_nginx.yaml
清理在此教程中创建的资源。
如果您使用 make deploy
命令测试了 Operator,请运行以下命令
$ make undeploy
如果您使用 operator-sdk run bundle
命令测试了 Operator,请运行以下命令
$ operator-sdk cleanup <project_name>
请参阅 基于 Helm 的 Operator 的项目布局,了解 Operator SDK 创建的目录结构。
如果配置了集群范围的出站代理,则具有 dedicated-admin
角色的管理员可以覆盖代理设置或为在 Operator Lifecycle Manager (OLM) 上运行的特定 Operator 注入自定义 CA 证书。