How do I make my Kubernetes replication controller use a certain secret to pull an image?

3/6/2016

I have specified a certain image pull secret for my replication controller, but it doesn't appear to be applied when downloading the Docker image:

$ ~/.local/bin/kubectl --kubeconfig=/etc/kubernetes/kube.conf get events
FIRSTSEEN   LASTSEEN   COUNT     NAME                                             KIND      SUBOBJECT              REASON           SOURCE                                                        MESSAGE
8h          8s         3074      web-73na4                                        Pod       spec.containers{web}   Pulling          {kubelet ip-172-31-29-110.eu-central-1.compute.internal}      Pulling image "quay.io/aknuds1/realtime-music"
8h          5s         3074      web-73na4                                        Pod       spec.containers{web}   Failed           {kubelet ip-172-31-29-110.eu-central-1.compute.internal}      Failed to pull image "quay.io/aknuds1/realtime-music": image pull failed for quay.io/aknuds1/realtime-music, this may be because there are no credentials on this request.  details: (Error: Status 403 trying to pull repository aknuds1/realtime-music: "{\"error\": \"Permission Denied\"}")

How do I make the replication controller use the image pull secret "quay.io" when downloading the image? The replication controller spec looks as follows:

{
  "kind": "ReplicationController",
  "apiVersion": "v1",
  "metadata": {
    "name": "web",
    "labels": {
      "app": "web"
    }
  },
  "spec": {
    "replicas": 1,
    "selector": {
      "app": "web"
    },
    "template": {
      "metadata": {
        "labels": {
          "app": "web"
        }
      },
      "spec": {
        "containers": [
          {
            "name": "web",
            "image": "quay.io/aknuds1/realtime-music",
            "ports": [
              {
                "name": "http-server",
                "containerPort": 80
              }
            ]
          }
        ],
        "imagePullSecrets": [
          {
            "name": "quay.io"
          }
        ]
      }
    }
  }
}

Edit

I created the quay.io secret like this: ~/.local/bin/kubectl --kubeconfig=/etc/kubernetes/kube.conf create -f /tmp/image-pull-secret.yaml. The content of /tmp/image-pull-secret.yaml is basically like this:

apiVersion: v1
kind: Secret
metadata:
  name: quay.io
data:
  .dockercfg: <base64 encoded dockercfg>
type: kubernetes.io/dockercfg

Output from kubectl get pods web-73na4 -o yaml, in response to @PaulMorie

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/created-by: |
      {"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicationController","namespace":"default","name":"web","uid":"e1b7a3f0-e349-11e5-a136-02420a022e02","apiVersion":"v1","resourceVersion":"31503"}}
  creationTimestamp: 2016-03-06T03:16:56Z
  generateName: web-
  labels:
    app: web
  name: web-73na4
  namespace: default
  resourceVersion: "31516"
  selfLink: /api/v1/namespaces/default/pods/web-73na4
  uid: e1b89066-e349-11e5-a136-02420a022e02
spec:
  containers:
  - image: quay.io/aknuds1/realtime-music
    imagePullPolicy: IfNotPresent
    name: web
    ports:
    - containerPort: 80
      name: http-server
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-5s7kd
      readOnly: true
  dnsPolicy: ClusterFirst
  nodeName: ip-172-31-29-110.eu-central-1.compute.internal
  restartPolicy: Always
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  volumes:
  - name: default-token-5s7kd
    secret:
      secretName: default-token-5s7kd
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: null
    status: "False"
    type: Ready
  containerStatuses:
  - image: quay.io/aknuds1/realtime-music
    imageID: ""
    lastState: {}
    name: web
    ready: false
    restartCount: 0
    state:
      waiting:
        message: 'image pull failed for quay.io/aknuds1/realtime-music, this may be
          because there are no credentials on this request.  details: (Error: Status
          403 trying to pull repository aknuds1/realtime-music: "{\"error\": \"Permission
          Denied\"}")'
        reason: PullImageError
  hostIP: 172.31.29.110
  phase: Pending
  podIP: 10.2.2.3
  startTime: 2016-03-06T03:16:56Z
-- aknuds1
docker
docker-registry
kubernetes

1 Answer

3/6/2016

Update (That is what I did to use a private image):

First log in quay.io:

$ docker login quay.io
Username (username):
Password:
WARNING: login credentials saved in /Users/user/.docker/config.json
Login Succeeded

Then I created a new file (my-credentials.json) that only had the quay.io credentials that docker added in the config.json file (I realized that it had more credentials apart from the quay.io).

$ cat config.json
{
  "quay.io": {
    "auth": "xxxxxxxxxxxxxxxxxxxxx",
    "email": "user@example.com"
  }
}

After that, I generated the base64:

 $ cat ./my-credentials.json | base64
 <base64-value>

And I created the secret resource:

apiVersion: v1
kind: Secret
metadata:
  name: myregistrykey
data:
  .dockercfg: <base64-value>
type: kubernetes.io/dockercfg

$ kubectl create -f image-pull-secret.yaml

Finally, I created the pod:

{
  "kind": "ReplicationController",
  "apiVersion": "v1",
  "metadata": {
    "name": "web",
    "labels": {
      "app": "web"
    }
  },
  "spec": {
    "replicas": 1,
    "selector": {
      "app": "web"
    },
    "template": {
      "metadata": {
        "labels": {
          "app": "web"
        }
      },
      "spec": {
        "containers": [
          {
            "name": "web",
            "image": "quay.io/username/myimage",
            "ports": [
              {
                "name": "http-server",
                "containerPort": 80
              }
            ]
          }
        ],
        "imagePullSecrets": [
          {
            "name": "myregistrykey"
          }
        ]
      }
    }
  }
}

$ kubectl create -f pod.yaml

I have used myregistrykey as the name of the imagePullSecrets instead of quay.io, but I don't think that the issue is for that.


The issue seems to be due to you didn't create a secret to save your credentials.

Note that the value of the name key in the imagePullSecrets section (in your case "quay.io") should be the same that you specified in your secret resource.

-- JesusTinoco
Source: StackOverflow