How to install Kubernetes with microk8s and deploy apps on Debian/Mint/Ubuntu Linux

Kubernetes Easy Beginners Tutorial/Architecture Guide

Kubernetes is known as container orchestration and we should start at explaining the container part of it.

A Container is what runs the actual application and based on an Image, and are more comparable to something like an LXC Container, Virtuozzo/OpenVZ using the Linux Kernel Namespaces feature.  Containers run these images as independent, isolated operating environments under the OS's existing kernel.  Unlike full virtualization which emulates a real computer, images run under the existing OS kernel and do not have their own virtual hardware, which makes them perform and deploy faster.

An Image is like a pre-built template that has everything we need to run the application eg. nginx, Apache, MySQL and almost anything can be turned into a purpose built application inside an image file.

Multiple Containers run within Pods (although most often 1 container will run inside a pod), and Multiple Pods can run on Nodes, and there can be Multiple Nodes in the Cluster, which is the general/basic hierarchy of Kubernetes.

Pods are basically just a grouping of Containers which are generally related or may need to have tighter coupling of storage and networking (many pods still have just 1 container).

Nodes can be anything that runs the kubernetes services, and would most commonly be some sort of VM or even a physical server.  VMs are recommended for Kubernetes as it is more easy to fix problems or troubleshoot and make changes/upgrades compared to bare metal dedicated servers.


Prerequisites

RAM: 4G minimum (8G and much higher recommended for any workloads)

HDD: 20G minium

Hostname: No capitals and no underscores

OS: Latest / newer Linux distro

This guide was written for Ubuntu 20/Mint 20 at the time.

At the time of update the latest microk8s classic is 1.26.3 and this worked fine on Ubuntu 22 and Debian 11.

https://microk8s.io/docs/troubleshooting


Step 1 - Install snapd and microk8s

https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/

Note that Linux Mint disables snap, read this post to fix snapd install missing in Linux Mint.

snapd installation

sudo apt install snapd
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  kubernetes
0 upgraded, 1 newly installed, 0 to remove and 123 not upgraded.
Need to get 3,340 B of archives.
After this operation, 19.5 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu focal/universe amd64 kubernetes all 1.0 [3,340 B]
Fetched 3,340 B in 0s (9,475 B/s)      
Selecting previously unselected package kubernetes.
(Reading database ... 378576 files and directories currently installed.)
Preparing to unpack .../kubernetes_1.0_all.deb ...
Unpacking kubernetes (1.0) ...
Setting up kubernetes (1.0) ...
Processing triggers for man-db (2.9.1-1) ...
 

microk8s installation

#the channel version is very important.  At the original time of writing the default channel was 1.20 and today it is 1.26.3, there are often big changes in each channel/version that may cause things to break.  For example at the time of writing the default channel of 1.20 worked fine on Ubuntu 20/Mint 20, but today version 1.26.3 which is the default, is broken (although it works fine on Debian 11).

So you should specify a certain channel and be aware of which one you are working on to avoid surprises, changes and incompatibilities in the future.

snap install microk8s --classic --channel=1.19

#I recommend you set this alias so you can call kubectl without using microk8s.kubectl

alias kubectl=microk8s.kubectl

 

Create our first app deployment using nginx

microk8s.kubectl create deployment nginx --image nginx
deployment.apps/nginx created
 

enable/expose it so it can start working

microk8s.kubectl expose deployment nginx --port 8000 --target-port 8000 --selector app=nginx --type ClusterIP --name rtttest
service/rtttest exposed
 

View all running services:

microk8s.kubectl get all
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-6799fc88d8-sm5gd   1/1     Running   0          3m43s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/kubernetes   ClusterIP   10.152.183.1             443/TCP    25m
service/areebtest    ClusterIP   10.152.183.191           8000/TCP   2m49s

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   1/1     1            1           3m43s

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-6799fc88d8   1         1         1       3m43s

 

Enable Dashboard

microk8s.enable dns dashboard
Enabling DNS
Applying manifest
serviceaccount/coredns created
configmap/coredns created
Warning: spec.template.metadata.annotations[scheduler.alpha.kubernetes.io/critical-pod]: non-functional in v1.16+; use the "priorityClassName" field instead
deployment.apps/coredns created
service/kube-dns created
clusterrole.rbac.authorization.k8s.io/coredns created
clusterrolebinding.rbac.authorization.k8s.io/coredns created
Restarting kubelet
DNS is enabled




Enabling Kubernetes Dashboard
Enabling Metrics-Server
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
clusterrolebinding.rbac.authorization.k8s.io/microk8s-admin created
Metrics-Server is enabled
Applying manifest
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
Warning: spec.template.spec.nodeSelector[beta.kubernetes.io/os]: deprecated since v1.14; use "kubernetes.io/os" instead
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created

If RBAC is not enabled access the dashboard using the default token retrieved with:

token=$(microk8s kubectl -n kube-system get secret | grep default-token | cut -d " " -f1)
microk8s kubectl -n kube-system describe secret $token

In an RBAC enabled setup (microk8s enable RBAC) you need to create a user with restricted
permissions as shown in:
https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md


microk8s.kubectl get all --all-namespaces
NAMESPACE     NAME                                             READY   STATUS              RESTARTS       AGE
default       pod/nginx-6799fc88d8-sm5gd                       1/1     Running             1 (134m ago)   147m
kube-system   pod/coredns-7f9c69c78c-jhhkq                     1/1     Running             0              2m25s
kube-system   pod/calico-node-2jnsp                            1/1     Running             1 (134m ago)   169m
kube-system   pod/calico-kube-controllers-58d7965c58-qpw8j     1/1     Running             1 (134m ago)   169m
kube-system   pod/dashboard-metrics-scraper-58d4977855-7dnzm   0/1     ContainerCreating   0              13s
kube-system   pod/kubernetes-dashboard-59699458b-7t52l         0/1     ContainerCreating   0              13s
kube-system   pod/metrics-server-85df567dd8-7rfsm              0/1     Running             0              13s

NAMESPACE     NAME                                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                  AGE
default       service/kubernetes                  ClusterIP   10.152.183.1             443/TCP                  169m
default       service/areebtest                   ClusterIP   10.152.183.191           8000/TCP                 146m
kube-system   service/kube-dns                    ClusterIP   10.152.183.10            53/UDP,53/TCP,9153/TCP   2m25s
kube-system   service/metrics-server              ClusterIP   10.152.183.124           443/TCP                  97s
kube-system   service/kubernetes-dashboard        ClusterIP   10.152.183.109           443/TCP                  77s
kube-system   service/dashboard-metrics-scraper   ClusterIP   10.152.183.24            8000/TCP                 77s

NAMESPACE     NAME                         DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
kube-system   daemonset.apps/calico-node   1         1         1       1            1           kubernetes.io/os=linux   169m

NAMESPACE     NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/calico-kube-controllers     1/1     1            1           169m
default       deployment.apps/nginx                       1/1     1            1           147m
kube-system   deployment.apps/coredns                     1/1     1            1           2m26s
kube-system   deployment.apps/dashboard-metrics-scraper   0/1     1            0           77s
kube-system   deployment.apps/metrics-server              0/1     1            0           97s
kube-system   deployment.apps/kubernetes-dashboard        0/1     1            0           77s

NAMESPACE     NAME                                                   DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/calico-kube-controllers-58d7965c58     1         1         1       169m
default       replicaset.apps/nginx-6799fc88d8                       1         1         1       147m
kube-system   replicaset.apps/coredns-7f9c69c78c                     1         1         1       2m26s
kube-system   replicaset.apps/dashboard-metrics-scraper-58d4977855   1         1         0       13s
kube-system   replicaset.apps/metrics-server-85df567dd8              1         1         0       13s
kube-system   replicaset.apps/kubernetes-dashboard-59699458b         1         1         0       13s
 

 


 

How to Expose the Dashboard

microk8s.kubectl expose service kubernetes-dashboard -n kube-system --port 8000 --type=NodePort --name kubserv


service/kubserv exposed

This is an excellent intro to namespaces, as you will notice the dashboard belongs to the namespace "kube-system" so we have to use "-n" for namespace and specify kube-system or it will not work (without -n it defaults to the "default" namespace).  As when we exposed nginx previously, it was running in the "default" namespace.

kube-system   service/kubernetes-dashboard        ClusterIP   10.152.183.130           443/TCP                                         42h

default       service/areebtest                   ClusterIP   10.152.183.157           80/TCP  

We can also delete the "kubserv" exposed service:

microk8s.kubectl delete service -n kube-system kubserv
service "kubserv" deleted
 

Troubleshooting

If you get these sorts of errors right after installing, you have bad or incompatible version of microk8s and should get an older version.

 

Kubernetes microk8s / calico won't start, stuck on initializing after the install

 

 

 

 

 

Let's Extend To an HA Kubernetes Cluster:

On the first node from above that you already created, run this command:

microk8s add-node
From the node you wish to join to this cluster, run the following:
microk8s join 10.10.10.7:25000/ad78ec7249c39d0870d77ea0199fe814/9d2708e1aae1

If the node you are adding is not reachable through the default interface you can use one of the following:
 microk8s join 10.10.10.7:25000/ad78ec7249c39d0870d77ea0199fe814/9d2708e1aae1

 

On the other nodes, use the join statement from above: microk8s join 10.10.10.7:25000/ad78ec7249c39d0870d77ea0199fe814/9d2708e1aae1
 

 

microk8s cluster invalid token (500)

Be sure that you have connectivity to the master node in the join statement, that no firewall is blocking the connection, and that the join statement is copied and pasted correctly without any extra whitespace in the middle or typos.

Resources:

 

https://kubernetes.io/docs/concepts/

 

 

Old Broken stuff

 

kubernetes install

Choose 1 for microk8s:

 

 

 

 


Tags:

install, kubernetes, debian, mint, ubuntu, linuxhttps, io, docs, tasks, kubectl, linux, https, microk, sudo, apt, snapd, lists, dependency, packages, installed, upgraded, newly, archives, kb, additional, disk, http, archive, focal, amd, fetched, selecting, previously, unselected, database, directories, currently, preparing, unpack, kubernetes_, _all, deb, unpacking, processing, triggers, db, enable, ips, ufw, firewall, apps, cni, default, routed, app, deployment, nginx, images, selector, clusterip, rtttest, restarts, pod, fc, sm, gd, cluster, ip, external, tcp, areebtest, desired, replicaset, dashboard, dns, enabling, applying, manifest, serviceaccount, coredns, configmap, spec, template, metadata, annotations, scheduler, alpha, functional, quot, priorityclassname, kube, clusterrole, rbac, authorization, clusterrolebinding, restarting, kubelet, enabled, metrics, server, aggregated, reader, rolebinding, auth, delegator, apiservice, apiregistration, beta, admin, certs, csrf, holder, settings, nodeselector, os, deprecated, scraper, token, retrieved, grep, user, restricted, permissions, github, blob, creating, md, namespaces, namespace, jhhkq, calico, node, jnsp, controllers, qpw, dnzm, containercreating, df, dd, rfsm, udp, daemonset, echo, nodeport, nic, microbot, vm, publicly,

Latest Articles

  • qemu: could not load PC BIOS 'bios-256k.bin' solution
  • Proxmox How To Custom Partition During Install
  • Hyper-V Linux VM Boots to Black Screen, Storage, NIC Not Found Issues
  • Ubuntu Mint How to Fix Missing/Broken /dev and /dev/pts which causes terminal to immediately close exit and not work
  • How high can a Xeon CPU get?
  • bash fix PATH environment variable "command not found" solution
  • Ubuntu Linux Mint Debian Redhat Youtube Cannot Play HD or 4K videos, dropped frames or high CPU usage with Nvidia or AMD Driver
  • hostapd example configuration for high speed AC on 5GHz using WPA2
  • hostapd how to enable and use WPS to connect wireless devices like printers
  • Dell Server Workstation iDRAC Dead after Firmware Update Solution R720, R320, R730
  • Cloned VM/Server/Computer in Linux won't boot and goes to initramfs busybox Solution
  • How To Add Windows 7 8 10 11 to GRUB Boot List Dual Booting
  • How to configure OpenDKIM on Linux with Postfix and setup bind zonefile
  • Debian Ubuntu 10/11/12 Linux how to get tftpd-hpa server setup tutorial
  • efibootmgr: option requires an argument -- 'd' efibootmgr version 15 grub-install.real: error: efibootmgr failed to register the boot entry: Operation not permitted.
  • Apache Error Won't start SSL Cert Issue Solution Unable to configure verify locations for client authentication SSL Library Error: 151441510 error:0906D066:PEM routines:PEM_read_bio:bad end line SSL Library Error: 185090057 error:0B084009:x509 certif
  • Linux Debian Mint Ubuntu Bridge br0 gets random IP
  • redis requirements
  • How to kill a docker swarm
  • docker swarm silly issues