Kubernetes - Getting Started (1/2)

Kubernetes, the software that is often referred to as the operating system for application development. It's true, Kubernetes changed a lot in the application development world. But what are Deployments, Ingress, Service or Namespaces?

Kubernetes - Getting Started (1/2)

Kubernetes, the software that is often referred to as the operating system for application development. It's true, Kubernetes changed a lot in the application development world. It is used in the public cloud, in datacenters and on IoT devices alike. But what are Deployments, Ingress, Service or Namespaces?

In this article, we will dig into the very first deployments on Kubernetes and explain some concepts, that will get you started. Please don't expect to be a master of Kubernetes after this article. Digging into Kubernetes made me feel dumb and learn things from scratch, even after over 10 years of professional IT experience.

Kubernetes

First, you may want to know: "Why should one use Kubernetes at all?". For me, this was one of the most interesting questions. There are so many alternatives to deploy something on a machine. Why should you care about deployments on Kubernetes?

The first benefit of Kubernetes is, that you will get one API standard to deploy something on a single machine, a cluster of servers, your local workstation and in the cloud. This makes it very easy to test a deployment or establish multiple stages of deployments.

Furthermore, the deployment is now written in YAML files, which is easier to understand and maintain than a script written in the language the author preferred. This allows writing automated deployments from basically everybody and also document this deployment.

One more huge benefit is, that you will get a set of standardized objects that must be described. So instead of thinking about firewalls, routing, partitions and CPU allocation per application, you can handle this for each application with the very same set of objects. These objects are Kubernetes specific, and you don't need to take care of the underlying GNU/Linux distribution.

Lastly, Kubernetes itself comes with tons of benefits for scaling, reproducibility and availability. You can start with a single node and grow with Kubernetes to a high available, automatically scaling infrastructure. The deployment of your application stays the same, if you want.

On top, you will get a vast ecosystem to add value to your setup. You can also add monitoring, automatic backups and scheduled jobs. There are ways to template your deployments, tools to interact with a cluster or a single deployment, create certificates and much more.

Some even consider/state: "Kubernetes is the new Operating System for developers", which is not entirely wrong from my perspective.

Setup (Minikube)

In another article, I explained how you can install Minikube on your Fedora machine and get started. This is a perfect environment for learning, since you don't need special hardware or read through hundreds of pages of documentation to install a production cluster.

Instead, let's focus on the basic ideas, concepts and deployments for now. In some future articles, I will address more setups for single instances and clusters and write about the many ways to use and deploy Kubernetes.

After reading and reproducing the above-mentioned article "Fedora - Minikube", you should be able to run the below commands successfully.

# Start a kubernetes instance
$ minikube start
...
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

# Add an Ingress Controller
$ minikube addons enable ingress
...
🌟  The 'ingress' addon is enabled

# Check nodes
$ kubectl get nodes
NAME       STATUS   ROLES                  AGE    VERSION
minikube   Ready    control-plane,master   119s   v1.23.1

# Check pods
$ kubectl get pods -A
NAMESPACE       NAME                                        READY   STATUS      RESTARTS      AGE
ingress-nginx   ingress-nginx-admission-create-ctlb7        0/1     Completed   1             113s
ingress-nginx   ingress-nginx-admission-patch-zg87h         0/1     Completed   2             113s
ingress-nginx   ingress-nginx-controller-6d5f55986b-sq8w2   1/1     Running     0             113s
kube-system     coredns-64897985d-kxdv4                     1/1     Running     0             113s
kube-system     etcd-minikube                               1/1     Running     1             2m7s
kube-system     kube-apiserver-minikube                     1/1     Running     1             2m5s
kube-system     kube-controller-manager-minikube            1/1     Running     1             2m7s
kube-system     kube-proxy-pxr64                            1/1     Running     0             113s
kube-system     kube-scheduler-minikube                     1/1     Running     1             2m7s
kube-system     storage-provisioner                         1/1     Running     1 (82s ago)   2m3s

If this works, we can have a look at Kubernetes deployments.

The Project

As always, let's start with a very simple project. I know, the dumb web server deployment is a bit boring, so... let's do something more interesting and useful. I have found this well-made To-Do/calendar/note-taking web application named DailyNotes. It is perfect to get started and explore more afterwards.

To deploy the application, we need to ensure a couple of things.

  1. The app must run
  2. The app must be accessible

And this is exactly what we will do now.

Deploying the web app

To understand how you can deploy something on Kubernetes and how everything works together, it is a good idea to understand a couple of concepts. It is best to focus on the declarative provisioning for now, but there are also options to describe things in an imperative way to create and manipulate objects.

During this guide, I will explain each of the objects we will use and provide the example files. At the end, you will have a couple files to deploy your own DailyNotes on Kubernetes.

Let's start! :-)

Hint
The guide is tested on Fedora 35 with Minikube 1.25.1.

Diagram

Before digging into every single object, you might want to have a quick look, how Kubernetes organizes things and "where" they do live. The below diagram should guide you through the next couple of sections.

© 2021, Daniel Schier, CC BY-SA 4.0

Namespace

In Kubernetes, everything is organized in Namespaces. Minikube (and most other Kubernetes distributions) already provide some default namespaces. We can have a quick look at these beforehand.

# Get namespaces
$ kubectl get namespace
NAME              STATUS   AGE
default           Active   3m31s
ingress-nginx     Active   3m28s
kube-node-lease   Active   3m33s
kube-public       Active   3m33s
kube-system       Active   3m33s

A namespace can be used to separate stages (prod, test, beta, etc.) or applications (website, blog, web shop, shared, etc.) and more. You can think of separated workspaces or drawers to put your deployments in.

For our small application, we need a workspace. For this, we need to create a very simple file namespace.yml. Such a file does not contain a lot (for now), since we just want to create an object with the "kind" of "Namespace" and give it a "name" of "dailynotes".

---
apiVersion: "v1"
kind: "Namespace"
metadata:
  name: "dailynotes"
...

namespace.yml

We can apply this object with a simple kubectl command, too.

# apply the namespace configuration
$ kubectl apply -f namespace.yml
namespace/dailynotes created

# Check namespace
$ kubectl get namespace
NAME              STATUS   AGE
dailynotes        Active   26s
...

This was pretty easy, and we can continue to talk about the workload we want to deploy in this namespace. BTW, you can also delete the namespace (including everything in it) again, if you want.

# delete the namespace
$ kubectl delete -f namespace.yml 
namespace "dailynotes" deleted

Container/Pod

Yes, Kubernetes is working with containers, but this works different from Docker or Podman. Nevertheless, under the hood, a container will be started and do the heavy lifting. Therefore, you will meet our old friends "image" or "expose".

The Pod is the smallest "workload object" in Kubernetes. A pod can contain multiple containers. And that's exactly what Kubernetes does per default. Instead of spawning the container on its own, Kubernetes also starts an init-container, which keeps care of the resource allocation and reservations.

Creating a new pod is quite easy and can be done with the below example pod.yml file.

---
apiVersion: "v1"
kind: "Pod"
metadata:
  name: "pod-web"
  namespace: "dailynotes"
spec:
  containers:
    - name: "ctr-web"
      image: "docker.io/m0ngr31/dailynotes:v1.0-beta18"
      ports:
        - containerPort: 5000
...

pod.yml

Creating and starting the pod works the same way as creating a namespace.

# Create the pod
$ kubectl apply -f pod.yml

# List pods
$ kubectl get pods -n dailynotes
NAME      READY   STATUS    RESTARTS   AGE
pod-web   1/1     Running   0          5s

# Delete the pod
$ kubectl delete -f pod.yml 
pod "pod-web" deleted

The "problem" here is, that Kubernetes does not manage a pod. It will keep it online, but changing something will not result in a re-deployment of the container/pod.

This is something, that can be done with deployments, though.

End of Part 1

Unfortunately, we have to stop for now. In the next article, we will see how deployments can be used and how we can access a deployed application and store data with Persistent Volumes. If you cannot wait until then, please have a look at the Docs & Links below.

Kubernetes provides a very exhaustive documentation to cover basically everything. But, it is also a good idea to check out other container options to get a better understanding.

Container - while-true-do.io
If you want to name a single technology, every IT enthusiast should know, it will be containers. If you are into containers and want to learn about container technologies, you may love this section.
Tutorials
Production-Grade Container Orchestration
Pods
Production-Grade Container Orchestration
Namespaces
In Kubernetes, namespaces provides a mechanism for isolating groups of resources within a single cluster. Names of resources need to be unique within a namespace, but not across namespaces. Namespace-based scoping is applicable only for namespaced objects (e.g. Deployments, Services, etc) and not fo…
Service
An abstract way to expose an application running on a set of Pods as a network service. With Kubernetes you don’t need to modify your application to use an unfamiliar service discovery mechanism. Kubernetes gives Pods their own IP addresses and a single DNS name for a set of Pods, and can load-balan…
Deployments
A Deployment provides declarative updates for Pods and ReplicaSets. You describe a desired state in a Deployment, and the Deployment Controller changes the actual state to the desired state at a controlled rate. You can define Deployments to create new ReplicaSets, or to remove existing Deployments …

Conclusion

Digging into Kubernetes was the first time for years, where I really needed to learn new things. It is not about adapting some minor tuning and tweaking or learning a new programming language. It is much more about understanding concepts and dependencies. But, it was also a very fun experience, and I am thrilled to deep dive this topic with you.