Why Enterprise AKS Clusters Need a Private API Server

A common AKS configuration leaves the Kubernetes API server reachable from the internet, protected only by authorized IP ranges. Here is why that falls short and how to remediate it.

September 20268 min readAzure Kubernetes Service · Private Link · DNS

The illusion of authorized IP ranges

When you create an Azure Kubernetes Service (AKS) cluster, the default configuration binds a public IP address to the Kubernetes control plane. Many security teams try to satisfy compliance requirements by enabling authorized IP ranges. That blocks arbitrary addresses, but it still leaves the control plane exposed to internet-wide port scans, to vulnerabilities in the kube-apiserver itself, and to drift whenever remote egress addresses change.

The real risk: control plane exploitation

If a Kubernetes vulnerability bypasses authentication (CVE-2018-1002105 is the well-known example), anyone who can reach the endpoint from an allowed range, for example through a compromised office network or a shared egress address, may be able to take over the cluster. A private IP removes the public route entirely.

The DNS challenge with Private Link

Teams usually fall back to public clusters because of DNS. When a private cluster replaces authorized IP ranges, Azure creates a private endpoint in your subnet and issues a fully qualified domain name such as:

cluster-aks-privatelink.eastus.azmk8s.io -> 10.240.0.14 (private IP)

Without an Azure Private DNS zone linked to every virtual network that needs it, including the management transit hub and your VPN or ExpressRoute gateways, CI/CD runners in GitHub Actions or Azure DevOps cannot resolve that hostname.

graph LR subgraph Public Internet Scan["Public internet scanners"] end subgraph Corporate Transit Network DevOps["Azure DevOps / GitHub runners"] Bastion["Azure Bastion host"] DNS["Private DNS resolver
privatelink.eastus.azmk8s.io"] end subgraph Private AKS VNet subgraph Subnet PE["API server private endpoint
10.240.0.14"] end subgraph Managed AKS Control Plane K8sAPI["Private kube-apiserver"] end end Scan -.-x|Blocked: no public IP| K8sAPI DevOps -->|Resolves via private DNS| PE Bastion -->|Resolves via private DNS| PE PE -->|Azure Private Link| K8sAPI
Runners and the Bastion host reach the API server through a private endpoint; there is no public route to block.

Production remediation blueprint

To close the public route without breaking automated deployments, work in three steps:

  1. Own the private DNS zone. Pre-provision a dedicated zone (privatelink.<region>.azmk8s.io) in your platform connectivity subscription instead of letting AKS generate one with the cluster.
  2. Run pipeline agents inside the network. Host CI/CD runners in a peered spoke virtual network that can resolve the private control plane name.
  3. Terminate ingress at a WAF. Route public workload traffic through Application Gateway WAF v2 to the cluster's ingress, while cluster administration stays private.

Find your tier in three questions.

Or book a free 30-minute architecture assessment.