How does Kubernetes pull images - docker

I have a private registry and when I try to pull images I get a DNS lookup error. This is after following the steps provided in kubernetes documentation.
I just wanted to know what steps will kubernetes perform to pull the images from a container registry. Will the kubernetes master pull the images and deploy it in the nodes or is this also scheduled to the nodes to pull the required images

No, the master won't access your registry.
The nodes will pull the images when they need it (ie. when a pod that uses the images will be scheduled)
In your case, you must check that accessing the registry is possible from the nodes (you can try a manual docker pull for that)
If your registry needs some authentification, you will also have to add some credential in your namespaces secrets (but your "DNS lookup error" does tell that it is not your actual issue)

Related

Use cache docker image for gitlab-ci

I was wondering is it possible to use cached docker images in gitlab registry for gitlab-ci?
for example, I want to use node:16.3.0-alpine docker image, can I cache it in my gitlab registry and pull it from that and speed up my gitlab ci instead of pulling it from docker hub?
Yes, GitLab's dependency proxy features allow you to configure GitLab as a "pull through cache". This is also beneficial for working around rate limits of upstream sources like dockerhub.
It should be faster in most cases to use the dependency proxy, but not necessarily so. It's possible that dockerhub can be more performant than a small self-hosted server, for example. GitLab runners are also remote with respect to the registry and not necessarily any "closer" to the GitLab registry than any other registry over the internet. So, keep that in mind.
As a side note, the absolute fastest way to retrieve cached images is to self-host your GitLab runners and hold images directly on the host. That way, when jobs start, if the image already exists on the host, the job will start immediately because it does not need to pull the image (depending on your pull configuration). (that is, assuming you're using images in the image: declaration for your job)
I'm using a corporate Gitlab instance where for some reason the Dependency Proxy feature has been disabled. The other option you have is to create a new Docker image on your local machine, then push it into the Container Registry of your personal Gitlab project.
# First create a one-line Dockerfile containing "FROM node:16.3.0-alpine"
docker pull node:16.3.0-alpine
docker build . -t registry.example.com/group/project/image
docker login registry.example.com -u <username> -p <token>
docker push registry.example.com/group/project/image
where the image tag should be constructed based on the example given on your project's private Container Registry page.
Now in your CI job, you just change image: node:16.3.0-alpine to image: registry.example.com/group/project/image. You may have to run the docker login command (using a deploy token for credentials, see Settings -> Repository) in the before_script section -- I think maybe newer versions of Gitlab will have the runner authenticate to the private Container Registry using system credentials, but that could vary depending on how it's configured.

How to get transferable docker compose stack without dockerhub

I have few docker images composed together in the stack using docker-compose.yml.
Now I want to transfer whole docker compose stack to the other host machine without uploading to the dockerhub,
And deploy it on the docker swarm.
I saw there is a thing called docker compose bundle, would that help?
If you’re deploying on a multi-host swarm (or something similar like Kubernetes or Nomad) you all but need a Docker registry. It doesn’t specifically have to be Docker Hub — quay.io, Amazon’s ECR, Google’s GCR, and self-hosted registries all work fine — but you do need to have pushed the built images somewhere where the orchestrator can retrieve them by name.
I’ve never used docker-compose bundle myself, but its documentation also notes that its operation “requires interaction with a Docker registry”.
The only real alternative is using docker save and docker load to manually move images between machines, but as a manual process it will get tedious very quickly, and you need to make sure an identical set of images are on every machine for consistency. Using a registry will be vastly easier.
The easyest way to do it is to use a Docker registry. The problem with Docker Hub is that you can only have one private registry, the rest must be public or paid.
Thankfully, there are other (free) alternatives:
Deploy your own private registry. Here is a nice tutorial where you can try it in the browser.
Use a free private registry. I personnaly use Codefresh. It can automatically build your image from a private repo (like bitbucket who has free plan too), but you can also just use it like a "simple" docker registry and push and pull your Docker images there.

Is there any way to cache loaded images on Kubernetes

I load an image (.tar) into local docker repository and then Kubernetes pulls that Image into a container. After the application is up and running I want to remove that image from local docker repository, is that right way or Kubernetes still needs that image inside docker local repository?
I have tested when deleting that image, my Application still works, but if I want to scale up or scale down, I got a problem because the image is missing.
I presume, if the Pod goes down, Kubernetes will seek for Image again in docker repository?
Is there any way to cache that Image inside Kubernetes, so no need to pull again from docker repository?
The reason why I want to delete these images right after Application run on Kubernetes is security, I don't want to leave my images inside docker repository so a user can't extract that image and export it somewhere...
I presume, if the Pod goes down, Kubernetes will seek for Image again in docker repository?
Yes.
Is there any way to cache that Image inside Kubernetes, so no need to pull again from docker repository?
When you pull an image it's cached locally by docker or your runtime manager.
The reason why I want to delete these images right after Application run on Kubernetes is security, I don't want to leave my images inside docker repository so a user can't extract that image and export it somewhere...
If you are concerned about security you shouldn't put sensitive information in the image (passwords, credentials, keys). That's why there are Kubernetes Secrets or tools like Hashicorp Vault.
If you are concerned about keeping intellectual property private you should consider using a private container image repository or private Docker registry

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.

clone docker images from local server?

I was wondering if there was a way to clone images from a local server.
The servers running containers will be hosted behind a bandwidth constrained connection. It would be great if there was a way to pull given containers for one server and then pull from that initial local server to update the containers on the remaining servers.
You could pull those images you want, give hem a new tag, and put them in your own registry.
For instance, let's say you pulled down the official registry image and stood it up at myregistry.internal.mycompany.com. Now, if you wanted to have a CentOS image available for all of your servers but didn't want to pull them all from the official repo (incurring the bandwitch charges) then you could pull a CentOS image (let's say centos:latest - docker pull centos) and then give that image a new tag, like this:
docker tag centos:latest myregistry.internal.mycompany.com/centos:latest
Now from your other servers you just pull 'myregistry.internal.mycompany.com/centos:latest'
Setting up your own repo is really easy as a docker container itself. You can pull the image and learn more at https://registry.hub.docker.com/_/registry/
I think you have a few options. If what you actually want to manage is images rather than containers:
You could set up a private Docker registry, and then push to/pull from that local repository. This may ultimately be the easiest if that is something that you want to do fairly often, because you're just using standard docker push/docker pull commands.
You could use docker save to save images on one server and docker load to load the images on another server.
If you are actually trying to move containers around:
You could use docker export on one server and docker import on another server.

Resources