How do I access a private Container Registry from IBM Cloud Delivery Pipeline (Tekton, dockerconfigjson)

723 Views Asked by At

I am trying to use a container image from a private container registry in one of my tasks.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: echo-hello-world
spec:
  steps:
    - name: echo
      image: de.icr.io/reporting/status:latest
      command:
        - echo
      args:
        - "Hello World"

But when I run this task within an IBM Cloud Delivery Pipeline (Tekton) the image can not be pulled

 message: 'Failed to pull image "de.icr.io/reporting/status:latest": rpc error: code = Unknown desc = failed to pull and unpack image "de.icr.io/reporting/status:latest": failed to resolve reference "de.icr.io/reporting/status:latest": failed to authorize: failed to fetch anonymous token: unexpected status: 401 Unauthorized'

I read several tutorials and blogs, but so far couldn't find a solution. This is probably what I need to accomplish, so that the IBM Cloud Delivery Pipeline (Tekton) can access my private container registry: https://tekton.dev/vault/pipelines-v0.15.2/auth/#basic-authentication-docker

So far I have created a secret.yaml file in my .tekton directory:

apiVersion: v1
kind: Secret
metadata:
 name: basic-user-pass
 annotations:
   tekton.dev/docker-0: https://de.icr.io # Described below
type: kubernetes.io/basic-auth
stringData:
  username: $(params.DOCKER_USERNAME)
  password: $(params.DOCKER_PASSWORD)

I am also creating a ServiceAccount

apiVersion: v1
kind: ServiceAccount
metadata:
 name: default-runner
secrets:
 - name: basic-user-pass

And in my trigger definition I telling the pipeline to use the default-runner ServiceAccount:

apiVersion: tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
  name: theTemplateTrigger
spec:
  resourcetemplates:
  - apiVersion: tekton.dev/v1beta1
    kind: PipelineRun
    metadata:
      name: pipelinerun-$(uid)
    spec:
      serviceAccountName: default-runner
      pipelineRef:
        name: hello-goodbye
3

There are 3 best solutions below

0
On BEST ANSWER

I found a way to pass my API key to my IBM Cloud Delivery Pipeline (Tekton) and the tasks in my pipeline are now able to pull container images from my private container registry.

This is my working trigger template:

apiVersion: tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
  name: theTemplateTrigger
spec:
  params:
    - name: pipeline-dockerconfigjson
      description: dockerconfigjson for images used in .pipeline-config.yaml
      default: "eyJhdXRocyI6e319" # ie. {"auths":{}} base64 encoded
  resourcetemplates:
    - apiVersion: v1
      kind: Secret
      data:
        .dockerconfigjson: $(tt.params.pipeline-dockerconfigjson)
      metadata:
        name: pipeline-pull-secret
      type: kubernetes.io/dockerconfigjson      
    - apiVersion: tekton.dev/v1beta1
      kind: PipelineRun
      metadata:
        name: pipelinerun-$(uid)
      spec:
        pipelineRef:
          name: hello-goodbye
        podTemplate:
          imagePullSecrets:
            - name: pipeline-pull-secret

It first defines a parameter called pipeline-dockerconfigjson:

  params:
    - name: pipeline-dockerconfigjson
      description: dockerconfigjson for images used in .pipeline-config.yaml
      default: "eyJhdXRocyI6e319" # ie. {"auths":{}} base64 encoded

The second part turns the value passed into this parameter into a Kubernetes secret:

    - apiVersion: v1
      kind: Secret
      data:
        .dockerconfigjson: $(tt.params.pipeline-dockerconfigjson)
      metadata:
        name: pipeline-pull-secret
      type: kubernetes.io/dockerconfigjson

And this secret is then pushed into the imagePullSecrets field of the PodTemplate.

The last step is to populate the parameter with a valid dockerconfigjson and this can be accomplished within the Delivery Pipeline UI (IBM Cloud UI).

To create a valid dockerconfigjson for my registry de.icr.io I had to use the following kubectl command:

kubectl create secret docker-registry mysecret \
 --dry-run=client \
 --docker-server=de.icr.io  \
 --docker-username=iamapikey \                     
 --docker-password=<MY_API_KEY> \
 --docker-email=<MY_EMAIL> \
 -o yaml

and then within the output there is a valid base64 encoded .dockerconfigjson field.

0
On
1
On

The secret you created (type basic-auth) would not allow Kubelet to pull your Pods images.

The doc mentions those secrets are meant to provision some configuration, inside your tasks containers runtime. Which may then be used during your build jobs, pulling or pushing images to registries.

Although Kubelet needs some different configuration (eg: type dockercfg), to authenticate when pulling images / starting containers.