https://microk8s.io/docs/registry-images So images. A container is based on an image. You can pull these images in from the outside world, e.g. from a Public, Private registry, or from the built-in registry. For this copy the "hello-python" directory we created in Part 2 into one called "hello-python3", you can delete the .tar file in there for now, its not needed. Push Image into Kubernetes Image Repository So in the earlier steps, we basically injected the image straight into the Kubernetes image cache, so not using the built-in registry. Now we’ll do the same but this time working with the Kubernetes registry, so firstly lets enable it if not already done: microk8s enable registry Right, so the registry is now available at localhost:32000, when we upload an image we need to tag it accordingly with localhost:32000/your-image-name. So let’s inject the image we used before, but this time tag with another name: docker build . -t localhost:32000/hello-python:registry Build the image:
Wait for the image to upload into the docker images library.
Now we want to push this into the Kubernetes registry:
At this point the image is then within the Kubernetes image repository and ready to be used in your application deployments. Deploy Container using Registry Image So lets create a cheeky application, create a deployment.yaml and service.yaml as follows:
And an service.yaml:
Oh look, we have an error, excellent. So let's look at why this happened. So so far, we’ve deployed the image registry on the master node, the worker nodes have no configuration for them to reach this registry at the moment. Now if we were to have built and pushed this registry in when we would have only had one node, then the only place the pod could have run would have been on the master node, which can get to the Kubernetes image registry. To fix this we need to complete the next section, as you can see the “ImagePullBackOff” basically means that the pods has been scheduled to a node which is unable to download the image. If we look at the log for the pod: "hello-python3-5fdcb55ccd-dvpnx" we see:
So we make the change to the deployment.yaml:
And then deploy again with: kubectl apply -f deployment.yaml We still are having problems. If we run this on the node where the pod is trying to start: tail -f /var/log/syslog | grep hello We see: Aug 2 14:48:49 k8s-worker-02 microk8s.daemon-kubelet[1324]: E0802 14:48:49.023084 1324 pod_workers.go:191] Error syncing pod 9490b872-87cd-48c9-90b6-952c7dc7b452 ("hello-python3-7b6df7676b-vt4v5_default(9490b872-87cd-48c9-90b6-952c7dc7b452)"), skipping: failed to "StartContainer" for "hello-python3" with ErrImagePull: "rpc error: code = Unknown desc = failed to pull and unpack image \"192.168.1.164:32000/hello-python:registry\": failed to resolve reference \"192.168.1.164:32000/hello-python:registry\": failed to do request: Head \"https://192.168.1.164:32000/v2/hello-python/manifests/registry\": http: server gave HTTP response to HTTPS client" So this exact error is described here: https://microk8s.io/docs/registry-private under the section “Configuring MicroK8s”. We need to make some changes to the configuration of the MicroK8s nodes. Allowing Insecure Registry Edit the file: /var/snap/microk8s/current/args/containerd-template.toml on ONLY the worker nodes, so in our case k8s-worker-01 and k8s-worker-02, right at the bottom of the file look for the following section: [plugins] -> [plugins."io.containerd.grpc.v1.cri".registry] -> [plugins."io.containerd.grpc.v1.cri".registry.mirrors]: Create a new section underneath to match the IP address of your master node where the image repository lies for example the below, in my case the k8s-master node is on 192.168.1.164.
The Microk8s documentation then talks about just restarting microk8s with a “microk8s stop” followed by a “microk8s start”, however I found this was not enough, so rebooted the worker and master nodes, once restarted, i attempted the deployment again: kubectl apply -f deployment.yaml Then a quick check on the progress:
As you can see it is there, the pod is running on the k8s-worker-01 node, lets have a quick look at the logs: cat /var/log/syslog | grep hello-python3 Now this time we see all is well:
kubectl apply -f service.yaml And have a quick check:
Yes, there it is: http://192.168.1.22:8080, so lets try to access it: Good stuff, we’ve done it. Doing it All Again! Well Why Not!? Lets run this command: microk8s kubectl create deployment hello-python4 --image=192.168.1.164:32000/hello-python:registry That will just create a deployment of that image as a new container and then schedule it on one of the worker nodes:
Cool, there it is “hello-python4-55bdb58666-sk8wg” working as expected on the k8s-worker-01 node, thats good that proves that the registry is working. Verifying the Registry Image is Used Okay so lets copy the existing directory: cp -r hello-python hello-python5 Now within there, if there is an image .tar file delete it, we don’t need it anymore. Let’s edit the application to show we are getting a new image. cd hello-python5/app Edit the “main.py”, and add something to the line saying “Hello from Python”, e.g. “This is a test page using Hello-python5 application!” Build the image, and tag it as the image name for the Kubernetes image registry when put into the docker image library.
docker images
Okay so now get docker to push it into the Kubernetes image library. docker push localhost:32000/hello-python5 Now edit the deployment.yaml and service.yaml, and where you have “hello-python3…” change it to “hello-python5”, including the image location in the deployment.yaml file, so we make sure we use our new image! So now deploy the service and deployment with:
If we run a quick: “tail -f /var/log/syslog | grep hello-python5” we can see the container image being deployed and started.
kubectl get services Gives us: NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
There it is running at http://192.168.1.23:8080, so let’s give it a connect in a browser: And you can see we really are running the expected image, because its the hello-python5 one as we wanted. Using an External Public Registry (e.g. DockerHub) https://microk8s.io/docs/registry-public Create an account at Docker Hub. You’ll also need to create a repository. On your master node run: Docker login Enter your logon details. Now lets create a new image and push it up into the Docker Hub. First make a copy of the existing application image definition.
Make a change to the image’s main.py, so you know its something different for when you run it. Build the image locally, then we’ll push it up. docker build . -t geekmungus/private:hello-python6 Where “geekmungus” is my DockerHub username, “private” is the repository name and “hello-python6” is the tag (in this case the name of the application).
Okay now we can push that repository up. docker push geekmungus/private Cool, and there it is: Let’s delete the local copy to ensure we only ever use the pulled version, when we now do a deployment. docker images
docker image rm 1dfc3b05a3ca So now that image has gone and is not available locally, so it should pull from DockerHub now when we refer to it. Change the deployment.yaml and service.yaml in the hello-python6/app folder, so everywhere where it did say “hello-python5” it now says “hello-python6”. Then ensure you put the image name in as: geekmungus/private:hello-python6
Watching the logs I got this error:
https://stackoverflow.com/questions/56642311/microk8s-cannot-pull-from-private-registry https://github.com/ubuntu/microk8s/issues/512 So run this to create a secret to be used when you connect to the external public repository. kubectl create secret docker-registry regcred --docker-username=<yourdockerhubusername> --docker-password=<password> --docker-email=<youremailaddress> And then we see:
We now have a secret called "regcred" we can use in our deployments. Now within the deployment.yaml, you need to refer to it so your deployment.yaml will end up looking like this:
Kubectl apply -f deployment.yaml It might take a little while because it will be downloading the image from dockerhub, but then:
Finally deploy the service: kubectl apply -f service.yaml
And we are done! We can see the application running on that port in our browser and it is the image we expected to see. |
Linux and Nagios >