Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

accessing ImageStream from private repository with auth delegated to a different server requires creating two secrets instead of one #9584

Closed
jperville opened this issue Jun 27, 2016 · 91 comments
Labels
component/image kind/bug Categorizes issue or PR as related to a bug. priority/P1

Comments

@jperville
Copy link

I want to declare an ImageStream that tracks an external docker image located on an authenticated docker registry.

My use-case is:

  • build docker images for our internal applications as part of our CI pipeline
  • have the CI pipeline push the docker image to external registry (eg. gitlab) on success
  • track the docker images from many OpenShift environments (using ImageStreams)
  • redeploy all relevant applications in OpenShift when their docker image has been updated (using image change triggers)

So far, I have found no way to declare an ImageStream which uses a secret to pull the image.

I have found 2 workarounds:

  • either use S2I source builds (then what we deploy wont be the docker image build in CI)
  • either use an inline dockerfile (eg. FROM registry.internal.mycompany.com/myapp) but then how do I trigger a new build since ImageStream still cannot follow the source image).

I have also tried without success to run docker login on the Openshift hosts, in the hope that the image puller would run as same user and implicitly use my dockercfg but no success.

Version
$ oc version
oc v1.2.0
kubernetes v1.2.0-36-g4a3f9c5
Steps To Reproduce

Run the following commands (after adjusting docker image source to point to an authenticated docker registry).

$ cat <<EOF | tee is.yaml
apiVersion: v1
kind: ImageStream
metadata:
  name: myapp
spec:
  tags:
  - from:
      kind: DockerImage
      name: registry.internal.company.com/projects/myapp:latest
    name: latest
EOF
$ oc create -f is.yaml
imagestream "myapp" created
$ oc get is
NAME               DOCKER REPO                               TAGS      UPDATED
myapp              10.10.166.188:5000/gio/myapp              latest    
$ oc import-image myapp
The import completed successfully.

Name:           myapp
Created:        14 seconds ago
Labels:         <none>
Annotations:        openshift.io/image.dockerRepositoryCheck=2016-06-27T14:15:06Z
Docker Pull Spec:   10.10.166.188:5000/project/myapp

Tag Spec                                Created     PullSpec    Image
latest  registry.internal.company.com/projects/myapp:latest 13 seconds ago          import failed: Internal error occurred: Get https://registry.intern....
Current Result

Image fails to import because the image puller does not use any secret.

Expected Result

ImageStream should provide a way to specify a secret to use when pulling the image (with a mechanism similar to pullSecret in BuildConfig dockerStrategy).

@soltysh
Copy link
Contributor

soltysh commented Jun 29, 2016

@jperville have you checked our docs at https://docs.openshift.org/latest/dev_guide/managing_images.html#allowing-pods-to-reference-images-from-other-secured-registries I think that topic fits your use case. If not lemme know where you're having problems, I'll help.

@jperville
Copy link
Author

Yes @soltysh , I know how to reference docker images on other registries in my pod definitions, however I would really like my pods to be automatically redeployed if their docker images are updated; to me this is the point of the ImageStream feature.

If there is another method, how to use use it with oc new-app --docker-image=some-external-registry/image?

@soltysh
Copy link
Contributor

soltysh commented Jun 29, 2016

@jperville
Copy link
Author

jperville commented Jun 29, 2016

Thanks @soltysh . I have created the secret, however I see no way with ImageStream object or with the oc import-image command to tell explicitly "use this secret when pulling the image".

Assuming I am in the 'project' project, here are my secrets:

$ oc secrets new-dockercfg registry-login --docker-server=registry.example.com \
  --docker-username=someuser --docker-password=somepassword [email protected]
$ oc secrets add serviceaccount/default secrets/registry-login --for=pull
$ oc secrets add serviceaccount/builder secrets/registry-login
$ oc get secrets/registry-login
NAME             TYPE                      DATA      AGE
registry-login   kubernetes.io/dockercfg   1         26s

I want to create the following image Stream:

$ cat <<EOF | tee is.yaml
apiVersion: v1
kind: ImageStream
metadata:
  name: myapp
spec:
  tags:
  - from:
      kind: DockerImage
      name: registry.internal.example.com/myapp:latest
    name: latest
EOF
$ oc create -f is.yaml
$ oc get is
NAME      DOCKER REPO                       TAGS      UPDATED
myapp     10.10.87.191:5000/default/myapp   latest    

If I oc import-image the image, here is the error I get:

$ oc import-image myapp
oc describe is myapp
Name:           myapp
Created:        About a minute ago
Labels:         <none>
Annotations:        openshift.io/image.dockerRepositoryCheck=2016-06-29T12:56:33Z
Docker Pull Spec:   10.10.87.191:5000/default/myapp

Tag Spec                                Created         PullSpec    Image
latest  registry.si.perfect-memory.com/core/exchange-manager:latest About a minute ago          import failed: Internal error occurred: Get https://registry.si.per...

$ oc get is/myapp -o yaml
apiVersion: v1
kind: ImageStream
metadata:
  annotations:
    openshift.io/image.dockerRepositoryCheck: 2016-06-29T12:56:33Z
  creationTimestamp: 2016-06-29T12:56:32Z
  generation: 2
  name: myapp
  namespace: default
  resourceVersion: "639"
  selfLink: /oapi/v1/namespaces/default/imagestreams/myapp
  uid: e75ff849-3df8-11e6-8434-080027c23ce5
spec:
  tags:
  - annotations: null
    from:
      kind: DockerImage
      name: registry.internal.example.com/myapp:latest
    generation: 2
    importPolicy: {}
    name: latest
status:
  dockerImageRepository: 10.10.87.191:5000/default/myapp
  tags:
  - conditions:
    - generation: 2
      lastTransitionTime: 2016-06-29T12:56:33Z
      message: 'Internal error occurred: Get https://registry.internal.example.com/myapp/manifests/latest:
        token auth attempt for registry: https://gitlab.example.com/jwt/auth?scope=repository%3Amyapp%3Apull&service=container_registry
        request failed with status: 403 Forbidden'
      reason: InternalError
      status: "False"
      type: ImportSuccess
    items: null
    tag: latest

Note that in the error above, the registry public endpoint is https://registry.internal.example.com which delegates authentication by redirecting to https://gitlab.example.com (a different domain name but still part of the same environment); that authentication fails with 403 .

From reading https://docs.openshift.org/latest/dev_guide/managing_images.html#private-registries I was expecting the secret to be automatically used to authenticate to the external registry, but it seems it is not used.

If the secret is to be associated with a specific serviceaccount so that all image stream pulls use that secret automatically, can it be documented somewhere?

@soltysh
Copy link
Contributor

soltysh commented Jun 29, 2016

Your use-case is different from what I've been testing/working on so far. Generally all this works like this: during importing image the importer will match against all secrets, in the same project the ImageStream is defined in, based on the hostname (see here). Having said that you start with changing the secret name so that it matches the registry uri, or rather auth endpoint uri in your case. If either won't help attach me log from import operation at level 8, I'll have a look, it might be that your use-case requires more work.

@jperville
Copy link
Author

I have tried again naming the secret after the registry name (eg. `oc get secrets/registry.internal.example.com) without success.

You will find below a trace of oc import-image myapp at level 8 below (with the real host and image names):

I0629 13:43:47.224945   29105 loader.go:242] Config loaded from file /root/.kube/config
I0629 13:43:47.227135   29105 round_trippers.go:264] GET https://192.168.56.220:8443/api
I0629 13:43:47.227148   29105 round_trippers.go:271] Request Headers:
I0629 13:43:47.227152   29105 round_trippers.go:274]     Accept: application/json, */*
I0629 13:43:47.227156   29105 round_trippers.go:274]     User-Agent: oc/v1.2.0 (linux/amd64) kubernetes/b12cbb6
I0629 13:43:47.227160   29105 round_trippers.go:274]     Authorization: Bearer 5x00cpdmr9mbsO1OuoZbyQJzc9BCN5Mi2SNzW86zQss
I0629 13:43:47.279596   29105 round_trippers.go:289] Response Status: 200 OK in 52 milliseconds
I0629 13:43:47.279620   29105 round_trippers.go:292] Response Headers:
I0629 13:43:47.279626   29105 round_trippers.go:295]     Cache-Control: no-store
I0629 13:43:47.279630   29105 round_trippers.go:295]     Content-Type: application/json
I0629 13:43:47.279634   29105 round_trippers.go:295]     Date: Wed, 29 Jun 2016 13:43:47 GMT
I0629 13:43:47.279638   29105 round_trippers.go:295]     Content-Length: 136
I0629 13:43:47.279681   29105 request.go:870] Response Body: {"kind":"APIVersions","versions":["v1"],"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"192.168.56.220:443"}]}
I0629 13:43:47.279909   29105 round_trippers.go:264] GET https://192.168.56.220:8443/apis
I0629 13:43:47.279918   29105 round_trippers.go:271] Request Headers:
I0629 13:43:47.279921   29105 round_trippers.go:274]     Accept: application/json, */*
I0629 13:43:47.279925   29105 round_trippers.go:274]     User-Agent: oc/v1.2.0 (linux/amd64) kubernetes/b12cbb6
I0629 13:43:47.279929   29105 round_trippers.go:274]     Authorization: Bearer 5x00cpdmr9mbsO1OuoZbyQJzc9BCN5Mi2SNzW86zQss
I0629 13:43:47.282089   29105 round_trippers.go:289] Response Status: 200 OK in 2 milliseconds
I0629 13:43:47.282111   29105 round_trippers.go:292] Response Headers:
I0629 13:43:47.282116   29105 round_trippers.go:295]     Content-Length: 778
I0629 13:43:47.282120   29105 round_trippers.go:295]     Cache-Control: no-store
I0629 13:43:47.282124   29105 round_trippers.go:295]     Content-Type: application/json
I0629 13:43:47.282128   29105 round_trippers.go:295]     Date: Wed, 29 Jun 2016 13:43:47 GMT
I0629 13:43:47.282162   29105 request.go:870] Response Body: {"kind":"APIGroupList","groups":[{"name":"autoscaling","versions":[{"groupVersion":"autoscaling/v1","version":"v1"}],"preferredVersion":{"groupVersion":"autoscaling/v1","version":"v1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"192.168.56.220:443"}]},{"name":"batch","versions":[{"groupVersion":"batch/v1","version":"v1"}],"preferredVersion":{"groupVersion":"batch/v1","version":"v1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"192.168.56.220:443"}]},{"name":"extensions","versions":[{"groupVersion":"extensions/v1beta1","version":"v1beta1"}],"preferredVersion":{"groupVersion":"extensions/v1beta1","version":"v1beta1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"192.168.56.220:443"}]}]}
I0629 13:43:47.282985   29105 round_trippers.go:264] GET https://192.168.56.220:8443/oapi
I0629 13:43:47.282995   29105 round_trippers.go:271] Request Headers:
I0629 13:43:47.282999   29105 round_trippers.go:274]     User-Agent: oc/v1.2.0 (linux/amd64) openshift/2e62fab
I0629 13:43:47.283003   29105 round_trippers.go:274]     Authorization: Bearer 5x00cpdmr9mbsO1OuoZbyQJzc9BCN5Mi2SNzW86zQss
I0629 13:43:47.283007   29105 round_trippers.go:274]     Accept: application/json, */*
I0629 13:43:47.284778   29105 round_trippers.go:289] Response Status: 200 OK in 1 milliseconds
I0629 13:43:47.284801   29105 round_trippers.go:292] Response Headers:
I0629 13:43:47.284808   29105 round_trippers.go:295]     Cache-Control: no-store
I0629 13:43:47.284814   29105 round_trippers.go:295]     Content-Type: application/json
I0629 13:43:47.284820   29105 round_trippers.go:295]     Date: Wed, 29 Jun 2016 13:43:47 GMT
I0629 13:43:47.284826   29105 round_trippers.go:295]     Content-Length: 93
I0629 13:43:47.284856   29105 request.go:870] Response Body: {"kind":"APIVersions","apiVersion":"v1","versions":["v1"],"serverAddressByClientCIDRs":null}
I0629 13:43:47.285248   29105 round_trippers.go:264] GET https://192.168.56.220:8443/oapi/v1/namespaces/default/imagestreams/myapp
I0629 13:43:47.285263   29105 round_trippers.go:271] Request Headers:
I0629 13:43:47.285268   29105 round_trippers.go:274]     Accept: application/json, */*
I0629 13:43:47.285274   29105 round_trippers.go:274]     User-Agent: oc/v1.2.0 (linux/amd64) openshift/2e62fab
I0629 13:43:47.285279   29105 round_trippers.go:274]     Authorization: Bearer 5x00cpdmr9mbsO1OuoZbyQJzc9BCN5Mi2SNzW86zQss
I0629 13:43:47.288234   29105 round_trippers.go:289] Response Status: 200 OK in 2 milliseconds
I0629 13:43:47.288254   29105 round_trippers.go:292] Response Headers:
I0629 13:43:47.288259   29105 round_trippers.go:295]     Cache-Control: no-store
I0629 13:43:47.288263   29105 round_trippers.go:295]     Content-Type: application/json
I0629 13:43:47.288267   29105 round_trippers.go:295]     Date: Wed, 29 Jun 2016 13:43:47 GMT
I0629 13:43:47.288272   29105 round_trippers.go:295]     Content-Length: 1122
I0629 13:43:47.288302   29105 request.go:870] Response Body: {"kind":"ImageStream","apiVersion":"v1","metadata":{"name":"myapp","namespace":"default","selfLink":"/oapi/v1/namespaces/default/imagestreams/myapp","uid":"e75ff849-3df8-11e6-8434-080027c23ce5","resourceVersion":"639","generation":2,"creationTimestamp":"2016-06-29T12:56:32Z","annotations":{"openshift.io/image.dockerRepositoryCheck":"2016-06-29T12:56:33Z"}},"spec":{"tags":[{"name":"latest","annotations":null,"from":{"kind":"DockerImage","name":"registry.si.perfect-memory.com/core/exchange-manager:latest"},"generation":2,"importPolicy":{}}]},"status":{"dockerImageRepository":"10.10.87.191:5000/default/myapp","tags":[{"tag":"latest","items":null,"conditions":[{"type":"ImportSuccess","status":"False","lastTransitionTime":"2016-06-29T12:56:33Z","reason":"InternalError","message":"Internal error occurred: Get https://registry.si.perfect-memory.com/v2/core/exchange-manager/manifests/latest: token auth attempt for registry: https://gitlab.si.perfect-memory.com/jwt/auth?scope=repository%3Acore%2Fexchange-manager%3Apull\u0026service=container_registry request failed with status: 403 Forbidden","generation":2}]}]}}
I0629 13:43:47.289274   29105 request.go:555] Request Body: {"kind":"ImageStreamImport","apiVersion":"v1","metadata":{"name":"myapp","namespace":"default","resourceVersion":"639","creationTimestamp":null},"spec":{"import":true,"images":[{"from":{"kind":"DockerImage","name":"registry.si.perfect-memory.com/core/exchange-manager:latest"},"to":{"name":"latest"},"importPolicy":{}}]},"status":{}}
I0629 13:43:47.289321   29105 round_trippers.go:264] POST https://192.168.56.220:8443/oapi/v1/namespaces/default/imagestreamimports
I0629 13:43:47.289328   29105 round_trippers.go:271] Request Headers:
I0629 13:43:47.289331   29105 round_trippers.go:274]     Accept: application/json, */*
I0629 13:43:47.289335   29105 round_trippers.go:274]     User-Agent: oc/v1.2.0 (linux/amd64) openshift/2e62fab
I0629 13:43:47.289338   29105 round_trippers.go:274]     Authorization: Bearer 5x00cpdmr9mbsO1OuoZbyQJzc9BCN5Mi2SNzW86zQss
I0629 13:43:47.289342   29105 round_trippers.go:274]     Content-Type: application/json
I0629 13:43:47.698538   29105 round_trippers.go:289] Response Status: 201 Created in 409 milliseconds
I0629 13:43:47.698569   29105 round_trippers.go:292] Response Headers:
I0629 13:43:47.698577   29105 round_trippers.go:295]     Cache-Control: no-store
I0629 13:43:47.698584   29105 round_trippers.go:295]     Content-Type: application/json
I0629 13:43:47.698590   29105 round_trippers.go:295]     Date: Wed, 29 Jun 2016 13:43:47 GMT
I0629 13:43:47.698643   29105 request.go:870] Response Body: {"kind":"ImageStreamImport","apiVersion":"v1","metadata":{"name":"myapp","namespace":"default","selfLink":"/oapi/v1/namespaces/default/imagestreamimports/myapp","uid":"8113c15e-3dff-11e6-8434-080027c23ce5","resourceVersion":"639","creationTimestamp":"2016-06-29T13:43:47Z"},"spec":{"import":true,"images":[{"from":{"kind":"DockerImage","name":"registry.si.perfect-memory.com/core/exchange-manager:latest"},"to":{"name":"latest"},"importPolicy":{}}]},"status":{"import":{"metadata":{"name":"myapp","namespace":"default","uid":"e75ff849-3df8-11e6-8434-080027c23ce5","resourceVersion":"639","generation":2,"creationTimestamp":"2016-06-29T12:56:32Z","annotations":{"openshift.io/image.dockerRepositoryCheck":"2016-06-29T12:56:33Z"}},"spec":{"tags":[{"name":"latest","annotations":null,"from":{"kind":"DockerImage","name":"registry.si.perfect-memory.com/core/exchange-manager:latest"},"generation":2,"importPolicy":{}}]},"status":{"dockerImageRepository":"10.10.87.191:5000/default/myapp","tags":[{"tag":"latest","items":null,"conditions":[{"type":"ImportSuccess","status":"False","lastTransitionTime":"2016-06-29T12:56:33Z","reason":"InternalError","message":"Internal error occurred: Get https://registry.si.perfect-memory.com/v2/core/exchange-manager/manifests/latest: token auth attempt for registry: https://gitlab.si.perfect-memory.com/jwt/auth?scope=repository%3Acore%2Fexchange-manager%3Apull\u0026service=container_registry request failed with status: 403 Forbidden","generation":2}]}]}},"images":[{"status":{"metadata":{},"status":"Failure","message":"Internal error occurred: Get https://registry.si.perfect-memory.com/v2/core/exchange-manager/manifests/latest: token auth attempt for registry: https://gitlab.si.perfect-memory.com/jwt/auth?scope=repository%3Acore%2Fexchange-manager%3Apull\u0026service=container_registry request failed with status: 403 Forbidden","reason":"InternalError","details":{"causes":[{"message":"Get https://registry.si.perfect-memory.com/v2/core/exchange-manager/manifests/latest: token auth attempt for registry: https://gitlab.si.perfect-memory.com/jwt/auth?scope=repository%3Acore%2Fexchange-manager%3Apull\u0026service=container_registry request failed with status: 403 Forbidden"}]},"code":500}}]}}
The import completed successfully.

I0629 13:43:47.699732   29105 round_trippers.go:264] GET https://192.168.56.220:8443/oapi/v1/namespaces/default/imagestreams/myapp
I0629 13:43:47.699744   29105 round_trippers.go:271] Request Headers:
I0629 13:43:47.699750   29105 round_trippers.go:274]     Authorization: Bearer 5x00cpdmr9mbsO1OuoZbyQJzc9BCN5Mi2SNzW86zQss
I0629 13:43:47.699756   29105 round_trippers.go:274]     Accept: application/json, */*
I0629 13:43:47.699761   29105 round_trippers.go:274]     User-Agent: oc/v1.2.0 (linux/amd64) openshift/2e62fab
I0629 13:43:47.702488   29105 round_trippers.go:289] Response Status: 200 OK in 2 milliseconds
I0629 13:43:47.702509   29105 round_trippers.go:292] Response Headers:
I0629 13:43:47.702515   29105 round_trippers.go:295]     Cache-Control: no-store
I0629 13:43:47.702518   29105 round_trippers.go:295]     Content-Type: application/json
I0629 13:43:47.702522   29105 round_trippers.go:295]     Date: Wed, 29 Jun 2016 13:43:47 GMT
I0629 13:43:47.702526   29105 round_trippers.go:295]     Content-Length: 1122
I0629 13:43:47.702556   29105 request.go:870] Response Body: {"kind":"ImageStream","apiVersion":"v1","metadata":{"name":"myapp","namespace":"default","selfLink":"/oapi/v1/namespaces/default/imagestreams/myapp","uid":"e75ff849-3df8-11e6-8434-080027c23ce5","resourceVersion":"639","generation":2,"creationTimestamp":"2016-06-29T12:56:32Z","annotations":{"openshift.io/image.dockerRepositoryCheck":"2016-06-29T12:56:33Z"}},"spec":{"tags":[{"name":"latest","annotations":null,"from":{"kind":"DockerImage","name":"registry.si.perfect-memory.com/core/exchange-manager:latest"},"generation":2,"importPolicy":{}}]},"status":{"dockerImageRepository":"10.10.87.191:5000/default/myapp","tags":[{"tag":"latest","items":null,"conditions":[{"type":"ImportSuccess","status":"False","lastTransitionTime":"2016-06-29T12:56:33Z","reason":"InternalError","message":"Internal error occurred: Get https://registry.si.perfect-memory.com/v2/core/exchange-manager/manifests/latest: token auth attempt for registry: https://gitlab.si.perfect-memory.com/jwt/auth?scope=repository%3Acore%2Fexchange-manager%3Apull\u0026service=container_registry request failed with status: 403 Forbidden","generation":2}]}]}}
Name:           myapp
Created:        47 minutes ago
Labels:         <none>
Annotations:        openshift.io/image.dockerRepositoryCheck=2016-06-29T12:56:33Z
Docker Pull Spec:   10.10.87.191:5000/default/myapp

Tag Spec                                Created     PullSpec    Image
latest  registry.si.perfect-memory.com/core/exchange-manager:latest 47 minutes ago          import failed: Internal error occurred: Get https://registry.si.per...

@soltysh
Copy link
Contributor

soltysh commented Jun 29, 2016

Sorry for not being clear, I need logs from openshift master, since the oc import-image just invokes the import on the server and the actual importing is being done on the master.

@jperville
Copy link
Author

Have no special logs appear on the master after I run the oc import-image command.

Here is how processes look on the master VM:

[root@master ~]# ps aux | grep origin
root      20908  0.3  2.4 578588 46580 ?        Ssl  12:37   0:25 /usr/bin/openshift start node --config=/etc/origin/node/node-config.yaml --loglevel=2
root      44545  3.4  9.3 834148 176644 ?       Ssl  14:48   0:13 /usr/bin/openshift start master --config=/etc/origin/master/master-config.yaml --loglevel=8

Notice the loglevel=8 on the master.

I get some verbose messages in journalctl -f -u origin-master when the master restarts, but no mew logs are visible when running the oc import-image command.

@soltysh
Copy link
Contributor

soltysh commented Jun 29, 2016

You should see the logs like this one in the log. Without them I won't be able to dig what's going on.

@jperville
Copy link
Author

I'm sorry but I really don't see anything in the origin-master log after the booting messages (the last ones being about listing service account tokens). In neither the origin-master nor on the origin-node, both running at loglevel=8, anything shows when I try my oc import-image.

@sdodson
Copy link
Member

sdodson commented Jun 29, 2016

@jperville Assuming those processes were started by systemd units the journalctl command used should be fine.
@soltysh loglevel for systemd units is set via the OPTIONS variable in /etc/sysconfig/origin-master and restarting the service.

@jperville
Copy link
Author

@sdodson yes I have set the loglevel in /etc/sysconfig, as shown by the output of systemctl status origin-master.service below:

Redirecting to /bin/systemctl status  origin-master.service
● origin-master.service - Origin Master Service
   Loaded: loaded (/usr/lib/systemd/system/origin-master.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2016-06-29 15:50:12 UTC; 4h 8min ago
     Docs: https://github.com/openshift/origin
 Main PID: 55796 (openshift)
   CGroup: /system.slice/origin-master.service
           └─55796 /usr/bin/openshift start master --config=/etc/origin/master/master-config.yaml --loglevel=8

Still nothing interesting in the origin-master log when trying to oc import-image the image.

@sdodson
Copy link
Member

sdodson commented Jun 29, 2016

@jperville thanks for confirming, @soltysh had asked me on irc how to properly configure loglevel for systemd units, sorry if that comment was a bit out of context.

However I have an idea, is the certificate for registry.si.perfect-memory.com trusted by the master host? If not you'll need to add the insecure annotation to the image stream, I think the error message for that condition is more clear than a 500 error, but I may be mistaken. See https://docs.openshift.org/latest/dev_guide/managing_images.html#insecure-registries

@jperville
Copy link
Author

I will try tomorrow the insecure annotation; for information the private registry is using a regular domain-validated certificate which poses no problem with docker pull.

@jperville
Copy link
Author

After trying all combinations of insecureRegistry and naming the secret after the registry URL and the registry authentication endpoint, I am proud to announce success with the following combination:

  • insecureRegistry annotation: NOT set
  • name of secret: hostname of registry authentication endpoint, which may NOT be the same as the hosthame of the public registry endpoint (that is: gitlab.internal.example.com instead of repository.internal.example.com).

Thank you very much for the help @soltysh and @sdodson.

Could you add a note in the documentation about the way secrets have to be named when working with authenticated image streams? This was not easy to figure out, I didn't even know about having to name the secret in a specific manner in the first place.

Sample working image stream definition:

apiVersion: v1
kind: ImageStream
metadata:
  name: myapp
spec:
  tags:
  - from:
      kind: DockerImage
      name: registry.internal.example.com/myapp:latest
    name: latest

Command-line to make a suitably named secret and add it to the default service accounts:

for name in gitlab.internal.example.com ; do
  oc secrets new-dockercfg ${name } --docker-server=${name } \
    --docker-username=someuser --docker-password=somepassword [email protected]
  oc secrets add serviceaccount/default secrets/${name } --for=pull
  oc secrets add serviceaccount/builder secrets/${name }
done

PS: found nothing relevant in the master log about image streams, even at loglevel8.

@jperville
Copy link
Author

After successfully importing my authenticated ImageStream, I finally can oc new-app --image-stream=myapp.

Surprisingly, after oc create-ing the application, the pod will refuse to start because ErrImagePull (can't find the credentials) so I added back the secret named after the public registry hostname (here: registry.internal.example.com).

In the end, I had to duplicate my secret and add it to the default and deployer service accounts twice to get my application working.

For now, this is OK, I have a workaround, but it would be nice to be able to have a single place to declare which secret to use to pull which docker image, which would work both for ImageStream and for instanciating pods.

@soltysh
Copy link
Contributor

soltysh commented Jun 30, 2016

Could you add a note in the documentation about the way secrets have to be named when working with authenticated image streams? This was not easy to figure out, I didn't even know about having to name the secret in a specific manner in the first place.

Actually after re-testing and re-checking the code the key is created from the value passed to --docker-server, so the secret name does not matter. Apologies for the confusion, but I wonder why it didn't work for you, though :/

Secondly, I don't understand why you need to update both deployer and default serviceaccount. Since your image is used only for deployment, default should be sufficient. Again, I just verified that.

The only thing that comes to my mind and would be worth checking would be the fact that your auth is done against different server, but that shouldn't be a problem, imho.

The logs I was looking into for look like that:

I0630 13:32:16.941779    5048 credentials.go:169] Being asked for https://auth.docker.io/token, trying index.docker.io/v1 for legacy behavior
I0630 13:32:16.941800    5048 credentials.go:174] Being asked for //index.docker.io/v1, trying docker.io for legacy behavior
I0630 13:32:16.941809    5048 credentials.go:177] Unable to find a secret to match //docker.io (docker.io)

And these should be available at level 5, already. I'm not sure why you're not seeing those :(

Finally, I'd really appreciate if you could give it a try once again with above details.

@jperville
Copy link
Author

I have done more testing @soltysh and indeed the name of secret can be anything, as long as there is two secrets:

  • one with a --docker-server matching the authentication endpoint (gitlab.internal.example.com), used by the ImageStream
  • and one with a --docker-server matching the public registry endpoint (registry.internal.example.com), used when pulling pods images.

Yes, my authentication is done versus a different server (using the new integrated container registry from gitlab), hence the need for two secrets because of the two endpoints. I just wish there was a way to DRY that but for the moment duplicating the secrets is acceptable.

Also, I have tried adding the secrets only to the default service account (and not to the deployer), and it still works. Thanks for pointing that to me.

@soltysh soltysh changed the title declaring ImageStream that follows an external docker image on authenticated docker registry accessing ImageStream from private repository with auth delegated to a different server requires creating two secrets instead of one Jul 1, 2016
@soltysh soltysh added the kind/bug Categorizes issue or PR as related to a bug. label Jul 1, 2016
@soltysh
Copy link
Contributor

soltysh commented Jul 1, 2016

@jperville thanks for the detailed info, I've changed the tile of the bug and recategorized this a bit, since it seems like a bug that we should address. I'll leave this open and will try to tackle that. Thanks a lot for your report and patience!

@bparees
Copy link
Contributor

bparees commented Oct 12, 2017

I wonder if this is another flavor of https://bugzilla.redhat.com/show_bug.cgi?id=1476330

in which the secret k8s creates is not the right format for artifactory.

@zonArt Can you try the workaround suggested in https://bugzilla.redhat.com/show_bug.cgi?id=1476330#c1 ?

@zonArt
Copy link

zonArt commented Oct 12, 2017

Still the same (but not exactly). Is it a problem if different kind of secrets are linked to a serviceaccount ?
What happened now is the following:

oc import-image anewtest --from=private.docker-registry.example.com --confirm
The import completed successfully.

Name:			anewtest
Namespace:		projectname
Created:		Less than a second ago
Labels:			<none>
Annotations:		openshift.io/image.dockerRepositoryCheck=2017-10-12T15:07:09Z
Docker Pull Spec:	<none>
Unique Images:		0
Tags:			1

latest
  tagged from private.docker-registry.example.com

  ! error: Import failed (InternalError): Internal error occurred: Get https://registry-1.docker.io/v2/library/private.docker-registry.example.com/manifests/latest: unauthorized: incorrect username or password
      Less than a second ago

Notice that the --from=private.docker-registry.example.com might be wrong as it is not pointing directly to an image but rather to the root of the registry, but I made the same mistake before and the error was different so maybe I'm coming closer. After trying to put the image location, the issue remains exactly the same:

oc delete is anewtest
imagestream "anewtest" deleted
~/w/E/g/workspace (master|✚3…) $ oc import-image anewtest --from=private.docker-registry.example.com/myimage --confirm
The import completed successfully.

Name:			anewtest
Namespace:		projectname
Created:		Less than a second ago
Labels:			<none>
Annotations:		openshift.io/image.dockerRepositoryCheck=2017-10-12T15:08:01Z
Docker Pull Spec:	<none>
Unique Images:		0
Tags:			1

latest
  tagged from private.docker-registry.example.com/myimage

  ! error: Import failed (Unauthorized): you may not have access to the Docker image "private.docker-registry.example.com/myimage"
      Less than a second ago

@zonArt
Copy link

zonArt commented Oct 12, 2017

@miminar maybe you're right somehow, I just tried your suggestion and here is what I got:

curl -sI https://private.docker-registry.example.com/v2/ | grep -i www-authenticate
WWW-Authenticate: Bearer realm="https://docker-registry.example.com:443/artifactory/api/docker/private/v2/token",service="docker-registry.example.com:443"

Is that expected ? Should I add anything special in my secret to handle that ?

@zonArt
Copy link

zonArt commented Oct 12, 2017

One more thing I wanted to share is that with my existing "artifactory" secret, I have no issue pulling images within a DeploymentConfig referencing the full path to the registry (without going through an ImageStream)

@bparees
Copy link
Contributor

bparees commented Oct 12, 2017

you definitely need to specify the --from as "registry.hostname.com/namespace/repositoryname" (the same way you'd specify the image if you were doing a "docker pull", but leave off the tag.

is private.docker-registry.example.com/myimage that value? i don't see a namespace path segment which makes me suspicious. Can you share the yaml for the deploymentconfig that is working for you? Is that in the same namespace as the imagestream?

@zonArt
Copy link

zonArt commented Oct 12, 2017

yes it is the value, here is a DC which is working fine:

apiVersion: v1
kind: DeploymentConfig
metadata:
  name: docker-demo-app
  namespace: projectname
spec:
  replicas: 1
  selector:
    name: docker-demo-app
  strategy:
    resources: {}
    rollingParams:
      intervalSeconds: 1
      maxSurge: 25%
      maxUnavailable: 25%
      timeoutSeconds: 600
      updatePeriodSeconds: 1
    type: Rolling
  template:
    metadata:
      creationTimestamp: null
      labels:
        name: docker-demo-app
    spec:
      containers:
      - image: private.docker-registry.example.com/myimage
        imagePullPolicy: Always
        name: docker-demo-app
        terminationMessagePath: /dev/termination-log
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      securityContext: {}
      terminationGracePeriodSeconds: 30
  test: false
  triggers:
  - type: ConfigChange

@bparees
Copy link
Contributor

bparees commented Oct 12, 2017

@miminar well i'm out of ideas... any known issues in v1.5 (the server level @zonArt is running) w/ respect to imagestream import? Any logging we can enable to ensure the secret is being used during import?

@zonArt regarding why your deploymentconfig works, is there any chance the image already existed on the node? (in which case it didn't actually pull it using the secret)

@zonArt
Copy link

zonArt commented Oct 13, 2017

@bparees not at all it has always been working this way and as I said, when the registry is accessed/required from let say "directly" (with spec.containers.image for instance), I never had any problem pulling it. It's just recently that I tried to used ImageStream (I first thought it was only possible with the openshift internal registry though never used them before) and experienced the issue.

I really think that the secret is absolutely not taken into account as when I check our Artifactory server's logs, the GET request is made with Anonymous user.

If you can point me to other kind of logs I can look at, I'll provide you details

@miminar
Copy link

miminar commented Oct 13, 2017

@zonArt From your prior comment:

tagged from private.docker-registry.example.com

! error: Import failed (InternalError): Internal error occurred: Get https://registry-1.docker.io/v2/library/private.docker-registry.example.com/manifests/latest: unauthorized: incorrect username or password
Less than a second ago

Looks inauthentic :-)

WWW-Authenticate: Bearer realm="https://docker-registry.example.com:443/artifactory/api/docker/private/v2/token",service="docker-registry.example.com:443"

I believe the port part prevents the keyring from matching the credentials. Can you please add the entry with the port to your dockerconfig secret? Or modify your proxy/lb in front of your registry to send port-less location?

@zonArt
Copy link

zonArt commented Oct 16, 2017

@miminar I added port and protocol and nothing changed

@zonArt
Copy link

zonArt commented Oct 16, 2017

One more question:
Regarding ImageStream object proxying a private authenticated registry, once I'll manage to get the secret working (if I get it one day), will it work to push to this registry ?
This is the finality of my problem, actually, as I pull using the registry's url and not the ImageStream (during build process)

@bparees
Copy link
Contributor

bparees commented Oct 16, 2017

I'm not exactly sure what you're asking, but the secret that you use to import the image should also be usable to push to the source registry (ie if you reference the secret in a buildconfig that has your source registry as the output image target).

@zonArt
Copy link

zonArt commented Oct 18, 2017

Hi,

Regarding the the possibility to push to an ImageStream (thanks to a BuildConfig) I got no problem in doing so by setting the pushSecret parametre. The issue was on the fabric8-maven-plugin which was overriding my BC (a PR was opened to propose a fix even if I'm not hundred per cent sure it's the right approach).

Regarding the pull secret, I'm still not able to get the tags from the ImageStream but I probably miss something. If you could suggest some logs and/or config files I could provide to help diagnose the issue further, I would appreciate.

@bparees
Copy link
Contributor

bparees commented Oct 18, 2017

@miminar does image import do any useful logging that would show us if the secret is being used when we try to do the import?

@zonArt the buildconfig that successfully did the push is in the same project as the imagestream that can't import?

@zonArt
Copy link

zonArt commented Oct 18, 2017

@bparees yes it is, having this BC:

apiVersion: v1
kind: BuildConfig
metadata:
  name: buildconfig
  namespace: projectname
spec:
  output:
    pushSecret:
      name: artifactory
    to:
      kind: ImageStream
      name: imagestream
  postCommit: {}
  resources: {}
  runPolicy: Serial
  source:
    binary: {}
    type: Binary
  strategy:
    dockerStrategy: {}
    type: Docker

makes the build success without any issue (thanks to the pushSecret section)

@miminar
Copy link

miminar commented Oct 19, 2017

@miminar does image import do any useful logging that would show us if the secret is being used when we try to do the import?

@zonArt you can try to run the import cmd with --loglevel=5 which may reveal some more info.

@zonArt
Copy link

zonArt commented Oct 19, 2017

Here is the info: (I see nothing really relevant though)

The import completed successfully.

Name:                   imagename
Namespace:              projectname
Created:                47 hours ago
Labels:                 app=imagename
                        group=com.sca.fo
                        provider=fabric8
                        version=0.9.7.0-SNAPSHOT
Annotations:            openshift.io/image.dockerRepositoryCheck=2017-10-18T10:13:40Z
Docker Pull Spec:       private.docker-registry.example.com/imagename
Unique Images:          0
Tags:                   1

latest
  tagged from private.docker-registry.example.com/imagename

  ~ importing latest image ...
  ! error: Import failed (Unauthorized): you may not have access to the Docker image "private.docker-registry.example.com/imagename"
      43 hours ago

Even with loglevel 8:

I1019 11:13:20.056412   25102 loader.go:330] Config loaded from file /home/nicko/.kube/config
I1019 11:13:20.057152   25102 round_trippers.go:296] GET https://openshift.example.com:443/api
I1019 11:13:20.057176   25102 round_trippers.go:303] Request Headers:
I1019 11:13:20.057182   25102 round_trippers.go:306]     Accept: application/json, */*
I1019 11:13:20.057215   25102 round_trippers.go:306]     User-Agent: oc/v1.3.0+52492b4 (linux/amd64) kubernetes/52492b4
I1019 11:13:20.057234   25102 round_trippers.go:306]     Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXX
I1019 11:13:20.148693   25102 round_trippers.go:321] Response Status: 200 OK in 91 milliseconds
I1019 11:13:20.148748   25102 round_trippers.go:324] Response Headers:
I1019 11:13:20.149010   25102 round_trippers.go:327]     Cache-Control: no-store
I1019 11:13:20.149094   25102 round_trippers.go:327]     Content-Type: application/json
I1019 11:13:20.149260   25102 round_trippers.go:327]     Content-Length: 146
I1019 11:13:20.149301   25102 round_trippers.go:327]     Date: Thu, 19 Oct 2017 09:13:20 GMT
I1019 11:13:20.149496   25102 request.go:901] Response Body: {"kind":"APIVersions","versions":["v1"],"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"openshift.example.com:8443"}]}
I1019 11:13:20.150642   25102 round_trippers.go:296] GET https://openshift.example.com:443/apis
I1019 11:13:20.150768   25102 round_trippers.go:303] Request Headers:
I1019 11:13:20.150785   25102 round_trippers.go:306]     Accept: application/json, */*
I1019 11:13:20.150791   25102 round_trippers.go:306]     User-Agent: oc/v1.3.0+52492b4 (linux/amd64) kubernetes/52492b4
I1019 11:13:20.150795   25102 round_trippers.go:306]     Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXX
I1019 11:13:20.166422   25102 round_trippers.go:321] Response Status: 200 OK in 15 milliseconds
I1019 11:13:20.166473   25102 round_trippers.go:324] Response Headers:
I1019 11:13:20.166553   25102 round_trippers.go:327]     Cache-Control: no-store
I1019 11:13:20.166591   25102 round_trippers.go:327]     Content-Type: application/json
I1019 11:13:20.166599   25102 round_trippers.go:327]     Content-Length: 2284
I1019 11:13:20.166616   25102 round_trippers.go:327]     Date: Thu, 19 Oct 2017 09:13:20 GMT
I1019 11:13:20.166675   25102 request.go:901] Response Body: {"kind":"APIGroupList","groups":[{"name":"apps","versions":[{"groupVersion":"apps/v1beta1","version":"v1beta1"}],"preferredVersion":{"groupVersion":"apps/v1beta1","version":"v1beta1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"openshift.example.com:8443"}]},{"name":"authentication.k8s.io","versions":[{"groupVersion":"authentication.k8s.io/v1beta1","version":"v1beta1"}],"preferredVersion":{"groupVersion":"authentication.k8s.io/v1beta1","version":"v1beta1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"openshift.example.com:8443"}]},{"name":"autoscaling","versions":[{"groupVersion":"autoscaling/v1","version":"v1"}],"preferredVersion":{"groupVersion":"autoscaling/v1","version":"v1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"openshift.example.com:8443"}]},{"name":"batch","versions":[{"groupVersion":"batch/v1","version":"v1"},{"groupVersion":"batch/v2alpha1","version":"v2alpha1"}],"preferredVersion":{"groupVersion":"batch/v1","version":"v1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"openshift.example.com:8443"}]},{"name":"certificates.k8s.io","versions":[{"groupVersion":"certificates.k8s.io/v1alpha1","version":"v1alpha1"}],"preferredVersion":{"groupVersion":"certificates.k8s.io/v1alpha1","version":"v1alpha1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"openshift.example.com:8443"}]},{"name":"extensions","versions":[{"groupVersion":"extensions/v1beta1","version":"v1beta1"}],"preferredVersion":{"groupVersion":"extensions/v1beta1","version":"v1beta1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"openshift.example.com:8443"}]},{"name":"policy","versions":[{"groupVersion":"policy/v1beta1","version":"v1beta1"}],"preferredVersion":{"groupVersion":"policy/v1beta1","version":"v1beta1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"openshift.example.com:8443"}]},{"name":"storage.k8s.io","versions":[{"groupVersion":"storage.k8s.io/v1beta1","version":"v1beta1"}],"preferredVersion":{"groupVersion":"storage.k8s.io/v1beta1","version":"v1beta1"},"serverAddressByClientCIDRs":[{"clientCIDR":"0.0.0.0/0","serverAddress":"openshift.example.com:8443"}]}]}
I1019 11:13:20.171753   25102 round_trippers.go:296] GET https://openshift.example.com:443/oapi
I1019 11:13:20.172030   25102 round_trippers.go:303] Request Headers:
I1019 11:13:20.172154   25102 round_trippers.go:306]     Accept: application/json, */*
I1019 11:13:20.172237   25102 round_trippers.go:306]     User-Agent: oc/v1.3.0 (linux/amd64) openshift/3ab7af3
I1019 11:13:20.172374   25102 round_trippers.go:306]     Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXX
I1019 11:13:20.181403   25102 round_trippers.go:321] Response Status: 200 OK in 8 milliseconds
I1019 11:13:20.181458   25102 round_trippers.go:324] Response Headers:
I1019 11:13:20.181470   25102 round_trippers.go:327]     Content-Type: application/json
I1019 11:13:20.181481   25102 round_trippers.go:327]     Content-Length: 93
I1019 11:13:20.181488   25102 round_trippers.go:327]     Date: Thu, 19 Oct 2017 09:13:20 GMT
I1019 11:13:20.181497   25102 round_trippers.go:327]     Cache-Control: no-store
I1019 11:13:20.181535   25102 request.go:901] Response Body: {"kind":"APIVersions","apiVersion":"v1","versions":["v1"],"serverAddressByClientCIDRs":null}
I1019 11:13:20.181942   25102 round_trippers.go:296] GET https://openshift.example.com:443/oapi/v1/namespaces/projectname/imagestreams/imagename
I1019 11:13:20.182013   25102 round_trippers.go:303] Request Headers:
I1019 11:13:20.182031   25102 round_trippers.go:306]     Accept: application/json, */*
I1019 11:13:20.182041   25102 round_trippers.go:306]     User-Agent: oc/v1.3.0 (linux/amd64) openshift/3ab7af3
I1019 11:13:20.182051   25102 round_trippers.go:306]     Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXX
I1019 11:13:20.218828   25102 round_trippers.go:321] Response Status: 200 OK in 36 milliseconds
I1019 11:13:20.218860   25102 round_trippers.go:324] Response Headers:
I1019 11:13:20.218867   25102 round_trippers.go:327]     Content-Length: 1255
I1019 11:13:20.218873   25102 round_trippers.go:327]     Date: Thu, 19 Oct 2017 09:13:20 GMT
I1019 11:13:20.218879   25102 round_trippers.go:327]     Cache-Control: no-store
I1019 11:13:20.218884   25102 round_trippers.go:327]     Content-Type: application/json
I1019 11:13:20.219792   25102 request.go:901] Response Body: {"kind":"ImageStream","apiVersion":"v1","metadata":{"name":"imagename","namespace":"projectname","selfLink":"/oapi/v1/namespaces/projectname/imagestreams/imagename","uid":"48da075a-b31f-11e7-b4b4-005056920908","resourceVersion":"5544817","generation":61,"creationTimestamp":"2017-10-17T09:41:00Z","labels":{"app":"imagename","group":"com.sca.fo","provider":"fabric8","version":"0.9.7.0-SNAPSHOT"},"annotations":{"openshift.io/image.dockerRepositoryCheck":"2017-10-18T10:13:40Z"}},"spec":{"dockerImageRepository":"private.docker-registry.example.com/imagename","tags":[{"name":"latest","annotations":null,"from":{"kind":"DockerImage","name":"private.docker-registry.example.com/imagename"},"generation":61,"importPolicy":{},"referencePolicy":{"type":"Source"}}]},"status":{"dockerImageRepository":"private.docker-registry.example.com/imagename","tags":[{"tag":"latest","items":null,"conditions":[{"type":"ImportSuccess","status":"False","lastTransitionTime":"2017-10-17T14:02:04Z","reason":"Unauthorized","message":"you may not have access to the Docker image \"private.docker-registry.example.com/imagename\"","generation":55}]}]}}
I1019 11:13:20.220956   25102 request.go:562] Request Body: {"kind":"ImageStreamImport","apiVersion":"v1","metadata":{"name":"imagename","namespace":"projectname","resourceVersion":"5544817","creationTimestamp":null},"spec":{"import":true,"images":[{"from":{"kind":"DockerImage","name":"private.docker-registry.example.com/imagename"},"to":{"name":"latest"},"importPolicy":{}}]},"status":{}}
I1019 11:13:20.221118   25102 round_trippers.go:296] POST https://openshift.example.com:443/oapi/v1/namespaces/projectname/imagestreamimports
I1019 11:13:20.221157   25102 round_trippers.go:303] Request Headers:
I1019 11:13:20.221244   25102 round_trippers.go:306]     Accept: application/json, */*
I1019 11:13:20.221326   25102 round_trippers.go:306]     Content-Type: application/json
I1019 11:13:20.221397   25102 round_trippers.go:306]     User-Agent: oc/v1.3.0 (linux/amd64) openshift/3ab7af3
I1019 11:13:20.221404   25102 round_trippers.go:306]     Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXX
I1019 11:13:21.386356   25102 round_trippers.go:321] Response Status: 201 Created in 1164 milliseconds
I1019 11:13:21.386525   25102 round_trippers.go:324] Response Headers:
I1019 11:13:21.386586   25102 round_trippers.go:327]     Content-Type: application/json
I1019 11:13:21.386641   25102 round_trippers.go:327]     Content-Length: 1898
I1019 11:13:21.386693   25102 round_trippers.go:327]     Date: Thu, 19 Oct 2017 09:13:21 GMT
I1019 11:13:21.386729   25102 round_trippers.go:327]     Cache-Control: no-store
I1019 11:13:21.387031   25102 request.go:901] Response Body: {"kind":"ImageStreamImport","apiVersion":"v1","metadata":{"name":"imagename","namespace":"projectname","selfLink":"/oapi/v1/namespaces/projectname/imagestreamimports/imagename","uid":"c010cd09-b4ad-11e7-b4b4-005056920908","resourceVersion":"5544817","creationTimestamp":"2017-10-19T09:13:20Z"},"spec":{"import":true,"images":[{"from":{"kind":"DockerImage","name":"private.docker-registry.example.com/imagename"},"to":{"name":"latest"},"importPolicy":{}}]},"status":{"import":{"metadata":{"name":"imagename","namespace":"projectname","uid":"48da075a-b31f-11e7-b4b4-005056920908","resourceVersion":"5544817","generation":61,"creationTimestamp":"2017-10-17T09:41:00Z","labels":{"app":"imagename","group":"com.sca.fo","provider":"fabric8","version":"0.9.7.0-SNAPSHOT"},"annotations":{"openshift.io/image.dockerRepositoryCheck":"2017-10-18T10:13:40Z"}},"spec":{"dockerImageRepository":"private.docker-registry.example.com/imagename","tags":[{"name":"latest","annotations":null,"from":{"kind":"DockerImage","name":"private.docker-registry.example.com/imagename"},"generation":61,"importPolicy":{},"referencePolicy":{"type":"Source"}}]},"status":{"dockerImageRepository":"private.docker-registry.example.com/imagename","tags":[{"tag":"latest","items":null,"conditions":[{"type":"ImportSuccess","status":"False","lastTransitionTime":"2017-10-17T14:02:04Z","reason":"Unauthorized","message":"you may not have access to the Docker image \"private.docker-registry.example.com/imagename\"","generation":55}]}]}},"images":[{"status":{"metadata":{},"status":"Failure","message":"you may not have access to the Docker image \"private.docker-registry.example.com/imagename\"","reason":"Unauthorized","code":401},"tag":"latest"}]}}
I1019 11:13:21.391126   25102 round_trippers.go:296] GET https://openshift.example.com:443/oapi/v1/namespaces/projectname/imagestreams/imagename
I1019 11:13:21.391417   25102 round_trippers.go:303] Request Headers:
I1019 11:13:21.391485   25102 round_trippers.go:306]     User-Agent: oc/v1.3.0 (linux/amd64) openshift/3ab7af3
I1019 11:13:21.391537   25102 round_trippers.go:306]     Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXX
I1019 11:13:21.391594   25102 round_trippers.go:306]     Accept: application/json, */*
I1019 11:13:21.420987   25102 round_trippers.go:321] Response Status: 200 OK in 29 milliseconds
I1019 11:13:21.421122   25102 round_trippers.go:324] Response Headers:
I1019 11:13:21.421159   25102 round_trippers.go:327]     Cache-Control: no-store
I1019 11:13:21.421189   25102 round_trippers.go:327]     Content-Type: application/json
I1019 11:13:21.421215   25102 round_trippers.go:327]     Content-Length: 1255
I1019 11:13:21.421245   25102 round_trippers.go:327]     Date: Thu, 19 Oct 2017 09:13:21 GMT
I1019 11:13:21.421470   25102 request.go:901] Response Body: {"kind":"ImageStream","apiVersion":"v1","metadata":{"name":"imagename","namespace":"projectname","selfLink":"/oapi/v1/namespaces/projectname/imagestreams/imagename","uid":"48da075a-b31f-11e7-b4b4-005056920908","resourceVersion":"5544817","generation":61,"creationTimestamp":"2017-10-17T09:41:00Z","labels":{"app":"imagename","group":"com.sca.fo","provider":"fabric8","version":"0.9.7.0-SNAPSHOT"},"annotations":{"openshift.io/image.dockerRepositoryCheck":"2017-10-18T10:13:40Z"}},"spec":{"dockerImageRepository":"private.docker-registry.example.com/imagename","tags":[{"name":"latest","annotations":null,"from":{"kind":"DockerImage","name":"private.docker-registry.example.com/imagename"},"generation":61,"importPolicy":{},"referencePolicy":{"type":"Source"}}]},"status":{"dockerImageRepository":"private.docker-registry.example.com/imagename","tags":[{"tag":"latest","items":null,"conditions":[{"type":"ImportSuccess","status":"False","lastTransitionTime":"2017-10-17T14:02:04Z","reason":"Unauthorized","message":"you may not have access to the Docker image \"private.docker-registry.example.com/imagename\"","generation":55}]}]}}
The import completed successfully.

Name:			imagename
Namespace:		projectname
Created:		47 hours ago
Labels:			app=imagename
			group=com.sca.fo
			provider=fabric8
			version=0.9.7.0-SNAPSHOT
Annotations:		openshift.io/image.dockerRepositoryCheck=2017-10-18T10:13:40Z
Docker Pull Spec:	private.docker-registry.example.com/imagename
Unique Images:		0
Tags:			1

latest
  tagged from private.docker-registry.example.com/imagename

  ~ importing latest image ...
  ! error: Import failed (Unauthorized): you may not have access to the Docker image "private.docker-registry.example.com/imagename"
      43 hours ago

@miminar
Copy link

miminar commented Oct 19, 2017

@zonArt I'm sorry, the log from the master service needs to be captured from the time of import with --loglevel=5.

@zonArt
Copy link

zonArt commented Oct 19, 2017

@miminar Mmmmh ok, where are these logs located ? I'm having quite a hard time to figure it out, looks like everything gets spread in daemon.log, is that possible ? And there is nothing in daemon.log related to import-image

@miminar
Copy link

miminar commented Oct 19, 2017

@zonArt do you run the cluster containerized? If yes, you need to docker logs <name-your-master-container>. If you run the openshift-master as a service (using e.g. systemd), you will need:

$ journalctl -u atomic-openshift-master.service -f | tee image-import.log
$ oc import-image --from=...  ...`

@zonArt
Copy link

zonArt commented Oct 19, 2017

@miminar thanks, here is the linked log output:

oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.111972   49915 panics.go:76] PUT /api/v1/nodes/openshift.example.com/status: (8.546383ms) 200 [[openshift/v1.5.2+43a9be4 (linux/amd64) kubernetes/43a9be4] xxx.xx.xxx.xxx:37192]
oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.126211   49915 panics.go:76] GET /api/v1/nodes?resourceVersion=0: (1.260212ms) 200 [[openshift/v1.5.2+43a9be4 (linux/amd64) kubernetes/43a9be4] xxx.xx.xxx.xxx:37172]
oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.372724   49915 panics.go:76] GET /api: (2.46666ms) 200 [[oc/v1.3.0+52492b4 (linux/amd64) kubernetes/52492b4] xx.xx.xxx.xx:52931]
oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.378061   49915 panics.go:76] GET /apis: (2.888212ms) 200 [[oc/v1.3.0+52492b4 (linux/amd64) kubernetes/52492b4] xx.xx.xxx.xx:52931]
oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.392347   49915 panics.go:76] GET /oapi: (2.966155ms) 200 [[oc/v1.3.0 (linux/amd64) openshift/3ab7af3] xx.xx.xxx.xx:52931]
oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.400887   49915 panics.go:76] GET /api/v1/namespaces/default/services/docker-registry: (1.231769ms) 404 [[openshift/v1.5.2+43a9be4 (linux/amd64) kubernetes/43a9be4] xxx.xx.xxx.xxx:37172]
oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.402395   49915 panics.go:76] GET /api/v1/namespaces/default/services/docker-registry: (936.554µs) 404 [[openshift/v1.5.2+43a9be4 (linux/amd64) kubernetes/43a9be4] xxx.xx.xxx.xxx:37172]
oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.402904   49915 panics.go:76] GET /oapi/v1/namespaces/projectname/imagestreams/imagename: (8.08406ms) 200 [[oc/v1.3.0 (linux/amd64) openshift/3ab7af3] xx.xx.xxx.xx:52931]
oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.458501   49915 panics.go:76] GET /api/v1/namespaces/projectname/resourcequotas: (1.685423ms) 200 [[openshift/v1.5.2+43a9be4 (linux/amd64) kubernetes/43a9be4] xxx.xx.xxx.xxx:37172] 
oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.482718   49915 panics.go:76] GET /api/v1/namespaces/projectname/secrets: (7.610672ms) 200 [[openshift/v1.5.2+43a9be4 (linux/amd64) kubernetes/43a9be4] xxx.xx.xxx.xxx:37172]
oct 19 15:28:09 openshift origin-master[49915]: I1019 15:28:09.483875   49915 panics.go:76] GET /oapi/v1/namespaces/projectname/imagestreams/imagename/secrets: (9.783863ms) 200 [[openshift/v1.5.1 (linux/amd64) openshift/7b451fc] xxx.xx.xxx.xxx:37172]
oct 19 15:28:10 openshift origin-master[49915]: I1019 15:28:10.519661   49915 panics.go:76] GET /api/v1/namespaces/default/services/docker-registry: (1.552176ms) 404 [[openshift/v1.5.2+43a9be4 (linux/amd64) kubernetes/43a9be4] xxx.xx.xxx.xxx:37172]
oct 19 15:28:10 openshift origin-master[49915]: I1019 15:28:10.522288   49915 panics.go:76] GET /api/v1/namespaces/default/services/docker-registry: (1.832307ms) 404 [[openshift/v1.5.2+43a9be4 (linux/amd64) kubernetes/43a9be4] xxx.xx.xxx.xxx:37172]
oct 19 15:28:10 openshift origin-master[49915]: I1019 15:28:10.523486   49915 trace.go:61] Trace "Create /oapi/v1/namespaces/projectname/imagestreamimports" (started 2017-10-19 15:28:09.417974961 +0200 CEST):
oct 19 15:28:10 openshift origin-master[49915]: [37.877215ms] [37.877215ms] About to convert to expected version
oct 19 15:28:10 openshift origin-master[49915]: [38.019256ms] [142.041µs] Conversion done 
oct 19 15:28:10 openshift origin-master[49915]: [41.246518ms] [3.227262ms] About to store object in database
oct 19 15:28:10 openshift origin-master[49915]: [1.105178634s] [1.063932116s] Object stored in database
oct 19 15:28:10 openshift origin-master[49915]: [1.105189942s] [11.308µs] Self-link added
oct 19 15:28:10 openshift origin-master[49915]: "Create /oapi/v1/namespaces/projectname/imagestreamimports" [1.105465153s] [275.211µs] END
oct 19 15:28:10 openshift origin-master[49915]: I1019 15:28:10.523543   49915 panics.go:76] POST /oapi/v1/namespaces/projectname/imagestreamimports: (1.108359098s) 201 [[oc/v1.3.0 (linux/amd64) openshift/3ab7af3] xx.xx.xxx.xx:52931]
oct 19 15:28:10 openshift origin-master[49915]: I1019 15:28:10.538851   49915 panics.go:76] GET /api/v1/namespaces/default/services/docker-registry: (1.943446ms) 404 [[openshift/v1.5.2+43a9be4 (linux/amd64) kubernetes/43a9be4] xxx.xx.xxx.xxx:37172]
oct 19 15:28:10 openshift origin-master[49915]: I1019 15:28:10.541654   49915 panics.go:76] GET /api/v1/namespaces/default/services/docker-registry: (1.886461ms) 404 [[openshift/v1.5.2+43a9be4 (linux/amd64) kubernetes/43a9be4] xxx.xx.xxx.xxx:37172]
oct 19 15:28:10 openshift origin-master[49915]: I1019 15:28:10.542445   49915 panics.go:76] GET /oapi/v1/namespaces/projectname/imagestreams/imagename: (10.077725ms) 200 [[oc/v1.3.0 (linux/amd64) openshift/3ab7af3] xx.xx.xxx.xx:52931]

Still not sure to find any interesting info, except on the fact it tries to reach the inexistent internal registry (which doesn't really help by the way)

@zonArt
Copy link

zonArt commented Nov 8, 2017

It case it may interest anybody: I found the solution in RedHat KB:
https://access.redhat.com/solutions/3019071
I never thought you needed to also specify the port in case it runs on 443. I therefore added a comment on the above mentioned article.

Thanks again for your support

@zonArt
Copy link

zonArt commented Jan 31, 2018

@miminar

@zonArt

You should be able to overcome this by adding the auth server of the private registry to you
dockerconfig secret:

{
"private.docker-registry.example.com": { ... },
"auth.docker-registry.example.com": { /* the same as above */ }
}

If you don't know the auth server name, you can:

$ curl -I https://private.docker-registry.example.com/v2/ |& grep -i www-authenticate
Www-Authenticate: Bearer realm="https://auth.docker-registry.example.com/token",service="registry.docker.io"

Please let me know if it works for you.

This is actually working, thanks

@andutt
Copy link

andutt commented May 28, 2019

@jperville jperville thanks for posting the solution! This works for me also (y)

@nqbao
Copy link

nqbao commented Aug 1, 2019

Thanks @zonArt , this is the only solution that works for me!

@3dbrows
Copy link

3dbrows commented Jan 23, 2020

For the convenience of people finding this through a search engine, here is a condensed answer. Thank you to everyone above for the excellent guidance.

Suppose you want an ImageStream that references a secured external registry such as GitLab, and the auth for said registry is done through a different hostname e.g. gitlab.com rather than registry.gitlab.com. The following has been tested in OpenShift Online 4.2.

First we find out the exact URI of the auth server with:

$ curl -sI https://registry.gitlab.com/v2/ | grep -i Www-Authenticate

Www-Authenticate: Bearer realm="https://gitlab.com/jwt/auth",service="container_registry"

We will therefore use https://gitlab.com/jwt/auth below.

Create secret

Have a dockerconfig.json file with contents like:

{"auths":
    {
        "registry.gitlab.com":{"username":"AzureDiamond","password":"hunter2","email":"[email protected]","auth":"QXp1cmVEaWFtb25kOmh1bnRlcjI="},
        "https://gitlab.com/jwt/auth":{"username":"AzureDiamond","password":"hunter2","email":"[email protected]","auth":"QXp1cmVEaWFtb25kOmh1bnRlcjI="}
    }
}

Then do:

kubectl create secret generic regsecret --from-file=.dockerconfigjson=dockerconfig.json --type=kubernetes.io/dockerconfigjson

Important: It seems necessary to name it regsecret. I haven't had success if the secret has any other name. If anyone can think why, please say.

Set default service account to use this secret:

kubectl get serviceaccounts default -o json |
     jq 'del(.metadata.resourceVersion)'|
     jq 'setpath(["imagePullSecrets"];[{"name":"regsecret"}])' |
     kubectl replace serviceaccount default -f -

Verify:

$ kubectl get serviceaccount default -o yaml

apiVersion: v1
imagePullSecrets:
- name: regsecret
- name: default-dockercfg-ls2wj
kind: ServiceAccount
... snip ...

Create the image stream

kind: ImageStream
apiVersion: image.openshift.io/v1
metadata:
  name: foobar
spec:
  tags:
    - name: latest
      from:
        kind: DockerImage
        name: registry.gitlab.com/foobar:latest

You should now have a working ImageStream.

@miminar miminar removed their assignment Jan 24, 2020
@gwagner
Copy link

gwagner commented May 25, 2021

confirmed that the solution from @3dbrows works for registry.digitalocean.com as well:

docker login -u API_KEY -p API_KEY registry.digitalocean.com gets you the value of XXX in ~/.docker/config.json

Then modify ~/.docker/config.json to look like this:

{
	"auths": {
		"registry.digitalocean.com": {
			"auth": "XXX"
		},
		"https://api.digitalocean.com/v2/registry/auth":{
			"username":"API_KEY","password":"API_KEY","email":"[email protected]","auth":"XXX"
		}
	}
}

Then run:

oc create secret generic registry.digitalocean.com --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson
oc secrets link default registry.digitalocean.com --for=pull

Setup your image stream as shown above, and it should work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component/image kind/bug Categorizes issue or PR as related to a bug. priority/P1
Projects
None yet
Development

Successfully merging a pull request may close this issue.