metadata.name
集群服务版本 (CSV) 由ClusterServiceVersion
对象定义,是从操作符元数据创建的YAML清单,它帮助操作符生命周期管理器 (OLM) 在集群中运行操作符。它是伴随操作符容器镜像的元数据,用于使用其徽标、描述和版本等信息填充用户界面。它也是运行操作符所需的详细信息来源,例如它所需的RBAC规则以及它管理或依赖的自定义资源 (CR)。
Operator SDK包含CSV生成器,用于为当前Operator项目生成CSV,并使用YAML清单和Operator源文件中包含的信息进行自定义。
Red Hat支持的Operator SDK CLI工具版本(包括相关的脚手架和Operator项目的测试工具)已弃用,并计划在未来版本的OpenShift Container Platform中删除。Red Hat将在当前发布周期内为此功能提供错误修复和支持,但此功能将不再接收增强功能,并将从未来的OpenShift Container Platform版本中删除。 不建议使用Red Hat支持的Operator SDK版本创建新的Operator项目。拥有现有Operator项目的Operator作者可以使用OpenShift Container Platform 4.17发布的Operator SDK CLI工具版本来维护他们的项目并创建针对较新版本的OpenShift Container Platform的操作符发行版。 以下与Operator项目相关的基础镜像未被弃用。这些基础镜像的运行时功能和配置API仍然支持错误修复和解决CVE。
有关OpenShift Container Platform中已弃用或删除的主要功能的最新列表,请参阅OpenShift Container Platform发行说明中的已弃用和已删除的功能部分。 有关不受支持的社区维护的Operator SDK版本的信息,请参阅Operator SDK (Operator Framework)。 |
生成 CSV 的命令消除了 Operator 作者需要深入了解 OLM 才能使其 Operator 与 OLM 交互或向 Catalog Registry 发布元数据的责任。此外,由于 CSV 规范可能会随着新 Kubernetes 和 OLM 功能的实现而随着时间推移而发生变化,因此 Operator SDK 能够轻松扩展其更新系统以处理未来的新 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。
make bundle
命令会在您的 Operator 项目中创建以下文件和目录
名为bundle/manifests
的捆绑清单目录,其中包含一个ClusterServiceVersion
(CSV) 对象
名为bundle/metadata
的捆绑元数据目录
config/crd
目录中的所有自定义资源定义 (CRD)
Dockerfile bundle.Dockerfile
CSV 中通常包含以下资源:
定义 Operator 在命名空间内的权限。
定义集群范围的 Operator 权限。
定义如何在 Pod 中运行 Operator 的操作对象。
定义您的 Operator 调和的自定义资源。
符合特定 CRD 规范的资源示例。
许多 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(例如,网站和文档),每个 URL 都包含 |
|
Operator 可以用来配对集群中资源的选择器。 |
|
Operator 独有的 base64 编码图标,设置在包含 |
|
此版本的软件已达到的成熟度级别。选项包括 |
有关上述每个字段应包含哪些数据的更多详细信息,请参阅CSV 规范。
目前需要用户干预的几个 YAML 字段可以从 Operator 代码中解析。 |
Operator 开发人员可以在集群服务版本 (CSV) 的元数据中设置某些注释,以启用功能或在用户界面 (UI) 中突出显示功能,例如 OperatorHub 或Red Hat 生态系统目录。通过在 CSV YAML 文件中设置metadata.annotations
字段来手动定义 Operator 元数据注释。
features.operators.openshift.io
组中的注释详细说明了 Operator 可能支持的基础设施功能,通过设置"true"
或"false"
值来指定。用户可以通过 Web 控制台或Red Hat 生态系统目录中的 OperatorHub 发现 Operator 时,查看和按这些功能进行筛选。这些注释在 OpenShift Container Platform 4.10 及更高版本中受支持。
|
注释 | 描述 | 有效值[1] |
---|---|---|
|
指定 Operator 是否支持被镜像到断开的目录中,包括所有依赖项,并且不需要互联网访问。Operator 利用 |
|
|
指定操作符是否接受底层平台的 FIPS-140 配置并在引导到 FIPS 模式的节点上工作。在此模式下,操作符及其管理的任何工作负载(操作数)仅调用已提交 FIPS-140 验证的 Red Hat Enterprise Linux (RHEL) 加密库。 |
|
|
指定操作符是否支持在代理后面的集群上运行,方法是接受标准的 |
|
|
指定操作符是否实现了众所周知的可调参数来修改操作符以及(如果适用)其管理的任何工作负载(操作数)使用的 TLS 密码套件。 |
|
|
指定操作符是否支持通过使用云凭据操作符 (CCO) 通过 AWS 安全令牌服务 (STS) 对 AWS API 进行令牌化身份验证的配置。 |
|
|
指定操作符是否支持通过使用云凭据操作符 (CCO) 通过 Azure 托管标识对 Azure API 进行令牌化身份验证的配置。 |
|
|
指定操作符是否支持通过使用云凭据操作符 (CCO) 通过 GCP 工作负载身份基础 (WIF) 对 Google Cloud API 进行令牌化身份验证的配置。 |
|
|
指定操作符是否提供云原生网络功能 (CNF) Kubernetes 插件。 |
|
|
指定操作符是否提供容器网络接口 (CNI) Kubernetes 插件。 |
|
|
指定操作符是否提供容器存储接口 (CSI) Kubernetes 插件。 |
|
有效值有意使用双引号显示,因为 Kubernetes 注解必须是字符串。
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"
为受限网络环境启用您的操作符(脱机模式)
从 OpenShift Container Platform 4.14 开始,operators.openshift.io/infrastructure-features
组的注解已被 features.operators.openshift.io
命名空间的注解组弃用。虽然鼓励您使用较新的注解,但目前同时使用这两个组时都会被接受。
这些注解详细说明了操作符支持的基础设施特性。用户可以在通过 Web 控制台或 Red Hat 生态系统目录 中发现操作符时查看并按这些特性进行筛选。
有效的注解值 | 描述 | ||
---|---|---|---|
|
操作符支持被镜像到脱机目录中,包括所有依赖项,并且不需要互联网访问。操作符列出了镜像所需的所有相关镜像。 |
||
|
操作符提供云原生网络功能 (CNF) Kubernetes 插件。 |
||
|
操作符提供容器网络接口 (CNI) Kubernetes 插件。 |
||
|
操作符提供容器存储接口 (CSI) Kubernetes 插件。 |
||
|
操作符接受底层平台的 FIPS 模式并在引导到 FIPS 模式的节点上工作。
|
||
|
操作符支持在代理后面的集群上运行。操作符接受标准的代理环境变量 |
disconnected
和proxy-aware
支持的示例 CSVapiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
annotations:
operators.openshift.io/infrastructure-features: '["disconnected", "proxy-aware"]'
以下操作符注解是可选的。
注释 | 描述 |
---|---|
|
提供具有最小配置集的自定义资源定义 (CRD) 模板。兼容的 UI 为用户预填充此模板以进行进一步自定义。 |
|
通过在操作符安装期间将 |
|
设置操作符应部署到的建议命名空间。 |
|
为 |
|
用于列出使用操作符所需的任何特定订阅的自由格式数组。例如, |
|
隐藏 UI 中不适合用户操作的 CRD。 |
apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
annotations:
operators.openshift.io/valid-subscription: '["OpenShift Container Platform"]'
apiVersion: operators.coreos.com/v1alpha1
kind: ClusterServiceVersion
metadata:
annotations:
operators.openshift.io/valid-subscription: '["3Scale Commercial License", "Red Hat Managed Integration"]'
作为操作符作者,您的操作符必须满足其他要求才能在受限网络或脱机环境中正常运行。
用环境变量替换硬编码的镜像引用。
在操作符的集群服务版本 (CSV) 中
列出任何相关镜像或操作符可能需要执行其功能的其他容器镜像。
通过摘要 (SHA) 而不是标签来引用所有指定的镜像。
操作符的所有依赖项也必须支持在脱机模式下运行。
您的操作符不得需要任何集群外资源。
包含 CSV 的操作符项目。以下过程使用 Memcached 操作符作为 Go、Ansible 和基于 Helm 的项目的示例。
为config/manager/manager.yaml
文件中操作符使用的附加镜像引用设置环境变量
config/manager/manager.yaml
文件示例...
spec:
...
spec:
...
containers:
- command:
- /manager
...
env:
- name: <related_image_environment_variable> (1)
value: "<related_image_reference_with_tag>" (2)
1 | 定义环境变量,例如RELATED_IMAGE_MEMCACHED 。 |
2 | 设置相关的镜像引用和标签,例如docker.io/memcached:1.4.36-alpine 。 |
在操作符项目类型的相关文件中用环境变量替换硬编码的镜像引用
对于基于 Go 的 Operator 项目,请按以下示例所示,将环境变量添加到 `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{{
...
1 | 删除镜像引用和标签。 |
2 | 使用 `os.Getenv` 函数调用 ` |
`os.Getenv` 函数在变量未设置时返回空字符串。更改文件之前,请先设置 ` |
对于基于 Ansible 的 Operator 项目,请按以下示例所示,将环境变量添加到 `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
...
1 | 删除镜像引用和标签。 |
2 | 使用 `lookup` 函数调用 ` |
对于基于 Helm 的 Operator 项目,请按以下示例所示,将 `overrideValues` 字段添加到 `watches.yaml` 文件中
...
- group: demo.example.com
version: v1alpha1
kind: Memcached
chart: helm-charts/memcached
overrideValues: (1)
relatedImage: ${<related_image_environment_variable>} (2)
1 | 添加 `overrideValues` 字段。 |
2 | 使用 ` |
按以下示例所示,将 `overrideValues` 字段的值添加到 `helm-charts/memchached/values.yaml` 文件中
...
relatedImage: ""
按以下示例所示,编辑 `helm-charts/memcached/templates/deployment.yaml` 文件中的图表模板
containers:
- name: {{ .Chart.Name }}
securityContext:
- toYaml {{ .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.pullPolicy }}
env: (1)
- name: related_image (2)
value: "{{ .Values.relatedImage }}" (3)
1 | 添加 `env` 字段。 |
2 | 命名环境变量。 |
3 | 定义环境变量的值。 |
使用以下更改将 `BUNDLE_GEN_FLAGS` 变量定义添加到您的 `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)
...
1 | 删除 `Makefile` 中的这一行。 |
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"]'
Operator 可以通过此基础架构功能在 OperatorHub 中进行筛选。
Operator Lifecycle Manager (OLM) 假设所有 Operator 都在 Linux 主机上运行。但是,作为 Operator 作者,您可以指定您的 Operator 是否支持在其他架构上管理工作负载(如果 OpenShift Container Platform 集群中提供工作节点)。
如果您的 Operator 支持除 AMD64 和 Linux 之外的变体,您可以向提供 Operator 的集群服务版本 (CSV) 添加标签,以列出支持的变体。指示支持的架构和操作系统的标签由以下内容定义:
labels:
operatorframework.io/arch.<arch>: supported (1)
operatorframework.io/os.<os>: supported (2)
1 | 将 ` |
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) 而不是标签来指定引用的镜像。
在 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 (1)
1 | 添加新的架构或操作系统后,现在还必须显式包含默认的 `os.linux` 和 `arch.amd64` 变体。 |
有关清单列表的更多信息,请参阅 镜像清单 V 2,模式 2 规范。
在 OpenShift Container Platform 上的 Operator Lifecycle Manager (OLM) 中,当标记或筛选支持多种架构和操作系统的 Operator 时,支持以下字符串:
架构 | 字符串 |
---|---|
AMD64 |
|
ARM64 |
|
IBM Power® |
|
IBM Z® |
|
操作系统 | 字符串 |
---|---|
Linux |
|
z/OS |
|
不同版本的 OpenShift Container Platform 和其他基于 Kubernetes 的发行版可能支持不同的架构和操作系统集。 |
某些 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 | 设置您的建议命名空间。 |
某些 Operator 期望仅在控制平面节点上运行,这可以通过 Operator 本身在 `Pod` 规范中设置 `nodeSelector` 来完成。
为了避免获得重复的且可能冲突的集群范围默认 `nodeSelector`,您可以在 Operator 运行的命名空间上设置默认节点选择器。默认节点选择器将优先于集群默认值,因此集群默认值不会应用于 Operator 命名空间中的 Pod。
使用 OperatorHub 将 Operator 添加到集群时,Web 控制台会在安装过程中为集群管理员自动填充建议的命名空间。建议的命名空间是使用包含在集群服务版本 (CSV) 中的 YAML 中的命名空间清单创建的。
在您的 CSV 中,使用 `Namespace` 对象的清单设置 `operatorframework.io/suggested-namespace-template`。以下示例是具有指定命名空间默认节点选择器的示例 `Namespace` 的清单:
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 中同时存在 `suggested-namespace` 和 `suggested-namespace-template` 注解,则 `suggested-namespace-template` 应优先。 |
Operator Lifecycle Manager (OLM) 为 Operator 提供了一个通道,用于传达影响 OLM 在管理 Operator 时的行为的复杂状态。默认情况下,OLM 在安装 Operator 时会创建一个 `OperatorCondition` 自定义资源定义 (CRD)。根据 `OperatorCondition` 自定义资源 (CR) 中设置的条件,OLM 的行为会相应更改。
为了支持 Operator 条件,Operator 必须能够读取 OLM 创建的 `OperatorCondition` CR,并能够完成以下任务:
获取特定条件。
设置特定条件的状态。
可以使用 operator-lib
库来实现此功能。操作符作者可以在他们的操作符中提供 controller-runtime
客户端,以便库访问集群中操作符拥有的 OperatorCondition
CR。
该库提供了一个通用的 Conditions
接口,该接口具有以下方法来在 OperatorCondition
CR 中 获取
和 设置
conditionType
获取
为了获取特定条件,该库使用 controller-runtime
中的 client.Get
函数,该函数需要 conditionAccessor
中存在的 types.NamespacedName
类型的 ObjectKey
。
设置
为了更新特定条件的状态,该库使用 controller-runtime
中的 client.Update
函数。如果 CRD 中不存在 conditionType
,则会发生错误。
操作符只能修改 CR 的 status
子资源。操作符可以删除或更新 status.conditions
数组以包含该条件。有关条件中字段的格式和说明的更多详细信息,请参见上游 Condition GoDocs。
Operator SDK 1.36.1 支持 |
使用 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
构造函数进一步用于创建 Condition
类型的变量 cond
。cond
变量将反过来具有 Get
和 Set
方法,这些方法可用于处理 OLM Upgradeable
条件。
Webhook 允许操作符作者在资源保存到对象存储并由操作符控制器处理之前拦截、修改和接受或拒绝资源。操作符生命周期管理器 (OLM) 在它们与您的操作符一起交付时可以管理这些 Webhook 的生命周期。
操作符的集群服务版本 (CSV) 资源可以包含一个 webhookdefinitions
部分来定义以下类型的 Webhook:
准入 Webhook(验证和变异)
转换 Webhook
在操作符 CSV 的 spec
部分添加一个 webhookdefinitions
部分,并使用 ValidatingAdmissionWebhook
、MutatingAdmissionWebhook
或 ConversionWebhook
的 type
包含任何 Webhook 定义。以下示例包含所有三种类型的 Webhook
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)
...
1 | 转换 Webhook 定向的 CRD 必须存在于此处。 |
2 | 验证准入 Webhook。 |
3 | 变异准入 Webhook。 |
4 | 转换 Webhook。 |
5 | 每个 CRD 的 spec.PreserveUnknownFields 属性必须设置为 false 或 nil 。 |
Kubernetes 文档
使用操作符生命周期管理器 (OLM) 部署具有 Webhook 的操作符时,必须定义以下内容:
type
字段必须设置为 ValidatingAdmissionWebhook
、MutatingAdmissionWebhook
或 ConversionWebhook
,否则 CSV 将处于失败阶段。
CSV 必须包含一个其名称等效于 webhookdefinition
的 deploymentName
字段中提供的值的部署。
创建 Webhook 时,OLM 确保 Webhook 只对与部署操作符的操作符组匹配的命名空间起作用。
OLM 配置为为每个部署提供单个证书颁发机构 (CA)。生成并安装 CA 到部署中的逻辑最初由 API 服务生命周期逻辑使用。因此
TLS 证书文件安装到部署的 /apiserver.local.config/certificates/apiserver.crt
位置。
TLS 密钥文件安装到部署的 /apiserver.local.config/certificates/apiserver.key
位置。
为防止操作符将集群配置到不可恢复的状态,如果准入 Webhook 中定义的规则拦截任何以下请求,OLM 会将 CSV 置于失败阶段:
目标为所有组的请求
目标为 operators.coreos.com
组的请求
目标为 ValidatingWebhookConfigurations
或 MutatingWebhookConfigurations
资源的请求
如果转换 Webhook 定义不符合以下约束,OLM 会将 CSV 置于失败阶段:
具有转换 Webhook 的 CSV 只能支持 AllNamespaces
安装模式。
转换 Webhook 定向的 CRD 必须将其 spec.preserveUnknownFields
字段设置为 false
或 nil
。
CSV 中定义的转换 Webhook 必须定向到已拥有的 CRD。
对于给定的 CRD,整个集群中只能有一个转换 Webhook。
您的操作符可以使用两种类型的自定义资源定义 (CRD):它拥有的 CRD 和它依赖的必需的 CRD。
您的操作符拥有的自定义资源定义 (CRD) 是 CSV 中最重要的部分。这建立了您的操作符与所需的 RBAC 规则、依赖项管理和其他 Kubernetes 概念之间的联系。
您的操作符通常使用多个 CRD 来链接概念,例如在一个对象中进行顶级数据库配置,而在另一个对象中表示副本集。每个 CRD 都应在 CSV 文件中列出。
字段 | 描述 | 必需/可选 |
---|---|---|
|
CRD 的完整名称。 |
必需 |
|
该对象 API 的版本。 |
必需 |
|
CRD 的机器可读名称。 |
必需 |
|
CRD名称的可读版本,例如 |
必需 |
|
此CRD如何被Operator使用或CRD提供的功能的简短描述。 |
必需 |
|
此CRD所属的API组,例如 |
可选 |
|
您的CRD拥有一个或多个Kubernetes对象类型。这些列在 建议仅列出对人而言重要的对象,而不是您编排的所有内容的详尽列表。例如,不要列出存储内部状态且不应由用户修改的配置映射。 |
可选 |
|
这些描述符是一种方法,可以提示UI显示对最终用户最重要的Operator的某些输入或输出。如果您的CRD包含用户必须提供的密钥或配置映射的名称,您可以在此处指定。这些项目在兼容的UI中链接并突出显示。 有三种类型的描述符
所有描述符都接受以下字段
有关描述符的更多信息,也请参阅openshift/console项目。 |
可选 |
以下示例描述了一个MongoDB Standalone
CRD,它需要以密钥和配置映射的形式进行一些用户输入,并编排服务、有状态集、Pod和配置映射。
- 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.
依赖其他必需的CRD完全可选,仅用于减少各个Operator的范围,并提供一种方法来组合多个Operator以解决端到端用例。
一个示例是,一个Operator可能会设置一个应用程序并安装一个etcd集群(来自etcd Operator)用于分布式锁定,以及一个Postgres数据库(来自Postgres Operator)用于数据存储。
Operator Lifecycle Manager (OLM) 会检查集群中可用的CRD和Operator以满足这些需求。如果找到合适的版本,则会在所需的命名空间中启动Operator,并为每个Operator创建一个服务帐户,以创建、监视和修改所需的Kubernetes资源。
字段 | 描述 | 必需/可选 |
---|---|---|
|
您需要的CRD的全名。 |
必需 |
|
该对象 API 的版本。 |
必需 |
|
Kubernetes对象类型。 |
必需 |
|
CRD的可读版本。 |
必需 |
|
组件如何适应您更大架构的摘要。 |
必需 |
required:
- name: etcdclusters.etcd.database.coreos.com
version: v1beta2
kind: EtcdCluster
displayName: etcd Cluster
description: Represents a cluster of etcd nodes.
如果CRD由单个集群服务版本 (CSV) 拥有,则OLM会立即升级自定义资源定义 (CRD)。如果CRD由多个CSV拥有,则在满足以下所有向后兼容条件后升级CRD。
当前CRD中的所有现有服务版本都存在于新的CRD中。
与CRD的服务版本关联的所有现有实例或自定义资源在针对新CRD的验证模式进行验证时都是有效的。
要向您的Operator添加新版本的CRD
在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推送到您的bundle。
Operator Lifecycle Manager (OLM) 不允许立即删除自定义资源定义 (CRD) 的服务版本。相反,必须首先通过将CRD中的served
字段设置为false
来禁用CRD的已弃用版本。然后,可以在后续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 (1)
1 | 相应地更新storage 字段。 |
要从CRD中删除特定版本(是或曾经是 |
使用上述更改升级CRD。
在后续升级周期中,可以完全从CRD中删除非服务版本。例如
versions:
- name: v1beta1
served: true
storage: true
如果从CRD中删除该版本,请确保相应地更新CSV的owned
部分中引用的CRD版本。
必须让您的Operator的用户知道哪些选项是必需的,哪些是可选的。您可以为每个自定义资源定义 (CRD) 提供模板,其中包含一组最小的配置,作为名为alm-examples
的注释。兼容的UI将预填充此模板,供用户进一步自定义。
此注释包含类型的列表,例如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>"}}}]
运营人员通常会在内部使用自定义资源定义 (CRD) 来完成任务。这些对象并非供用户操作,可能会让运营人员用户感到困惑。例如,数据库运营人员可能拥有一个 `Replication` CRD,该 CRD 会在用户创建具有 `replication: true` 的数据库对象时创建。
作为运营人员作者,您可以通过向运营人员的集群服务版本 (CSV) 添加 `operators.operatorframework.io/internal-objects` 注解,在用户界面中隐藏任何不供用户操作的 CRD。
在将某个 CRD 标记为内部对象之前,请确保任何调试信息或可能需要管理应用程序的配置都反映在您的 CR 的状态或 `spec` 块中(如果适用于您的运营人员)。
将 `operators.operatorframework.io/internal-objects` 注解添加到运营人员的 CSV 中,以指定要在用户界面中隐藏的任何内部对象。
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 设置为字符串数组。 |
运营人员可能需要用户在运营人员完全发挥功能之前实例化自定义资源。但是,用户可能难以确定需要什么或如何定义资源。
作为运营人员开发人员,您可以通过在运营人员安装期间将 `operatorframework.io/initialization-resource` 添加到集群服务版本 (CSV) 来指定单个必需的自定义资源。然后,系统会提示您通过 CSV 中提供的模板创建自定义资源。此注解必须包含一个模板,其中包含在安装期间初始化资源所需的完整 YAML 定义。
如果定义了此注解,则在从 OpenShift Container Platform Web 控制台安装运营人员后,系统会提示用户使用 CSV 中提供的模板创建资源。
将 `operatorframework.io/initialization-resource` 注解添加到运营人员的 CSV 中,以指定所需的自定义资源。例如,以下注解需要创建一个 `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": {}
}
]
}
}
...
与 CRD 一样,您的运营人员可以使用两种类型的 API 服务:*拥有* 的和*必需* 的。
当 CSV 拥有 API 服务时,它负责描述支持它的扩展 `api-server` 的部署及其提供的组/版本/种类 (GVK)。
API 服务由其提供的组/版本唯一标识,并且可以列出多次以表示其预期提供的不同种类。
字段 | 描述 | 必需/可选 |
---|---|---|
|
API 服务提供的组,例如 `database.example.com`。 |
必需 |
|
API 服务的版本,例如 `v1alpha1`。 |
必需 |
|
API 服务预期提供的种类。 |
必需 |
|
提供的 API 服务的复数名称。 |
必需 |
|
CSV 定义的与您的 API 服务相对应的部署的名称(对于拥有的 API 服务是必需的)。在 CSV 等待阶段,OLM 运营人员会在您的 CSV 的 `InstallStrategy` 中搜索具有匹配名称的 `Deployment`规范,如果找不到,则不会将 CSV 转变为“安装就绪”阶段。 |
必需 |
|
API 服务名称的可读版本,例如 `MongoDB Standalone`。 |
必需 |
|
关于此 API 服务如何被运营人员使用或 API 服务提供的功能的简短描述。 |
必需 |
|
您的 API 服务拥有 Kubernetes 对象的一种或多种类型。这些列在资源部分中,以告知您的用户他们可能需要排查的对象或如何连接到应用程序,例如公开数据库的服务或入口规则。 建议仅列出对人而言重要的对象,而不是您编排的所有内容的详尽列表。例如,不要列出存储内部状态且不应由用户修改的配置映射。 |
可选 |
|
与拥有的 CRD 基本相同。 |
可选 |
运营人员生命周期管理器 (OLM) 负责为每个唯一的拥有的 API 服务创建或替换服务和 API 服务资源。
服务 Pod 选择器从与 API 服务描述的 `DeploymentName` 字段匹配的 CSV 部署中复制。
为每个安装生成一个新的 CA 密钥/证书对,并且 base64 编码的 CA 捆绑包嵌入到相应的 API 服务资源中。
每当安装拥有的 API 服务时,OLM 都会处理生成服务密钥/证书对。服务证书具有包含生成的 `Service` 资源的主机名的公用名 (CN),并由嵌入在相应 API 服务资源中的 CA 捆绑包的私钥签名。
证书存储为部署命名空间中的类型 `kubernetes.io/tls` 密钥,并且名为 `apiservice-cert` 的卷会自动附加到 CSV 中与 API 服务描述的 `DeploymentName` 字段匹配的部署的卷部分。
如果不存在,则还会将具有匹配名称的卷挂载附加到该部署的所有容器。这允许用户定义具有预期名称的卷挂载,以适应任何自定义路径要求。生成的卷挂载的路径默认为 `/apiserver.local.config/certificates`,并且任何具有相同路径的现有卷挂载都将被替换。
OLM 确保所有必需的 CSV 都具有可用的 API 服务,并且在尝试安装之前所有预期的 GVK 都是可发现的。这允许 CSV 依赖于它不拥有的 API 服务提供的特定种类。
字段 | 描述 | 必需/可选 |
---|---|---|
|
API 服务提供的组,例如 `database.example.com`。 |
必需 |
|
API 服务的版本,例如 `v1alpha1`。 |
必需 |
|
API 服务预期提供的种类。 |
必需 |
|
API 服务名称的可读版本,例如 `MongoDB Standalone`。 |
必需 |
|
关于此 API 服务如何被运营人员使用或 API 服务提供的功能的简短描述。 |
必需 |