The module lifecycle stage: Preview

The module has requirements for installation

To use images from a custom registry inside the DKP cluster where it is deployed, use the methods described below.

Prerequisites

Access to the registry is provided via Ingress, which exposes the service at payload-registry.${PUBLIC_DOMAIN}. The certificate for HTTPS is issued automatically according to the certificate management settings.

When using a custom Certificate Authority (CA) or another CA that cannot be verified by cluster nodes, you must add the appropriate configuration for an additional registry. Otherwise, cluster nodes will not be able to pull images due to certificate verification errors.

Using images for authentication with Kubernetes tokens

For more information about this authentication method, see the section Authentication with Kubernetes tokens.

To use Kubernetes tokens as imagePullSecrets:

  1. Create a ServiceAccount and grant it access using PayloadRepositoryAccess (see RBAC and PayloadRepositoryAccess). The ServiceAccount must opt in to image-pull token issuance with the payload-registry.deckhouse.io/allow-image-pull: "true" annotation:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: my-pull-sa
      annotations:
        payload-registry.deckhouse.io/allow-image-pull: "true"

    Without the allow-image-pull annotation the controller refuses to issue a token for the ServiceAccount: this prevents a user who can only create Secrets from referencing a more privileged ServiceAccount and obtaining its token.

  2. Create a Secret to be used as imagePullSecrets:

    apiVersion: v1
    kind: Secret
    metadata:
      name: my-pull-secret
      annotations:
        payload-registry.deckhouse.io/service-account.name: my-pull-sa
        # Optional: token lifetime for this secret, in seconds (minimum 600).
        # If omitted, the module default is used.
        # payload-registry.deckhouse.io/token-ttl: "3600"
    type: kubernetes.io/dockerconfigjson
    data:
      # Temporary value that will be overwritten with actual credentials.
      .dockerconfigjson: eyJhdXRocyI6e319

    The specified Secret will be automatically deleted when the corresponding ServiceAccount is deleted.

    If the ServiceAccount referenced in the annotation does not exist (for example, the Secret was created in the wrong namespace), the controller does not delete the Secret: it keeps it and records a Warning Event (ServiceAccountNotFound) on it explaining why. Inspect with d8 k describe secret <name>.

  3. Verify that the data in the Secret has been updated:

    d8 k get secret my-pull-secret -o yaml

    Example output:

    apiVersion: v1
    kind: Secret
    metadata:
      name: my-pull-secret
      annotations:
        payload-registry.deckhouse.io/expires-at: "2026-03-06T02:14:19Z"
        payload-registry.deckhouse.io/hash: e3ba7bd9aeae15fdbce8ae1eed05f26732ebd82e4563115d34f335702071929e
        payload-registry.deckhouse.io/service-account.name: my-pull-sa
        payload-registry.deckhouse.io/service-account.uid: f847810d-bcdd-42b8-9f95-2c2d8d10bc8c
    type: kubernetes.io/dockerconfigjson
    data:
      # Value filled with actual credentials.
      .dockerconfigjson: ...

    The presence of these annotations indicates that the credentials for accessing the registry have been successfully added and will be kept up to date.

    By default, data in the Secret is valid for 24 hours from the last update. The lifetime can be set per secret with the payload-registry.deckhouse.io/token-ttl annotation (in seconds, minimum 600). The expiration time is shown in the payload-registry.deckhouse.io/expires-at annotation. Data is updated some time before the expiration.

  4. Add imagePullSecrets to the cluster component and specify the image:

    apiVersion: v1
    kind: Pod
    metadata:
      name: ubuntu
    spec:
      containers:
        - name: ubuntu
          image: payload-registry.${PUBLIC_DOMAIN}/project-1/ubuntu:latest
      imagePullSecrets:
        - name: my-pull-secret