Documentation Index
Fetch the complete documentation index at: https://resources.devweekends.com/llms.txt
Use this file to discover all available pages before exploring further.
Kubernetes on Windows & Linux
Kubernetes was originally Linux-only, but now supports Windows worker nodes, enabling hybrid clusters. This matters because many enterprises run critical workloads on .NET Framework, IIS, and SQL Server — applications that cannot run on Linux without a costly rewrite. Hybrid clusters let you manage everything from one control plane while running each workload on its native operating system.Why Windows Containers?
Think of a hybrid Kubernetes cluster like a bilingual office: everyone follows the same company policies (Kubernetes API, scheduling, networking), but different teams work in different languages (Linux or Windows). The control plane is the management layer that speaks both.- Legacy Apps: Lift-and-shift .NET Framework applications that are tightly coupled to Windows APIs (Win32, COM, registry). Rewriting them for Linux is often a multi-year project. Containerizing them on Windows buys you orchestration benefits immediately.
- Unified Management: Manage Windows and Linux apps with the same tool (Kubernetes), same CI/CD pipelines, same monitoring stack, same RBAC model. Without this, teams maintain two completely separate infrastructure stacks.
- Modernization: Gradually refactor monoliths into microservices. New services run on Linux, legacy services stay on Windows, and they communicate through Kubernetes Services and DNS. This is the “strangler fig” pattern applied to infrastructure.
Architecture: Hybrid Cluster
A Kubernetes cluster can contain both Linux and Windows nodes.- Control Plane: MUST run on Linux.
- Worker Nodes: Can be Linux or Windows.
Scheduling Workloads
You must ensure Windows Pods land on Windows Nodes and Linux Pods land on Linux Nodes.Using nodeSelector
The kubernetes.io/os label is automatically applied to every node by the kubelet. You do not need to add it manually — it is a built-in label that Kubernetes populates based on the node’s operating system.
Using Taints and Tolerations
nodeSelector tells Kubernetes where a pod wants to go. Taints and tolerations tell Kubernetes where a pod cannot go. In a hybrid cluster, you need both — nodeSelector is the “pull” (attract to the right node) and taints are the “push” (repel from the wrong node). This belt-and-suspenders approach prevents scheduling accidents, especially from DaemonSets and system pods that do not have OS-specific selectors.
-
Taint the Windows Node (prevents any pod without a matching toleration from landing here):
-
Add Toleration to Windows Pod (allows this pod to be scheduled on tainted nodes):
Key Differences & Limitations
Understanding these differences is critical for capacity planning and debugging. The most common surprise for teams new to Windows containers is image size and its cascading effects on pull times, disk usage, and node scaling speed.| Feature | Linux | Windows |
|---|---|---|
| Container Base Image | Small (Alpine ~5MB, Debian ~120MB) | Large (Server Core ~3GB, Nano Server ~250MB) |
| Startup Time | Seconds | Seconds to Minutes (image pull dominates) |
| Networking | Bridge, Overlay, Host | Host Networking not supported |
| Privileged Containers | Supported | Not Supported (HostProcess containers are the closest alternative, K8s 1.26+) |
| Filesystem | Case-sensitive | Case-insensitive (can break apps that rely on case-sensitive paths) |
| Active Directory | Via LDAP/Kerberos | GMSA (Group Managed Service Accounts) |
| Container Isolation | Kernel namespaces | Process isolation (same kernel) or Hyper-V isolation (separate kernel) |
| OS Version Matching | N/A (shared kernel) | Container OS version must match host OS version for process isolation |
Best Practices
Use Taints and Tolerations
Use Taints and Tolerations
Image Management
Image Management
nerdctl or ctr to inspect the OS version of an image before deploying.GMSA for Auth
GMSA for Auth
Choose the Right Base Image
Choose the Right Base Image
Common Pitfalls
Interview Questions & Answers
Can the Kubernetes control plane run on Windows?
Can the Kubernetes control plane run on Windows?
How do you ensure pods land on the correct OS node?
How do you ensure pods land on the correct OS node?
kubernetes.io/os: windows (or linux) to attract pods to the right nodes, and 2) Taints and tolerations to repel pods from the wrong nodes. The nodeSelector alone is not enough because DaemonSets and third-party charts may not include selectors. Taints provide the safety net.What is process isolation vs Hyper-V isolation?
What is process isolation vs Hyper-V isolation?
Congratulations! You have completed the Kubernetes Crash Course and the entire DevOps Tools Mastery course!
Interview Deep-Dive
Your company wants to run a legacy .NET Framework 4.8 application alongside Linux microservices in the same Kubernetes cluster. What are the architectural constraints and operational challenges?
Your company wants to run a legacy .NET Framework 4.8 application alongside Linux microservices in the same Kubernetes cluster. What are the architectural constraints and operational challenges?
- The control plane must run on Linux — there is no Windows control plane. Windows nodes are workers only.
- Every pod spec must declare which OS it targets using
nodeSelector: kubernetes.io/os: windows(or linux). Without this, Kubernetes might schedule a Linux container on a Windows node, which fails immediately. - DaemonSets are the biggest pain point. Fluentd, node-exporter, and CNI plugins are Linux containers and fail on Windows nodes. You need Windows-specific DaemonSets for monitoring, and those tools have less mature Windows support.
- Windows images are huge (Server Core is 3+ GB vs 5MB Alpine). Pull times affect deployment speed and autoscaling responsiveness. Use image caching or pre-pulling.
- Windows containers do not support privileged mode, so security tools relying on privileged access will not work.
How do you handle Active Directory authentication for Windows containers in Kubernetes?
How do you handle Active Directory authentication for Windows containers in Kubernetes?
- Windows containers cannot join a domain directly, so Kubernetes supports Group Managed Service Accounts (GMSA). A GMSA is a domain account that multiple machines share without knowing the password — the domain controller manages credentials.
- Setup: create a GMSA in Active Directory, configure a
GMSACredentialSpecresource in Kubernetes, and reference it in the pod’ssecurityContext.windowsOptions.gmsaCredentialSpecName. - The kubelet on the Windows node retrieves credentials from AD and makes them available to the container. The application authenticates to SQL Server, file shares, or other AD services using Kerberos.
- The operational challenge: Windows nodes must be domain-joined. This complicates autoscaling because new nodes need domain joining before they can run GMSA-enabled pods.
You need to run GPU nodes for ML, Windows nodes for .NET, and standard Linux nodes in the same cluster. How do you ensure workloads land on the right nodes?
You need to run GPU nodes for ML, Windows nodes for .NET, and standard Linux nodes in the same cluster. How do you ensure workloads land on the right nodes?
- Use taints and tolerations (repel wrong workloads) combined with nodeSelectors (attract right workloads).
- GPU nodes: taint with
nvidia.com/gpu=true:NoSchedule. Only ML pods with the toleration and a GPU resource request land there. Without the taint, non-GPU workloads consume GPU node resources. - Windows nodes: taint with
os=windows:NoSchedule. Only Windows pods with the toleration andnodeSelector: kubernetes.io/os: windowsland there. Prevents Linux DaemonSets from failing on Windows nodes. - Standard Linux nodes: no special taints, but add
nodeSelector: kubernetes.io/os: linuxto Linux workloads as a safety net. - For cost optimization, GPU and Windows nodes should be in separate autoscaling node pools that can scale to zero when idle.
NoSchedule prevents new pods from scheduling on the node but leaves existing pods alone. NoExecute also evicts existing pods that do not tolerate the taint. You can add tolerationSeconds to NoExecute tolerations for graceful eviction — “tolerate for 300 seconds, then get evicted” gives in-flight requests time to complete before the pod is removed.Next: Back to Overview →