Several reasons can justify the need to do local Kubernetes deployments, it can be and often is for learning reasons with a lack of resources or with limited resources, or for testing reasons where either we don't want to pay the bill for our use in the cloud, or it is not allowed to do tests on the production environment in case of on-prem deployment. as bootstrapping a Kubernetes cluster still requires considerable resources in terms of computing and time which may not be worth it when doing just simple tests.
So in this article, I show you an example of deploying a website on Kubernetes without worrying about your resources problems (in a light way).
Tools used in this lab :
Kubectl: It will be used to interact with the Kubernetes cluster. It is the Kubernetes command-line tool, which allows running commands against Kubernetes clusters. How to install kubctl
Docker: Docker Engine is an open-source containerization technology for building and containerizing applications. It will be used to containerize the website. How to install Docker
Minikube: Minikube is a local light Kubernetes, focusing on making it easy to learn and develop for Kubernetes. How to install Minikube
Once all these tools are installed, you are ready to start. Create a directory for the lab, then in this directory create another one where you will put the website files.
mkdir lab cd lab mkdir files
Once the website files are in place go back to the lab directory and let's start the containerization
In the lab directory, create the Dockerfile.
Docker builds images automatically by reading the instructions from a Dockerfile -- a text file that contains all commands, in order, needed to build a given image. A Dockerfile adheres to a specific format and set of instructions which you can find at Dockerfile reference
For this lab, we will create a dockerfile as simply as possible. Use nano Dockerfile to create the file and paste below content in it then save it.
FROM nginx COPY /files /usr/share/nginx/html
the image we will create here will use a Nginx image as a base image and will copy the website files from the /files directory to the /usr/share/nginx/html directory in the container. you can use another image if you want, like an apache image for example.
After that, we can start building the container image of our website.
Build the container with the docker build command. the dot . in the command bellow indicates the location of the dockerfile which is the current directory
docker build -t website .
Let's check if the image is available by running docker images command
We can see that our image is available, now let's try to run it and access our website
docker run -it -d -p 80:80 website
The “-d” option detaches the container from the current shell and runs in the background. as output we will have the container ID.
The -p 80:80 maps to container’s port 80 to local machine port 80.
Once this command is executed we can access our website from the browser via localhost:80
Congratulations, you just deployed a website using a container. now let's move on to the next phase of this lab by scaling up a bit and deploying our website using Kubernetes.
Deployment on Kubernetes
if not already done, start the cluster with the minikube start command.
Before you continue we need to make a small basic adjustment to minikube. By default the minikube node uses its own Docker repository that’s not connected to the Docker registry on the local machine, so without pulling, it doesn’t know where to get the image from. If we don't fix this, we'll observe an error ErrImageNeverPull. To fix this, let's use
minikube docker-env the command that outputs environment variables needed to point the local Docker daemon to the minikube internal Docker registry.
As a recommendation on the output, To point the shell to minikube's docker-daemon, run: eval $(minikube -p minikube docker-env)
After that, the image has to be rebuilt again. Once this is done, we can move on to the actual deployment.
We can create a K8s deployment either via an imperative method (by writing directly the commands in the terminal) or via a declarative method where we declare in a yaml or json manifest file the desired state of our deployment and apply it. We will proceed with the declarative method here.
We can either start writing a manifest from scratch and deal with all the possible errors, or we can save ourselves from all that and use a really cool option of kubectl and quickly generate a file ready to use or on which we can work.
So to save us from all this hustle let's generate a yaml file with the dry-run option.
kubectl create deployment website --image=website --replicas=3 --port=80 --dry-run=client -o yaml > website.yaml
Then apply the manifest file
kubectl create -f website.yaml
Now let's see if the deployment has been successful.
kubectl get po
Oh oh ! It seems we have a problem.
Kubernetes tries to pull the image specified in
the manifest, but this image is not in the minikube registry or a public Docker registry. So to fix this you have to prevent the image from being pulled from a public registry by setting the image pull policy to never. Edit the website.yaml file the in container section add imagePullPolicy: Never
then save the file then apply tby first deleting the erroneous deployment recheck again.
kubectl delete -f website.yaml kubectl create -f website.yaml kubectl get po
It should work now
Voila, it's okay now.
Next, expose the website deployment as a Kubernetes Service, specifying a port where it will be accessible with --type=NodePort and --port=80
kubectl expose deployment website --type=NodePort --port=80
Let's check whether the service is running.
kubectl get svc
Now let's retrieve a URL that is accessible outside of the container.
minikube service website --url
once the url has been obtained, it can be accessed via a browser.
Well, that's what ends this article, thank you and see you very soon