Kubernetes, also called K8s, is an open-source system used for automating deployment, scaling and management of containerized applications. It provides a framework to run distributed systems. It's very useful to deploy a server-side application with high reliability, low downtime, and great load balancing.
In this tutorial, we'll show you how to set up a single node Kubernete cluster on Ubuntu 20.04.
Requirements
- A cloud server running Ubuntu 20.04 with 4 GB RAM.
- A root password set up on your server.
Let's begin!
Install Snapd
First, you will need to install Snapd to install MicroK8s in your system. You can do it with the following command:
# apt-get install snapd -y
Once installed, export the Snapd path and activate it with the following command:
# echo "export PATH=$PATH:/snap/bin" >> ~/.bashrc
# source ~/.bashrc
Once you are finished, you can proceed to the next step.
Install MicroK8s
MicroK8s is a powerful, lightweight, reliable production-ready Kubernetes distribution. It's used to set up and manage the Kubernetes cluster.
You can install it using the snap package manager as shown below:
# snap install microk8s --classic
Once the installation is completed, check out the MicroK8s status using the following command:
# microk8s.status --wait-ready
You should get the following output:
microk8s is running
high-availability: no
datastore master nodes: 127.0.0.1:19001
datastore standby nodes: none
addons:
enabled:
ha-cluster # Configure high availability on the current node
disabled:
ambassador # Ambassador API Gateway and Ingress
cilium # SDN, fast with full network policy
dashboard # The Kubernetes dashboard
dns # CoreDNS
fluentd # Elasticsearch-Fluentd-Kibana logging and monitoring
gpu # Automatic enablement of Nvidia CUDA
helm # Helm 2 - the package manager for Kubernetes
helm3 # Helm 3 - Kubernetes package manager
host-access # Allow Pods connecting to Host services smoothly
ingress # Ingress controller for external access
istio # Core Istio service mesh services
jaeger # Kubernetes Jaeger operator with its simple config
keda # Kubernetes-based Event Driven Autoscaling
knative # The Knative framework on Kubernetes.
kubeflow # Kubeflow for easy ML deployments
linkerd # Linkerd is a service mesh for Kubernetes and other frameworks
metallb # Loadbalancer for your Kubernetes cluster
metrics-server # K8s Metrics Server for API access to service metrics
multus # Multus CNI enables attaching multiple network interfaces to pods
portainer # Portainer UI for your Kubernetes cluster
prometheus # Prometheus operator for monitoring and logging
rbac # Role-Based Access Control for authorisation
registry # Private image registry exposed on localhost:32000
storage # Storage class; allocates storage from host directory
traefik # traefik Ingress controller for external access
Enable Kubernetes Dashboard
By default, all add-ons are disabled. So you will need to enable the basic Kubernetes services dashboard and kube-dns.
You can enable them with the following command:
# microk8s.enable dashboard dns
You should get the following output:
Enabling DNS
Applying manifest
serviceaccount/coredns created
configmap/coredns created
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
Next, check on the deployment of these add-ons with the following command:
# microk8s.kubectl get pods --all-namespaces
You should see the following output:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system metrics-server-8bbfb4bdb-c5rf8 1/1 Running 0 4m39s
kube-system calico-kube-controllers-847c8c99d-bp8mp 1/1 Running 0 9m20s
kube-system calico-node-ftb5n 1/1 Running 1 9m20s
kube-system kubernetes-dashboard-7ffd448895-88hnf 1/1 Running 0 4m35s
kube-system dashboard-metrics-scraper-6c4568dc68-868tr 1/1 Running 0 4m35s
kube-system coredns-86f78bb79c-9jlzx 1/1 Running 0 4m34s
You will need to wait for a few minutes to get all the pods in the “RUNNING” state.
Retrieve Kubernetes Admin User and Password
First, find the internal IP address of your server with the following command:
# hostname -I
You should get the following output:
69.87.218.121 10.1.89.0
Next, retrieve the admin username and password with the following command:
# microk8s.config
You should get the following output:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURBVENDQWVtZ0F3SUJBZ0lKQU1iaWp6RENQR09ETUEwR0NTcUdTSWIzRFFFQkN3VUFNQmN4RlRBVEJnTlYKQkFNTURERXdMakUxTWk0eE9ETXVNVEFlRncweU1UQXlNVEV3TWpRMU1qZGFGdzB6TVRBeU1Ea3dNalExTWpkYQpNQmN4RlRBVEJnTlZCQU1NRERFd0xqRTFNaTR4T0RNdU1UQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQCkFEQ0NBUW9DZ2dFQkFNN2tTNWR2NXRJZjB4QlI4VzJ3MWZZTzVqVm1KUmNwM3NNOUpkNnB1Qjg0R0lsSkRiaGQKTUJiMjgxaXYrM3hERXNDOHNLM2RQNVR0Qld3eGdCaUNYOERuN0orVVZra09vblA4VFlzNWxBWEFRMEZLb3BHVgpleHhiQTlySlA1RFNKT1VhOVlSd2VNcFl3ODY2MkM4cE9lOW1uWFE3VS9BcStYWlA2Nk0vWjVsbVQrSldIUHY2ClRKN2lHc2tPMTZtSE5LQnVsS0xHaWg2MEhvN2I2K0ZqOGRYOGNSd2EwUi9rOVl3TmNKbEtoeUtGNittYmxpQ2UKQ2cvci9BOXllWUZLeWhZZUFkVVIveGJIbGhFc2xmQnVJYlJvb01lN3p4cXIwamZwWUVYSE1mWFNzaFMrY0s2cApmRXFZWjNLMzlURVA3c21xQTBEcHZmM21sVHFIYkc4STlBOENBd0VBQWFOUU1FNHdIUVlEVlIwT0JCWUVGSlNBCkROUUwrZW5JYVBtdlorREFZK094WGcwZk1COEdBMVVkSXdRWU1CYUFGSlNBRE5RTCtlbklhUG12WitEQVkrT3gKWGcwZk1Bd0dBMVVkRXdRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUVCeDhrUkNzaHc1THpFeApwWjNwRnh1cGR3RW1PZndHbjM5RDZXdnRKUHZhOUNMRzNaenRDQitxT3pXanIzcDBSZmoxZE9KQkYvd3djUmFiCncyNHZ2QjBHZVJkTzUrWldiNGxZRno5cmx5UFdmMVM0OUZSeEM5czFaY3FqeTEvcGxiMm5FdjJHSlNhVkNrZzkKUXpwbW1ZVHFwaWoxSWV0Tk5JRG1hTXZBVHBJRUxmd2R0aUxRbHFJR1JKSzRiemJoZHdXSlUvVmd4Z2k0YlplbApGOGhWbTZSNy9KMnpKc1A0K0Q5aVVlZG9YZ3YreElOc1pXdnZJaHFJNHhodDdQZzEwd3hBYm0zVk0rY3hrRjF3ClVVcE1BRHI2WjB3ZkRqYTV2MWcwTmNQazAyMk5HRkhTb3AzTk5ySVZ2QkdvRHcxdm5vY3g0Y3o5cHlkSGlXaUcKRkZWeDBaQT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: https://69.87.218.121:16443
name: microk8s-cluster
contexts:
- context:
cluster: microk8s-cluster
user: admin
name: microk8s
current-context: microk8s
kind: Config
preferences: {}
users:
- name: admin
user:
token: TnR2VVZaRXJHY2xMSXNTK0E0eit2NSs0ek5Zam85YWEzemQrMlJlUVg2OD0K
You can also retrieve the admin username and password from the following file:
# cat /var/snap/microk8s/current/credentials/known_tokens.csv
You should see the following output:
TnR2VVZaRXJHY2xMSXNTK0E0eit2NSs0ek5Zam85YWEzemQrMlJlUVg2OD0K,admin,admin,"system:masters"
TmZEdC9xRGNMTkl1cFN3V1NoTzl2UmlHU2l6ZFd0cFRXeDkybndWcnljTT0K,system:kube-proxy,kube-proxy
V2kyeVVtdjVkdFRKcFBJOXNFZVpjUkZZUVQ1cmV2WnloRG80NW00ZGlnYz0K,system:node:ubuntu2004,kubelet-0,"system:nodes"
QXBma2JxeFRQZDJ0amthaGpiNGxuNy9OZVdPYmtDYVFVall5MEhTUFhtTT0K,system:kube-controller-manager,controller
N3cyTmkzbXJqUzU5WU9RdWtVVzAwQ0NqN2dsd3FJNkZ6NWs4NFhWSmJYUT0K,system:kube-scheduler,scheduler
You can now check the cluster status with the following command:
# microk8s.kubectl cluster-info
You should get the following output:
Kubernetes control plane is running at https://127.0.0.1:16443
Metrics-server is running at https://127.0.0.1:16443/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
CoreDNS is running at https://127.0.0.1:16443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Create a Deployment
Next, we'll deploy a microbot application on the Kubernetes cluster. To deploy a microbot application, run the following command:
# microk8s.kubectl create deployment microbot --image=dontrebootme/microbot:v1
Once deployed, check it with the following command:
# microk8s.kubectl get pods --all-namespaces
You should get the following output:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system metrics-server-8bbfb4bdb-c5rf8 1/1 Running 0 14m
kube-system calico-kube-controllers-847c8c99d-bp8mp 1/1 Running 0 19m
kube-system calico-node-ftb5n 1/1 Running 1 19m
kube-system kubernetes-dashboard-7ffd448895-88hnf 1/1 Running 0 14m
kube-system dashboard-metrics-scraper-6c4568dc68-868tr 1/1 Running 0 14m
kube-system coredns-86f78bb79c-9jlzx 1/1 Running 0 14m
default microbot-5f5499d479-vjt5d 1/1 Running 0 20s
You can now scale the deployment with the following command:
# microk8s.kubectl scale deployment microbot --replicas=5
Now, verify all replica with the following command:
# microk8s.kubectl get pods -n default
You should get the following output:
NAME READY STATUS RESTARTS AGE
microbot-5f5499d479-vjt5d 1/1 Running 0 56s
microbot-5f5499d479-qtmbd 1/1 Running 0 15s
microbot-5f5499d479-tzdvl 1/1 Running 0 15s
microbot-5f5499d479-422cc 1/1 Running 0 15s
microbot-5f5499d479-mq7mn 1/1 Running 0 15s
Now, expose the deployment with the following command:
# microk8s.kubectl expose deployment microbot --type=NodePort --port=80 --name=microbot-service
Now, confirm the deployment with the following command:
# microk8s.kubectl get all --all-namespaces
You should get the following output:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/metrics-server-8bbfb4bdb-c5rf8 1/1 Running 0 15m
kube-system pod/calico-kube-controllers-847c8c99d-bp8mp 1/1 Running 0 20m
kube-system pod/calico-node-ftb5n 1/1 Running 1 20m
kube-system pod/kubernetes-dashboard-7ffd448895-88hnf 1/1 Running 0 15m
kube-system pod/dashboard-metrics-scraper-6c4568dc68-868tr 1/1 Running 0 15m
kube-system pod/coredns-86f78bb79c-9jlzx 1/1 Running 0 15m
default pod/microbot-5f5499d479-vjt5d 1/1 Running 0 102s
default pod/microbot-5f5499d479-qtmbd 1/1 Running 0 61s
default pod/microbot-5f5499d479-tzdvl 1/1 Running 0 61s
default pod/microbot-5f5499d479-422cc 1/1 Running 0 61s
default pod/microbot-5f5499d479-mq7mn 1/1 Running 0 61s
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/kubernetes ClusterIP 10.152.183.1 443/TCP 20m
kube-system service/metrics-server ClusterIP 10.152.183.211 443/TCP 15m
kube-system service/kubernetes-dashboard ClusterIP 10.152.183.62 443/TCP 15m
kube-system service/dashboard-metrics-scraper ClusterIP 10.152.183.248 8000/TCP 15m
kube-system service/kube-dns ClusterIP 10.152.183.10 53/UDP,53/TCP,9153/TCP 15m
default service/microbot-service NodePort 10.152.183.138 80:32163/TCP 14s
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 20m
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
kube-system deployment.apps/metrics-server 1/1 1 1 15m
kube-system deployment.apps/calico-kube-controllers 1/1 1 1 20m
kube-system deployment.apps/kubernetes-dashboard 1/1 1 1 15m
kube-system deployment.apps/dashboard-metrics-scraper 1/1 1 1 15m
kube-system deployment.apps/coredns 1/1 1 1 15m
default deployment.apps/microbot 5/5 5 5 102s
NAMESPACE NAME DESIRED CURRENT READY AGE
kube-system replicaset.apps/metrics-server-8bbfb4bdb 1 1 1 15m
kube-system replicaset.apps/calico-kube-controllers-847c8c99d 1 1 1 20m
kube-system replicaset.apps/kubernetes-dashboard-7ffd448895 1 1 1 15m
kube-system replicaset.apps/dashboard-metrics-scraper-6c4568dc68 1 1 1 15m
kube-system replicaset.apps/coredns-86f78bb79c 1 1 1 15m
default replicaset.apps/microbot-5f5499d479 5 5 5 102s
As you can see, Microbot service is started and listening on port 32163.
You can verify it with the following command:
# curl http://localhost:32163
You should get the following output:
<!DOCTYPE html>
<html>
<style type=“text/css”>
.centered
{
text-align:center;
margin-top:0px;
margin-bottom:0px;
padding:0px;
}
</style>
<body>
<p class=“centered”><img src=“microbot.png” alt=“microbot”/></p>
<p class=“centered”>Container hostname: microbot-5f5499d479-qtmbd</p>
</body>
</html>
You can also access it using the URL http://your-server-ip:32163/. You should see the following page:
If you want to stop the Cluster at anytime, run the following command:
# microk8s.stop
You can start it again using the following command:
# microk8s.start
Conclusion
Congratulations! You have successfully set up a single-node Kubernetes cluster with MicroK8s.
You can now deploy and scale your application on the Kubernetes cluster.