I have a small 2 node Kubernetes cluster, running on Proxmox. My TP-Link Omada controller was running on a Docker VM in a Portainer stack. I moved the controller from the docker container to Kubernetes.
The docker-compose for the stack is below:
Notes:
- network mode is host
- two persistent volumes
version: "3.1"
services:
omada-controller:
container_name: omada-controller
image: mbentley/omada-controller:latest
restart: unless-stopped
ulimits:
nofile:
soft: 4096
hard: 8192
stop_grace_period: 60s
network_mode: host
environment:
- PUID=508
- PGID=508
- MANAGE_HTTP_PORT=8088
- MANAGE_HTTPS_PORT=8043
- PORTAL_HTTP_PORT=8088
- PORTAL_HTTPS_PORT=8844
- PORT_APP_DISCOVERY=27001
- PORT_DISCOVERY=29810
- PORT_MANAGER_V1=29811
- PORT_ADOPT_V1=29812
- PORT_UPGRADE_V1=29813
- PORT_MANAGER_V2=29814
- PORT_TRANSFER_V2=29815
- PORT_RTTY=29816
- SHOW_SERVER_LOGS=true
- SHOW_MONGODB_LOGS=false
- SSL_CERT_NAME=tls.crt
- SSL_KEY_NAME=tls.key
- TZ=Etc/UTC
volumes:
- /root/omada-port/omada-data:/opt/tplink/EAPController/data
- /root/omada-port/omada-logs:/opt/tplink/EAPController/logs
volumes:
omada-data:
omada-logs:
My Kubernetes cluster notes:
- i am using MetalLB, and i have a range of 10 IPs for cases where pods need to be accessed from the network. Range is
192.168.100.81 - 192.168.100.90
- i use TrueNAS Scale with NFS shares provisioned dynamically.
Initially it didn’t discover TP-Link devices on the network because i was missing the UDP ports.

The namespace is omada.
omada-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: omada-data-nfs
namespace: omada
spec:
storageClassName: nfs
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: omada-logs-nfs
namespace: omada
spec:
storageClassName: nfs
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
omada-service.yaml
apiVersion: v1
kind: Service
metadata:
name: omada-controller
namespace: omada
spec:
type: LoadBalancer
loadBalancerIP: 192.168.100.83 # Static IP assigned by MetalLB
ports:
- name: http
protocol: TCP
port: 8088
targetPort: 8088
- name: https
protocol: TCP
port: 8043
targetPort: 8043
- name: app-discovery
protocol: TCP
port: 27001
targetPort: 27001
- name: udp-management
protocol: UDP
port: 19810
targetPort: 19810
- name: udp-discovery
protocol: UDP
port: 29810
targetPort: 29810
- name: tcp-manager-v1
protocol: TCP
port: 29811
targetPort: 29811
- name: tcp-adopt-v1
protocol: TCP
port: 29812
targetPort: 29812
- name: tcp-upgrade-v1
protocol: TCP
port: 29813
targetPort: 29813
- name: tcp-manager-v2
protocol: TCP
port: 29814
targetPort: 29814
- name: tcp-transfer-v2
protocol: TCP
port: 29815
targetPort: 29815
- name: tcp-rtty
protocol: TCP
port: 29816
targetPort: 29816
selector:
app: omada-controller
omada-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: omada-controller
namespace: omada
spec:
replicas: 1
selector:
matchLabels:
app: omada-controller
template:
metadata:
labels:
app: omada-controller
spec:
#hostNetwork: true
containers:
- name: omada-controller
image: mbentley/omada-controller:latest
env:
- name: PUID
value: "508"
- name: PGID
value: "508"
- name: MANAGE_HTTP_PORT
value: "8088"
- name: MANAGE_HTTPS_PORT
value: "8043"
- name: PORTAL_HTTP_PORT
value: "8088"
- name: PORTAL_HTTPS_PORT
value: "8844"
- name: PORT_APP_DISCOVERY
value: "27001"
- name: PORT_ADOPT_V1
value: "29812"
- name: PORT_UPGRADE_V1
value: "29813"
- name: PORT_MANAGER_V1
value: "29811"
- name: PORT_MANAGER_V2
value: "29814"
- name: PORT_DISCOVERY
value: "29810"
- name: PORT_TRANSFER_V2
value: "29815"
- name: PORT_RTTY
value: "29816"
- name: SHOW_SERVER_LOGS
value: "true"
- name: SHOW_MONGODB_LOGS
value: "false"
- name: SSL_CERT_NAME
value: "tls.crt"
- name: SSL_KEY_NAME
value: "tls.key"
- name: TZ
value: "Etc/UTC"
volumeMounts:
- name: omada-data
mountPath: /opt/tplink/EAPController/data
- name: omada-logs
mountPath: /opt/tplink/EAPController/logs
securityContext:
capabilities:
add: ["SYS_RESOURCE"] # Required to change ulimits
resources: {} # Ensure no invalid entries
volumes:
- name: omada-data
persistentVolumeClaim:
claimName: omada-data-nfs
- name: omada-logs
persistentVolumeClaim:
claimName: omada-logs-nfs
In order to transfer the backup data i used method 3 described here: https://community.tp-link.com/en/business/forum/topic/663178
But my AP HD620 was not migrating to the new controller so i had to reset it, connect my laptop to the default open network it generated, go to my router to see what IP the AP was using, access that IP with the default admin/admin credentials and then adopt it.