GKE Windows Node Pool Creation & Mental Model
Vì Sao Quan Trọng
Windows Server containers trên GKE là niche nhưng không thể tránh với enterprise chạy .NET Framework legacy hoặc dependency Windows-only (COM, IIS, MSMQ). GKE cho phép mix Linux và Windows worker nodes trong cùng một cluster, nhưng đây không phải "thêm một node pool bình thường" — có những constraint kiến trúc riêng biệt mà nếu bỏ qua sẽ dẫn tới cluster không schedule được pod, hoặc image không pull được.
Mental model cốt lõi cần nắm:
- Control plane luôn luôn là Linux. GKE không có "Windows control plane". API server, etcd, scheduler — tất cả chạy trên Linux VM do Google quản lý. Windows chỉ tồn tại ở worker node layer.
- Windows node pool là một resource riêng biệt, tách khỏi Linux node pool, với image type, machine type, và disk size constraint khác.
- Một cluster có thể có nhiều OS song song — Linux node pool cho phần lớn workload, Windows node pool cho phần cần Windows API surface.
Kiến Trúc: Mixed-OS Cluster
GKE Cluster
├── Control Plane (Linux, Google-managed) — luôn luôn
│
├── Node Pool "linux-default" (Linux, containerd)
│ ├── Node 1 (Ubuntu/COS)
│ └── Node 2 (Ubuntu/COS)
│
└── Node Pool "windows-workers" (Windows Server, containerd)
├── Node 1 (Windows Server 2022 LTSC Core)
└── Node 2 (Windows Server 2022 LTSC Core)Điểm quan trọng: kubelet, kube-proxy, và container runtime chạy native trên Windows ở Windows node — không phải chạy trong VM lồng Linux. GKE build image Windows Server riêng (LTSC hoặc SAC channel) có sẵn containerd, kubelet.exe, và các Windows-specific component đã đóng gói.
LTSC vs SAC: Lựa Chọn Channel
| Channel | Chu kỳ release | Support lifecycle | Khi nào dùng |
|---|---|---|---|
| LTSC (Long-Term Servicing Channel) | ~3 năm/version | Dài hạn (nhiều năm) | Production, stability ưu tiên |
| SAC (Semi-Annual Channel) | 2 lần/năm | Ngắn (18 tháng) | Cần feature mới nhất, container-optimized workload |
Quan trọng: channel của node image phải tương thích với channel của base image container app dùng — mismatch giữa host OS build và container base image build là nguồn lỗi phổ biến nhất (chi tiết ở bài image registry).
Constraint Khi Tạo Windows Node Pool
1. Container Runtime: Containerd Bắt Buộc
Windows node pool trên GKE hiện tại chỉ hỗ trợ containerd làm runtime — image type dạng Docker-based (legacy) đã bị deprecate. Điều này quan trọng vì:
- containerd trên Windows dùng HCS (Host Compute Service) shim khác biệt so với Linux runc shim
- Một số Docker-specific behavior (ví dụ: certain networking flag) không map 1:1 sang containerd
2. VPC-Native Cluster Là Yêu Cầu
Windows node pool yêu cầu cluster dùng VPC-native (alias IP ranges), không hỗ trợ routes-based (legacy) networking. Lý do: Windows CNI plugin (win-bridge/win-overlay) cần alias IP range để assign Pod IP trực tiếp từ VPC subnet, tương tự cách Linux node hoạt động với Dataplane V1 VPC-native mode.
3. Machine Type & Resource Floor
Windows Server có baseline resource overhead cao hơn Linux đáng kể (OS services, .NET runtime nếu dùng, GUI-less nhưng vẫn nhiều subsystem chạy nền). Vì vậy:
- Không nên dùng machine type nhỏ (ví dụ e2-small) cho Windows node — OS overhead sẽ chiếm phần lớn resource, để lại rất ít cho pod
- Khuyến nghị bắt đầu từ machine type tương đương 4 vCPU / 16GB trở lên cho production workload thực tế (chi tiết sizing ở bài resource requests)
4. Boot Disk Size
Windows Server image (kể cả bản Server Core, không GUI) nặng hơn Linux image (COS/Ubuntu) rất nhiều — thường gấp 5-10 lần. Boot disk quá nhỏ dẫn tới:
- Node fail để pull node image ban đầu
- Không đủ disk space để cache container image layers, gây
ImagePullBackOffdù network hoạt động tốt
Nguyên tắc: luôn set boot disk size rộng rãi hơn mức bạn nghĩ cần — image OS + vài container image lớn (servercore-based) có thể dễ dàng chiếm hàng chục GB.
OS Labels, NodeSelector, và Taints
GKE tự động gắn label phân biệt OS lên mọi node — đây là built-in Kubernetes label, không phải GKE-specific:
# Labels tự động trên Windows node
kubernetes.io/os: windows
kubernetes.io/arch: amd64
node.kubernetes.io/windows-build: "10.0.20348" # build number cụ thểVấn đề cần hiểu: nếu không có cơ chế nào ngăn chặn, scheduler có thể cố schedule pod Linux lên node Windows (và ngược lại) — dẫn tới pod stuck ở Pending hoặc crash ngay khi container runtime cố chạy binary sai OS.
Pattern Bắt Buộc: nodeSelector + Toleration
Mọi Pod spec chạy trên Windows phải khai báo nodeSelector rõ ràng:
apiVersion: v1
kind: Pod
spec:
nodeSelector:
kubernetes.io/os: windows
tolerations:
- key: "os"
operator: "Equal"
value: "windows"
effect: "NoSchedule"
containers:
- name: my-windows-app
image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022Nhiều tổ chức tự thêm custom taint lên Windows node pool khi provision (ví dụ os=windows:NoSchedule) để bảo đảm double-safety — không chỉ dựa vào nodeSelector từ phía application team (dễ bị quên).
Nguyên tắc thiết kế: treat Windows node pool như một "khu vực đặc biệt" — mọi Deployment/DaemonSet target Windows phải qua review để đảm bảo nodeSelector + toleration được khai báo đúng, tránh việc pod Linux vô tình lọt vào node pool đắt đỏ và khan hiếm này.
Version Skew & Lifecycle
Windows node pool trên GKE có xu hướng theo sau Linux về việc hỗ trợ phiên bản Kubernetes mới nhất — features GA trên Linux có thể ở trạng thái preview hoặc chưa available trên Windows trong vài minor version. Khi lập kế hoạch nâng cấp cluster:
- Kiểm tra release notes GKE riêng cho phần Windows trước khi nâng cấp minor version
- Windows node pool upgrade (surge upgrade) thường chậm hơn Linux đáng kể vì thời gian boot + pull image lớn hơn — cần tính vào maintenance window
Những Gì Không Thể Làm
- Không thể chạy Windows container trên Linux node hoặc ngược lại — không có cross-OS emulation ở container runtime level
- Không thể dùng Hyper-V isolation trên GKE — chỉ hỗ trợ process isolation, nghĩa là container OS build phải tương thích chặt với host OS build (xem bài image registry)
- Không thể giảm control plane xuống Windows — architecture này không tồn tại trên GKE (và thực tế không tồn tại trên bất kỳ managed Kubernetes nào hiện nay)