Connectors CSI 驱动

概述

Connectors CSI Driver 是基于 Container Storage Interface (CSI) 规范实现的存储驱动。它可以将 Connector 中的配置作为卷挂载到 Kubernetes 工作负载中。主要特性包括:

  • 将 Connector 中的配置文件挂载到 Pod 中
  • 支持在配置文件中进行动态变量渲染,以自动注入运行时信息
  • 支持同时挂载多个配置文件

所有配置数据都来自与 Connector 关联的 ConnectorClass configuration

INFO

使用本文档了解工作负载如何挂载 Connector 渲染后的配置并消费与代理相关的运行时数据。

本文档重点介绍挂载和渲染行为。有关代理流量和身份验证,请参阅 Connectors Proxy。有关权限门控和由审批触发的运行时访问,请参阅 Connectors Approval & Permission Gating

快速开始

1. 创建一个 ConnectorClass

首先,创建一个包含 Git 配置的 ConnectorClass:

cat << EOF | kubectl apply -f -
apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: my-git
spec:
  address:
    type: string
  configurations:
  - name: config
    data:
      .gitconfig: |
        this is git config
EOF

2. 创建一个 Connector

然后,创建一个连接到 GitHub 的 Connector:

cat << EOF | kubectl apply -f -
apiVersion: connectors.alauda.io/v1alpha1
kind: Connector
metadata:
  name: git-connector
spec:
  address: https://github.com
  connectorClassName: my-git
EOF

3. 创建一个使用 CSI Driver 的 Pod

创建一个挂载该配置的 Pod:

cat << EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
  name: csi-demo
  namespace: default
spec:
  restartPolicy: Never
  containers:
  - name: web
    image: bitnami/git:2.47.1
    imagePullPolicy: IfNotPresent
    command: ["sleep", "3600"]
    volumeMounts:
    - name: git-config
      mountPath: /tmp/config
  volumes:
  - name: git-config
    csi:
      readOnly: true
      driver: connectors-csi
      volumeAttributes:
        connectors: "default/git-connector"
        configuration.names: "config"
EOF

验证挂载的文件:

# 列出所有挂载的文件(包括内置配置)
kubectl exec -ti csi-demo -- ls -l /tmp/config

# 查看来自 ConnectorClass 的自定义配置
kubectl exec -ti csi-demo -- cat /tmp/config/.gitconfig

内置配置

CSI Driver 默认会自动提供内置配置文件,并将其挂载到 Pod 中。 你可以在 configuration.names 中使用 !<fileName> 排除指定的挂载文件(例如 !context.token),这同样适用于内置文件以及由 configuration.names 选中的 ConnectorClass 渲染文件。

文件名描述
.env包含 http_proxyhttps_proxyno_proxy 的环境变量文件,格式为 key=value
如果存在多个 Connector Category,则会应用最后一个 ConnectorClass 的代理设置。
http.proxy用于 HTTP 的带认证正向代理 URL。
如果存在多个 Connector Category,则会应用最后一个 ConnectorClass 的代理设置。
https.proxy用于 HTTPS 的带认证正向代理 URL。
如果存在多个 Connector Category,则会应用最后一个 ConnectorClass 的代理设置。
context.token代理服务的身份验证令牌
context.proxy.caCertConnectors 代理的 CA 证书
connector.status.proxyAddress代理地址(参见 Connectors Proxy)。
如果存在多个 Connector,则将使用最后一个 ConnectorClass 的代理信息。
ca.certConnectors 代理的 CA 证书,与 context.proxy.caCert 相同,即将废弃;请改用 ca.crt
ca.crtConnectors 代理的 CA 证书,与 context.proxy.caCert 相同
.error.json仅在审批被拒绝时出现。该文件存在时,不会挂载其他任何配置文件。详情请参阅 Connectors Approval

正向代理用法:

# 方案 1
export http_proxy=$(cat /{mount-path}/http.proxy)
export https_proxy=$(cat /{mount-path}/https.proxy)

# 方案 2
source /{mount-path}/.env

反向代理用法:

export TOKEN=$(cat /{mount-path}/context.token)
export SERVER=$(cat /{mount-path}/connector.status.proxyAddress)

{cli} --server $SERVER --token $TOKEN

CSI 卷参数

卷参数

参数是否必填描述
readOnly必须为 true
driver必须为 connectors-csi

卷属性

参数是否必填描述
connector.nameConnector 名称 (已弃用 — 请改用 connectors)
connector.namespaceConnector 命名空间,默认为 Pod 的命名空间 (已弃用 — 请改用 connectors)
configuration.names以逗号分隔的选择器。使用配置名称(例如 config1,config2)来包含 ConnectorClass 配置;使用 !<fileName>(例如 !context.token)来从最终挂载结果中排除指定文件。
configuration.params命名配置的运行时参数 JSON 字符串(参见 configuration.params
token.expiration令牌过期时间(默认:30m
connectors以逗号分隔的 connector 列表,格式为 namespace/namename;如果省略命名空间,则使用 Pod 的命名空间。用于指定多个 connector。

示例

挂载单个配置:

volumes:
- name: config
  csi:
    driver: connectors-csi
    readOnly: true
    volumeAttributes:
      connectors: "my-connector"
      configuration.names: "config1"

挂载多个配置:

volumes:
- name: config
  csi:
    driver: connectors-csi
    readOnly: true
    volumeAttributes:
      connectors: "my-connector"
      configuration.names: "config1,config2"

挂载多个 connector 进行代理身份验证:

volumes:
- name: config
  csi:
    driver: connectors-csi
    readOnly: true
    volumeAttributes:
      connectors: "namespace1/connector1,namespace2/connector2"
      configuration.names: "config1,config2"

排除指定的挂载文件:

volumes:
- name: config
  csi:
    driver: connectors-csi
    readOnly: true
    volumeAttributes:
      connectors: "my-connector"
      configuration.names: "config1,!config1.conf"

仅挂载内置配置,同时排除一个内置文件:

volumes:
- name: config
  csi:
    driver: connectors-csi
    readOnly: true
    volumeAttributes:
      connectors: "my-connector"
      configuration.names: "!context.token"

注意:

  • 如果省略 configuration.names,则仅挂载内置配置
  • 当多个配置包含同名文件时,后面的配置会覆盖前面的配置
  • 排除项(!<fileName>)会在配置收集和合并后,应用于最终挂载的文件名。
  • 如果指定了要包含的配置名称但未找到任何匹配项,即使提供了排除项,请求也会失败。
  • connectors 参数用于指定多个 connector 以挂载配置。

configuration.params

configuration.params 允许调用方在挂载时向配置模板传递运行时参数。ConnectorClass 中的每个配置都可以声明一组命名参数;在创建 CSI 卷时,configuration.params 会为这些参数提供值。

格式

该值是一个 以配置名称为键 的 JSON 对象,其中每个值都是一个键值对对象:

configuration.params: '{"<configName>": {"key": "value", ...}, ...}'

示例 — 在一次挂载中,将 mirrorRepository 传递给 settings 配置,并将 registry 传递给 npmrc 配置:

volumeAttributes:
  configuration.names: "settings,npmrc"
  configuration.params: '{"settings": {"mirrorRepository": "maven-public"}, "npmrc": {"registry": "npm-proxy"}}'

按配置名称进行作用域划分后,无论挂载了多少个 connector 或它们的名称是什么,参数都能保持稳定。与 connector 相关的值应放在 Connector.spec.params 中,并可在模板中通过 .connectors[i].spec.params 访问。

默认值的工作方式

当 ConnectorClass 配置为某个参数声明了默认值,而调用方未提供该参数时,CSI Driver 会在渲染模板之前自动注入默认值。此时无需在 configuration.params 中显式提供该值。

示例 — strictSSL 的默认值为 "true",因此可以省略:

# 这等同于传入 '{"npmrc": {"registry": "npm-proxy", "strictSSL": "true"}}'
configuration.params: '{"npmrc": {"registry": "npm-proxy"}}'

模板中可用的变量

处理完成后,提供的参数(以及默认参数)在配置模板中可通过 .configurations.<paramName> 访问:

{{ .configurations.mirrorRepository }}
{{ .configurations.registry }}

多个 Connector

Connectors CSI Driver 支持将多个 Connector 用于配置。你可以使用 connectors 卷属性指定多个 Connector,格式为 namespace/namename;如果省略命名空间,则使用 Pod 的命名空间。多个 Connector 之间应以逗号分隔。

INFO

在一个 CSI 卷中使用多个 Connector 之前,请先在 connectors-config 中启用 enable-multi-connector 功能开关。详情请参阅 Feature Flags

volumes:
- name: config
  csi:
    driver: connectors-csi
    readOnly: true
    volumeAttributes:
      connectors: "namespace1/connector1,namespace2/connector2"
      configuration.names: "config1,config2"

当指定多个 Connector 时,CSI Driver 会根据 configuration.names 属性合并配置文件。合并行为的详细说明请参见 Configuration Merging 部分。

WARNING

可列出的 connector 数量没有严格限制;不过,请避免指定过多 Connector,以防请求头过大以及其他与代理相关的问题。

配置合并

当指定多个 Connector 时,CSI Driver 会根据 configuration.names 属性合并所有指定 Connector 的配置文件。

配置文件的处理可能存在多种场景;以下情况说明了各自的行为。

相同的配置名称

对于配置名称相同的 Connector,当指定多个 Connector 时,它们的配置数据会合并为一个配置文件。

配置模板应支持为多个 Connector 渲染数据,以便单个文件可以包含多个 connector 的专属数据集。

例如:

apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: multi-connector
spec:
  configurations:
  - name: config
    data:
      .multi-connector-config: |
        {{- range .connectors }}
        # Configuration for Connector: {{ .name }}
        param_name = {{ .name }}
        param_value = {{ .spec.address }}
        {{- end }}

在上面的示例中,配置文件 .multi-connector-config 将包含 connectors 卷属性中指定的每个 Connector 的内容段。

kubectl exec -ti pod-name -- ls -l /mount-path/
# 输出:
# - .multi-connector-config
WARNING

如果合并后的 connector 来自不同的 ConnectorClass,且它们具有同名配置文件,则后面的 ConnectorClass 中的配置会覆盖前面的 ConnectorClass 中的配置。因此,在这种情况下建议使用不同的配置文件名,以避免冲突。

不同的配置名称

当指定的 Connector 具有不同的配置名称时,CSI Driver 会分别挂载所有配置。

apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: connector-a
spec:
  configurations:
  - name: config-a
    data:
      config.xml: |
        {{- range .connectors }}
        # Configuration for Connector: {{ .name }}
        param_name = {{ .name }}
        param_value = {{ .spec.address }}
        {{- end }}
---
apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:   
  name: connector-b
spec:
  configurations:
  - name: config-b
    data:
      settings.json: |
        {"connectors": [
        {{- range .connectors }}
          {"name": "{{ .name }}", "address": "{{ .spec.address }}"},
        {{- end }}
        ]}

当同时使用 connectors 和 configuration names 进行挂载时:

- name: config
  csi:
    driver: connectors-csi
    readOnly: true
    volumeAttributes:
      connectors: "namespace-a/connector-a,namespace-b/connector-b"
      configuration.names: "config-a,config-b"

挂载后的卷将同时包含 config.xmlsettings.json,并分别填充各自对应 Connector 的数据。

kubectl exec -ti pod-name -- ls -l /mount-path/
# 输出:
# - config.xml
# - settings.json

配置文件渲染

CSI Driver 在挂载配置文件时会使用 Go template 语法进行变量渲染。

可用变量

变量描述
.connector.status.proxyAddressConnector 的代理地址;请参阅 connectors-proxy
.connector.spec.*Connector 的 Spec,你可以获取 Connector Spec 的所有字段,例如 .connector.spec.address.connector.spec.params
.context.token用于访问代理服务的身份验证令牌
.context.proxy.caCert用于访问 connectors 代理(正向代理)的 CA 证书;请参阅 connectors-proxy
.connectors在指定多个 Connector 时的 Connector 列表;每个 Connector 的结构与 .connector 相同
.connectorclass.proxyAddress在指定多个 ConnectorClass 时,ConnectorClass 的代理地址。

内置函数

有关支持的函数,请参阅 sprig

例如:b64enc:对字符串进行 Base64 编码

关于代理服务

Connectors 为每个 Connector 提供代理服务,使客户端能够访问目标资源,而无需存储原始凭据。更多详情请参阅 connectors-proxy

配置示例

固定内容

apiVersion: connectors.alauda.io/v1alpha1
kind: ConnectorClass
metadata:
  name: my-git
spec:
  address:
    type: string
  configurations:
  - name: config
    data:
      .gitconfig: |
        this is git config

使用 connector.spec.params

以下 ConnectorClass 定义了一个参数 sslVerify,用于控制 git clone 期间的 SSL 校验。

kind: ConnectorClass
metadata:
  name: git
spec:

  params:
  - name: sslVerify
    type: string
    default: "true"

  configurations:
  - name: config
    data:
      .gitconfig: |
        {{ $sslVerify := "true" -}}
        {{- range .connector.spec.params }}{{- if eq .name "sslVerify" }}{{$sslVerify = .value }}{{ end }}{{- end }}
        [http]
          sslVerify = {{ $sslVerify }}

使用代理服务和令牌

以下 ConnectorClass 提供了一个名为 .gitconfig 的文件,它会通过代理服务和令牌自动注入请求头,并在 git clone 期间替换 git URL。

kind: ConnectorClass
metadata:
  name: git
spec:
  configurations:
  - name: config
    data:
      .gitconfig: |
        [http]
            extraHeader = Authorization: Basic {{ printf ":%s" .context.token | b64enc }}
        {{- range .connectors }}
        [url "{{ .status.proxyAddress }}"]
            insteadOf = {{.spec.address}}
        {{- end }}

后续步骤