{"id":12662,"date":"2020-04-15T03:33:32","date_gmt":"2020-04-15T07:33:32","guid":{"rendered":"https:\/\/qxf2.com\/blog\/?p=12662"},"modified":"2020-04-15T03:33:32","modified_gmt":"2020-04-15T07:33:32","slug":"deploying-a-web-application-using-kubernetes","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/deploying-a-web-application-using-kubernetes\/","title":{"rendered":"Deploying a web application using Kubernetes"},"content":{"rendered":"<p>This post outlines the steps I followed in deploying a website in Kubernetes.<\/p>\n<p>Kubernetes is a platform for automating deployment, scaling and management of our application across a cluster of hosts. It works with a different range of container tools and the one we will be using here is the popular Docker.<\/p>\n<p>I have divided the process into 3 main sections:<\/p>\n<ol>\n<li>Creating a Docker image for the website<\/li>\n<li>Build the Docker image and upload it to Docker hub<\/li>\n<li>Deploy the Docker image on Kubernetes<\/li>\n<\/ol>\n<p>I will be using the example of <a href=\"https:\/\/qainterview.pythonanywhere.com\/\" target=\"_blank\" rel=\"noopener\">Factorial application<\/a>\u00a0&#8211; a simple web application created by Qxf2 that can be used as a QA interview tool.<\/p>\n<p>Note: Skip to section 3 if you already have a Docker image of your website.<\/p>\n<hr \/>\n<h4><span>Creating a Docker image for the website<\/span><\/h4>\n<p>First, we need a Docker image that will be used while creating the Kubernetes deployment.<br \/>\nYou can directly download the Docker image for the Factorial app from our Docker Hub repository using the following command:<\/p>\n<pre lang=\"bash\">docker pull sravantit25\/factorial-qxf2:0.1<\/pre>\n<p>Below I have listed the steps to create the Docker file from scratch.<\/p>\n<p>I have Windows Home version, so had 2 options to use Docker : <a href=\"https:\/\/docs.docker.com\/toolbox\/toolbox_install_windows\/\" target=\"_blank\" rel=\"noopener\">Docker Toolbox<\/a> or create a Linux AWS instance (free one) and install <a href=\"https:\/\/docs.docker.com\/engine\/install\/ubuntu\/\" target=\"_blank\" rel=\"noopener\">docker<\/a> on it. I used the later approach.\u00a0Images that are built using Docker are portable across operating systems.<\/p>\n<p>Building the Docker file includes the following steps:<\/p>\n<p style=\"text-align: left;\"><span>a. Installing essential tools &#8211; We will need python, pip and git<\/span><\/p>\n<pre lang=\"bash\">RUN apt-get update &amp;&amp; apt-get install -y \\\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0curl \\\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0python \\\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0python-setuptools \r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0python-pip git<\/pre>\n<p><span>b. Clone the repository. It is present at\u00a0<a href=\"https:\/\/github.com\/qxf2\/qa-interview-web-application\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/qxf2\/qa-interview-web-application<\/a><br \/>\n<\/span><\/p>\n<pre lang=\"bash\">RUN git clone https:\/\/github.com\/qxf2\/qa-interview-web-application.git<\/pre>\n<p><span>c. Putting it all together<br \/>\nWORKDIR helps to define the working directory we want to run the command from.\u00a0Using CMD will start the server after the docker image is completely built.<br \/>\n<\/span><\/p>\n<pre lang=\"bash\">WORKDIR qa-interview-web-application\r\npip install -r requirements.txt\r\nCMD python qa_interview.py<\/pre>\n<p>The final docker file will look like this:<\/p>\n<pre lang=\"bash\">#Docker file for Factorial application\r\nFROM ubuntu\r\nMAINTAINER Qxf2 Services\r\n\r\n#Install essential tools\r\nRUN apt-get update &amp;&amp; apt-get install -y \\\r\ncurl \\\r\npython \\\r\npython-setuptools \\\r\npython-pip git\r\n\r\n#Clone the Factorial application\r\nRUN git clone https:\/\/github.com\/qxf2\/qa-interview-web-application.git\r\n\r\nWORKDIR qa-interview-web-application\r\nRUN pip install -r requirements.txt\r\n\r\n#Start the server\r\nCMD python qa_interview.py<\/pre>\n<p>Save the above final file as Dockerfile in your working or any other directory.<\/p>\n<hr \/>\n<h4>Build the docker image and upload it to docker hub<\/h4>\n<p><span>a. Build the docker image. Make sure you are in the same directory where the Dockerfile is present.<\/span><\/p>\n<pre lang=\"bash\">docker build .<\/pre>\n<p><span>b. Upload the docker image to docker hub<\/span><br \/>\nI created a repo in my account and used this repo to tag the docker image.<\/p>\n<div>\n<pre lang=\"bash\">docker tag 634a7b88de75 sravantit25\/factorial-qxf2:0.1<\/pre>\n<p>c. push the image to the hub<\/p>\n<\/div>\n<pre lang=\"bash\">docker push sravantit25\/factorial-qxf2<\/pre>\n<hr \/>\n<h4>Deploy the website docker image on Kubernetes<\/h4>\n<p>Applications need to be packaged into one of the supported container formats in order to be deployed on Kubernetes. We will now create a kubernetes pod where we will deploy our docker image. A pod is the basic execution unit of a Kubernetes application and is a group of one or more containers tied together for the purposes of administration and networking. A Kubernetes Deployment checks on the health of your Pod and restarts the pod\u2019s Container if it terminates. Deployments are the recommended way to manage the creation and scaling of Pods.<\/p>\n<p>a. Installation and set up on Windows<br \/>\nWe will use minikube, which makes it easy to run Kubernetes locally. It runs a\u00a0single-node Kubernetes cluster in a virtual machine on your computer.<br \/>\nInstall Minikube on Windows using Chocolatey (run as an administrator):<\/p>\n<pre lang=\"bash\">choco install minikube<\/pre>\n<p><span>A Hypervisor is also required. I downloaded <a href=\"https:\/\/www.virtualbox.org\/wiki\/Downloads\" target=\"_blank\" rel=\"noopener\">VirtualBox<\/a><br \/>\n<\/span><\/p>\n<p>Use the following command to start up minikube:<\/p>\n<pre lang=\"bash\">minikube start --driver=VirtualBox<\/pre>\n<p>Run the below command to check the status of cluster:<\/p>\n<pre lang=\"bash\">minikube status\r\nhost: Running\r\nkubelet: Running\r\napiserver: Running\r\nkubeconfig: Configured<\/pre>\n<p>b. Verify kubectl is installed<br \/>\nOnce the minikube is successfully configured, we can use kubectl, the Kubernetes command-line tool. It allows to run commands against Kubernetes clusters.<br \/>\nUse the following command to verify if kubectl is working<\/p>\n<pre lang=\"bash\">$kubectl version\r\nClient Version: version.Info{Major:\"1\", Minor:\"17\", GitVersion:\"v1.17.1\", GitCommit:\"d224476cd0730baca2b6e357d144171ed74192d6\", GitTreeState:\"clean\", BuildDate:\"2020-01-14T21:04:32Z\", GoVersion:\"go1.13.5\", Compiler:\"gc\", Platform:\"windows\/amd64\"}\r\nServer Version: version.Info{Major:\"1\", Minor:\"17\", GitVersion:\"v1.17.3\", GitCommit:\"06ad960bfd03b39c8310aaf92d1e7c12ce618213\", GitTreeState:\"clean\", BuildDate:\"2020-02-11T18:07:13Z\", GoVersion:\"go1.13.6\", Compiler:\"gc\", Platform:\"linux\/amd64\"}<\/pre>\n<p>c. Create a Kubernetes deployment using the docker image<\/p>\n<div>\n<pre lang=\"bash\">$ kubectl create deployment qxf2-factorial-app --image=sravantit25\/factorial-qxf2:0.1\r\ndeployment.apps\/qxf2-factorial-app created<\/pre>\n<\/div>\n<p>d. Check if the pod is running<\/p>\n<pre lang=\"bash\">$ kubectl get pod\r\nNAME READY STATUS RESTARTS AGE\r\nqxf2-factorial-app-58dcdbc97f-5zzt5 1\/1 Running 0 3m20s<\/pre>\n<p>This means that the website is running inside the pod.<span><\/span><\/p>\n<p>e.\u00a0To test the running server (pod), port-forward the pod port 6464 to localhost port 8081 (or any other port of your choice)<\/p>\n<pre lang=\"bash\">$ kubectl port-forward qxf2-factorial-app-58dcdbc97f-5zzt5 8081:6464\r\nForwarding from 127.0.0.1:8081 &gt; 6464\r\nForwarding from [::1]:8081 &gt; 6464<\/pre>\n<p>f. Test by running<\/p>\n<pre lang=\"bash\">http:\/\/localhost:8081\/<\/pre>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/04\/Factorial_app.png\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-12735\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/04\/Factorial_app.png\" alt=\"\" width=\"436\" height=\"250\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/04\/Factorial_app.png 808w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/04\/Factorial_app-300x172.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2020\/04\/Factorial_app-768x440.png 768w\" sizes=\"auto, (max-width: 436px) 100vw, 436px\" \/><\/a><br \/>\nThat is it. We can get our server running in the pod. Next steps, look at ingress, load balancing, auto scaling etc.<\/p>\n<hr \/>\n<p>References:<br \/>\n<a href=\"https:\/\/kubernetes.io\/docs\/setup\/learning-environment\/minikube\/\" target=\"_blank\" rel=\"noopener\">https:\/\/kubernetes.io\/docs\/setup\/learning-environment\/minikube\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post outlines the steps I followed in deploying a website in Kubernetes. Kubernetes is a platform for automating deployment, scaling and management of our application across a cluster of hosts. It works with a different range of container tools and the one we will be using here is the popular Docker. I have divided the process into 3 main [&hellip;]<\/p>\n","protected":false},"author":27,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[140,150,151],"tags":[],"class_list":["post-12662","post","type-post","status-publish","format-standard","hentry","category-docker","category-kubernetes","category-minikube"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/12662","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=12662"}],"version-history":[{"count":44,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/12662\/revisions"}],"predecessor-version":[{"id":12756,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/12662\/revisions\/12756"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=12662"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=12662"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=12662"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}