My story is:
1, I create a spring-boot project, with a Dockerfile inside.
2, I successfully create the docker image IN LOCAL with above docker file.
3, I have a minikube build a K8s for my local.
4, However, when I try to apply the k8s.yaml, it tells me that there is no such docker image. Obviously my docker app search in public docker hub, so what I can do?
Below is my dockerfile
FROM openjdk:17-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
expose 8080
ENTRYPOINT ["java","-jar","/app.jar"]
Below is my k8s.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pkslow-springboot-deployment
spec:
selector:
matchLabels:
app: springboot
replicas: 2
template:
metadata:
labels:
app: springboot
spec:
containers:
- name: springboot
image: cicdstudy/apptodocker:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
labels:
app: springboot
name: pkslow-springboot-service
spec:
ports:
- port: 8080
name: springboot-service
protocol: TCP
targetPort: 8080
nodePort: 30080
selector:
app: springboot
type: NodePort
In Kubernetes there is no centralized built-in Container Image Registry exist.
Depending on the container runtime in the K8S cluster nodes you have, it might search first dockerhub to pull images.
Since free pull is not suggested or much allowed by Dockerhub now, it is suggested to create an account for development purposes. You will get 1 private repository and unlimited public repository which means that whatever you pushed to public repositories, there somebody can access it.
If there is no much concern on Intellectual Property issues, you can continue that free account for development purposes. But when going production you need to change that account with a service/robot account.
Create an Account on DockerHub https://id.docker.com/login/
Login into your DockerHub account locally on the machine where you are building your container image
docker login --username=yourhubusername --email=youremail#company.com
Build,re-tag and push your image once more (go to the folder where Dockerfile resides)
docker build -t mysuperimage:v1 .
docker tag mysuperimage:v1 yourhubusername/mysuperimage:v1
docker push yourhubusername/mysuperimage:v1
Create a secret for image registry credentials
kubectl create secret docker-registry regcred --docker-server=https://index.docker.io/v1/ --docker-username= --docker-password= --docker-email=
Create a service account for deployment
kubectl create serviceaccount yoursupersa
Attach secret to the service account named "yoursupersa"
kubectl patch serviceaccount yoursupersa -p '{"imagePullSecrets": [{"name": "docker-registry"}]}'
Now create your application as deployment resource object in K8S
kubectl create deployment mysuperapp --image=yourhubusername/mysuperimage:v1 --port=8080
Then patch your deployment with service account which has attached registry credentials.(which will cause for re-deployment)
kubectl patch deployment mysuperapp -p '{"spec":{"template":{"spec":{"serviceAccountName":"yoursupersa"}}}}'
the last step is expose your service
kubectl expose deployment/mysuperapp
Then everything is awesome! :)
if you just want to be able to pull images from your local computer with minikube you can use eval $(minikube docker-env) this leads to all docker related commands being used on your minikube cluster to use your local docker daemon. so a pull will first look in your hosts local images instead of hub.docker.io.
more information can be found here
Related
I got problem with connecting my k3s cluster to GitLab Docker Registry.
On cluster I got created secret in default namespace like this
kubectl create secret docker-registry regcred --docker-server=https://gitlab.domain.tld:5050 --docker-username=USERNAME --docker-email=EMAIL --docker-password=TOKEN
Then in Deployment config I got this secret included, my config:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
labels:
app.kubernetes.io/name: "app"
app.kubernetes.io/version: "1.0"
namespace: default
spec:
template:
metadata:
labels:
app: app
spec:
imagePullSecrets:
- name: regcred
containers:
- image: gitlab.domain.tld:5050/group/appproject:1.0
name: app
imagePullPolicy: Always
ports:
- containerPort: 80
But the created pod is still unable to pull this image.
There is still error message of:
failed to authorize: failed to fetch anonymous token: unexpected status: 403 Forbidden
Can you help me, where the error may be?
If I try connect to this GitLab registry via secrets above on local docker, it working fine, docker login is right, also a pulling of this image.
Thanks
To pull from a private container registry on Gitlab you must first create a Deploy Token similar to how the pipeline or similar "service" would access it. Go to the repository then go to Settings -> Repository -> Deploy Tokens
Give the deploy token a name, and a username(it says optional but we'll be able to use this custom username with the token) and make sure it has read_registry access. That is all it needs to pull from the registry. If you later need to push then you would need write_registry. Once you click create deploy token it will show you the token be sure to copy it as you won't see it again.
Now just recreate your secret in your k8s cluster.
kubectl create secret docker-registry regcred --docker-server=<private gitlab registry> --docker-username=<deploy token username> --docker-password=<deploy token>
Make sure to apply the secret to the same namespace as your deployment that is pulling the image.
[See Docs] https://docs.gitlab.com/ee/user/project/deploy_tokens/#gitlab-deploy-token
I am trying to create a Kubernetes deployment from local docker images. And using imagePullPolicy as Never such that Kubernetes would pick it up from local docker image imported via tar.
Environment
SingleNodeMaster # one node deployment
But Kubernetes always trying to fetch the private repository although local docker images are present.
Any pointers on how to debug and resolve the issue such that Kubernetes would pick the images from the local docker registry? Thank you.
Steps performed
docker load -i images.tar
docker images # displays images from myprivatehub.com/nginx/nginx-custom:v1.1.8
kubectl create -f local-test.yaml with imagepullPolicy as Never
Error
Pulling pod/nginx-custom-6499765dbc-2fts2 Pulling image "myprivatehub.com/nginx/nginx-custom:v1.1.8"
Failed pod/nginx-custom-6499765dbc-2fts2 Error: ErrImagePull
Failed pod/nginx-custom-6499765dbc-2fts2 Failed to pull image "myprivatehub.com/nginx/nginx-custom:v1.1.8": rpc error: code = Unknown desc = failed to pull and unpack image "myprivatehub.com/nginx/nginx-custom:v1.1.8": failed to resolve reference "myprivatehub.com/nginx/nginx-custom:v1.1.8": failed to do request: Head "https://myprivatehub.com/v2/nginx/nginx-custom/manifests/v1.1.8": dial tcp: lookup myprivatehub.com: no such host
docker pull <imagename>
Error response from daemon: Get https://myprivatehub.com/v2/: dial tcp: lookup myprivatehub.com on 172.31.0.2:53: no such host
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-custom
namespace: default
spec:
selector:
matchLabels:
run: nginx-custom
replicas: 5
template:
metadata:
labels:
run: nginx-custom
spec:
containers:
- image: myprivatehub.com/nginx/nginx-custom:v1.1.8
imagePullPolicy: Never
name: nginx-custom
ports:
- containerPort: 80
This happens due to container runtime being different than docker. I am using containerd , after switching container runtime to docker , it started working.
This is to update another approach that can be taken to achieve the similar result. In this case, one can use Docker Registry. Docker Registry Doc
We can create a Docker registry on the machine where Kubernetes is running and docker too is installed. One of the easiest way to achieve the same can be done as following:
Create a local private docker registry. If the registry:2 image is not present, then it would download it and run.
sudo docker run -d -p 5000:5000 --restart=always --name registry registry:2
Build the image or load the image from a tar as required. For my example, i am creating it to add it to the local repository.
sudo docker build -t coolapp:v1 .
Once the build is done, create a tag with this image such that it represents a host and a port.
sudo docker tag coolapp:v1 localhost:5000/coolapp:v1
Push the new tag to the local private registry
sudo docker push localhost:5000/coolapp:v1
Now in the Kubernetes YAML, we can specify the deployment as following:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mycoolapp
spec:
replicas: 1
selector:
matchLabels:
app: mycoolapp
template:
metadata:
labels:
app: mycoolapp
spec:
containers:
- name: mycoolapp
image: localhost:5000/coolapp:v1
ports:
- containerPort: 3000
and we apply the YAML
sudo kubectl apply -f deployment.yaml
Once this is done, we will be able to see that Kubernetes has pulled the image from the local private repository and is running it.
Let's say I have a deployment that looks something like this:
apiVersion: v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
template:
kind: Pod
metadata: myapp-pod
labels:
apptype: front-end
containers:
- name: nginx
containers: <--what is supposed to go here?-->
How do I properly build a container using an existing Dockerfile without having to push a build image up to Docker hub?
Kubernetes can't build images. You all but are required to use an image registry. This isn't necessarily Docker Hub: the various public-cloud providers (AWS, Google, Azure) all have their own registry offerings, there are some third-party ones out there, or you can run your own.
If you're using a cloud-hosted Kubernetes installation (EKS, GKE, ...) the "right" way to do this is to push your built image to the corresponding image registry (ECR, GCR, ...) before you run it.
docker build -t gcr.io/my/image:20201116 .
docker push gcr.io/my/image:20201116
containers:
- name: anything
image: gcr.io/my/image:20201116
There are some limited exceptions to this in a very local development environment. For example, if you're using Minikube as a local Kubernetes installation, you can point docker commands at it, so that docker build builds an image inside the Kubernetes context.
eval $(minikube docker-env)
docker build -t my-image:20201116 .
containers:
- name: anything
image: my-image:20201116 # matches `docker build -t` option
imagePullPolicy: Never # since you manually built it inside the minikube Docker
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#creating-a-deployment check this out.
Make sure you give a good read at the documentation :)
I have successfully built Docker images and ran them in a Docker swarm. When I attempt to build an image and run it with Docker Desktop's Kubernetes cluster:
docker build -t myimage -f myDockerFile .
(the above successfully creates an image in the docker local registry)
kubectl run myapp --image=myimage:latest
(as far as I understand, this is the same as using the kubectl create deployment command)
The above command successfully creates a deployment, but when it makes a pod, the pod status always shows:
NAME READY STATUS RESTARTS AGE
myapp-<a random alphanumeric string> 0/1 ImagePullBackoff 0 <age>
I am not sure why it is having trouble pulling the image - does it maybe not know where the docker local images are?
I just had the exact same problem. Boils down to the imagePullPolicy:
PC:~$ kubectl explain deployment.spec.template.spec.containers.imagePullPolicy
KIND: Deployment
VERSION: extensions/v1beta1
FIELD: imagePullPolicy <string>
DESCRIPTION:
Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always
if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
More info:
https://kubernetes.io/docs/concepts/containers/images#updating-images
Specifically, the part that says: Defaults to Always if :latest tag is specified.
That means, you created a local image, but, because you use the :latest it will try to find it in whatever remote repository you configured (by default docker hub) rather than using your local. Simply change your command to:
kubectl run myapp --image=myimage:latest --image-pull-policy Never
or
kubectl run myapp --image=myimage:latest --image-pull-policy IfNotPresent
I had this same ImagePullBack error while running a pod deployment with a YAML file, also on Docker Desktop.
For anyone else that finds this via Google (like I did), the imagePullPolicy that Lucas mentions above can also be set in the deployment yaml file. See the spec.templage.spec.containers.imagePullPolicy in the yaml snippet below (3 lines from the bottom).
I added that and my app deployed successfully into my local kube cluser, using the kubectl yaml deploy command: kubectl apply -f .\Deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-deployment
labels:
app: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web-app
image: node-web-app:latest
imagePullPolicy: Never
ports:
- containerPort: 3000
You didn't specify where myimage:latest is hosted, but essentially ImagePullBackoff means that I cannot pull the image because either:
You don't have networking setup in your Docker VM that can get to your Docker registry (Docker Hub?)
myimage:latest doesn't exist in your registry or is misspelled.
myimage:latest requires credentials (you are pulling from a private registry). You can take a look at this to configure container credentials in a Pod.
I am running kubeadm alpha version to set up my kubernates cluster.
From kubernates , I am trying to pull docker images which is hosted in nexus repository.
When ever I am trying to create a pods , It is giving "ImagePullBackOff" every time. Can anybody help me on this ?
Detail for this are present in https://github.com/kubernetes/kubernetes/issues/41536
Pod definition :
apiVersion: v1
kind: Pod
metadata:
name: test-pod
labels:
name: test
spec:
containers:
- image: 123.456.789.0:9595/test
name: test
ports:
- containerPort: 8443
imagePullSecrets:
- name: my-secret
You need to refer to the secret you have just created from the Pod definition.
When you create the secret with kubectl create secret docker-registry my-secret --docker-server=123.456.789.0 ... the server must exactly match what's in your Pod definition - including the port number (and if it's a secure one then it also must match up with the docker command line in systemd).
Also, the secret must be in the same namespace where you are creating your Pod, but that seems to be in order.
I received similar error while launching containers from the amazon ECR registry. The issue was that I didn;t mention the exact "Image URI" location in deployment file.