Search code examples
ibm-cloudtektontekton-pipelinesdelivery-pipeline

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


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

Solution

  • 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.