Image cannot be pulled due to unauthorized with private container registry
Closed this issue · 6 comments
Issue
OS: Macos
K8s cluster version: 1.21
When we start a build then the following error is reported as kubernetes event within the Build pod created
Describe(demo/buildpack-quarkus-buildrun-1-5zzzb-pod-8v64x) ─────────
Normal Pulling 5m4s (x3 over 5m48s) kubelet Pulling image "registry.local:5000/redhat-builder/quarkus"
Warning Failed 5m4s (x3 over 5m48s) kubelet Failed to pull image "registry.local:5000/redhat-builder/quarkus": rpc error:
code = Unknown desc = failed to pull and unpack image "registry.local:5000/redhat-builder/quarkus:latest":
failed to resolve reference "registry.local:5000/redhat-builder/quarkus:latest":
unexpected status code [maniests latest[]: 401 Unauthorized
Normal BackOff 25s (x23 over 5m47s) kubelet Back-off pulling image "registry.local:5000/redhat-builder/quarkus"
K8s files
apiVersion: shipwright.io/v1alpha1
kind: ClusterBuildStrategy
metadata:
name: quarkus-buildpacks
spec:
buildSteps:
- name: prepare
image: docker.io/paketobuildpacks/builder:full
imagePullPolicy: Always
securityContext:
runAsUser: 0
capabilities:
add:
- CHOWN
command:
- chown
args:
- -R
- "1000:1000"
- /tekton/home
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 250m
memory: 65Mi
- name: build-and-push
image: registry.local:5000/redhat-builder/quarkus
imagePullPolicy: Always
securityContext:
runAsUser: 1000
runAsGroup: 1000
command:
- /bin/bash
args:
- -c
- |
set -euo pipefail
mkdir /tmp/cache /tmp/layers
/cnb/lifecycle/creator \
'-app=$(params.shp-source-context)' \
-cache-dir=/tmp/cache \
-layers=/tmp/layers \
-report=/tmp/report.toml \
'$(params.shp-output-image)'
# Store the image digest
grep digest /tmp/report.toml | tr -d ' \"\n' | sed s/digest=// > "$(results.shp-image-digest.path)"
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 250m
memory: 65Mi
---
apiVersion: shipwright.io/v1alpha1
kind: Build
metadata:
name: buildpack-quarkus-build
namespace: demo
spec:
source:
url: https://github.com/snowdrop/quarkus-tap-petclinic
contextDir: .
strategy:
name: quarkus-buildpacks
kind: ClusterBuildStrategy
output:
image: registry.local:5000/quarkus-petclinic
credentials:
name: registry-creds
---
apiVersion: shipwright.io/v1alpha1
kind: BuildRun
metadata:
name: buildpack-quarkus-buildrun-1
namespace: demo
spec:
buildRef:
name: buildpack-quarkus-build
Creds to access the local registry have been created
REGISTRY_HOST="registry.local:5000" REGISTRY_USER=admin REGISTRY_PASSWORD=snowdrop
kubectl create secret docker-registry registry-creds -n demo \
--docker-server="${REGISTRY_HOST}" \
--docker-username="${REGISTRY_USER}" \
--docker-password="${REGISTRY_PASSWORD}"
I guess we lack at least some documentation on this, but to analyze:
- To pull private images, one needs an imagePullSecret.
- ImagePullSecrets can be defined at different places:
- On the pod, that's not under the control of the build strategy author
- On the ServiceAccount that is referenced in the BuildRun, that's under the control of the build user, but that user does not necessarily know which images a build strategy needs
- In the Kubernetes node.
- What complicates the situation is that we support ClusterBuildStrategies which therefore can reference an image in a cluster-scoped resource, but secrets (and service accounts) are always namespaced. For the namespaced build strategy, we could probably easily add an
imagePullSecrets
field that we propagate to the Pod.
Actually, in my local cluster for my own stuff, I use a namespace build strategy and have the imagePullSecret defined in the service account that all BuildRuns are using.
In Code Engine, we have the secret in the node.
Tekton's ClusterTasks probably face the same issue, but I have never checked if they have creative ideas for this problem.
To immediately help you @cmoulliard. You seem to be working in a namespace called demo
. You could add the secret to the default ServiceAccount as imagePullSecret, as you don't specify any ServiceAccount information in the BuildRun.
To immediately help you @cmoulliard. You seem to be working in a namespace called
demo
. You could add the secret to the default ServiceAccount as imagePullSecret, as you don't specify any ServiceAccount information in the BuildRun.
Thanks. will do that and try :-)
Actually, in my local cluster for my own stuff, I use a namespace build strategy and have the imagePullSecret defined in the service account that all BuildRuns are using.
Can you show me with an example where you specify that ? @SaschaSchwarze0
Can you show me with an example where you specify that ? @SaschaSchwarze0
Fix using -->
apiVersion: shipwright.io/v1alpha1
kind: BuildRun
metadata:
name: buildpack-quarkus-buildrun-1
namespace: demo
spec:
serviceAccount:
name: registry-creds
generate: false
buildRef:
name: buildpack-quarkus-build
My idea was that you continue to NOT specify a ServiceAccount in the BuildRun and then do the following in the default Service Account of your namespace:
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
namespace: demo
imagePullSecrets:
- name: registry-creds
Alternatively you can also create another ServiceAccount where you reference the imagePullSecret, but you'll then have to reference it in all BuildRuns.
Alternatively you can also create another ServiceAccount where you reference the imagePullSecret, but you'll then have to reference it in all BuildRuns.
This is what I did and that works