Running the UniFi Network Application on Kubernetes MicroK8s

Share with:


If you use Ubiquiti for your wireless routing hardware you will need to run the Unifi Network Application to manage your hardware. In this post I’ll show you how to run the Unifi Network Application on a local Kubernetes instance. In this case I am using MicroK8s, but the approach should work for any Kubernetes stack.

This post leverages load balancing and the endpoint is secured with TLS. Setting up load balancing is another topic entirely so I won’t cover that here, for more information see Load Balancing with MicroK8s Kubernetes

Installing the Unifi Network Application

Please create each Kubernetes component, in the order as follows (top to bottom).

Persistent-Volume.yaml

Create a persistent volume to ensure that data is maintained between recycles and container upgrades. There are several types of persistent volumes, this example leverages a local folder on the Kubernetes worker node at /data/unifi. Create this folder on each of your worker nodes first. Alternatively, you could mount a network volume.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: unifi-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /data/unifi
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - MicroK8sWorker1.local

Persistent-Volume-Claim.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: unifi-pv-claim
  labels:
    app: unifi
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: "" # Empty string must be explicitly set otherwise default StorageClass will be set
  volumeName: unifi-pv

Deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: unifi-deployment
  labels:
    app: unifi
spec:
  replicas: 1
  selector:
    matchLabels:
      app: unifi
  template:
    metadata:
      labels:
        app: unifi
    spec:
      containers:
        - name: unifi
          image: linuxserver/unifi-controller:latest
          ports:
            - containerPort: 3478
              protocol: UDP
            - containerPort: 10001
              protocol: UDP
            - containerPort: 8080
              protocol: TCP
            - containerPort: 8443
              protocol: TCP
            - containerPort: 1900
              protocol: UDP
            - containerPort: 8843
              protocol: TCP
            - containerPort: 8880
              protocol: TCP
            - containerPort: 6789
              protocol: TCP
            - containerPort: 5514
              protocol: UDP
          volumeMounts:
            - name: unifi-persistent-storage
              mountPath: /config
      volumes:
      - name: unifi-persistent-storage
        persistentVolumeClaim:
          claimName: unifi-pv-claim

Service.yaml

apiVersion: v1
kind: Service
metadata:
  name: unifi
spec:
  type: ClusterIP
  selector:
    app: unifi
  ports:
    - name: http
      port: 80
      targetPort: 8080
      protocol: TCP
    - name: https
      port: 443
      targetPort: 8443
      protocol: TCP
    - name: port3478
      port: 3478
      targetPort: 3478
      protocol: UDP
    - name: unifidiscovery
      port: 10001
      targetPort: 10001
      protocol: UDP
    - name: port8080
      port: 8080
      targetPort: 8080
      protocol: TCP
    - name: port8443
      port: 8443
      targetPort: 8443
      protocol: TCP
    - name: port1900
      port: 1900
      targetPort: 1900
      protocol: UDP
    - name: port8843
      port: 8843
      targetPort: 8843
      protocol: TCP
    - name: port8880
      port: 8880
      targetPort: 8880
      protocol: TCP
    - name: port6789
      port: 6789
      targetPort: 6789
      protocol: TCP
    - name: port5514
      port: 5514
      targetPort: 5514
      protocol: UDP

Service-Lb-Udp.yaml

The UDP and TCP services are separated due to Kubernetes requirement. Multiple protocols cannot currently be described within the same service.

apiVersion: v1
kind: Service
metadata:
  name: unifi-ingress-udp
  namespace: ingress
  annotations:
    metallb.universe.tf/allow-shared-ip: "unifi-shared-ip"
spec:
  selector:
    name: nginx-ingress-microk8s
  type: LoadBalancer
  # loadBalancerIP is optional. MetalLB will automatically allocate an IP 
  # from its pool if not specified. You can also specify one manually.
  # loadBalancerIP: x.y.z.a
  ports:
    - name: udp-1900
      protocol: UDP
      port: 1900
      targetPort: 1900
    - name: udp-3478
      protocol: UDP
      port: 3478
      targetPort: 3478
    - name: udp-5514
      protocol: UDP
      port: 5514
      targetPort: 5514
    - name: udp-10001
      protocol: UDP
      port: 10001
      targetPort: 10001

Service-Lb-Tcp.yaml

apiVersion: v1
kind: Service
metadata:
  name: unifi-ingress-tcp
  namespace: ingress
  annotations:
    metallb.universe.tf/allow-shared-ip: "unifi-shared-ip"
spec:
  selector:
    name: nginx-ingress-microk8s
  type: LoadBalancer
  # loadBalancerIP is optional. MetalLB will automatically allocate an IP 
  # from its pool if not specified. You can also specify one manually.
  # loadBalancerIP: x.y.z.a
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
    - name: https
      protocol: TCP
      port: 443
      targetPort: 443
    - name: tcp-8080
      protocol: TCP
      port: 8080
      targetPort: 8080
    - name: tcp-8443
      protocol: TCP
      port: 8443
      targetPort: 8443
    - name: tcp-6789
      protocol: TCP
      port: 6789
      targetPort: 6789
    - name: tcp-8843
      protocol: TCP
      port: 8843
      targetPort: 8843
    - name: tcp-8880
      protocol: TCP
      port: 8880
      targetPort: 8880

Secret-Tls.yaml

This is where you will determine the host name which will be used to serve the Unifi Network Application. To create the TLS secret, you’ll need to first create or obtain a TLS key and certificate associated with your desired host name. Convert the key and cert files to base64 with:

base64 -w 0 /path/to/your/cert

Insert the base64 encoded values into the following yaml and create the secret.

apiVersion: v1
kind: Secret
metadata:
  name: unifi-tls
type: kubernetes.io/tls
data:
  tls.crt: (single line base64 encoded certificate goes here)
  tls.key: (single line base64 encoded key goes here)

Ingress.yaml

Replace “unifi.local” with the host name that matches certificate from the above step. Ensure that this name is setup in your local DNS and can be resolved by your Ubiquiti hardware. You can find the IP for the Unifi Network Application by running microk8s.kubektl get svc -n ingress. Look for the External-Ip under unifi-ingress-tcp.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: unifi-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  tls:
    - hosts:
        - unifi.local
      secretName: unifi-tls
  rules:
    - host: unifi.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: unifi
                port:
                  number: 443

Ingress-Udp-Config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-ingress-udp-microk8s-conf
  namespace: ingress
data:
  1900: "default/unifi:1900"
  3478: "default/unifi:3478"
  5514: "default/unifi:5514"
  10001: "default/unifi:10001"

Ingress-Tcp-Config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-ingress-tcp-microk8s-conf
  namespace: ingress
data:
  6789: "default/unifi:6789"
  8080: "default/unifi:8080"
  8443: "default/unifi:8443"
  8843: "default/unifi:8843"
  8880: "default/unifi:8880"

You should be able to log into your Unifi Network Application at https://unifi.local or the name chosen when creating the TLS secret.

Upgrading the Unifi Network Application

Before upgrading, always take a backup and store it in a secure location. Failure to do so may lead to irretrievable loss and require access to all hardware for reset.

To upgrade the Unifi Network Application run the following, and replace ‘latest’ with the desired version:

microk8s.kubectl set image deployment unifi-deployment unifi=linuxserver/unifi-controller:latest

Share with:


Leave a Reply

Your email address will not be published. Required fields are marked *

*


The reCAPTCHA verification period has expired. Please reload the page.