Add ImagePullSecrets to ServiceAccount

If the image repository requires authentication, you need to add the corresponding ImagePullSecrets to the ServiceAccount used by the application. This ensures that the application can successfully pull images from the private repository.

Create an ImagePullSecret

To create an ImagePullSecret, please refer to Creating a Secret for detailed steps on creating an ImagePullSecret.

Add an ImagePullSecret to a ServiceAccount

If the Pod of your application uses the ServiceAccount example, you can add the ImagePullSecret to the example ServiceAccount in the namespace where your application is located.

Edit the ServiceAccount example with patch command:

kubectl patch serviceaccount example -p '{"imagePullSecrets": [{"name": "my-registry-creds"}]}' -n <namespace>

Replace <namespace> with the namespace where your application is located, and my-registry-creds with the name of the ImagePullSecret you created.

You can verify the addition of the ImagePullSecret by describing the ServiceAccount:

kubectl describe serviceaccount example -n <namespace>
Name:                example
Namespace:           <namespace>
Labels:              <none>
Annotations:         <none>
Image pull secrets:  my-registry-creds
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>

You should see the Image pull secrets section showing the added secret.

NOTE

Note: If your Pod does not specify a ServiceAccount, it will use the default ServiceAccount in the namespace by default. You can add the ImagePullSecret to the default ServiceAccount in the same way.

Verify that imagePullSecrets are set for new Pods

When you create a new Pod that uses the ServiceAccount example, the Pod will automatically use the ImagePullSecrets specified in the ServiceAccount.

You can verify this by run the command:

kubectl get pod <pod-name> -n <namespace> -o=jsonpath='{.spec.imagePullSecrets}'

Use an ImagePullSecret with an OCI Connector

When a workload image is selected through an OCI Connector, the workload still needs an image pull Secret to authenticate to the Connector proxy. The Connector avoids distributing long-lived credentials for the original registry to workload namespaces, but this does not mean that the workload needs no Kubernetes image pull Secret. The Connector proxy Secret uses a ServiceAccount token that is authorized to access the Connector instead of the original registry password.

You can reference the Secret directly from the Pod template, or attach it to the ServiceAccount used by the workload. Either method is sufficient.

Prerequisites

Before creating the Secret, confirm the following:

  • Alauda DevOps Connectors is installed, the Connector is Ready, and enable-pod-image-pull-via-connector is enabled.
  • The OCI proxy is exposed through NodePort or Ingress, and every target node's container runtime can access the proxy address. If the proxy uses HTTP, the runtime must allow that proxy address.
  • The ServiceAccount used to create the token is authorized to access the Connector.
  • The Secret is created in the same namespace as the workload.

Create the Connector proxy Secret

Get the Connector proxy address and create a token for the workload ServiceAccount:

kubectl get connector <connector-name> -n <connector-namespace> \
  -o jsonpath='{.status.proxy.httpAddress.url}'

kubectl create token <service-account> \
  -n <workload-namespace> \
  --duration=<approved-duration>

Create the image pull Secret:

kubectl create secret docker-registry <connector-pull-secret> \
  --docker-server='<connector-proxy-host-and-port>' \
  --docker-username='u' \
  --docker-password='<service-account-token>' \
  --docker-email='<email>' \
  -n <workload-namespace>

The --docker-server value must identify the Connector proxy, not the original registry. If .status.proxy.httpAddress.url includes a Connector path, use the proxy host and port as the registry server. The command creates a Secret of type kubernetes.io/dockerconfigjson.

The token must come from a ServiceAccount that has permission to access the Connector. A token created without an approved duration is valid for approximately one hour by default. Select --duration according to your organization's security policy, and rotate or recreate the Secret before the token expires. Do not treat a manually copied token as a permanent credential or rotation mechanism.

Reference the Secret

To reference the Secret directly from the Pod template, configure:

spec:
  imagePullSecrets:
    - name: <connector-pull-secret>

Alternatively, attach the Secret to the ServiceAccount used by the workload:

kubectl patch serviceaccount <service-account> \
  -n <workload-namespace> \
  -p '{"imagePullSecrets":[{"name":"<connector-pull-secret>"}]}'

The Pod template reference and ServiceAccount inheritance are alternative valid sources. You do not need to configure both.

Verify and troubleshoot

After creating or updating the workload, verify the Connector path in this order:

  1. Check that the workload Pod template has the expected connectors.<baseDomain>/connectors annotation, including mappings for every container and init container that uses an OCI Connector.
  2. Check the image pull Secret selected by the Pod or inherited from its ServiceAccount.
  3. Check that the actual Pod image was rewritten to the Connector proxy address.
  4. Check that the Pod reaches Running (or Completed for a completed Job), and then review its Events.

Run the following commands:

kubectl get serviceaccount <service-account> -n <workload-namespace> -o yaml
kubectl get pod <pod-name> -n <workload-namespace> -o jsonpath='{.spec.imagePullSecrets}'
kubectl get pod <pod-name> -n <workload-namespace> -o jsonpath='{.spec.containers[*].image}'
kubectl get pod <pod-name> -n <workload-namespace>
kubectl describe pod <pod-name> -n <workload-namespace>

If the actual Pod image still points to the original registry, check the Connector annotation, Secret namespace and type, ServiceAccount association, and token validity first. An HTTPS error for the original HTTP registry can indicate that the workload did not enter the Connector proxy path; do not work around it by permanently allowing the original registry as an insecure registry.