How to Configure Windows Server 2019 Helm Charts

Helm is the package manager for Kubernetes, enabling you to define, install, and upgrade complex Kubernetes applications using reusable packages called charts. When working with Windows Server 2019 nodes in a Kubernetes cluster, Helm charts need to be configured with Windows-specific node selectors and tolerations to ensure workloads are scheduled on the correct node type. This guide covers installing Helm, creating and customizing charts for Windows workloads, and deploying applications to Windows Server 2019 Kubernetes nodes.

Installing Helm on Windows

Helm can be installed on a Windows management workstation using several methods. The easiest approach on Windows is using the Chocolatey package manager or downloading the binary directly:

choco install kubernetes-helm

Or download and install manually using PowerShell:

$helmVersion = "3.13.2"
Invoke-WebRequest `
    -Uri "https://get.helm.sh/helm-v${helmVersion}-windows-amd64.zip" `
    -OutFile "C:helm.zip" `
    -UseBasicParsing

Expand-Archive -Path "C:helm.zip" -DestinationPath "C:helm" -Force
$env:Path += ";C:helmwindows-amd64"
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:helmwindows-amd64", [System.EnvironmentVariableTarget]::Machine)

helm version

Adding Helm Repositories

Add commonly used Helm chart repositories to access pre-built charts for deployment:

helm repo add stable https://charts.helm.sh/stable
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add jetstack https://charts.jetstack.io
helm repo update

List all configured repositories:

helm repo list

Search for available charts in a repository:

helm search repo bitnami --max-col-width 50 | head -30

Creating a Custom Helm Chart for Windows Applications

Create a new Helm chart scaffold for a Windows IIS application:

helm create windows-iis-app

This creates the chart directory structure. Edit the Chart.yaml to define chart metadata:

apiVersion: v2
name: windows-iis-app
description: IIS Web Application for Windows Server 2019 Nodes
type: application
version: 1.0.0
appVersion: "1.0"
keywords:
  - windows
  - iis
  - web
maintainers:
  - name: Infrastructure Team
    email: [email protected]

Configuring Windows Node Selectors in values.yaml

The most important customization for Windows charts is ensuring workloads only schedule on Windows nodes. Edit values.yaml to set the Windows node selector and tolerations as defaults:

replicaCount: 2

image:
  repository: mcr.microsoft.com/windows/servercore/iis
  pullPolicy: IfNotPresent
  tag: "windowsservercore-ltsc2019"

service:
  type: LoadBalancer
  port: 80

nodeSelector:
  kubernetes.io/os: windows

tolerations:
  - key: "os"
    operator: "Equal"
    value: "windows"
    effect: "NoSchedule"

resources:
  limits:
    cpu: "2"
    memory: "2Gi"
  requests:
    cpu: "500m"
    memory: "512Mi"

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70

Configuring the Deployment Template

Edit templates/deployment.yaml to incorporate the Windows-specific settings from values.yaml and add Windows-compatible health probes:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "windows-iis-app.fullname" . }}
  labels:
    {{- include "windows-iis-app.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "windows-iis-app.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "windows-iis-app.selectorLabels" . | nindent 8 }}
    spec:
      nodeSelector:
        {{- toYaml .Values.nodeSelector | nindent 8 }}
      tolerations:
        {{- toYaml .Values.tolerations | nindent 8 }}
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
          periodSeconds: 15
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 15
          periodSeconds: 10
        resources:
          {{- toYaml .Values.resources | nindent 12 }}

Installing the Chart

Install the chart into the Kubernetes cluster:

helm install my-iis-app ./windows-iis-app `
    --namespace production `
    --create-namespace `
    --values ./windows-iis-app/values.yaml

helm status my-iis-app -n production

Override specific values at install time:

helm install my-iis-app ./windows-iis-app `
    --set replicaCount=3 `
    --set image.tag=windowsservercore-ltsc2019 `
    --set service.type=ClusterIP `
    -n staging `
    --create-namespace

Upgrading and Rolling Back

Upgrade the release when a new chart version or image is available:

helm upgrade my-iis-app ./windows-iis-app `
    --set image.tag=windowsservercore-ltsc2019-v2 `
    -n production `
    --atomic `
    --timeout 5m

View upgrade history and roll back if needed:

helm history my-iis-app -n production
helm rollback my-iis-app 1 -n production

Packaging and Sharing Charts

Package the chart for distribution or upload to a chart repository:

helm lint ./windows-iis-app
helm package ./windows-iis-app --destination C:charts

Helm charts are the standard way to deploy and manage applications in Kubernetes. For Windows Server 2019 workloads, ensuring that charts always include Windows node selectors and tolerations is essential to prevent scheduling failures on Linux nodes. Well-structured Helm charts with configurable values files enable consistent, repeatable deployments across development, staging, and production environments.