Docker registry mirror - docker

I'm trying to set a docker mirror to be the default mirror to pull/push images.
As per documentation I already set the file /etc/docker/daemon.json with the following:
{
"registry-mirrors": ["https://localregistry"]
}
Then I try the following:
docker login localregistry
docker pull localregistry/image:tag > it works
docker pull image:tag > doesn't work
I'm always getting "no basic auth credentials error" from the docker daemon, but from the registry log I get err.code="manifest unknown" err.detail="unknown tag"
Any idea?
I'm using docker version 19.03.08

docker login localregistry
First, I hope this is changing the name for the question, because the registry name localregistry will not work...
docker pull localregistry/image:tag > it works
The fact that this works indicates that you likely have a registry name with a . or : in the hostname. Otherwise docker would try to pull localregistry/image:tag from the localregistry user on Docker Hub.
docker pull image:tag > doesn't work
This should always work, failures should be transparent to the user if it's really a mirror of Docker Hub. What happens is it resolves that name to docker.io/library/image:tag, first tries to pull from localregistry/library/image:tag, and any error falls back to a pull from Docker Hub, and any error there finally shows to the user.
Most likely the issue is that you didn't include library as the repo name for your image in the local registry.
If you are using this to include images that don't exist on Docker Hub, then I would skip the mirror and simply refer to the mirror explicitly. Doing otherwise creates many opportunities for nonintuitive failures that aren't easy to see. E.g. a stale image can be pushed to your mirror in place of an upstream image, and Docker will stop pulling updates from upstream. And because any mirror errors fall back to Hub, if you use an image name that you have no control over upstream, someone else could take that name on Hub and begin injecting unknown or even malicious images into your server.
If this doesn't answer your question, then I'd recommend using your question with actual image names and error messages from the logs showing what specifically failed (you can mask out part of the registry name of necessary).

Related

docker login private registry succeeded docker run failed

Try to login to login to my private compagny docker (jfrog) registry, it was working ...
[rabxxxx.xxx#vmxxx]$ docker login registry.x.xx-xx-xxxxx.xx.xx.xxxx.net -u xxx
Password:
WARNING! Your password will be stored unencrypted in /home/rabxxxx.xxx/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[rabxxxx.xxx#vmxxx]$ docker run -p 8080:8080 -p 50000:50000 jenkins
Unable to find image 'jenkins:latest' locally
docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": context deadline exceeded.
See 'docker run --help'.
cat /etc/docker/daemon.json
{
"insecure-registries": ["registry.x.xx-xx-xxxxx.xx.xx.xxxx.net"],
"registry-mirrors": ["registry.x.xx-xx-xxxxx.xx.xx.xxxx.net"]
}
Please can you tell what I must check and why it's return me this
Error response from daemon: Get "https://registry-1.docker.io/v2/"
Thx
docker pull registry.x.xx-xx-xxxxx.xx.xx.xxxx.net/jenkins`
Using default tag: latest Error response from daemon: manifest for registry.repo.proxy-dev-forge.asip.hst.fluxus.net/jenkins:latest not found: manifest unknown: The named manifest is not known to the registry.
( same with /library/jenkins ]
When you docker run jenkins, docker will expand that to docker.io/library/jenkins, where docker.io is Docker Hub and the actual underlying registry server is registry-1.docker.io. When you define a mirror for that, you need to keep the repository names the same, so not registry.example.org/jenkins, but registry.example.org/library/jenkins.
In your case, it appears your mirror has neither of those, making it an incomplete mirror, assuming it's a mirror at all. But you don't really want to run the library/jenkins image anyway, since they've indicated it's deprecated with a recommendation to use the jenkins/jenkins repo instead (likely maintained by Cloudbees).
Please can you tell what I must check and why it's return me this
Error response from daemon: Get "https://registry-1.docker.io/v2/"
Mirroring in docker is a best effort. If the mirror fails for any reason, or you try to do a push instead of a pull, docker will fall back to going direct to Docker Hub.
If you only want to talk to your local registry, then you should put that registry in all your image names. This is particularly important if your mirror doesn't match Docker Hub and you make assumptions based on your local registry. In those cases, the same definition for an image on one machine may run very different code if the network has an issue or you deploy on a different machine without the mirroring specification. RedHat documented many of these risks after pushing hard to add the ability to overload the top level namespace, and we had a wave of dependency confusion attacks impact other software repositories.
Your company registry did not cache image from official registry. Try to make it auto cache or pull the jenkins image from docker official registry and push to your company registry then you can use it. I will suggest you to make the company registry auto cache, when the registry exists in your private registry, just use it, if did not exists, cache from the official registry.

Docker: get list of all the registries configured on a host

Can docker be connected to more than one registry at a time and how to figure out which registries it is currently connected too?
$ docker help | fgrep registr
login Log in to a Docker registry
logout Log out from a Docker registry
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
As you can see, there is no option to list the registries. I did find
a way by running:
$ docker system info | fgrep -i registr
Registry: https://index.docker.io/v1/
So... one regsitry at a time only? It is not like apt where one can point to more than one source? Anybody can point me to some good documentation about docker and registries?
Oddly, I search the web to no vail.
Aside from docker login, Docker isn't "connected to a registry" per se. Registry names are part of the image name, and Docker will connect to a registry server if it needs to pull an image.
As a specific example, the official Docker image for Elasticsearch is on a non-default registry run by Elastic. The example in that documentation is
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.17.0
# ^^^^^^^^^^^^^^^^^
# registry host name
You don't need to otherwise configure your system to connect to that registry, download an index, or anything else. In fact, you don't even need this docker pull command; if you directly docker run the image, Docker will download it if it doesn't have a copy locally.
The default registry is Docker Hub, docker.io, and this cannot be changed.
There are several alternate registries out there. The various public-cloud providers each have their own, and there are also several free-standing image registries. Each has its own instructions on how to set it up. You always need to include the registry name as part of the image name. The Google Container Registry has a simple name syntax, for example, so if you use GCR then you can
# build an image locally, labeled to be stored in GCR
# (this step does not contact or use GCR at all)
docker build gcr.io/my-name/my-image:tag
# authenticate to the registry
# (normally GCR has a Google-specific login sequence)
docker login https://gcr.io
# push the image
docker push gcr.io/my-name/my-image:tag
# run the image, pulling it if not present
docker run ... gcr.io/my-name/my-image:tag

Docker registry not getting used when trying to pull without the registry mirrors in the command line. Error: manifest unknown: manifest unknown

I am trying to pull docker image from Nexus repo without using the registry mirror in the command line and it is throwing an error. If I use the registry mirror in the pull it is succeeding but the image name is not I would like.
My docker version is:
Docker version 20.10.8, build 3967b7d
My nexus version is
Sonatype Nexus Repository ManagerOSS 3.31.1-01
docker system info:
Insecure Registries:
xxx.xxx.x.xxx:8083
127.0.0.0/8
Registry Mirrors:
http://xxx.xxx.x.xxx:8083/
When I run: sudo docker pull xxx.xxx.x.xxx:8083/mongo:4.2.3, it succeeds and the debug info is:
DEBU[2021-08-17T10:37:19.364681226-04:00] Calling HEAD /_ping
DEBU[2021-08-17T10:37:19.365301100-04:00] Calling POST /v1.41/images/create?fromImage=192.168.9.175%3A8083%2Fmongo&tag=4.2.3
DEBU[2021-08-17T10:37:19.367151579-04:00] Trying to pull xxx.xxx.x.xxx:8083/mongo from https://xxx.xxx.x.xxx:8083 v2
WARN[2021-08-17T10:37:19.374915464-04:00] Error getting v2 registry: Get https://xxx.xxx.x.xxx:8083/v2/: http: server gave HTTP response to HTTPS client
INFO[2021-08-17T10:37:19.374944418-04:00] Attempting next endpoint for pull after error: Get https://xxx.xxx.x.xxx:8083/v2/: http: server gave HTTP response to HTTPS client
DEBU[2021-08-17T10:37:19.374964188-04:00] Trying to pull xxx.xxx.x.xxx:8083/mongo from http://xxx.xxx.x.xxx:8083 v2
DEBU[2021-08-17T10:37:19.398630498-04:00] Fetching manifest from remote digest="sha256:92814bb60dc673bb68b6aca0b24bcb8738d7b2c267b97ce62fa92adc3746a0ea" error="<nil>" remote="192.168.9.175:8083/mongo:4.2.3"
DEBU[2021-08-17T10:37:19.429454057-04:00] Pulling ref from V2 registry: xxx.xxx.x.xxx:8083/mongo:4.2.3
When I run: sudo docker pull mongo:4.2.3 it fails to pull the image from Nexus with an error and pulls from docker.io on the next try. Debug info as below:
DEBU[2021-08-17T10:26:25.078886904-04:00] Calling HEAD /_ping
DEBU[2021-08-17T10:26:25.079306196-04:00] Calling GET /v1.41/info
DEBU[2021-08-17T10:26:25.097994642-04:00] Calling POST /v1.41/images/create?fromImage=mongo&tag=4.2.3
DEBU[2021-08-17T10:26:25.099642151-04:00] Trying to pull mongo from http://xxx.xxx.x.xxx:8083/ v2
INFO[2021-08-17T10:26:25.116000813-04:00] **Attempting next endpoint for pull after error: manifest unknown: manifest unknown**
DEBU[2021-08-17T10:26:25.116039299-04:00] Trying to pull mongo from https://registry-1.docker.io v2
DEBU[2021-08-17T10:26:25.305043063-04:00] Fetching manifest from remote digest="sha256:58b25d51baa11a85b6aedf7c4e05710d12a27ddc2883e2692e7d58527d98bd73" error="<nil>" remote="docker.io/library/mongo:4.2.3"
DEBU[2021-08-17T10:26:25.360955030-04:00] Pulling ref from V2 registry: mongo:4.2.3
DEBU[2021-08-17T10:26:25.361036645-04:00] docker.io/library/mongo:4.2.3 resolved to a manifestList object with 5 entries; looking for a unknown/amd64 match
Issue with Image name:
REPOSITORY TAG IMAGE ID CREATED SIZE
xxx.xxx.x.xxx:8083/mongo 4.2.3 97a9a3e85158 17 months ago 386MB
Any guidance on this would help.
Nexus Docker ( xxx.xxx.x.xxx:8083) is pointed to hosted Type on port 8083 and the mongo:4.2.3 is uploaded into this docker type. We ultimately want to use this in a air gapped system where there is no internet connection.
There are three things going on here:
I am trying to pull docker image from Nexus repo without using the registry mirror in the command line and it is throwing an error. If I use the registry mirror in the pull it is succeeding but the image name is not I would like.
I'm going to recommend changing your likes. :)
If you want to pull from a specific registry, then use that registry in the image name. Trying to refer to your local registry with short names is merging two different image registry namespaces, which means it's trivial to run an image from the wrong namespace and result in a security breach. This was a large issue for other package repositories (see "dependency confusion" attacks) that docker was not susceptible to because they require the registry name as part of the image name (the only exception being Docker Hub). Even RedHat who tried to get options like add-registry and block-registry into the upstream docker engine (and failed, these options only ever appeared in a RedHat specific fork) is now telling users that it was a very bad idea and now their users are exposed to security vulnerabilities they can't easily fix because removing the feature will break lots of user environments.
Next, why doesn't the pull go to your registry? Because your image name doesn't match that of Docker Hub. Official images without a username are actually under the library repository. This is typically hidden from view, but you can do things like docker pull library/alpine or even docker pull docker.io/library/alpine instead of docker pull alpine, and all 3 will be pulling from the same place.
The fix is to run
docker pull xxx.xxx.x.xxx:8083/mongo:4.2.3
docker tag xxx.xxx.x.xxx:8083/mongo:4.2.3 xxx.xxx.x.xxx:8083/library/mongo:4.2.3
docker push xxx.xxx.x.xxx:8083/library/mongo:4.2.3
The last issue I actually can't help you with, it comes from the error message you're seeing when pulling from Hub, which should work:
docker.io/library/mongo:4.2.3 resolved to a manifestList object with 5 entries; looking for a unknown/amd64 match
The unknown/amd64 is unexpected to me, typically that would be linux/amd64 so there is something unexpected with the platform you're running your commands on. If you want to get into debugging that, update your question with docker info. You can try working around that with:
docker pull --platform linux/amd64 mongo:4.2.3
to force the platform, but that still doesn't explain why it doesn't know your current platform.
I guess you are trying to set your nexus docker repository to be the default one for the machine in the sealed network.
that needs changing because of the following from docker documentation:
Tag an image for a private repository
To push an image to a private registry and not the central Docker registry you must tag it with the registry hostname and port (if needed).
$ docker tag 0e5574283393 myregistryhost:5000/fedora/httpd:version1.0
with more upfront configuration and upkeep but no changes requiered for the client machines
Is if you have a DNS server in your network you could point docker.io to your nexus host ip address and put a proxy to intercept the communication and redirect and adapt the requests as they were to the nexus docker registry
Hopes this solves your pickle :)
Update 1:
It could be that you need to also change /etc/containers/registries.conf like specified here to only or also specify your nexus docker registry.
Update 2:
Before letting Gopi give up entirely, I would suggest using Podman as an alternative to Docker. Podman is a daemon-less container engine that works by forking processes to handle each running container. It seamlessly works with docker images thanks to the OCI standard, and on top of that, the only change when using it is replacing the docker command prefix with podman since all the commands are exactly the same. Podman was created by RedHat so by default it searches RedHat repos and you can add your own too as shown in this article that I mentioned before.

Controlling access to docker registry with Sonatype nexus

In our current setup we are do proxy to entire docker hub to pull the images, but what we want is limit this proxy to only official indexes like ubuntu, apache etc.
During configuration of repository there was this option to set custom index for the repository, so my two questions are :
With this custom index option will I be able to achieve what I explained above?
If yes, then from where I should get the URL for custom index. so far I tried using https://hub.docker.com/_/centos/ for centos but it didn't worked.
Please suggest how to go about this.
Yes, you can use a custom index to limit what's available in your repo. To achieve that you have to deploy and maintain your own docker registry index service and use that when configuring your docker proxy repository.
However, an easier solution would be to use a content selector to limit what's allowed to be access via your docker proxy repository while still using Docker Hub with it's original index.
Using the simplified content selector solution is a bit hacky, but might work for you. Essentially you have to provide a whitelist (or a blacklist) in a form of a regex. The implication of this solution is that users of your registry will still be able to search for any available image, because you can keep using the Docker Hub's index for simplicity.
Create a docker proxy repository pointing to the Docker Hub.
Create a content selector with a white/black list of images, eg. path =~ '^/v2/library/(alpine|ubuntu).*$' will only allow alpine and ubuntu to be downloaded.
Create a new privilege of type Repository Content Selector.
Create a role containing the above privilege.
Create a user with an above role.
Now, the user you have created shall log into your registry, eg. $ docker login nexus.local:8085. That user will be authorised to pull both alpine and ubuntu (based on the content selector from step 2), but will fail to download anything else.
A sample succesful pull:
$ docker pull nexus.local:8085/alpine
Using default tag: latest
latest: Pulling from alpine
Digest: sha256:0873c923e00e0fd2ba78041bfb64a105e1ecb7678916d1f7776311e45bf5634b
Status: Image is up to date for nexus.local:8085/alpine:latest
A sample failed pull:
$ docker pull nexus.local:8085/postgres
Using default tag: latest
Error response from daemon: unauthorized: access to the requested resource is not authorized
we are do proxy to entire docker hub to pull the images, but what we want is limit this proxy to only official indexes like ubuntu, apache
What I did was:
Create a routing rule
Mode: ALLOW
I wanted only alpine and centos so I created two matches with:
^/v2/library/centos.*$
^/v2/library/alpine.*$
Go to configuration of the docker proxy repository
Go to Routing Rule
And pick the routing rule you created.
That way all except centos and alpine are available from that docker proxy repo. Pulling anything else results in "manigest unknown" error from docker.

Docker show current registry

In docker, how can one display the current registry info you are currently logged in? I installed docker, if I now do docker push, where does it send my images?
I spend over 30min searching this info from Google and docker docs, and couldn't find it, so I think it deserves its own question.
There's no concept of a "current" registry - full image tags always contain the registry address, but if no registry is specified then the Docker Hub is used as the default.
So docker push user/app pushes to Docker Hub. If you want to push it to a local registry you need to explicitly tag it with the registry address:
docker tag user/app localhost:5000/user/app
docker push localhost:5000/user/app
If your local registry is secured, you need to run docker login localhost:5000 but that does not change the default registry. If you push or pull images without a registry address in the tag, Docker will always use the Hub.
This issue explains the rationale.
The way docker images work is not the most obvious but it is easy to explain.
The location where your images will be sent to must be define in the image name.
When you commit an image you must name it [registry-IP]:[registry-port]/[imagepath]/[image-name]
If you already have the image created and you want to send it to the local registry you must tagged it including the registry path before you push it:
docker tag [image-name] [registry-IP]:[registry-port]/[image-name]
docker push [registry-IP]:[registry-port]/[image-name]

Resources