πŸ‡¬πŸ‡§ Baby steps with Minikube - Part I

The origins of this blog post

I decided to learn and understand Kubernetes, so each time I think I understood something, I write something (for me, and I hope it could help at least one person in the world)

Disclaimer 1: I'm πŸ‡«πŸ‡·, so sometimes my πŸ‡¬πŸ‡§ could be strange, so be nice and don't hesitate to propose a MR on https://gitlab.com/k33g/k33g.gitlab.io πŸ˜‰

Disclaimer 2: I'm more a developer than an admin sys, so be nice too and help me grow: propose a kindly MR 😍

The first part(s) of this blog post is a simplified version of the "how to" of https://kubernetes.io/docs/setup/minikube/, but I need it for myself.

But what's Minikube?

First, "Ok Google, what's Kubernetes?"

Kubernetes is an open-source container-orchestration system for automating deployment, scaling and management of containerized applications.

Ok, now what's Minikube?

I cannot do better than the definition on https://kubernetes.io/docs/setup/minikube/ :

Minikube is a tool that makes it easy to run Kubernetes locally. Minikube runs a single-node Kubernetes cluster inside a VM on your laptop for users looking to try out Kubernetes or develop with it day-to-day.

So, in 5 words: Minikube is a Kubernetes Baby 🐣

Prerequisites

  • You need VirtualBox
  • For some exercises, you will probably need Docker

Setup

OSX

brew install kubernetes-cli
brew cask install minikube

kubernetes-cli allows to install kubectl, the CLI thatwe'll use to send commands to Kubernetes.

Linux

🚧 Work In Progress for the next blog post

I plan to setup a "real Kubernetes" on Linux (on a NUC), but it's another story

Currently, go there https://github.com/kubernetes/minikube/releases and read the Linux section

Windows

... Offer me a lot of 🍺 and a Microsoft Surface

Start Minikube

Just type this command

minikube start

By default the allocated memory is about 1024 GB, if you need more, type this command at startup:

minikube start --memory 2048

... And wait a little β˜•οΈ (the first time it could be long)

You should get something like that:

Starting local Kubernetes v1.10.0 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.

Check the setup

The simplest way is to check if you can reach the k8s dashboard (btw k8s is the nickname of Kubernetes), so type the command:

minikube dashboard

If your setup is ok, it will open automatically a panel in your browser at this url http://192.168.99.100:30000/#!/overview?namespace=default

Dashboard

Btw, if you need the IP of your Minikube instance, type this command:

minikube ip

First pod

"Ok Google, what's a pod?"

A Kubernetes pod is a group of containers that are deployed together on the same host. If you frequently deploy single containers, you can generally replace the word "pod" with "container" and accurately understand the concept.

Just one thing before the fun

Before to go further, we are going to reuse the Docker daemon. On the Minikube section of the website (https://kubernetes.io/docs/setup/minikube/), you can read this:

When using a single VM of Kubernetes, it’s really handy to reuse the minikube’s built-in Docker daemon; as this means you don’t have to build a docker registry on your host machine and push the image into it - you can just build inside the same docker daemon as minikube which speeds up local experiments. Just make sure you tag your Docker image with something other than β€˜latest’ and use that tag while you pull the image.

So to simplify, we are going to use the docker client of the Minikube VM instead of the docker client of your laptop (or desktop or what ever). To do that, type this command:

eval $(minikube docker-env)
# now you can try a `docker ps`

Create a dockerized nodejs application

Why node? Because I ❀️ (a lot) JavaScript

First create a hello directory with 2 files:

  • index.js
  • Dockerfile

with this contents:

index.js content:

const http = require('http')
const port = process.env.PORT || 8080

const requestHandler = (request, response) => {
  response.writeHead(200, {"Content-Type": "text/html; charset=utf-8"});
  response.end(`
    <div style="text-align: center;">
      <h1 style="font-family: Sans-Serif; font-size: 70px;">
        πŸ‘‹ 🌍 Hello World!
      </h1>              
    </div>
  `)
}

const server = http.createServer(requestHandler)

server.listen(port, (err) => {
  if (err) {
    console.log('😑 something bad happened', err)
    process.exit(1)
  }
  console.log(`🌍 server is listening on ${port}`)
})

Dockerfile content:

FROM node:10.8-slim
EXPOSE 8080
COPY index.js .
CMD node index.js

Create the docker image of our application

To create an docker image from our application, type these commands:

cd hello
docker build -t hello:v1 .
  • Don't forget the . at the end of the command
  • We have tagged our image (hello:v1)

Take an other β˜•οΈ if you want (it depends of your 🌍 connection):

Sending build context to Docker daemon  3.584kB
Step 1/4 : FROM node:10.8-slim
10.8-slim: Pulling from library/node
5bba3ecb4cd6: Downloading  8.297MB/30.12MB

And if all is ok:

5bba3ecb4cd6: Pull complete
196b8e3c919d: Pull complete
7d083412657b: Pull complete
86b61999e012: Pull complete
4b4bb8b2aedd: Pull complete
Digest: sha256:be33a4a4450661c324c71d47dc189a959e9d8a7224c6448e9e51dfb01a671de9
Status: Downloaded newer image for node:10.8-slim
 ---> b6be7a623c56
Step 2/4 : EXPOSE 8080
 ---> Running in 2ddbc988c8a5
Removing intermediate container 2ddbc988c8a5
 ---> 2135dbadde3e
Step 3/4 : COPY index.js .
 ---> 29f187553b2f
Step 4/4 : CMD node index.js
 ---> Running in ec272935a90b
Removing intermediate container ec272935a90b
 ---> 02d4f669bdcc
Successfully built 02d4f669bdcc
Successfully tagged hello:v1

It's time to deploy a pod on Minikube

kubectl run hello --image=hello:v1 --port=8080
# you remember that the image is "inside the Minikube VM"

In the best of worlds, you'll get:

deployment.apps/hello created

Be curious and refresh the dashboard:

Dashboard

Cool πŸ•Ί, then, in a terminal, type:

kubectl get pods

You'll get something like that:

NAME                     READY     STATUS    RESTARTS   AGE
hello-6d756bf4d5-m79tc   1/1       Running   0          3m

so this is your pod

You can get the deployments list to:

kubectl get deployments
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello     1         1         1            1           4m

and this is one deployment of your pod (you can have several deployments for one pod)

It's time to present your amazing web application to the world

  1. we need to expose the hello deployment to an external ip:
kubectl expose deployment hello --type=NodePort
# result
service/hello exposed
  1. check:
kubectl get services
# result
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
hello        NodePort    10.108.204.38   <none>        8080:31500/TCP   28s
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          1h
  1. check again with the dashboard:

Dashboard

  1. get the url of your ✨ web application:
minikube service hello --url
# result
http://192.168.99.100:31500
  1. of course reach http://192.168.99.100:31500 with your browser

✨ web application

Tada! πŸŽ‰

That'all folks for today. You can stop your Minikube instance with the minikube stop command (and of course start again with minikube start ... You can check πŸ˜‰)

Next time, We'll speak about "how to scale our deployment".

Last Articles

Last Updated: 11/30/2019, 5:56:28 PM