Veröffentlicht am

Windows Container auf Kubernetes betreiben

Teilen:
Authors

TL;DR

Kubernetes unterstützt Windows Worker Nodes neben Linux Nodes im selben Cluster. Die Control Plane läuft immer auf Linux. Mit nodeSelector und Taints steuerst du, welche Pods auf Windows Nodes landen. Beachte die Einschränkungen: kein Privileged Mode, kein HostNetwork, kein DaemonSet auf Windows ohne spezielle Konfiguration.


Windows Container auf Kubernetes — Hybrid-Cluster einrichten

Nicht jede Anwendung lässt sich auf Linux portieren. Legacy-.NET-Framework-Apps, Windows-Dienste oder IIS-basierte Workloads brauchen einen Windows-Kernel. Kubernetes kann seit Version 1.14 (GA seit 1.22) Windows Worker Nodes in den Cluster einbinden.

Architektur: Was läuft wo?

Die wichtigste Regel zuerst:

# Control Plane prüfen — läuft immer auf Linux
kubectl get nodes -o wide
# NAME          STATUS   OS-IMAGE             KERNEL-VERSION
# master-01     Ready    Ubuntu 22.04         5.15.0
# worker-lin    Ready    Ubuntu 22.04         5.15.0
# worker-win    Ready    Windows Server 2022  10.0.20348
KomponenteBetriebssystemAnmerkung
etcd, API Server, SchedulerLinuxImmer Linux, nicht verhandelbar
CoreDNS, kube-proxyLinux + Windowskube-proxy läuft auf beiden
Anwendungs-PodsLinux oder WindowsÜber nodeSelector gesteuert

Windows Nodes führen das kubelet und kube-proxy als Windows-Services aus. Container laufen entweder als Windows Server Container (Process Isolation) oder als Hyper-V-isolierte Container.

Node Pool einrichten

Bei Managed-Kubernetes-Diensten wie AKS ist ein Windows Node Pool schnell erstellt:

# AKS: Windows Node Pool hinzufügen
az aks nodepool add \
  --resource-group mein-rg \
  --cluster-name mein-cluster \
  --name winnp \
  --os-type Windows \
  --os-sku Windows2022 \
  --node-count 2 \
  --node-vm-size Standard_D4s_v3

Bei Self-Managed-Clustern musst du das kubelet manuell auf einem Windows Server installieren. Microsoft stellt dafür das Tool wins.exe und Installationsskripte bereit. Die offizielle Dokumentation unter kubernetes.io/docs/setup beschreibt den Prozess im Detail.

Workloads auf Windows Nodes schedulen

Kubernetes braucht explizite Anweisungen, damit Pods auf Windows Nodes landen. Ohne nodeSelector würde der Scheduler versuchen, einen Windows-Container auf einem Linux Node auszuführen — das schlägt fehl.

nodeSelector setzen

apiVersion: apps/v1
kind: Deployment
metadata:
  name: iis-webapp
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: iis-webapp
  template:
    metadata:
      labels:
        app: iis-webapp
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      containers:
        - name: iis
          image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022
          ports:
            - containerPort: 80
          resources:
            requests:
              cpu: 250m
              memory: 512Mi
            limits:
              cpu: "1"
              memory: 1Gi

Taints und Tolerations

Damit Linux-Pods nicht versehentlich auf Windows Nodes gescheduled werden, setzt du einen Taint:

# Taint auf Windows Node setzen
kubectl taint nodes worker-win os=windows:NoSchedule

# Prüfen
kubectl describe node worker-win | grep -A 3 Taints

Im Deployment brauchst du dann eine passende Toleration:

spec:
  template:
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      tolerations:
        - key: "os"
          operator: "Equal"
          value: "windows"
          effect: "NoSchedule"
      containers:
        - name: dotnet-app
          image: mein-registry.azurecr.io/meine-app:v1.2
          ports:
            - containerPort: 8080

.NET-Framework-App als Windows Container

Ein typischer Anwendungsfall ist eine ASP.NET-Framework-4.8-Anwendung, die nicht auf .NET 8 migriert werden kann:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: legacy-dotnet-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: legacy-dotnet
  template:
    metadata:
      labels:
        app: legacy-dotnet
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      containers:
        - name: app
          image: mein-registry.azurecr.io/legacy-app:v3.1
          ports:
            - containerPort: 80
          env:
            - name: ASPNET_ENVIRONMENT
              value: "Production"
          readinessProbe:
            httpGet:
              path: /health
              port: 80
            initialDelaySeconds: 30
            periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: legacy-dotnet-svc
spec:
  selector:
    app: legacy-dotnet
  ports:
    - port: 80
      targetPort: 80
  type: ClusterIP

Einschränkungen von Windows Nodes

Windows Nodes haben gegenüber Linux einige harte Limitierungen. Diese musst du vor der Planung kennen:

Nicht unterstützt auf Windows:

  • Privileged Containers — gibt es nicht. Windows hat kein Äquivalent zu --privileged
  • HostNetwork — Pods können nicht das Host-Netzwerk nutzen
  • HostPID / HostIPC — kein Zugriff auf Host-Prozesse
  • Bestimmte Volume-Typen — kein hostPath mit Unix-Sockets, kein configMap mit subPath (seit 1.25 teilweise behoben)
  • DaemonSets — funktionieren, aber viele Linux-basierte DaemonSets (z.B. Monitoring-Agents) haben kein Windows-Image
  • Single Container Runtime — nur containerd (Docker wurde ab Kubernetes 1.24 generell entfernt)

Networking-Besonderheiten:

# Windows nutzt Host Networking Service (HNS) statt iptables
# Unterstützte CNI-Plugins: Calico, Flannel (Overlay), Azure CNI
# NICHT unterstützt: Cilium, Weave, Canal

Best Practices für Hybrid-Cluster

Halte dich an diese Regeln, um Probleme zu vermeiden:

  1. Immer nodeSelector setzen — in jedem Pod-Template, egal ob Linux oder Windows. Setze kubernetes.io/os: linux auch für Linux-Pods explizit.

  2. RuntimeClass nutzen — ab Kubernetes 1.25 kannst du RuntimeClasses definieren, die automatisch nodeSelector und Tolerations injizieren.

  3. Image-Kompatibilität prüfen — Windows-Container-Images müssen zur Windows-Version des Hosts passen. Ein ltsc2022-Image läuft nicht auf einem Server 2019 Node.

  4. Monitoring anpassen — Standard-Monitoring-Stacks wie kube-prometheus haben oft keine Windows-Exporter. Du brauchst windows-exporter als DaemonSet auf Windows Nodes.

FAQ

Kann ich Linux- und Windows-Container im selben Pod mischen?

Nein. Ein Pod läuft komplett auf einem Node und damit auf einem Betriebssystem. Wenn du Linux- und Windows-Komponenten brauchst, deploye sie als separate Pods mit einem Service dazwischen.

Welche Windows-Version brauche ich für Kubernetes?

Windows Server 2019 (LTSC) oder neuer. Empfohlen ist Windows Server 2022 (LTSC), da es die beste Kubernetes-Unterstützung und Performance bietet. Windows 10/11 ist nur für Entwicklung geeignet.

Wie groß sind Windows-Container-Images?

Windows-Basis-Images sind deutlich größer als Linux-Images. servercore ist ca. 5 GB, nanoserver ca. 300 MB. Nutze nanoserver wo möglich, um Pull-Zeiten und Speicherverbrauch zu reduzieren.

Kann ich Windows Nodes in einem On-Premises-Cluster nutzen?

Ja, mit kubeadm oder Rancher. Du installierst das kubelet und kube-proxy manuell auf dem Windows Server und joinst den Node zum Cluster. Die Kubernetes-Dokumentation beschreibt den Prozess unter „Adding Windows nodes".


Legacy zu Kubernetes migrieren?

Wir begleiten Ihre Migration von VMs zu Containern – ohne Produktionsausfall. Erfahrung aus 50+ Migrationsprojekten.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen