6.8. 使用 Service Binding Operator 绑定工作负载
应用程序开发人员必须使用绑定 secret 将工作负载绑定到一个或多个后端服务。生成此 secret 是为了存储工作负载要使用的信息。
例如,假设您要连接的服务已公开绑定数据。在这种情况下,您还需要将工作负载与 ServiceBinding
自定义资源(CR)一同使用。通过使用此 ServiceBinding
CR,工作负载发送带有要绑定的服务详情的绑定请求。
ServiceBinding
CR 示例
apiVersion: binding.operators.coreos.com/v1alpha1 kind: ServiceBinding metadata: name: spring-petclinic-pgcluster namespace: my-petclinic spec: services: 1 - group: postgres-operator.crunchydata.com version: v1beta1 kind: PostgresCluster name: hippo application: 2 name: spring-petclinic group: apps version: v1 resource: deployments
如上例所示,您还可以直接使用 ConfigMap
或 Secret
本身用作绑定数据源的服务资源。
6.8.1. 命名策略
命名策略仅适用于 binding.operators.coreos.com
API 组。
命名策略使用 Go 模板来帮助通过服务绑定请求定义自定义绑定名称。命名策略适用于所有属性,包括 ServiceBinding
自定义资源(CR)中的映射。
后端服务项目将名称作为文件或环境变量绑定到工作负载。如果工作负载需要特定格式的项目绑定名称,但从后端服务投射绑定名称不能以该格式提供,那么您可以使用命名策略更改绑定名称。
预定义的后处理功能
在使用命名策略时,根据您的工作负载的期望或要求,您可以在任意组合中使用以下预定义的后处理功能来转换字符字符串:
-
大写
:将字符串中的字符转换为大写。 -
小写
:将字符串中的字符转换为小写。 -
标题
:转字符串中的每个单词的第一个字母大写(某些次要单词除外)。
预定义的命名策略
根据以下预定义的命名策略,处理通过注解声明的绑定名称来更改工作负载:
none
:应用时,绑定名称没有任何更改。示例
在模板编译后,绑定名称采用
{{ .name }}
形式。host: hippo-pgbouncer port: 5432
upper
: 在没有定义namingStrategy
时应用。应用时,将绑定名称的字符串转换为大写。示例
模板编译后,绑定名称采用
{{ .service.kind | upper}}_{{ .name | upper }}
格式。DATABASE_HOST: hippo-pgbouncer DATABASE_PORT: 5432
如果您的工作负载需要不同的格式,您可以定义自定义命名策略并使用前缀和分隔符更改绑定名称,如
PORT_DATABASE
。
-
当绑定名称作为文件进行投射时,默认情况下会应用预定义的
none
命名策略,绑定名称不会改变。 -
当绑定名称作为环境变量进行投射且没有定义
namingStrategy
时,会默认应用预定义的uppercase
命名策略。 - 您可以使用自定义绑定名称和预定义的后处理函数定义自定义命名策略来覆盖预定义的命名策略。
6.8.2. 高级绑定选项
您可以定义 ServiceBinding
自定义资源 (CR) 以使用以下高级绑定选项:
-
更改绑定名称:此选项仅适用于
binding.operators.coreos.com
API 组。 -
编写自定义绑定数据:此选项仅适用于
binding.operators.coreos.com
API 组。 -
使用标签选择器绑定工作负载:此选项可用于
binding.operators.coreos.com
和servicebinding.io
API 组。
6.8.2.1. 在将绑定名称改到工作负载前更改绑定名称
您可以指定规则来更改 ServiceBinding
CR 的 .spec.namingStrategy
属性中的绑定名称。例如,假设一个连接到 PostgreSQL 数据库的 Spring PetClinic 示例应用程序。在本例中,PostgreSQL 数据库服务公开数据库的 host
和 port
字段,以用于绑定。Spring PetClinic 示例应用程序可以通过绑定名称访问此公开绑定数据。
示例: ServiceBinding
CR 中的 Spring PetClinic 示例应用程序
... application: name: spring-petclinic group: apps version: v1 resource: deployments ...
示例: ServiceBinding
CR 中的 PostgreSQL 数据库服务
... services: - group: postgres-operator.crunchydata.com version: v1beta1 kind: PostgresCluster name: hippo ...
如果未定义 namingStrategy
且绑定名称作为环境变量,则后备服务中的 host: hippo-pgbouncer
值,并且投射环境变量将如以下示例所示:
示例
DATABASE_HOST: hippo-pgbouncer
其中:
|
指定 |
| 指定绑定名称。 |
应用 POSTGRESQL_{{ .service.kind | upper }}_{{ .name | upper }}_ENV
命名策略后,服务绑定请求准备的自定义绑定名称列表如下所示:
示例
POSTGRESQL_DATABASE_HOST_ENV: hippo-pgbouncer POSTGRESQL_DATABASE_PORT_ENV: 5432
以下项目描述了 POSTGRESQL_{{ .service.kind | upper }}_{{ .name | upper }}_ENV
命名策略中定义的表达式:
-
.name
: 请参阅由支持服务公开的绑定名称。在上例中,绑定名称为HOST
和PORT
。 -
.service.kind
:请参阅其绑定名称通过命名策略更改的服务资源类型。 -
upper
:用于在编译 Go 模板字符串时处理字符字符串的字符串的字符串。 -
POSTGRESQL
:自定义绑定名称的前缀。 -
ENV
:自定义绑定名称的修复。
与前面的示例类似,您可以在 namingStrategy
中定义字符串模板,以定义如何由服务绑定请求准备绑定名称的每个键。
6.8.2.2. 编写自定义绑定数据
作为应用程序开发人员,您可以在以下情况下编写自定义绑定数据:
- 后备服务不公开绑定数据。
- 所公开的值不能以所需格式提供,工作负载符合预期。
例如,如果后备服务 CR 将主机、端口和数据库用户公开为绑定数据,但工作负载要求将绑定数据用作连接字符串。您可以使用代表支持服务的 Kubernetes 资源中的属性编写自定义绑定数据。
示例
apiVersion: binding.operators.coreos.com/v1alpha1 kind: ServiceBinding metadata: name: spring-petclinic-pgcluster namespace: my-petclinic spec: services: - group: postgres-operator.crunchydata.com version: v1beta1 kind: PostgresCluster name: hippo 1 id: postgresDB 2 - group: "" version: v1 kind: Secret name: hippo-pguser-hippo id: postgresSecret application: name: spring-petclinic group: apps version: v1 resource: deployments mappings: ## From the database service - name: JDBC_URL value: 'jdbc:postgresql://{{ .postgresDB.metadata.annotations.proxy }}:{{ .postgresDB.spec.port }}/{{ .postgresDB.metadata.name }}' ## From both the services! - name: CREDENTIALS value: '{{ .postgresDB.metadata.name }}{{ translationService.postgresSecret.data.password }}' ## Generate JSON - name: DB_JSON 3 value: {{ json .postgresDB.status }} 4
6.8.2.3. 使用标签选择器绑定工作负载
您可以使用标签选择器指定要绑定的工作负载。如果您使用标签选择器声明服务绑定来获取工作负载,Service Binding Operator 会定期尝试查找和绑定与给定标签选择器匹配的新工作负载。
例如,作为集群管理员,您可以通过在 ServiceBinding
CR 中设置适当的 labelSelector
字段来将服务绑定到带有 environment: production
标签的命名空间中的所有 Deployment
。这可让 Service Binding Operator 将每个工作负载与一个 ServiceBinding
CR 绑定。
binding.operators.coreos.com/v1alpha1
API 中的 ServiceBinding
CR 示例
apiVersion: binding.operators.coreos.com/v1alpha1
kind: ServiceBinding
metadata:
name: multi-application-binding
namespace: service-binding-demo
spec:
application:
labelSelector: 1
matchLabels:
environment: production
group: apps
version: v1
resource: deployments
services:
group: ""
version: v1
kind: Secret
name: super-secret-data
- 1
- 指定正在绑定的工作负载。
servicebinding.io
API 中的 ServiceBinding
CR 示例
apiVersion: servicebindings.io/v1beta1
kind: ServiceBinding
metadata:
name: multi-application-binding
namespace: service-binding-demo
spec:
workload:
selector: 1
matchLabels:
environment: production
apiVersion: app/v1
kind: Deployment
service:
apiVersion: v1
kind: Secret
name: super-secret-data
- 1
- 指定正在绑定的工作负载。
如果定义以下字段对,Service Binding Operator 会拒绝绑定操作,并生成错误:
-
binding.operators.coreos.com/v1alpha1
API 中的name
和labelSelector
字段。 -
servicebinding.io
API (Spec API) 中的name
和selector
字段。
了解重新绑定(rebinding)行为
例如,在成功绑定后,您可以使用 name
字段识别工作负载。如果删除并重新创建那个工作负载,ServiceBinding
协调器不会重新绑定工作负载,Operator 无法将绑定数据的项目到工作负载。但是,如果您使用 labelSelector
字段识别工作负载,ServiceBinding
协调器会重新绑定工作负载,Operator 则项目绑定数据。
6.8.3. 绑定与 PodSpec 不兼容的二级工作负载
服务绑定中的典型场景涉及配置后端服务、工作负载(Deployment)和 Service Binding Operator。考虑涉及与 PodSpec 不兼容且位于主工作负载(Deployment)和 Service Binding Operator 之间的辅助工作负载(也可以是一个应用程序 Operator)的场景。
对于这样的辅助工作负载资源,容器路径的位置是任意的。对于服务绑定,如果 CR 中的辅助工作负载与 PodSpec 不兼容,您必须指定容器路径的位置。这样做可以将数据绑定到 ServiceBinding
自定义资源(CR)的二级工作负载中指定的容器路径中,例如,当您不想在一个 pod 中绑定数据时。
在 Service Binding Operator 中,您可以配置容器或 secret 驻留在工作负载中的路径,并在自定义位置绑定这些路径。
6.8.3.1. 配置容器路径的自定义位置
当 Service Binding Operator 项目作为环境变量时,这个自定义位置可用于 binding.operators.coreos.com
API 组。
考虑辅助工作负载 CR,它不与 PodSpec 兼容,并且具有位于 spec.containers
路径的容器:
示例:二级工作负载 CR
apiVersion: "operator.sbo.com/v1" kind: SecondaryWorkload metadata: name: secondary-workload spec: containers: - name: hello-world image: quay.io/baijum/secondary-workload:latest ports: - containerPort: 8080
流程
通过在
ServiceBinding
CR 中指定值并将此路径绑定到spec.application.bindingPath.containersPath
自定义位置来配置spec.containers
路径:示例:带有自定义位置的
spec.containers
路径的ServiceBinding
CRapiVersion: binding.operators.coreos.com/v1alpha1 kind: ServiceBinding metadata: name: spring-petclinic-pgcluster spec: services: - group: postgres-operator.crunchydata.com version: v1beta1 kind: PostgresCluster name: hippo id: postgresDB - group: "" version: v1 kind: Secret name: hippo-pguser-hippo id: postgresSecret application: 1 name: spring-petclinic group: apps version: v1 resource: deployments application: 2 name: secondary-workload group: operator.sbo.com version: v1 resource: secondaryworkloads bindingPath: containersPath: spec.containers 3
指定容器路径的位置后,Service Binding Operator 会生成绑定数据,该数据在 ServiceBinding
CR 的二级工作负载中指定的容器路径中可用。
以下示例显示了带有 envFrom
和 secretRef
字段的 spec.containers
路径:
示例:带有 envFrom
和 secretRef
字段的二级工作负载 CR
apiVersion: "operator.sbo.com/v1" kind: SecondaryWorkload metadata: name: secondary-workload spec: containers: - env: 1 - name: ServiceBindingOperatorChangeTriggerEnvVar value: "31793" envFrom: - secretRef: name: secret-resource-name 2 image: quay.io/baijum/secondary-workload:latest name: hello-world ports: - containerPort: 8080 resources: {}
6.8.3.2. 配置 secret 路径的自定义位置
当 Service Binding Operator 项目作为环境变量时,这个自定义位置可用于 binding.operators.coreos.com
API 组。
考虑与 PodSpec 不兼容的辅助工作负载 CR,且只有 spec.secret
路径中的 secret:
示例:二级工作负载 CR
apiVersion: "operator.sbo.com/v1" kind: SecondaryWorkload metadata: name: secondary-workload spec: secret: ""
流程
通过在
ServiceBinding
CR 中指定值并在spec.application.bindingPath.secretPath
自定义位置上绑定这个路径来配置spec.secret
路径:示例:带有自定义位置
spec.secret
路径的ServiceBinding
CRapiVersion: binding.operators.coreos.com/v1alpha1 kind: ServiceBinding metadata: name: spring-petclinic-pgcluster spec: ... application: 1 name: secondary-workload group: operator.sbo.com version: v1 resource: secondaryworkloads bindingPath: secretPath: spec.secret 2 ...
指定 secret 路径的位置后,Service Binding Operator 会生成绑定数据,该数据在 ServiceBinding
CR 的二级工作负载中指定的 secret 路径中可用。
以下示例显示了带有 binding-request
值的 spec.secret
路径:
示例:使用 binding-request
值进行二级工作负载 CR
...
apiVersion: "operator.sbo.com/v1"
kind: SecondaryWorkload
metadata:
name: secondary-workload
spec:
secret: binding-request-72ddc0c540ab3a290e138726940591debf14c581 1
...
- 1
- Service Binding Operator 生成的
Secret
资源的唯一名称。
6.8.3.3. 工作负载资源映射
-
工作负载资源映射可用于 API groups:
binding.operators.coreos.com
和servicebinding.io
的ServiceBinding
自定义资源 (CR) 的辅助工作负载。 -
您必须仅在
servicebinding.io
API 组下定义ClusterWorkloadResourceMapping
资源。但是,ClusterWorkloadResourceMapping
资源与binding.operators.coreos.com
和servicebinding.io
API 组中的ServiceBinding
资源交互。
如果无法使用配置方法配置容器路径,则无法配置自定义路径位置,您可以精确定义需要投射绑定数据的位置。通过在 servicebinding.io
API 组中定义 ClusterWorkloadResourceMapping
资源,指定给定工作负载类型的绑定数据的位置。
以下示例演示了如何为 CronJob.batch/v1
资源定义映射。
示例: CronJob.batch/v1
资源的映射
apiVersion: servicebinding.io/v1beta1 kind: ClusterWorkloadResourceMapping metadata: name: cronjobs.batch 1 spec: versions: - version: "v1" 2 annotations: .spec.jobTemplate.spec.template.metadata.annotations 3 containers: - path: .spec.jobTemplate.spec.template.spec.containers[*] 4 - path: .spec.jobTemplate.spec.template.spec.initContainers[*] name: .name 5 env: .env 6 volumeMounts: .volumeMounts 7 volumes: .spec.jobTemplate.spec.template.spec.volumes 8
- 1
ClusterWorkloadResourceMapping
资源的名称,它必须符合映射负载资源的plural.group
。- 2
- 正在映射的资源版本。未指定的任何版本都可以与 "*" 通配符匹配。
- 3
- 可选:一个 pod 中的
.annotations
字段标识符,使用固定 JSONPath 指定。默认值为.spec.template.spec.annotations
。 - 4
- pod 中的
.containers
和.initContainers
字段的标识符,使用 JSONPath 指定。如果没有定义containers
字段下的条目,Service Binding Operator 默认为两个路径:.spec.template.spec.containers[*]
和.spec.template.spec.initContainers[\*]
,所有其他字段都设为默认值。但是,如果您指定了条目,则必须定义.path
字段。 - 5
- 可选:容器中的
.name
字段的标识符,使用固定 JSONPath 指定。默认值为.name
。 - 6
- 可选:容器中的
.env
字段的标识符,使用固定 JSONPath 指定。默认值为.env
。 - 7
- 可选:容器中的
.volumeMounts
字段的标识符,使用固定 JSONPath 指定。默认值为.volumeMounts
。 - 8
- 可选:一个 pod 中的
.volumes
字段的标识符,使用固定 JSONPath 指定。默认值为.spec.template.spec.volumes
。
在这个上下文中,固定 JSONPath 是 JSONPath grammar 的子集,它只接受以下操作:
-
字段查找:
.spec.template
-
数组索引:
.spec['template']
所有其他操作都不接受。
-
字段查找:
-
大多数字段都是可选的。如果没有指定,Service Binding Operator 会假定与
PodSpec
资源兼容。 -
Service Binding Operator 要求每个字段都结构化地与 pod 部署中的对应字段相同。例如,工作负载资源中的
.env
字段的内容必须能够接受 Pod 资源中的.env
字段相同的数据结构。否则,将绑定数据绑定到这样的工作负载可能会导致 Service Binding Operator 意外行为。
特定于 binding.operators.coreos.com
API 组的行为
当 ClusterWorkloadResourceMapping
资源与 binding.operators.coreos.com
API 组中的 ServiceBinding
资源交互时,您可以预期以下行为:
-
如果将带有
bindAsFiles: false
标志值的ServiceBinding
资源与其中一个映射一同创建,那么环境变量将投射到对应ClusterWorkloadResourceMapping
资源中指定的每个path
字段下的.envFrom
字段。 作为集群管理员,您可以在
ServiceBinding.bindings.coreos.com
资源中指定ClusterWorkloadResourceMapping
资源和.spec.application.bindingPath.containersPath
字段。Service Binding Operator 会尝试将数据绑定到
ClusterWorkloadResourceMapping
资源和.spec.application.bindingPath.containersPath
字段中指定的位置。这个行为等同于在对应的ClusterWorkloadResourceMapping
资源中添加带有path: $containersPath
属性的容器条目,所有其他值都取取其默认值。
6.8.4. 从后备服务中取消绑定工作负载
您可以使用 oc
工具从后端服务中取消绑定工作负载。
要从后备服务中取消绑定工作负载,请删除链接到该服务的
ServiceBinding
自定义资源(CR):$ oc delete ServiceBinding <.metadata.name>
示例
$ oc delete ServiceBinding spring-petclinic-pgcluster
其中:
spring-petclinic-pgcluster
指定
ServiceBinding
CR 的名称。