I am Learning Kubernetes? How do I get a Cluster?
Author: W. Jenks Gibbons
I started learning Kubernetes out of necessity. It was coming up constantly at work and therefore I was continually struggling. Kubernetes is a strange beast in that even the documentation is confusing at first unless you know YAML (YAML Ain’t Markup Language™) which is the foundational language in which the documentation is written. To make things more complicated, I found it very confusing to create and use a cluster in which to learn.
I started my journey using Mumshad Mannambeth’s course “Certified Kubernetes Administrator (CKA) with Practice Tests” For some people this is too in-depth. If this is the case Mumshad also offers an excellent introductory course “Kubernetes for the Absolute Beginners - Hands-on” If you are looking for a foundation that includes an introduction to Kubernetes, cloud computing concepts and architecture, microservices, software delivery and other topics then the course “Kubernetes and Cloud Native Associate (KCNA)” may be right for you. From my experience, these courses all offer a solid start on your journey to becoming an expert-beginner in Kubernetes. An expert-beginner will get many people where they need to be with the technology.
As I was making my way through the CKA course, I needed an environment. My issue was that everything from bringing up an environment to accessing an application was confusing to me. So, my first step was simply to open a lab in the CKA course to get a cluster for an hour. Eventually however, I needed to learn how to create my own environment.
While there are many ways to bring up a cluster such as on your laptop, using a cloud service or on a virtual machine let’s start where it makes sense and get straight into clearing up the confusion. minikube and kind… Both can be used on a laptop to create a Kubernetes environment¹.
minikube
When I first started using minikube it required VirtualBox. In addition to my confusion, this was also a reason I did not use it. Now I often find it a very nice, quick environment to use, albeit with some drawbacks.
To start, you can now use the docker
driver². This means you can use it on your laptop with software such as “Docker Desktop³” To create a cluster with default parameters install minikube and start it:
$ minikube start --driver=docker
😄 minikube v1.31.2 on Darwin 14.3.1 (arm64)
▪ KUBECONFIG=:/Users/jenks.gibbons/.kube/kubeadm.config
🎉 minikube 1.32.0 is available! Download it: https://github.com/kubernetes/minikube/releases/tag/v1.32.0
💡 To disable this notice, run: 'minikube config set WantUpdateNotification false'
✨ Using the docker driver based on existing profile
👍 Starting control plane node minikube in cluster minikube
🚜 Pulling base image ...
🏃 Updating the running docker "minikube" container ...
🐳 Preparing Kubernetes v1.27.4 on Docker 24.0.4 ...
🔎 Verifying Kubernetes components...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟 Enabled addons: storage-provisioner, default-storageclass
🏄 Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
$
Now we have a basic cluster we can use:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 12s v1.27.4
$ kubectl get po
No resources found in default namespace.
$ kubectl run nginx --image nginx
pod/nginx created
$ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 32s
$ minikube delete
🔥 Deleting "minikube" in docker ...
🔥 Deleting container "minikube" ...
🔥 Removing /Users/jenks.gibbons/.minikube/machines/minikube ...
💀 Removed all traces of the "minikube" cluster.
$
kind
kind, or “Kubernetes in Docker”, is another solution to create a cluster on your laptop.
$ # config - cluster config
$ $ cat config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
kubeProxyMode: ipvs
nodes:
- role: control-plane
- role: worker
$ $ kind create cluster --name "test-cluster" --config config.yaml
Creating cluster "test-cluster" ...
✓ Ensuring node image (kindest/node:v1.27.3) 🖼
✓ Preparing nodes 📦 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
✓ Joining worker nodes 🚜
Set kubectl context to "kind-test-cluster"
You can now use your cluster with:
kubectl cluster-info --context kind-test-cluster
Have a nice day! 👋
$ $ kubectl get nodes
NAME STATUS ROLES AGE VERSION
test-cluster-control-plane Ready control-plane 46s v1.27.3
test-cluster-worker Ready <none> 22s v1.27.3
$ kubectl get po
No resources found in default namespace.
$ kubectl run nginx --image nginx
pod/nginx created
$ $ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 36s
So, we are moving right along… we have two ways to create a cluster. So, let’s hit nginx
from our laptop.
$ curl
Hmmmmmm….. how?
Connecting to Applications
We are a bit stuck, but we asked for help. A collegue told us to use a load balancer to access the application. In Kubernetes, there are different types of services. The documentation says “a Service is a method for exposing a network application that is running as one or more Pods in your cluster.”
While there are various types, the most common you will see are:
type: ClusterIP
the documentation notes “This default Service type assigns an IP address from a pool of IP addresses that your cluster has reserved for that purpose.” This type provides internal, cluster access to/for applications. This won’t help us to access our application from our laptop.type: NodePort
this will allocate a port on the node from 30000–32767. This will allow you to access the application from <ip>:<port> This is a bit confusing using minikube and kind.type: LoadBalancer
this is only available in cloud-managed solutions such as AWS EKS, Azure AKS and GCP GKE. We can’t use this⁴.
NodePort
On minikube you can expose the pod on a NodePort like such:
$ kubectl expose pod nginx --type=NodePort --port=80
service/nginx exposed
$ $ kubectl get svc nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.97.185.82 <none> 80:31142/TCP 84s
The cluster IP won’t help us and there is no external IP. The documentation says we have to run a command to get the service tunnel?
$ minikube service nginx --url
http://127.0.0.1:63222
❗ Because you are using a Docker driver on darwin, the terminal needs to be open to run it.
$ curl http://127.0.0.1:63222
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
The message above references OSX, however I don’t see how this would be different on any supported OS. Still though? The loopback to what port? This is just a fancy port-forward from the host. So, from a port on your host a tunnel will open to 31142 in minikube which will then forward to 80 on the pod(s).
Using kind, you have to setup port-forwards in the cluster config to use this option.
For what we are doing it seems like a lot of work to use a NodePort service with these tools to create port-forwards.
Port-Forward
This will get us what we need with less effort.
$ kubectl port-forward --help
Forward one or more local ports to a pod.
$ # nginx is running on port 80
$ kubectl port-forward pod/nginx 33333:80
Forwarding from 127.0.0.1:33333 -> 80
Forwarding from [::1]:33333 -> 80
# after we connect
Handling connection for 33333
$ curl localhost:33333
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
As your Kubernetes experience and needs increase these solutions may not always offer you what you need. The more I learn about Kubernetes however the more often I use one of them for something quick. For now this can support your journey by providing an environment where you can deploy and connect to applications.
Have fun.
¹ Neither minikube nor kind support Windows node pools.
² My understanding is this is the default driver now, but I don’t see that explicitly stated anywhere.
³ Refer to the documentation to see other container solutions supported as well as what might be required by your operating system (e.g. Windows).
⁴ You may see documentation referring to an Ingress or LoadBalaner (e.g. within kind). These work differently with these solutions than they do with a public cloud offering and are more advanced than we need here.