This documents how to set up microk8s with nginx-ingress. I wanted this set-up so I can self-host multiple websites on a single-node Kubernetes cluster. I will use NAT from my router to forward traffic to port 443 and port 80.

These are mostly notes for me to remember how I set everything up.

First, install microk8s on Ubuntu 20.04 LTS.

sudo snap install microk8s --classic

Enable kubectl to access it from another machine. Solution from:

https://github.com/ubuntu/microk8s/issues/421
Open insecure port 8080 to everyone. To do this you need to edit /var/snap/microk8s/current/args/kube-apiserver and set the --insecure-bind-address=127.0.0.1 to 0.0.0.0. Then restart MicroK8s with microk8s.stop and microk8s.start.
--insecure-port=8080
--insecure-bind-address=0.0.0.0

Restart microk8s

microk8s.stop
microk8s.start

Enable addons

microk8s enable dns
microk8s enable storage

On another machine, set up connection in ~/.kube/config

apiVersion: v1
clusters:
- cluster:
    server: http://kubernetes:8080
  name: microk8s-cluster
contexts:
- context:
    cluster: microk8s-cluster
    user: admin
  name: microk8s
current-context: microk8s
kind: Config
preferences: {}
users:
- name: admin
  user:
    username: admin

Run this command:

kubectl get all --all-namespaces

To display the current enabled addons:

NAMESPACE     NAME                                        READY   STATUS    RESTARTS   AGE
kube-system   pod/coredns-588fd544bf-lsj6j                1/1     Running   0          2m32s
kube-system   pod/hostpath-provisioner-75fdc8fccd-72hr7   1/1     Running   0          119s


NAMESPACE     NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
default       service/kubernetes   ClusterIP   10.152.183.1    <none>        443/TCP                  9m20s
kube-system   service/kube-dns     ClusterIP   10.152.183.10   <none>        53/UDP,53/TCP,9153/TCP   2m32s


NAMESPACE     NAME                                   READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/coredns                1/1     1            1           2m32s
kube-system   deployment.apps/hostpath-provisioner   1/1     1            1           2m

NAMESPACE     NAME                                              DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/coredns-588fd544bf                1         1         1       2m32s
kube-system   replicaset.apps/hostpath-provisioner-75fdc8fccd   1         1         1       2m

I couldn’t get the included nginx-ingress to work. What worked for me after being stuck for hours, was to use the Bitnami helm chart. (Thanks Todd!)

Check your helm version

helm version --short
v3.2.1+gfe51cd1

Add the Bitnami repo

helm repo add bitnami https://charts.bitnami.com/bitnami

Specify a namespace

kubectl create namespace nginx-ingress

I will use some assigned high port numbers and map port 80 and 443 to 31180 and 31443.

helm install nginx-ingress bitnami/nginx-ingress-controller \
	--namespace nginx-ingress \
	--set service.nodePorts.http=31180 \
	--set service.nodePorts.https=31443

This will create a LoadBalancer listening on those ports.

nginx-ingress   service/nginx-ingress-nginx-ingress-controller                   LoadBalancer   10.152.183.213   <pending>     80:31180/TCP,443:31443/TCP   11m

Load a bunch of yaml in:

kubectl apply -f test-site.yml

test-site.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-site
spec:
  selector:
    matchLabels:
      run: test-site
  replicas: 1
  template:
    metadata:
      labels:
        run: test-site
    spec:
      containers:
      - name: test-site
        image: nginx
        ports:
        - containerPort: 80
      imagePullSecrets:
      - name: gcr-json-key

---

apiVersion: v1
kind: Service
metadata:
  name: test-site
  labels:
    run: test-site
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: test-site

---

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-site-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: test.timestretch.com
    http:
      paths:
      - backend:
          serviceName: test-site
          servicePort: 80

---