Skip to content

Instantly share code, notes, and snippets.

@diegofcornejo
Created February 7, 2025 01:38
Show Gist options
  • Save diegofcornejo/29d9b748aa1ad97968859fbbdea5423c to your computer and use it in GitHub Desktop.
Save diegofcornejo/29d9b748aa1ad97968859fbbdea5423c to your computer and use it in GitHub Desktop.
How to Install MicroK8S on Ubuntu 24.04 (Single Node)

How to Install MicroK8S on Ubuntu 24.04 (Single Node)

Install MicroK8S

sudo snap install microk8s --classic

Add the current user to the microk8s group

sudo usermod -a -G microk8s $USER
newgrp microk8s

Check MicroK8S status

microk8s status --wait-ready

For convenience, create a kubectl alias

alias kubectl="microk8s kubectl"

Enable MicroK8S features

Note

Its recommended to enable the features one by one, this way you can troubleshoot any issues that may arise.

microk8s enable dns
microk8s enable dashboard
microk8s enable ingress
microk8s enable cert-manager

Add a certificate cluster issuer

Create the addon_letsencrypt_cluster.yml file

nano addon_letsencrypt_cluster.yml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    email: [email protected] # Replace with your email
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: public
mkctl apply -f addon_letsencrypt_cluster.yml

Check the status of the cluster issuer

mkctl get clusterissuer -o wide

Launch a basic Express API with Nginx ingress

Use any of the following yml files to create the deployment

mkctl apply -f express-api-nginx-ingress.yml # With cert-manager
#or
mkctl apply -f express-api2-nginx-ingress.yml # Without cert-manager

Check the status of the deployment

mkctl get pods -o wide

Go to the url defined in the ingress resource

http://<hostname>

You should see the Express API running

Connect to cluster remotely with local kubectl

Connect to your cluster and get the config

mkctl config > config

Copy the config to your local machine

scp config $USER@$HOSTNAME:~/.kube/config

On your local machine

Replace the IP address with the public IP address of your cluster

nano ~/.kube/config
# find this line
server: https://<ip>:16443
# replace it with
server: https://<public-ip>:16443

Check the status of the cluster

kubectl get pods -o wide

Note

If you get an error about accessing the cluster, because your IP is not whitelisted, you can try the following:

Connect to the cluster

sudo nano /var/snap/microk8s/current/certs/csr.conf.template

Add your IP to the csr.conf.template file

IP.1=<your-ip> # Continue adding your IP until you reach the last IP

Restart the microk8s

microk8s stop
microk8s start

Check your Public IP is whitelisted

openssl x509 -in /var/snap/microk8s/current/certs/server.crt -noout -text | grep "IP Address"
# you should see your IP in the output

Now copy the config again to your local machine and connect to the cluster

apiVersion: apps/v1
kind: Deployment
metadata:
name: api1-deployment
labels:
app: api1
spec:
replicas: 3
selector:
matchLabels:
app: api1
template:
metadata:
labels:
app: api1
spec:
containers:
- name: api1
image: diegofcornejo/express-basic-api:env
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: api1
spec:
selector:
app: api1
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api1-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- api1.diegocornejo.com
secretName: api1-tls
rules:
- host: api1.diegocornejo.com
http:
paths:
- path: /
pathType: Exact
backend:
service:
name: api1
port:
number: 80
apiVersion: apps/v1
kind: Deployment
metadata:
name: api2-deployment
labels:
app: api2
spec:
replicas: 3
selector:
matchLabels:
app: api2
template:
metadata:
labels:
app: api2
spec:
containers:
- name: api2
image: diegofcornejo/express-basic-api:env
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: api2
spec:
selector:
app: api2
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api2-ingress
spec:
rules:
- host: api2.diegocornejo.com
http:
paths:
- path: /
pathType: Exact
backend:
service:
name: api2
port:
number: 80
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment