5.6. 定义集群服务版本(CSV)
由 ClusterServiceVersion
对象定义的 集群服务版本(CSV)是一个利用 Operator 元数据创建的 YAML 清单,可辅助 Operator Lifecycle Manager(OLM)在集群中运行 Operator。它是 Operator 容器镜像附带的元数据,用于在用户界面填充徽标、描述和版本等信息。此外,CSV 还是运行 Operator 所需的技术信息来源,类似于其需要的 RBAC 规则及其管理或依赖的自定义资源 (CR)。
Operator SDK 包括 CSV 生成器,用于为当前 Operator 项目生成 CSV,使用 YAML 清单和 Operator 源文件中包含的信息自定义。
红帽支持的 Operator SDK CLI 工具版本,包括 Operator 项目的相关构建和测试工具已被弃用,计划在以后的 OpenShift Dedicated 发行版本中删除。红帽将在当前发行生命周期中提供对这个功能的程序错误修复和支持,但此功能将不再获得改进,并将在以后的 OpenShift Dedicated 版本中删除。
对于创建新 Operator 项目,不建议使用红帽支持的 Operator SDK 版本。现有 Operator 项目的 Operator 作者可使用 OpenShift Dedicated 4 发布的 Operator SDK CLI 工具版本来维护其项目,并创建针对较新版本的 OpenShift Dedicated 的 Operator 发行版本。
以下与 Operator 项目相关的基础镜像 没有被弃用。这些基础镜像的运行时功能和配置 API 仍然会有程序错误修复和并提供对相关 CVE 的解决方案。
- 基于 Ansible 的 Operator 项目的基础镜像
- 基于 Helm 的 Operator 项目的基础镜像
有关 Operator SDK 不支持的、社区维护版本的信息,请参阅 Operator SDK (Operator Framework)。
借助生成 CSV 的命令,Operator 作者便无需深入掌握为了让其 Operator 与 OLM 交互或向 Catalog Registry 发布元数据所需的 OLM 知识。此外,因为实现了新的 Kubernetes 和 OLM 功能,CSV spec 可能会随着时间的推移而有所变化,而 Operator SDK 可轻松扩展其更新系统,以应对 CSV 的未来新功能。
5.6.1. CSV 生成的工作方式
Operator 捆绑包清单,其中包括集群服务版本(CSV),描述如何使用 Operator Lifecycle Manager(OLM)显示、创建和管理应用程序。Operator SDK 中的 CSV 生成器(由 generate bundle
子命令调用)是将 Operator 发布到目录并使用 OLM 部署的第一个步骤。子命令需要特定的输入清单来构造 CSV 清单,在调用命令时会读取所有输入,以及 CSV 基础,以便预先生成或重新生成 CSV。
通常,generate kustomize manifests
子命令会首先运行,以生成由 generate bundle
子命令使用的输入 Kustomize 基础。但是,Operator SDK 提供 make bundle
命令,它自动执行一些任务,包括按顺序运行以下子命令:
-
generate kustomize manifests
-
generate bundle
-
bundle validate
其他资源
- 如需了解包括生成捆绑包和 CSV 的完整流程,请参阅捆绑 Operator。
5.6.1.1. 生成的文件和资源
make bundle
命令在 Operator 项目中创建以下文件和目录:
-
名为
bundle/manifests
的捆绑包清单目录,其中包含ClusterServiceVersion
(CSV)对象 -
名为
bundle/metadata
的捆绑包元数据目录 -
config/crd
目录中的所有自定义资源定义(CRD) -
一个 Dockerfile
bundle.Dockerfile
以下资源通常包含在 CSV 中:
- 角色
- 定义命名空间中的 Operator 权限。
- ClusterRole
- 定义集群范围的 Operator 权限。
- Deployment
- 定义如何在 pod 中运行 Operator 的 Operand。
- CustomResourceDefinition (CRD)
- 定义 Operator 协调的自定义资源。
- 自定义资源示例
- 遵循特定 CRD 规格的资源示例。
5.6.1.2. 版本管理
generate bundle
子命令的 --version
标志在首次创建以及升级现有捆绑包时,为您提供语义版本。
通过在 Makefile
中设置 VERSION
变量,当使用 make bundle
命令运行 generate bundle
子命令时使用该值自动调用 --version
标志。CSV 版本与 Operator 版本相同,在升级 Operator 版本时会生成新 CSV。
5.6.2. 手动定义的 CSV 字段
很多 CSV 字段无法使用生成的、不属于 Operator SDK 的特殊通用清单进行填充。这些字段大多由人工编写,是一些有关 Operator 和各种自定义资源定义 (CRD) 的元数据。
Operator 作者必须直接修改其集群服务版本(CSV)YAML 文件,将个性化数据添加到以下必填字段。当检测到任何必填字段中缺少数据时,Operator SDK 在生成 CSV 时发出警告。
下表详细介绍了需要手动定义的 CSV 字段,哪些是可选的。
字段 | 描述 |
---|---|
|
该 CSV 的唯一名称。Operator 版本应包含在名称中,以保证唯一性,如 |
|
根据 Operator 成熟度模型划分的能力等级。选项包括 |
| 用于标识 Operator 的公共名称。 |
| 有关 Operator 功能的简短描述。 |
| 描述 Operator 的关键词。 |
|
维护 Operator 的个人或组织实体,含 |
|
Operator 的供应商(通常是机构),含 |
| 供 Operator 内部使用的键值对。 |
|
Operator 的语义版本,如 |
|
Operator 使用的任何 CRD。如果
|
字段 | 描述 |
---|---|
| 被该 CSV 替换的 CSV 名称。 |
|
与被管理的 Operator 或应用程序相关的 URL(如网站和文档),各自含 |
| Operator 可用于配对群集中资源的选择器。 |
|
Operator 独有的 base64 编码图标,通过 |
|
软件在这个版本中达到的成熟度。选项包括 |
有关以上每个字段应包含哪些数据的更多详情,请参见 CSV spec。
目前需要用户干预的几个 YAML 字段可能会从 Operator 代码中解析。
其他资源
5.6.3. Operator 元数据注解
Operator 开发人员可以在集群服务版本(CSV)的元数据中设置某些注解,以启用功能或在用户界面(UI)中突出显示功能,如 OperatorHub 或 Red Hat Ecosystem Catalog。通过在 CSV YAML 文件中设置 metadata.annotations
字段来手动定义 Operator 元数据注解。
5.6.3.1. 基础架构功能注解
features.operators.openshift.io
组中的注解详细说明 Operator 可能支持的基础架构功能,通过设置 "true"
或 "false"
值来指定。在 web 控制台或 红帽生态系统目录 中通过 OperatorHub 发现 Operator 时,用户可以查看和过滤这些功能。OpenShift Dedicated 4.10 及更新的版本支持这些注解。
features.operators.openshift.io
基础架构功能注解弃用早期版本的 OpenShift Dedicated 中使用的 operators.openshift.io/infrastructure-features
注解。如需更多信息,请参阅"过时的基础架构功能注解"。
注解 | 描述 | 有效值[1] |
---|---|---|
|
指定 Operator 支持被镜像到断开连接的目录中,包括所有依赖项,且不需要访问互联网。Operator 利用 |
|
| 指定 Operator 是否接受底层平台的 FIPS-140 配置,并可用于引导到 FIPS 模式的节点。在这个模式中,Operator 及其管理(操作)的任何工作负载都只调用为 FIPS-140 验证提交的 Red Hat Enterprise Linux (RHEL)加密库。 |
|
|
通过接受标准 |
|
| 指定 Operator 是否实现已知的可调项,以修改 Operator 使用的 TLS 密码套件;如果适用,它管理的任何工作负载(操作)。 |
|
| 使用 Cloud Credential Operator (CCO)指定 Operator 是否支持通过 AWS Secure Token Service (STS)配置 AWS API 的令牌验证。 |
|
| 指定 Operator 是否支持使用 Cloud Credential Operator (CCO)通过 Azure Managed Identity 配置对 Azure API 进行令牌身份验证。 |
|
| 使用 Cloud Credential Operator (CCO)指定 Operator 是否支持通过 GCP Workload Identity Foundation (WIF)配置 Google Cloud API 进行令牌化身份验证。 |
|
| 指定 Operator 是否提供 Cloud-Native Network Function (CNF) Kubernetes 插件。 |
|
| 指定 Operator 是否提供 Container Network Interface (CNI) Kubernetes 插件。 |
|
| 指定 Operator 是否提供 Container Storage Interface (CSI) Kubernetes 插件。 |
|
- 这里我们有意在有效值中使用了双引号,因为 Kubernetes 注解必须是字符串。
具有基础架构功能注解的 CSV 示例
apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: annotations: features.operators.openshift.io/disconnected: "true" features.operators.openshift.io/fips-compliant: "false" features.operators.openshift.io/proxy-aware: "false" features.operators.openshift.io/tls-profiles: "false" features.operators.openshift.io/token-auth-aws: "false" features.operators.openshift.io/token-auth-azure: "false" features.operators.openshift.io/token-auth-gcp: "false"
其他资源
- 为受限网络环境启用 Operator (断开连接模式)
5.6.3.2. 弃用的基础架构功能注解
从 OpenShift Dedicated 4.14 开始,带有 features.operators.openshift.io
命名空间的注解组 operators.openshift.io/infrastructure-features
已弃用。虽然我们推荐使用较新的注解,但当前可以并行使用这两个组。
这些注解详细介绍了 Operator 支持的基础架构功能。在 web 控制台或 红帽生态系统目录 中通过 OperatorHub 发现 Operator 时,用户可以查看和过滤这些功能。
有效注解值 | 描述 |
---|---|
| Operator 支持被镜像到断开连接的目录中,包括所有依赖项,且不需要访问互联网。Operator 列出了镜像所需的所有相关镜像。 |
| Operator 提供了一个 Cloud-native Network Function(CNF)Kubernetes 插件。 |
| Operator 提供了一个 Container Network Interface (CNI) Kubernetes 插件。 |
| Operator 提供了一个 Container Storage Interface (CSI) Kubernetes 插件。 |
| Operator 接受底层平台的 FIPS 模式,并可用于引导到 FIPS 模式的节点。 重要 当以 FIPS 模式运行 Red Hat Enterprise Linux (RHEL)或 Red Hat Enterprise Linux CoreOS (RHCOS)时,OpenShift Dedicated 核心组件使用 RHEL 加密库,在 x86_64、ppc64le 和 s390x 架构上提交给 NIST 的 FIPS 140-2/140-3 Validation。 |
|
Operator 支持在代理后面的集群上运行。Operator 接受标准代理环境变量 |
支持断开连接的
和代理支持的
CSV 示例
apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: annotations: operators.openshift.io/infrastructure-features: '["disconnected", "proxy-aware"]'
5.6.3.3. 其他可选注解
以下 Operator 注解是可选的。
注解 | 描述 |
---|---|
| 提供自定义资源定义(CRD)模板最小配置集。兼容的 UI 会预先填充此模板,供用户进一步自定义。 |
|
通过在 Operator 安装过程中将 |
| 设置部署 Operator 的建议命名空间。 |
|
为 |
|
用于列出使用 Operator 所需的任何特定订阅的空闲数组。例如, |
| 在 UI 中隐藏不用于用户操作的 CRD。 |
具有 OpenShift Dedicated 许可证要求的 CSV 示例
apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: annotations: operators.openshift.io/valid-subscription: '["OpenShift Container Platform"]'
具有 3scale 许可证要求的 CSV 示例
apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: annotations: operators.openshift.io/valid-subscription: '["3Scale Commercial License", "Red Hat Managed Integration"]'
5.6.4. 为受限网络环境启用 Operator
作为 Operator 作者,您的 Operator 必须满足额外要求才能在受限网络或断开连接的环境中正常运行。
支持断开连接模式的 Operator 的要求
- 使用环境变量替换硬编码的镜像引用。
在 Operator 的集群服务版本(CSV)中:
- 列出 Operator 执行其功能可能需要的任何 相关镜像或其他容器镜像。
- 通过摘要 (SHA) 而不是标签来引用所有指定的镜像。
- Operator 的所有依赖项还必须支持以断开连接的模式运行。
- 您的 Operator 不得要求任何非集群资源。
先决条件
- 包含 CSV 的 Operator 项目。以下流程使用 Memcached Operator 作为基于 Go-、Ansible 和 Helm 的项目的示例。
流程
为 Operator 在
config/manager/manager.yaml
文件中被 Operator 使用的额外镜像引用设置环境变量:将硬编码镜像引用替换为 Operator 项目类型的相关文件中的环境变量:
对于基于 Go 的 Operator 项目,将环境变量添加到
controllers/memcached_controller.go
文件中,如下例所示:例 5.4.
controllers/memcached_controller.go
文件示例// deploymentForMemcached returns a memcached Deployment object ... Spec: corev1.PodSpec{ Containers: []corev1.Container{{ - Image: "memcached:1.4.36-alpine", 1 + Image: os.Getenv("<related_image_environment_variable>"), 2 Name: "memcached", Command: []string{"memcached", "-m=64", "-o", "modern", "-v"}, Ports: []corev1.ContainerPort{{ ...
注意如果未设置变量,则
os.Getenv
函数会返回空字符串。在更改文件前设置<related_image_environment_variable>
。对于基于 Ansible 的 Operator 项目,将环境变量添加到
roles/memcached/tasks/main.yml
文件,如下例所示:例 5.5.
roles/memcached/tasks/main.yml
文件示例spec: containers: - name: memcached command: - memcached - -m=64 - -o - modern - -v - image: "docker.io/memcached:1.4.36-alpine" 1 + image: "{{ lookup('env', '<related_image_environment_variable>') }}" 2 ports: - containerPort: 11211 ...
对于基于 Helm 的 Operator 项目,将
overrideValues
字段添加到watches.yaml
文件中,如下例所示:例 5.6.
watches.yaml
文件示例将
overrideValues
字段的值添加到helm-charts/memchached/values.yaml
文件中,如下例所示:helm-charts/memchached/values.yaml
文件示例... relatedImage: ""
编辑
helm-charts/memcached/templates/deployment.yaml
文件中的 chart 模板,如下例所示:例 5.7.
helm-charts/memcached/templates/deployment.yaml
文件示例
使用以下更改将
BUNDLE_GEN_FLAGS
变量定义添加到Makefile
中:Makefile
示例BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) # USE_IMAGE_DIGESTS defines if images are resolved via tags or digests # You can enable this value if you would like to use SHA Based Digests # To enable set flag to true USE_IMAGE_DIGESTS ?= false ifeq ($(USE_IMAGE_DIGESTS), true) BUNDLE_GEN_FLAGS += --use-image-digests endif ... - $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS) 1 + $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle $(BUNDLE_GEN_FLAGS) 2 ...
要将 Operator 镜像更新为使用摘要(SHA)而不是标签,请运行
make bundle
命令,并将USE_IMAGE_DIGESTS
设置为true
:$ make bundle USE_IMAGE_DIGESTS=true
添加
disconnected
注解,这表示 Operator 在断开连接的环境中工作:metadata: annotations: operators.openshift.io/infrastructure-features: '["disconnected"]'
OperatorHub 中可根据此基础架构功能来过滤 Operator。
5.6.5. 为多个架构和操作系统启用您的 Operator
Operator Lifecycle Manager (OLM) 假设所有 Operator 都在 Linux 主机中运行。但是,作为 Operator 作者,如果 OpenShift Dedicated 集群中有 worker 节点,您可以指定 Operator 是否支持管理其他架构上的工作负载。
如果 Operator 支持 AMD64 和 Linux 以外的变体,您可以向 CSV 添加标签,从而提供 Operator 列出支持的变体。标注支持的架构和操作系统的标签定义如下:
labels: operatorframework.io/arch.<arch>: supported 1 operatorframework.io/os.<os>: supported 2
只有默认频道的频道头的标签才会在根据标签进行过滤时考虑软件包清单。例如,这表示有可能在非默认频道中为 Operator 提供额外的架构,但该架构在 PackageManifest
API 中不可用。
如果 CSV 不包括 os
标签,它将被视为默认具有以下 Linux 支持标签:
labels: operatorframework.io/os.linux: supported
如果 CSV 不包括 arch
标签,它将被视为默认具有以下 AMD64 支持标签:
labels: operatorframework.io/arch.amd64: supported
如果 Operator 支持多个节点架构或操作系统,您也可以添加多个标签。
先决条件
- 包含 CSV 的 Operator 项目。
- 要支持列出多个架构和操作系统,CSV 中引用的 Operator 镜像必须是清单列表镜像。
- 要使 Operator 在受限网络或断开连接的环境中正常工作,还必须使用摘要(SHA)而不是标签(tag)来指定引用的镜像。
流程
在 CSV 的
metadata.labels
中为每个 Operator 支持的架构和操作系统添加标签:labels: operatorframework.io/arch.s390x: supported operatorframework.io/os.zos: supported operatorframework.io/os.linux: supported 1 operatorframework.io/arch.amd64: supported 2
其他资源
- 如需有关清单列表的更多信息 ,请参阅Image Manifest V 2, Schema 2 说明。
5.6.5.1. Operator 的架构和操作系统支持
在标记或过滤支持多个架构和操作系统的 Operator 时,OpenShift Dedicated 上的 Operator Lifecycle Manager (OLM) 支持以下字符串:
架构 | 字符串 |
---|---|
AMD64 |
|
ARM64 |
|
IBM Power® |
|
IBM Z® |
|
操作系统 | 字符串 |
---|---|
Linux |
|
z/OS |
|
OpenShift Dedicated 和其他基于 Kubernetes 的发行版本的不同版本可能支持一组不同的架构和操作系统。
5.6.6. 设置建议的命名空间
有些 Operator 必须部署到特定命名空间中,或使用特定命名空间中的辅助资源进行部署,才能正常工作。如果从订阅中解析,Operator Lifecycle Manager(OLM)会将 Operator 的命名空间的资源默认设置为订阅的命名空间。
作为 Operator 作者,您可以将所需的目标命名空间作为集群服务版本(CSV)的一部分来控制为 Operator 安装的资源的最终命名空间。当使用 OperatorHub 将 Operator 添加到集群时,这可让 Web 控制台在安装过程中为安装程序自动填充建议的命名空间。
流程
在 CSV 中,将
operatorframework.io/suggested-namespace
注解设置为建议的命名空间:metadata: annotations: operatorframework.io/suggested-namespace: <namespace> 1
- 1
- 设置建议的命名空间。
5.6.7. 使用默认节点选择器设置建议的命名空间
有些 Operator 只在 control plane 节点上运行,这可以通过由 Operator 本身在 Pod
规格中设置 nodeSelector
来完成。
为了避免重复重复且可能冲突集群范围的默认 nodeSelector
,您可以在运行 Operator 的命名空间上设置默认节点选择器。默认节点选择器优先于集群默认值,因此集群默认不会应用到 Operator 命名空间中的 pod。
当使用 OperatorHub 将 Operator 添加到集群时,Web 控制台会在安装过程中自动填充安装程序的建议命名空间。建议的命名空间使用 YAML 中的命名空间清单创建,该清单包含在集群服务版本 (CSV) 中。
流程
在 CSV 中,使用
Namespace
对象的清单设置operatorframework.io/suggested-namespace-template
。以下示例是指定了命名空间默认节点选择器的示例命名空间
的清单:metadata: annotations: operatorframework.io/suggested-namespace-template: 1 { "apiVersion": "v1", "kind": "Namespace", "metadata": { "name": "vertical-pod-autoscaler-suggested-template", "annotations": { "openshift.io/node-selector": "" } } }
- 1
- 设置建议的命名空间。
注意如果 CSV 中存在
recommendations-namespace
和recommended-namespace-template
注解,则 recommend-namespace-template
应该优先使用。
5.6.8. 启用 Operator 条件
Operator Lifecycle Manager(OLM)为 Operator 提供一个频道来交流影响 Operator 在管理 Operator 的复杂状态。默认情况下,OLM 在安装 Operator 时会创建一个 OperatorCondition
自定义资源定义(CRD)。根据 OperatorCondition
自定义资源(CR)中设置的条件,OLM 的行为会相应更改。
要支持 Operator 条件,Operator 必须能够读取 OLM 创建的 OperatorCondition
CR,并能够完成以下任务:
- 获取特定条件。
- 设置特定条件的状态。
这可以通过使用 operator-lib
库来实现。Operator 作者可在 Operator 中提供 controller-runtime
客户端,以便该程序库访问集群中 Operator 拥有的 OperatorCondition
CR。
该程序库提供了一个通用的 Conditions
接口,它使以下方法在 OperatorCondition
CR 中 Get
和 Set
一个 conditionType
:
Get
-
要获得特定条件,程序库使用来自
controller-runtime
的client.Get
函数,它需要在conditionAccessor
中存在类型type.NamespacedName
的ObjectKey
。 Set
-
要更新特定条件的状态,程序库使用来自
controller-runtime
的client.Update
功能。如果 CRD 中不存在conditionType
,则会出现错误。
Operator 只允许修改 CR 的 status
子资源。operator 可以删除或更新 status.conditions
数组,使其包含条件。有关条件中字段的格式和描述的详情,请查看上游的条件 GoDocs。
Operator SDK 1.36.1 支持 operator-lib
v0.11.0。
先决条件
- 使用 Operator SDK 生成一个 Operator 项目。
流程
在 Operator 项目中启用 Operator 条件:
在 Operator 项目的
go.mod
文件中,将operator-framework/operator-lib
添加为所需的库:module github.com/example-inc/memcached-operator go 1.19 require ( k8s.io/apimachinery v0.26.0 k8s.io/client-go v0.26.0 sigs.k8s.io/controller-runtime v0.14.1 operator-framework/operator-lib v0.11.0 )
在 Operator 逻辑中编写您自己的构造器会导致以下结果:
-
接受
controller-runtime
客户端。 -
接受
conditionType
。 -
返回一个
Condition
接口以更新或添加条件。
由于 OLM 目前支持
Upgradeable
条件,因此可以创建一个接口,它具有访问Upgradeable
条件的方法。例如:import ( ... apiv1 "github.com/operator-framework/api/pkg/operators/v1" ) func NewUpgradeable(cl client.Client) (Condition, error) { return NewCondition(cl, "apiv1.OperatorUpgradeable") } cond, err := NewUpgradeable(cl);
在这个示例中,
NewUpgradeable
constructor 被进一步使用来创建类型为Condition
的一个变量cond
。cond
变量依次使用Get
和Set
方法,可用于处理 OLM 的Upgradeable
条件。-
接受
其他资源
5.6.9. 定义 webhook
Webhook 允许 Operator 作者在资源被保存到对象存储并由 Operator 控制器处理之前,拦截、修改、接受或拒绝资源。当 webhook 与 Operator 一同提供时,Operator Lifecycle Manager(OLM)可以管理这些 webhook 的生命周期。
Operator 的集群服务版本(CSV)资源可能包含 webhookdefinitions
部分,以定义以下 Webhook 类型:
- Admission webhook(validating and mutating)
- webhook 转换
流程
在 Operator 的
spec
部分添加webhookdefinitions
部分,并使用ValidatingAdmissionWebhook
、MutatingAdmissionWebhook
或ConversionWebhook
type
包括任何 webhook 定义。以下示例包含所有三种类型的 Webhook:包含 Webhook 的 CSV
apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: name: webhook-operator.v0.0.1 spec: customresourcedefinitions: owned: - kind: WebhookTest name: webhooktests.webhook.operators.coreos.io 1 version: v1 install: spec: deployments: - name: webhook-operator-webhook ... ... ... strategy: deployment installModes: - supported: false type: OwnNamespace - supported: false type: SingleNamespace - supported: false type: MultiNamespace - supported: true type: AllNamespaces webhookdefinitions: - type: ValidatingAdmissionWebhook 2 admissionReviewVersions: - v1beta1 - v1 containerPort: 443 targetPort: 4343 deploymentName: webhook-operator-webhook failurePolicy: Fail generateName: vwebhooktest.kb.io rules: - apiGroups: - webhook.operators.coreos.io apiVersions: - v1 operations: - CREATE - UPDATE resources: - webhooktests sideEffects: None webhookPath: /validate-webhook-operators-coreos-io-v1-webhooktest - type: MutatingAdmissionWebhook 3 admissionReviewVersions: - v1beta1 - v1 containerPort: 443 targetPort: 4343 deploymentName: webhook-operator-webhook failurePolicy: Fail generateName: mwebhooktest.kb.io rules: - apiGroups: - webhook.operators.coreos.io apiVersions: - v1 operations: - CREATE - UPDATE resources: - webhooktests sideEffects: None webhookPath: /mutate-webhook-operators-coreos-io-v1-webhooktest - type: ConversionWebhook 4 admissionReviewVersions: - v1beta1 - v1 containerPort: 443 targetPort: 4343 deploymentName: webhook-operator-webhook generateName: cwebhooktest.kb.io sideEffects: None webhookPath: /convert conversionCRDs: - webhooktests.webhook.operators.coreos.io 5 ...
其他资源
Kubernetes 文档:
5.6.9.1. 针对 OLM 的 Webhook 注意事项
使用 Operator Lifecycle Manager(OLM)部署带有 webhook 的 Operator 时,您必须定义以下内容:
-
type
字段必须设置为ValidatingAdmissionWebhook
、MutatingAdmissionWebhook
或ConversionWebhook
,否则 CSV 会进入失败的阶段。 -
CSV 必须包含一个部署,它的名称相当于
webhookdefinition
的deploymentName
字段中提供的值。
创建 webhook 时,OLM 确保 webhook 仅在与 Operator 部署的 Operator 组相匹配的命名空间上操作。
证书颁发机构限制
将 OLM 配置为为每个部署提供一个单独的证书颁发机构(CA)。将 CA 生成并挂载到部署的逻辑最初由 API 服务生命周期逻辑使用。因此:
-
TLS 证书文件挂载到部署的
/apiserver.local.config/certificates/apiserver.crt
。 -
TLS 密钥文件挂载到部署的
/apiserver.local.config/certificates/apiserver.key
。
Admission webhook 规则约束
为防止 Operator 将集群配置为无法恢复的状态,OLM 如果准入 webhook 中定义的规则拦截了以下请求中的规则,则 OLM 会将 CSV 放置到失败的阶段:
- 请求目标所有组
-
请求以
operators.coreos.com
组为目标 -
请求目标为
ValidatingWebhookConfigurations
或MutatingWebhookConfigurations
资源
转换 Webhook 约束
如果转换 Webhook 定义未遵循以下限制,OLM 会将 CSV 放置到失败的阶段:
-
带有转换 Webhook 的 CSV 只能支持
AllNamespaces
安装模式。 -
转换 Webhook 的目标 CRD 必须将其
spec.preserveUnknownFields
字段设置为false
或nil
。 - CSV 中定义的转换 webhook 必须针对拥有的 CRD。
- 在整个集群中,给定 CRD 只能有一个转换 Webhook。
5.6.10. 了解您的自定义资源定义(CRD)
您的 Operator 可能会使用两类自定义资源定义 (CRD):一类归 Operator 拥有,另一类为 Operator 依赖的必要 CRD。
5.6.10.1. 拥有的 CRD
Operator 拥有的自定义资源定义(CRD)是 CSV 最重要的部分。这类 CRD 会在您的 Operator 与所需 RBAC 规则、依赖项管理和其他 Kubernetes 概念之间建立联系。
Operator 通常会使用多个 CRD 将各个概念链接在一起,例如一个对象中的顶级数据库配置和另一对象中的副本集表示代表。这在 CSV 文件中应逐一列出。
字段 | 描述 | 必需/可选 |
---|---|---|
| CRD 的全名。 | 必填 |
| 该对象 API 的版本。 | 必填 |
| CRD 的机器可读名称。 | 必填 |
|
CRD 名称的人类可读版本,如 | 必填 |
| 有关 Operator 如何使用该 CRD 的简短描述,或有关 CRD 所提供功能的描述。 | 必填 |
|
该 CRD 所属的 API 组,如 | 选填 |
|
您的 CRD 可能拥有一类或多类 Kubernetes 对象。它们将在 建议仅列出对人重要的对象,而不必列出您编排的所有对象。例如,不要列出存储用户不会修改的内部状态的配置映射。 | 选填 |
| 这些描述符是通过对终端用户来说最重要的 Operator 的某些输入或输出提示 UI 的一种方式。如果您的 CRD 包含用户必须提供的 Secret 或 ConfigMap 的名称,您可在此处指定。这些项目在兼容的 UI 中链接并突出显示。 共有以下三类描述符:
所有描述符都接受以下字段:
有关描述符的更多一般信息,请参见 openshift/console 项目。 | 选填 |
以下示例描述了一个 MongoDB Standalone
CRD,要求某些用户以 Secret 和配置映射的形式输入,并编排服务、有状态集、pod 和 配置映射:
拥有的 CRD 示例
- displayName: MongoDB Standalone group: mongodb.com kind: MongoDbStandalone name: mongodbstandalones.mongodb.com resources: - kind: Service name: '' version: v1 - kind: StatefulSet name: '' version: v1beta2 - kind: Pod name: '' version: v1 - kind: ConfigMap name: '' version: v1 specDescriptors: - description: Credentials for Ops Manager or Cloud Manager. displayName: Credentials path: credentials x-descriptors: - 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:Secret' - description: Project this deployment belongs to. displayName: Project path: project x-descriptors: - 'urn:alm:descriptor:com.tectonic.ui:selector:core:v1:ConfigMap' - description: MongoDB version to be installed. displayName: Version path: version x-descriptors: - 'urn:alm:descriptor:com.tectonic.ui:label' statusDescriptors: - description: The status of each of the pods for the MongoDB cluster. displayName: Pod Status path: pods x-descriptors: - 'urn:alm:descriptor:com.tectonic.ui:podStatuses' version: v1 description: >- MongoDB Deployment consisting of only one host. No replication of data.
5.6.10.2. 必需的 CRD
是否依赖其他必需 CRD 完全可以自由选择,它们存在的目的只是为了缩小单个 Operator 的范围,并提供一种将多个 Operator 组合到一起来解决端到端用例的办法。
例如,一个 Operator 可设置一个应用程序并(从 etcd Operator)安装一个 etcd 集群以用于分布式锁定,以及一个 Postgres 数据库(来自 Postgres Operator)以用于数据存储。
Operator Lifecycle Manager (OLM) 对照集群中可用的 CRD 和 Operator 进行检查,以满足这些要求。如果找到合适的版本,Operator 将在所需命名空间中启动,并为每个 Operator 创建一个服务账户,以创建、监视和修改所需的 Kubernetes 资源。
字段 | 描述 | 必需/可选 |
---|---|---|
| 所需 CRD 的全称。 | 必填 |
| 该对象 API 的版本。 | 必填 |
| Kubernetes 对象类型。 | 必填 |
| CRD 的人类可读版本。 | 必填 |
| 概述该组件如何适合您的更大架构。 | 必填 |
必需的 CRD 示例
required: - name: etcdclusters.etcd.database.coreos.com version: v1beta2 kind: EtcdCluster displayName: etcd Cluster description: Represents a cluster of etcd nodes.
5.6.10.3. CRD 升级
如果自定义资源定义(CRD)属于单一集群服务版本(CSV),OLM 会立即对其升级。如果某个 CRD 被多个 CSV 拥有,则当该 CRD 满足以下所有向后兼容条件时才会升级:
- 所有已存在于当前 CRD 中的服务版本都包括在新 CRD 中。
- 在根据新 CRD 的验证模式(schema)进行验证后,与 CRD 的服务版本关联的所有现有实例或自定义资源均有效。
5.6.10.3.1. 添加新版 CRD
流程
将新版 CRD 添加到 Operator:
在 CSV 的
versions
部分的 CRD 资源中添加新条目。例如,如果当前 CRD 有一个
v1alpha1
版本,而您想要添加新的v1beta1
版本并 将其标记为新的存储版本,请为v1beta1
添加新条目:versions: - name: v1alpha1 served: true storage: false - name: v1beta1 1 served: true storage: true
- 1
- 新条目。
如果 CSV 打算使用新版本,请确保更新您的 CSV
owned
部分中的 CRD 引用版本:customresourcedefinitions: owned: - name: cluster.example.com version: v1beta1 1 kind: cluster displayName: Cluster
- 1
- 更新
version
。
- 将更新的 CRD 和 CSV 推送至您的捆绑包中。
5.6.10.3.2. 弃用或删除 CRD 版本
Operator Lifecycle Manager(OLM)不允许立即删除自定义资源定义(CRD)的服务版本。弃用的 CRD 版本应首先通过将 CRD 的 served
字段设置为 false
来禁用。随后在升级 CRD 时便可将非服务版本删除。
流程
要弃用和删除特定 CRD 版本:
将弃用版本标记为非服务版本,表明该版本已不再使用且后续升级时可删除。例如:
versions: - name: v1alpha1 served: false 1 storage: true
- 1
- 设置为
false
。
如果要弃用的版本目前为
storage
版本,则将该storage
版本切换至服务版本。例如:versions: - name: v1alpha1 served: false storage: false 1 - name: v1beta1 served: true storage: true 2
注意要从 CRD 中删除曾是或现在是
storage
的特定版本,该版本必须从 CRD 状态下的storedVersion
中删除。OLM 一旦检测到某个已存储版本在新 CRD 中不再存在,OLM 将尝试执行这一操作。- 使用以上更改来升级 CRD。
在后续升级周期中,非服务版本可从 CRD 中完全删除。例如:
versions: - name: v1beta1 served: true storage: true
-
如果该版本已从 CRD 中删除,请确保相应更新您的 CSV
owned
部分中的引用 CRD 版本。
5.6.10.4. CRD 模板
Operator 用户必须了解哪个选项必填,而不是可选选项。您可为您的每个 CRD 提供模板,并以最小配置集作为名为 alm-examples
的注解。兼容 UI 会预先填充该模板,供用户进一步自定义。
该注解由一个 kind 列表组成,如 CRD 名称和对应的 Kubernetes 对象的 metadata
和 spec
。
以下完整示例提供了 EtcdCluster
、EtcdBackup
和 EtcdRestore
模板:
metadata: annotations: alm-examples: >- [{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdCluster","metadata":{"name":"example","namespace":"<operator_namespace>"},"spec":{"size":3,"version":"3.2.13"}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdRestore","metadata":{"name":"example-etcd-cluster"},"spec":{"etcdCluster":{"name":"example-etcd-cluster"},"backupStorageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}},{"apiVersion":"etcd.database.coreos.com/v1beta2","kind":"EtcdBackup","metadata":{"name":"example-etcd-cluster-backup"},"spec":{"etcdEndpoints":["<etcd-cluster-endpoints>"],"storageType":"S3","s3":{"path":"<full-s3-path>","awsSecret":"<aws-secret>"}}}]
5.6.10.5. 隐藏内部对象
Operator 在内部使用自定义资源定义 (CRD) 来完成任务是常见的。这些对象并不是供用户操作的,且可能会让 Operator 用户混淆。例如,数据库 Operator 可能会有一个 Replication
CRD,当用户创建带有 replication:true
的数据库对象时就会创建它。
作为 Operator 作者,您可以通过将 operators.operatorframework.io/internal-objects
注解添加到 Operator 的 ClusterServiceVersion(CSV)来隐藏用户界面中不用于用户操作的任何 CRD。
流程
-
在将一个 CRD 标记为 internal 之前,请确保任何管理应用程序所需的调试信息或配置都会反映在 CR 的状态或
spec
块中(如果适用于您的 Operator)。 向 Operator 的 CSV 添加
operators.operatorframework.io/internal-objects
注解,以指定要在用户界面中隐藏的任何内部对象:内部对象注解
apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: name: my-operator-v1.2.3 annotations: operators.operatorframework.io/internal-objects: '["my.internal.crd1.io","my.internal.crd2.io"]' 1 ...
- 1
- 将任何内部 CRD 设置为字符串数组。
5.6.10.6. 初始化所需的自定义资源
Operator 可能需要用户在 Operator 完全正常工作前实例化自定义资源。然而,用户很难确定需要什么或怎样定义资源。
作为 Operator 开发人员,您可以通过在 Operator 安装过程中将 operatorframework.io/initialization-resource
添加到集群服务版本 (CSV) 来指定单个所需的自定义资源。然后,系统会提示您通过 CSV 中提供的模板创建自定义资源。该注解必须有包含完整 YAML 定义模板,该定义是在安装过程中初始化资源所需的。
如果定义了此注解,在从 OpenShift Dedicated Web 控制台安装 Operator 后,会提示用户使用 CSV 中提供的模板创建资源。
流程
为 Operator 的 CSV 添加
operatorframework.io/initialization-resource
注解,以指定所需的自定义资源。例如,以下注解需要创建StorageCluster
资源,并提供完整的 YAML 定义:初始化资源注解
apiVersion: operators.coreos.com/v1alpha1 kind: ClusterServiceVersion metadata: name: my-operator-v1.2.3 annotations: operatorframework.io/initialization-resource: |- { "apiVersion": "ocs.openshift.io/v1", "kind": "StorageCluster", "metadata": { "name": "example-storagecluster" }, "spec": { "manageNodes": false, "monPVCTemplate": { "spec": { "accessModes": [ "ReadWriteOnce" ], "resources": { "requests": { "storage": "10Gi" } }, "storageClassName": "gp2" } }, "storageDeviceSets": [ { "count": 3, "dataPVCTemplate": { "spec": { "accessModes": [ "ReadWriteOnce" ], "resources": { "requests": { "storage": "1Ti" } }, "storageClassName": "gp2", "volumeMode": "Block" } }, "name": "example-deviceset", "placement": {}, "portable": true, "resources": {} } ] } } ...
5.6.11. 了解您的 API 服务
与 CRD 一样,您的 Operator 可使用两类 APIService:拥有的和必需的。
5.6.11.1. 拥有的 API 服务
当 CSV 拥有 API 服务时,它将负责描述为其提供支持的扩展 api-server
的部署及其提供的组/version/kind(GVK)。
API 服务由它提供的 group/version 唯一标识,并可以多次列出,以表示期望提供的不同类型。
字段 | 描述 | 必需/可选 |
---|---|---|
|
API 服务提供的组,如 | 必填 |
|
API 服务的版本,如 | 必填 |
| API 服务应提供的类型。 | 必填 |
| 提供的 API 服务的复数名称。 | 必填 |
|
由您的 CSV 定义的部署名称,对应您的 API 服务(对于拥有的 API 服务是必需的)。在 CSV 待定阶段,OLM Operator 会在您的 CSV | 必填 |
|
API 服务名称的人类可读版本,如 | 必填 |
| 有关 Operator 如何使用此 API 服务的简短描述,或有关 API 服务提供的功能描述。 | 必填 |
| 您的 API 服务拥有一类或多类 Kubernetes 对象。它们将在 resources 部分列出,用于告知用户他们可能需要排除故障的对象或如何连接至应用程序,如公开数据库的服务或 Ingress 规则。 建议仅列出对人重要的对象,而不必列出您编排的所有对象。例如,不要列出存储用户不会修改的内部状态的配置映射。 | 选填 |
| 与拥有的 CRD 基本相同。 | 选填 |
5.6.11.1.1. API 服务资源创建
Operator Lifecycle Manager (OLM) 负责为每个唯一拥有的 API 服务创建或替换服务及 API 服务资源:
-
Service pod 选择器从与 API 服务描述的
DeploymentName
字段匹配的 CSV 部署中复制。 - 每次安装都会生成一个新的 CA 密钥/证书对,并且将 base64 编码的 CA 捆绑包嵌入到对应的 API 服务资源中。
5.6.11.1.2. API service serving 证书
每当安装拥有的 API 服务时,OLM 均会处理服务密钥/证书对的生成。服务证书有一个通用名称(CN),其中包含生成的 Service
资源的主机名,并由嵌入在对应 API 服务资源中的 CA 捆绑包的私钥签名。
该证书作为类型 kubernetes.io/tls
secret 存储在部署命名空间中,名为 apiservice-cert
的卷会自动附加至 CSV 中与 API 服务描述的 DeploymentName
字段匹配的 volumes 部分中。
如果尚不存在,则具有匹配名称的卷挂载也会附加至该部署的所有容器中。这样用户便可使用预期名称来定义卷挂载,以适应任何自定义路径要求。所生成的卷挂载的默认路径为 /apiserver.local.config/certificates
,具有相同路径的任何现有卷挂载都会被替换。
5.6.11.2. 所需的 API 服务
OLM 可保证所有必需的 CSV 均有可用的 API 服务,且所有预期的 GVK 在试图安装前均可发现。这允许 CSV 依赖于由它拥有的 API 服务提供的特定类型。
字段 | 描述 | 必需/可选 |
---|---|---|
|
API 服务提供的组,如 | 必填 |
|
API 服务的版本,如 | 必填 |
| API 服务应提供的类型。 | 必填 |
|
API 服务名称的人类可读版本,如 | 必填 |
| 有关 Operator 如何使用此 API 服务的简短描述,或有关 API 服务提供的功能描述。 | 必填 |