Quick Start

This document will help you quickly understand how to create an OCI Connector and use it for securely accessing container registries without directly handling credentials.

TOC

Introduction

Applicable Scenarios

The OCI (Open Container Initiative) Connector provides a secure way to:

  • Access container registries (Docker Hub, Harbor, etc.) without embedding credentials in workloads
  • Centrally manage registry authentication information
  • Use a proxy mechanism to securely push and pull container images
  • Configure container tools to work with the registry proxy

This approach is particularly useful for:

  • CI/CD pipelines that need to push images to private registries
  • Multi-team environments where registry credentials need to be shared securely
  • Container build processes within Kubernetes

Estimated Reading Time

15 minutes

Notes

  • The OCI connector uses CSI driver integration to inject registry credentials securely.
  • Different container tools (Docker, Buildah, etc.) may require specific configuration for insecure registry access.
  • Configuration files generated by the connector expire after 30 minutes.

Prerequisites

  • Kubernetes cluster with Connectors system installed (Operator, Core, and OCI components). See the Installation Guide for details on installing these components.
  • kubectl configured to communicate with your cluster
  • Access credentials for a container registry (Docker Hub, Harbor, etc.)
  • Basic knowledge of Kubernetes resources

Process Overview

No.Operation StepDescription
1Create NamespaceCreate a dedicated namespace for the demonstration
2Create Registry Credentials and OCI ConnectorConfigure the connector to a container registry
3Configure RBAC PermissionsGrant appropriate permissions to use the connector
4Create a Container Build/Push JobDeploy a job that uses the connector to interact with the registry
5Verify OperationCheck that the registry operation completed successfully

Steps to Operate

Step 1: Create Namespace

Create a dedicated namespace for this demonstration:

kubectl create ns oci-connector-demo

Step 2: Create Registry Credentials and OCI Connector

Create both the Secret containing registry credentials and the OCI Connector resource. For more detailed information about creating and configuring connectors, please refer to the Connectors Quick Start Guide.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: registry-auth
  namespace: oci-connector-demo
type: cpaas.io/distribution-registry-token
stringData:
  username: your-username  # Replace with your registry username
  password: your-token     # Replace with your registry password/token
---
apiVersion: connectors.alauda.io/v1alpha1
kind: Connector
metadata:
  name: oci-connector
  namespace: oci-connector-demo
spec:
  connectorClassName: oci
  address: "https://index.docker.io"  # Replace with your registry address
  auth:
    name: tokenAuth
    secretRef:
      name: registry-auth
EOF

Verify that the connector is in "Ready" status:

kubectl get connector oci-connector -n oci-connector-demo

The output should show:

NAME           CLASS   ADDRESS               READY   AGE
oci-connector  oci     https://index.docker.io True    1m

Step 3: Create a Container Build/Push Job

Create a ConfigMap with a sample Dockerfile:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: dockerfile
  namespace: oci-connector-demo
data:
  Dockerfile: |
    FROM scratch
    LABEL maintainer="example@example.com"
    WORKDIR /app
    ENV APP_VERSION="1.0.0"
EOF

Create a job that uses the connector to build and push a container image:

cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: Job
metadata:
  name: image-build
  namespace: oci-connector-demo
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: buildkit
        image: moby/buildkit:v0.11.0
        securityContext:
          privileged: true
        env:
        - name: BUILDKITD_FLAGS
          value: "--config /etc/buildkit/buildkitd.toml"
        command:
        - /bin/sh
        - -c
        args:
        - |
          set -ex
          buildctl-daemonless.sh \
          build \
          --progress=plain \
          --frontend=dockerfile.v0 \
          --local context=/workspace \
          --local dockerfile=/workspace \
          --output type=image,name=c-oci-connector.oci-connector-demo.svc.cluster.local/your-username/test-image:v1,push=true
        volumeMounts:
        - name: dockerfile
          mountPath: /workspace
        - name: docker-config
          mountPath: /root/.docker
        - name: buildkitd-config
          mountPath: /etc/buildkit
      volumes:
      - name: dockerfile
        configMap:
          name: dockerfile
      - name: docker-config
        csi:
          readOnly: true
          driver: connectors-csi
          volumeAttributes:
            connector.name: "oci-connector"
            configuration.names: "docker-config"
      - name: buildkitd-config
        csi:
          readOnly: true
          driver: connectors-csi
          volumeAttributes:
            connector.name: "oci-connector"
            configuration.names: "buildkitd"
EOF

Key parameters in the volume definition:

  • connector.name: The name of your OCI connector
  • configuration.names: Specifies which configuration to generate from the OCI ConnectorClass:
    • "docker-config": Generates authentication config (config.json) needed for any registry operations
    • "buildkitd": Generates BuildKit daemon config for insecure registry access
  • mountPath: Specifies where the configuration file should be mounted in the container:
    • "/root/.docker" for Docker authentication configuration
    • "/etc/buildkit" for BuildKit configuration

Step 4: Verify Operation

Check the job's logs to confirm the image was built and pushed successfully:

kubectl logs -f job/image-build -n oci-connector-demo

You should see the build process completing and the image being pushed to the registry.

Expected Results

After successfully completing all steps, you will see:

  1. An OCI connector in "Ready" status:

    NAME           CLASS   ADDRESS               READY   AGE
    oci-connector  oci     https://index.docker.io True    5m
  2. A successful image build and push operation in the job logs, showing that the image was pushed to the registry via the connector proxy.

  3. The connector's proxy address in the status field:

    status:
      proxy:
        httpAddress:
          url: http://c-oci-connector.oci-connector-demo.svc.cluster.local

How It Works

The OCI Connector works by:

  1. Creating a proxy service that sits between your workloads and the container registry
  2. Injecting authentication information when requests pass through the proxy
  3. Providing configuration files for container tools to work with the proxy

The connector generates three types of configuration files that serve different purposes:

  1. docker-config: Creates a config.json file with the necessary authentication information to access the proxy service

    {
      "auths": {
        "<proxy-address>": {
          "auth": "<auth-token>"
        }
      }
    }

    This configuration is essential for authentication and is required for all container operations.

  2. buildkitd: Creates a buildkitd.toml file that configures BuildKit to trust the insecure registry proxy

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

    This is only needed when using BuildKit to build and push images.

To examine the generated configuration:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: inspect-config
  namespace: oci-connector-demo
spec:
  containers:
  - name: inspector
    image: busybox
    command: ["sleep", "3600"]
    volumeMounts:
    - name: docker-config
      mountPath: /mnt/docker
  volumes:
  - name: docker-config
    csi:
      readOnly: true
      driver: connectors-csi
      volumeAttributes:
        connector.name: "oci-connector"
        configuration.names: "docker-config"
EOF

View the generated configuration:

kubectl exec -it inspect-config -n oci-connector-demo -- cat /mnt/docker/config.json

Troubleshooting

If your container operation fails, check the following:

  1. Connector Status: Ensure the connector is in "Ready" state:

    kubectl describe connector oci-connector -n oci-connector-demo
  2. RBAC Permissions: Verify the RoleBinding is correctly configured.

  3. Registry Access: Confirm that the credentials have access to the specified repository.

  4. Configuration Mounting: Ensure the configuration volumes are correctly mounted in the job.

  5. Proxy Address: Make sure you're using the correct proxy address from status.proxy.httpAddress.url in your image references.

Next Steps

After successfully pushing your first image using the OCI Connector, you can:

  • Use the connector in Kubernetes workloads to pull private images
  • Integrate with CI/CD pipelines to build and push images
  • Configure different container tools to work with the connector
  • Use the connector with different registry services