8.6 Windows Container Networking & AKS Enabled by Azure Arc
Key Takeaways
- Windows container networking is implemented by the Host Network Service (HNS), which also provides IP address management for the nat and l2bridge drivers.
- The default nat driver attaches containers to an internal Hyper-V switch and requires published ports, and NAT networks created on Windows Server 2019 and above are not persisted across a reboot.
- The transparent driver gives containers a real physical-network address from DHCP or a static subnet, but requires MAC address spoofing when the host is a VM and is therefore not supported on Azure VMs.
- l2bridge rewrites container traffic to the host MAC address on ingress and egress, while the otherwise identical l2tunnel driver is Azure-only and hair-pins traffic to the virtualization host so SDN policy such as Network Security Groups applies.
- In a mixed AKS Hybrid cluster, Windows workloads must be pinned to nodes labelled kubernetes.io/os: windows with nodeSelector, plus tolerations when the Windows node pool is tainted, or they are scheduled onto Linux nodes and fail to start.
Windows Container Networking & AKS Enabled by Azure Arc
A container that cannot be reached is not much use. Section 8.5 covered running and constraining instances; this section covers connecting them — first on a single host through the Host Network Service (HNS), then across many hosts through AKS enabled by Azure Arc.
1. Windows Container Networking Modes
Windows container networking is implemented by the Host Network Service (HNS):
| Network mode | IP assignment | Routing | Primary use case |
|---|---|---|---|
| nat (default) | Internal WinNAT private subnet | Host port forwarding required (-p 8080:80) | Single-host development and standalone hosts |
| transparent | Physical subnet IP from DHCP or static | Directly addressable, no NAT | Workloads that must hold a real corporate IP |
| overlay | Overlay subnet via an SDN controller | VXLAN encapsulation across hosts | Multi-host Docker Swarm and Kubernetes |
| l2bridge | Physical subnet IP via a host bridge | Layer-2 packet rewrite on the same subnet | Kubernetes clusters using Azure CNI or SDN |
# List the container networks HNS currently owns
Get-HnsNetwork | Select-Object Name, Type, @{n='Subnet';e={$_.Subnets.AddressPrefix}}
# Create a transparent network bound to the physical corporate subnet
docker network create -d transparent `
-o com.docker.network.windowsshim.interface="Ethernet0" `
--subnet=192.168.10.0/24 --gateway=192.168.10.1 CorpTransparent
A container that must receive an address directly from the corporate DHCP server needs the transparent driver. NAT will not do it: NAT allocates from an internal WinNAT subnet and requires published ports.
Driver Mechanics the Exam Tests
- nat attaches containers to an internal Hyper-V switch. HNS performs IPAM from the internal NAT prefix, and you customise the default subnet with the
fixed-cidrsetting in the Docker daemon configuration file. Only one NAT internal prefix exists, so cross-subnet container-to-container traffic is not supported. NAT networks created on Windows Server 2019 and above are not persisted across a reboot. - transparent attaches containers to an external Hyper-V switch, so they take a real address from the physical network either statically or from an external DHCP server. Two hard limits: when the container host is itself a VM, MAC address spoofing must be enabled, and for that reason transparent networking is not supported on Azure VMs. Transparent networks also have no service discovery.
- overlay uses VXLAN encapsulation so containers on different hosts share a subnet, which is what Docker Swarm and Kubernetes need. On Windows Server 2019 and above, Swarm overlay networks use VFP NAT rules for outbound traffic, so ICMP tools such as
pingandTest-NetConnectionmust be run with their TCP/UDP options when debugging. - l2bridge also uses an external switch, but rewrites the container MAC address to the host's MAC on ingress and egress. In a datacenter this spares physical switches from learning the MAC address of every short-lived container.
- l2tunnel is created identically to l2bridge but should only be used in a Microsoft cloud stack (Azure). All container traffic is hair-pinned to the virtualization host so SDN policy — including Azure Network Security Groups for containers — can be applied.
2. Troubleshooting Container Networking
# Inspect what HNS believes exists
Get-HnsNetwork | Select-Object Name, Type, Id
Get-HnsEndpoint | Select-Object Id, VirtualNetworkName, IPAddress, MacAddress
# Confirm the published port mapping actually landed on the host
docker port web01
Get-NetNatStaticMapping
# Last resort: restarting HNS tears down and rebuilds container networking
Restart-Service hns
A useful diagnostic order is to confirm the network exists in Get-HnsNetwork, confirm the container has an endpoint with a sane IP in Get-HnsEndpoint, and only then look at the port mapping. A container that has an endpoint and an IP but is unreachable from outside the host on a nat network almost always means the port was never published with -p.
3. Azure Kubernetes Service Enabled by Azure Arc (AKS Hybrid)
Once a workload outgrows one host, AKS enabled by Azure Arc brings a managed Kubernetes control-plane experience to on-premises Windows Server and Azure Local infrastructure, governed from the Azure portal alongside cloud clusters.
Scheduling in a mixed Windows and Linux cluster is the exam-relevant detail. Kubernetes nodes are automatically labelled with kubernetes.io/os, and a Windows workload must be pinned to Windows nodes or it will be scheduled onto a Linux node and fail to start:
apiVersion: apps/v1
kind: Deployment
metadata:
name: iis-frontend
spec:
replicas: 3
selector:
matchLabels:
app: iis-frontend
template:
metadata:
labels:
app: iis-frontend
spec:
nodeSelector:
kubernetes.io/os: windows # pin to Windows Server worker nodes
containers:
- name: iis
image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022
resources:
limits:
cpu: "1"
memory: 2Gi
Where a cluster taints its Linux nodes, the Windows deployment also needs a matching tolerations block. The reverse is equally true: Linux workloads must be kept off Windows nodes, which is normally handled by tainting the Windows node pool.
Operating an Arc-Enabled Cluster
Because the cluster is projected into Azure Resource Manager as an Arc resource, it inherits the same governance surface as a cloud cluster:
| Capability | What it gives you on-premises |
|---|---|
| Azure Policy for Kubernetes | Audits and enforces cluster configuration through Gatekeeper admission control |
| Azure Monitor container insights | Node and pod telemetry from on-premises clusters in the same workspace as cloud clusters |
| Microsoft Defender for Containers | Threat detection for the on-premises cluster |
| GitOps (Flux) | Declarative, repository-driven configuration applied to the cluster |
| Microsoft Entra RBAC | Cluster access governed by directory identity rather than local kubeconfig files |
Exam trap: mixing operating systems in one cluster is the recurring scenario. Windows nodes are labelled kubernetes.io/os: windows, and a Windows container scheduled onto a Linux node fails to start. Pin Windows workloads with nodeSelector, add tolerations when the Windows node pool is tainted, and remember that troubleshooting a container on those worker nodes uses crictl, not docker, because Kubernetes nodes run containerd.
An administrator deploys a Windows Server container host as an Azure IaaS virtual machine and wants each container to receive an IP address directly from the virtual network's DHCP scope. They create a network with the transparent driver, but containers fail to obtain addresses. What is the cause?
A Windows container workload runs on a Microsoft cloud stack and must have Azure Network Security Group rules applied to individual containers. Which container network driver is designed for this requirement?
A mixed AKS Hybrid cluster contains both Windows Server and Linux worker nodes. After deploying a Windows Server Core based IIS workload, the pods remain in a failed state. Which manifest change resolves the problem?