Azure Kubernetes Service (AKS)
Read this page before step 1. It covers what's specific to Azure Kubernetes Service (AKS). Everything else follows the standard installation steps.
Before you start
Plan the cluster with these recommendations:
| Item | Recommendation |
|---|---|
| Kubernetes | A version AKS supports without the LTS plan (check az aks get-versions) |
| Nodes | A system pool for AKS add-ons, plus a user pool for OpenLM Platform. For the standard set: 3 × Standard_D8s_v5 (8 vCPU / 32 GiB) in the user pool. Larger sites: see Sizing. |
| Networking | Azure CNI Overlay. Outbound traffic through a NAT gateway with a static public IP, so you can allow that IP in the Azure SQL and Redis firewalls |
| API access | If you restrict the API server to authorized IP ranges, include the NAT gateway IP, or nodes can't join (K8SAPIServerConnFail) |
Ingress
Install ingress-nginx (or Traefik) behind the Azure Standard Load Balancer:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginx -n ingress --create-namespace \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
--set controller.config.proxy-body-size=50m
kubectl -n ingress get service ingress-nginx-controller # EXTERNAL-IP for your DNS A record
Set INGRESS_CLASS=nginx in your worksheet. The AKS application routing add-on (managed nginx) also works: its class is webapprouting.kubernetes.azure.com.
AGIC terminates TLS on the Application Gateway, with its own certificate handling and annotations. The OpenLM Platform Ingress isn't built for it. Put ingress-nginx or Traefik in the cluster instead. An Application Gateway or Front Door in front of that controller works, as long as it passes the Host header and uses a certificate for the same DOMAIN.
Storage
Use managed-csi (Azure Disk, disk.csi.azure.com). Don't use an Azure Files class for OpenLM Platform volumes or for databases you run in the cluster, even if it's the cluster default.
Node settings
Set the file-watch limits with the DaemonSet, or with the node pool's custom node configuration (linuxOSConfig.sysctls) if your AKS version supports those keys.
Node pools
To use node placement, which is optional, create the pools with the label and the taint:
az aks nodepool add -g <rg> --cluster-name <aks> -n openlmmain \
--node-vm-size Standard_D4s_v5 --node-count 4 \
--labels openlm.com/role=main --node-taints openlm.com/role=main:NoSchedule
az aks nodepool add -g <rg> --cluster-name <aks> -n openlmspark \
--node-vm-size Standard_D4s_v5 --node-count 1 \
--labels openlm.com/role=spark --node-taints openlm.com/role=spark:NoSchedule
Pool names can have at most 12 characters. The label values are exactly main and spark.
Values
AKS needs no values beyond what step 4 gives you. If you use labeled pools, also set global.affinity.enabled: true and global.taints.enabled: true.
Data services
Use these Azure services, or your own, for the data services:
| Service | Azure option | Worksheet settings |
|---|---|---|
| SQL Server | Azure SQL Database (single databases or an Elastic Pool) or SQL Managed Instance | SQL_HOST=<server>.database.windows.net, SQL_ENCRYPT=True. Allow the NAT gateway IP in the server firewall, or use a private endpoint. |
| Redis | Azure Managed Redis or Azure Cache for Redis | REDIS_TLS=true. Azure Managed Redis: port 10000, clustering policy non-clustered. Azure Cache for Redis: port 6380. Use an access key as REDIS_PASSWORD. |
| Kafka | Your own Kafka (in the cluster or on VMs), or Confluent Cloud | Plaintext listener inside your network is the standard. OpenLM hasn't validated Azure Event Hubs (Kafka endpoint) with OpenLM Platform. Confluent Cloud needs SASL: contact OpenLM first. |
| MongoDB | MongoDB Atlas (private endpoint or peering), or MongoDB in the cluster | Azure Cosmos DB for MongoDB isn't supported. |
With the clustered policies, commands that touch several keys fail with CROSSSLOT errors in the API gateway and in the services' background jobs. Choose the non-clustered policy when you create the cache.
On Azure SQL, create the four databases in the portal, with az sql db create, or in an Elastic Pool, named as in step 2. The sqlcmd loop from step 2 works too, connected to the master database. Azure SQL Database has no SQL Agent and no cross-database queries. OpenLM Platform doesn't need either.
Checks specific to AKS
Confirm the AKS settings with these commands:
kubectl get nodes -L openlm.com/role: nodesReady, labels as you intended.kubectl -n ingress get service: the controller has a public (or internal) IP.- From a pod, SQL Server and Redis answer (the checks in step 2). A timeout usually means the firewall doesn't allow the NAT gateway IP.
The documentation team might draft this page using a large language model. A technical writer reviews every page and verifies it against the product before publishing it. A human makes the final decision.