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

1
指定服务资源列表。
2
示例应用程序,指向带有嵌入式 PodSpec 的 Deployment 或任何其他类似资源。

如上例所示,您还可以直接使用 ConfigMapSecret 本身用作绑定数据源的服务资源。

6.8.1. 命名策略

命名策略仅适用于 binding.operators.coreos.com API 组。

命名策略使用 Go 模板来帮助通过服务绑定请求定义自定义绑定名称。命名策略适用于所有属性,包括 ServiceBinding 自定义资源(CR)中的映射。

后端服务项目将名称作为文件或环境变量绑定到工作负载。如果工作负载需要特定格式的项目绑定名称,但从后端服务投射绑定名称不能以该格式提供,那么您可以使用命名策略更改绑定名称。

预定义的后处理功能

在使用命名策略时,根据您的工作负载的期望或要求,您可以在任意组合中使用以下预定义的后处理功能来转换字符字符串:

  • 大写:将字符串中的字符转换为大写。
  • 小写:将字符串中的字符转换为小写。
  • 标题 :转字符串中的每个单词的第一个字母大写(某些次要单词除外)。

预定义的命名策略

根据以下预定义的命名策略,处理通过注解声明的绑定名称来更改工作负载:

  • none :应用时,绑定名称没有任何更改。

    Example

    在模板编译后,绑定名称采用 {{ .name }} 形式。

    host: hippo-pgbouncer
    port: 5432
  • upper: 在没有定义 namingStrategy 时应用。应用时,将绑定名称的字符串转换为大写。

    Example

    模板编译后,绑定名称采用 {{ .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.comservicebinding.io API 组。

6.8.2.1. 在将绑定名称改到工作负载前更改绑定名称

您可以指定规则来更改 ServiceBinding CR 的 .spec.namingStrategy 属性中的绑定名称。例如,假设一个连接到 PostgreSQL 数据库的 Spring PetClinic 示例应用程序。在本例中,PostgreSQL 数据库服务公开数据库的 hostport 字段,以用于绑定。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 值,并且投射环境变量将如以下示例所示:

Example

DATABASE_HOST: hippo-pgbouncer

其中:

DATABASE

指定 kind 后端服务。

HOST

指定绑定名称。

应用 POSTGRESQL_{{ .service.kind | upper }}_{{ .name | upper }}_ENV 命名策略后,服务绑定请求准备的自定义绑定名称列表如下所示:

Example

POSTGRESQL_DATABASE_HOST_ENV: hippo-pgbouncer
POSTGRESQL_DATABASE_PORT_ENV: 5432

以下项目描述了 POSTGRESQL_{{ .service.kind | upper }}_{{ .name | upper }}_ENV 命名策略中定义的表达式:

  • .name: 请参阅由支持服务公开的绑定名称。在上例中,绑定名称为 HOSTPORT
  • .service.kind :请参阅其绑定名称通过命名策略更改的服务资源类型。
  • upper :用于在编译 Go 模板字符串时处理字符字符串的字符串的字符串。
  • POSTGRESQL :自定义绑定名称的前缀。
  • ENV :自定义绑定名称的修复。

与前面的示例类似,您可以在 namingStrategy 中定义字符串模板,以定义如何由服务绑定请求准备绑定名称的每个键。

6.8.2.2. 编写自定义绑定数据

作为应用程序开发人员,您可以在以下情况下编写自定义绑定数据:

  • 后备服务不公开绑定数据。
  • 所公开的值不能以所需格式提供,工作负载符合预期。

例如,如果后备服务 CR 将主机、端口和数据库用户公开为绑定数据,但工作负载要求将绑定数据用作连接字符串。您可以使用代表支持服务的 Kubernetes 资源中的属性编写自定义绑定数据。

Example

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

1
后端服务资源的名称。
2
可选标识符。
3
Service Binding Operator 生成的 JSON 名称。Service Binding Operator 会将此 JSON 名称作为文件或环境变量的名称。
4
Service Binding Operator 生成的 JSON 值。Service Binding Operator 将此 JSON 值作为文件或环境变量。JSON 值包含来自后备服务自定义资源的指定字段中的属性。

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 中的 namelabelSelector 字段。
  • servicebinding.io API (Spec API) 中的 nameselector 字段。

了解重新绑定(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 CR

    apiVersion: 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

    1
    示例应用程序,指向带有嵌入式 PodSpec 的 Deployment 或任何其他类似资源。
    2
    辅助工作负载,不与 PodSpec 兼容。
    3
    容器路径的自定义位置。

指定容器路径的位置后,Service Binding Operator 会生成绑定数据,该数据在 ServiceBinding CR 的二级工作负载中指定的容器路径中可用。

以下示例显示了带有 envFromsecretRef 字段的 spec.containers 路径:

示例:带有 envFromsecretRef 字段的二级工作负载 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: {}

1
具有 Service Binding Operator 生成的值的唯一容器数组。这些值基于后端服务 CR。
2
Service Binding Operator 生成的 Secret 资源的名称。

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 CR

    apiVersion: 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
    ...

    1
    辅助工作负载,不与 PodSpec 兼容。
    2
    包含 Secret 资源名称的 secret 路径的自定义位置。

指定 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.comservicebinding.ioServiceBinding 自定义资源 (CR) 的辅助工作负载。
  • 您必须仅在 servicebinding.io API 组下定义 ClusterWorkloadResourceMapping 资源。但是,ClusterWorkloadResourceMapping 资源与 binding.operators.coreos.comservicebinding.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>

    Example

    $ oc delete ServiceBinding spring-petclinic-pgcluster

    其中:

    spring-petclinic-pgcluster

    指定 ServiceBinding CR 的名称。

6.8.5. 其他资源