Minikube Tutorial 1 ------------------- The idea behind this tutorial is to replicate the steps in the following Google Kubernetes tutorial: https://codelabs.developers.google.com/codelabs/cloud-springboot-kubernetes/#0 but this time on your local computer, using "minikube". Minikube is a a version of kubernetes that emulates a full cluster on your local computer. It and can be used to experiment with kubernetes, test your microservices application, etc. You need to carry out this tutorial on your local machine, as you will be using minikube for Phase 2 of Project 1. First you need to install minikube on your local computer. Follow the instructions here for installation: https://minikube.sigs.k8s.io/docs/start/. Documentation is also available in the same site. The idea now is to follow the same steps as in the Google tutorial mentioned above. In particular, all kubectl commands are available in minikube, with the only change that you have to type "minikube kubectl" instead of just "kubectl". Some slight modifications will be needed in some of the steps, as discussed below. - The first step is to run "minikube start", or "minikube --driver=docker start". This creates the cluster (or actually, an emulation of the cluster) within your machine. Note, the basic version of minikube only allows one cluster, and that too, a single-node cluster. If you run "minikube dashboard" you will get a lot of info in the browser. From within this Dashboard you can do almost everything that can be done via kubectl. - Creating the deployment: An important detail is that minikube's docker server runs inside its own container on your machine. This is distinct from any docker server that may be running directly on your localhost. "minikube ssh" logs you into the shell of this container. If you do "docker images" within the container, you will see the images actually available to minikube. See https://dzone.com/articles/running-local-docker-images-in-kubernetes-1 for all the details of this. [Note 1: It is not at all necessary for you to do "minikube ssh", as you will issue all minikube client commands from your localhost only; your machine acts as the kubernetes command client, while the minikube container acts as the kubernetes (and docker) server. Note 2: From within the minikube shell, if you do "ps", you will only see processes related to the minikube container. However, if you run some process from within the shell, say "yes", and do "ps" from your normal localhost terminal, you will see this process as a separate process. This is evidence that the container process and its child processes are also processes on the host system, but with isolation. The container process and its child processes can see each other via "ps", and they share a common isolated file system, and they all use the same IP address.] Therefore, any docker image available on your localhost machine will not be visible inside minikube, and hence cannot be directly deployed. If you attempt to create a deployment under minikube, it will look for the given image in a set of repositories only. For instance, one could run: minikuble kubectl -- create deployment \ hello-minikube --image=k8s.gcr.io/echoserver:1.4 If you would like to build a docker image from a project in your localhost and make this image available to minikube's docker server, you have three choices. The first choice is to push your image onto a repository ("mvnw" has an option for this, as seen in the Google tutorial), and then run the image as shown above. The second choice is to upload an image from your localhost's docker server to minikube's docker server using the "minikube image load " command. The third choice is as follows, and is the one we use in our demos. Run "eval $(minikube docker-env)" in a terminal in your localhost machine. It will set various shell variables, which will then force the docker commands that you subsequently issue within the same terminal to be sent to minikube's docker server. In other words, it connects your terminal as a docker client to the docker server within minikube. Now cd to the directory that has the code (e.g., ~/your-path/gs-spring-boot/), and type "docker build -t your-name/gs-spring-boot .", and it will build the image directly into the minikube container. Then deploy the image as follows: minikube kubectl -- create deployment hello-java \ --image=your-name/gs-spring-boot Note: if you want to keep around multiple versions of the image, append ":v0", ":v1", etc., at the end of the image names. As a result of the command above, the deployment gets created. However, unexpectedly, it does not run properly. If you go to the Dashboard, you will see an error message that the image your-name/gs-spring-boot was not found (even though it is available locally within the container). To rectify this, click on the "..." next to the deployment in the Dashboard, choose Edit, and set the option ImagePullPolicy to Never or IfNotPresent (which tells kubernetes to use the local image if the image is not available in its default repositories). In case this does not work, another idea is to append a unique tag to the image name, such as ":v0", when you create the image and when you create the deployment. This way, any lookup by minikube's docker server on remote repositories fails, hence forcing it to use the local image. - Run the following command to wrap a service around the deployment created above: minikube kubectl -- expose deployment hello-java \ --type=LoadBalancer --port=8080 Then run "minikube tunnel" in a different terminal window (and don't kill this process, let it stay running). Now, in the Dashboard you will see an external IP address for the service (you can also see this using "minikube kubectl -- get services"). Now you can visit http://:8080. Note, if your service is only going to be invoked by other services (i.e, Spring Boot apps) that you are going to run within the same minikube instance (as you will in Tutorial 2 below), you can drop the "--type=LoadBalancer". In this case it will use by default the ClusterIP type, which also provides load balancing. In either case, since the name of the deployment and service as created above is hello-java, the other services can access this service using the URL http://hello-java:8080. - Now you can scale the deployment using kubectl or using the Dashboard. Note, if you scale it up, it may scale it down automatically after a while if the load goes down. If you do "ps aux | grep java" immediately after scaling, you will see multiple instances, corresponding to the multiple pods. This proves that the pods are actually running as processes within your machine. If you do "minikube ssh" and then run "ps aux | grep java" within that shell, you will see the same set of pods, but with different PIDs (PID namespaces in action). Minikube Tutorial 2 ------------------- This tutorial is not mandatory. You are encouraged to try it out. It contains steps that will be necessary in your Project 1, Phase 2. First start minikube, and deploy hello-java within it as a service as per Tutorial 1 above. Use ClusterIP type for the service. The rest of this tutorial is about deploying another service that will act as a client and invoke the hello-java service. Write another Spring Boot application. The main controller in this application could have code such as the following: InetAddress ip = null; StringBuffer content = new StringBuffer(); try { URL url = new URL("http://hello-java:8080"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); ip = InetAddress.getLocalHost(); con.setRequestMethod("GET"); int status = con.getResponseCode(); Reader streamReader = null; if (status <= 299) { BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { content.append(inputLine); } in.close(); } } catch (Exception e) { return "Internal error " + e + " encountered in server " + ip + " !"; } return "Greetings from Spring Boot running at " + ip + "." + " hello-app service returned the following message: " + content; Now build this application as an image, and deploy it also into minikube just as in Tutorial 1. For this application, wrap the deployment as a LoadBalancer service. Now reach out to this application as an end-user from your browser. It will in turn send requests to hello-java.