Openshift: CI/CD access imagestream from different clusters

1.3k views Asked by At

I'm configuring CI/CD in OpenShift: Dev > Stage > Prod and I'm facing some issues in Stage to reach Dev ImageStream. The whole setup looks like this:

Dev - runs Tekton pipeline and on the last task triggers BuildConfig > Build outputs new image to ImageStream > ImageStream new tag triggers DeploymentConfig > Deployment happens

Stage - I'd like to reach tag in ImageStream in Dev so I could build and deploy application in Stage.

I'm using OpenShift internal registry image-registry.openshift-image-registry.svc:port

In Stage what I've done is one Task in Pipeline to execute image-pull command:

oc import-image image-registry.openshift-image-registry.svc:port/namespace/name:version --confirm

but I get the following error:

Error from server (Forbidden): imagestreams.image.openshift.io "name" is forbidden: 
User "system:serviceaccount:namespace:sa" cannot get resource "imagestreams" in API group "image.openshift.io" in the namespace "namespace"

I've a serviceAccount sa in Dev and Stage the same which only has github-secret.

According to some examples like OpenShift documentation Cluster-role bindings:

$ oc adm policy add-cluster-role-to-user <role> <username>

Binds a given role to specified users for all projects in the cluster.

This meaning in same cluster boundaries.

and stackoverflow previous post:

oc policy add-role-to-user \
    system:image-puller system:serviceaccount:testing2:default \
    --namespace=testing1

Your project testing2 will be able to access images from project testing1 in your openshift.

This meaning between projects (good) but in the same cluster (I need different cluster)

is there a way to set a role binding to be able to reach ImageStream from a different cluster? Or a cluster role? Or is it other way to achieve this?

Any help is appreciated

1

There are 1 answers

0
TecHunter On

You need a service account with system:image-puller role in the namespace you have your image stream then get the token from this service account and use this token as a pull secret from your other cluster.

I would recommend making a mirror ImageStream in your pulling cluster to manage the link.

schema

CLUSTER_TARGET=cluster-b
CLUSTER_PULLING=cluster-a
C_B_NAMESPACE=Y
C_B_SERVICEACCOUNT_FOR_PULL=${CLUSTER_PULLING}-sa
C_B_REGISTRY=image-registry.cluster-b.com:5000

IMAGE_ID=image:tag

# in oc command for Cluster B
oc create sa $C_B_SERVICEACCOUNT_FOR_PULL -n $C_B_NAMESPACE
oc policy add-role-to-user system:image-puller system:serviceaccount:$C_B_SERVICEACCOUNT_FOR_PULL -n $C_B_NAMESPACE
SA_TOKEN=$(oc sa get-token $C_B_SERVICEACCOUNT_FOR_PULL -n $C_B_NAMESPACE)

# in oc command for Cluster A
C_A_NAMESPACE=X
SECRET="{\"auths\":{\"$C_B_REGISTRY\":{\"auth\":\"$(base64 $SA_TOKEN)\",\"email\":\"[email protected]\"}}"
oc create secret generic ${CLUSTER_TARGET}-pullsecret \
    --from-literal=.dockerconfigjson=$SECRET \
    --type=kubernetes.io/dockerconfigjson -n $C_A_NAMESPACE
oc secrets link default ${CLUSTER_TARGET}-pullsecret --for=pull -n $C_A_NAMESPACE
oc tag $C_B_REGISTRY/${C_B_NAMESPACE}/${IMAGE_ID} ${C_A_NAMESPACE}/${IMAGE_ID} --scheduled -n $C_A_NAMESPACE

# now you have a scheduled pull between A and B to your local ImageStream.
#If you want to use from another namespace in Cluster A:
oc create namespace Z
oc policy add-role-to-user system:image-puller system:serviceaccount:Z:default -n $C_A_NAMESPACE
echo "now pods in Z can reference image-registry.openshift-image-registry.svc/${C_A_NAMESPACE}/${IMAGE_ID}"

Checkout the pull secrets here For Tekton, I'm not sure but basically you need:

  • pull secret to pull from external repo
  • service account with image-puller to pull locally (hense the local mirroring image stream to make your life easier)