OCI Connector

OCI Connector 是一个与平台无关的连接器,允许你连接到任意 OCI Registry,例如 Docker Hub、Harbor 等。你可以使用 OCI Connector 在 CI/CD 流水线中安全访问私有 OCI 仓库,或者在容器化工作负载中执行 OCI 操作,而无需提供凭证。此外,你还可以集中管理 OCI 访问配置,避免在每个 namespace 中重复配置 OCI 凭证。

本文将介绍:

  • OCI Registry 的访问要求
  • 如何基于 OCI Connector 类型创建 OCI Connector
  • OCI Connector 的代理和配置能力

OCI Registry 要求

要访问的 OCI Registry 必须满足以下条件:

  1. 接口实现要求:

  2. 认证方式要求:

基于 OCI Connector 类型创建 OCI Connector

以下是创建基础 OCI Connector 的方法:

apiVersion: connectors.alauda.io/v1alpha1
kind: Connector
metadata:
  name: dockerhub-demo
spec:
  connectorClassName: oci
  address: https://index.docker.io
  auth:
    name: tokenAuth

spec.connectorClassName

使用常量值 oci

描述

你可以通过 annotations 字段为 OCI Connector 添加描述信息。

  • cpaas.io/description:OCI Connector 的描述。

例如:

apiVersion: connectors.alauda.io/v1alpha1
kind: Connector
metadata:
  name: dockerhub-demo
  annotations:
    cpaas.io/description: "Connect to Docker Hub for team public repository access"

地址

spec.address 指定 OCI Registry 的访问地址,例如:https://index.docker.io

认证

OCI Connector 支持以下认证类型:

  • tokenAuth:基于 Token 的认证(可选)

使用基于 Token 的认证

例如:

apiVersion: connectors.alauda.io/v1alpha1
kind: Connector
metadata:
  name: dockerhub-demo
spec:
  connectorClassName: oci
  address: https://index.docker.io
  # . . .
  auth:
    name: tokenAuth
    secretRef:
      name: oci-secret
---
apiVersion: v1
stringData:
  password: your-password
  username: your-username
kind: Secret
metadata:
  name: oci-secret
type: cpaas.io/distribution-registry-token

如果目标 OCI Registry 不需要认证,可以省略认证信息。配置示例如下:

apiVersion: connectors.alauda.io/v1alpha1
kind: Connector
metadata:
  name: dockerhub-demo
spec:
  connectorClassName: oci
  address: https://index.docker.io
  auth:
    name: tokenAuth

所需 Token 权限

配置的 Token 所需权限取决于你打算在 Pods/Pipelines 中如何使用它。

例如:

  • 镜像拉取操作:如果你只需要使用该连接器拉取镜像,那么 Token 只需要对目标仓库具有读取权限。
  • 镜像拉取和推送操作:如果你需要使用该连接器推送镜像,那么 Token 必须同时具有目标仓库的读取和写入权限。换句话说,Token 应允许你既能从 registry 拉取,也能向其推送。

出于安全最佳实践,我们建议创建仅具有最小所需权限的 Token。若需要额外权限,可以创建单独的 Connector,并为其配置权限更高的 Secret,同时使用 namespace 隔离来控制哪些用户可以访问每个 Connector。

代理和配置

为了让客户端在无需凭证的情况下访问 OCI 仓库,OCI Connector 类型提供了一个代理服务器,用于自动注入认证信息。

有权访问该连接器的客户端可以使用此代理服务器访问 OCI 仓库,而无需在客户端侧配置凭证。

为简化使用,OCI Connector 类型提供了可通过 CSI 挂载到 Pod 中的配置信息。在 Pod 中执行 OCI 操作时,可以自动使用代理服务来完成 OCI 操作。

代理

代理地址

创建 Connector 时,系统将:

  1. 自动为代理创建一个 Service。
  2. 将代理地址记录到 status.proxy.httpAddress 字段中。

你可以使用此代理地址执行镜像推送和拉取操作。

例如:

apiVersion: connectors.alauda.io/v1alpha1
kind: Connector
metadata:
  name: dockerhub-demo
  namespace: default
spec:
  address: https://index.docker.io
  auth:
    name: tokenAuth
    secretRef:
      name: dockerhub-demo
  connectorClassName: oci
status:
  conditions:
  # . . .
  proxy:
    httpAddress:
      url: http://c-dockerhub-demo.default.svc.cluster.local/namespaces/oci-connector-demo/connectors/oci-connector

正向代理

你可以通过 CSI 将代理信息挂载到 Pod 中,然后通过环境变量或配置文件使用该代理信息。

volumes:
- name: proxyconfig
  csi:
    readOnly: true
    driver: connectors-csi
    volumeAttributes:
      connector.name: "harbor"

然后,在执行容器操作之前,通过环境变量或配置文件使用代理信息。

export http_proxy=$(cat /{mount-path}/http.proxy)
export https_proxy=$(cat /{mount-path}/https.proxy)
export HTTP_PROXY=$http_proxy
export HTTPS_PROXY=$https_proxy
export no_proxy=localhost,127.0.0.1
export NO_PROXY=$no_proxy
echo "Using proxy: http_proxy=$http_proxy, https_proxy=$https_proxy, no_proxy=$no_proxy"

反向代理

使用反向代理时,需要将目标镜像地址修改为代理地址。

示例: index.docker.io/test/abc:v1 → c-dockerhub-demo.default.svc.cluster.local/namespaces/oci-connector-demo/connectors/oci-connector/test/abc:v1

并将凭证配置文件挂载到 Pod 中,同时在 insecure-registries 中配置代理地址。

基于 OCI Connector 类型创建的 OCI Connector 提供以下配置:

docker-config:OCI CLI 等 buildkit、buildah 所需的凭证配置。

  • 提供 config.json 配置文件。
  • 包含访问代理所需的认证信息。

例如:

// config.json

{
  "auths": {
      "<proxy address of the connector>": {
          "auth": "<authentication information required to access the connector proxy>"
      }
  }
}

buildkitd:BuildKit Daemon 所需的配置信息。

  • 提供 buildkitd.toml 配置文件。
  • 在配置文件中,当前 connector 默认会被设置为 insecure-registries

例如:

insecure-entitlements = [ "network.host", "security.insecure" ]
[registry."<proxy address of the connector>"]
  http = true

你可以使用 connectors-csi 将这些配置信息挂载到 Pod 中,并结合代理能力,实现无需 Secret 的镜像推送或拉取操作。

更多内容