Windows containers in Kubernetes
Windows applications constitute a large portion of the services and applications that run in many organizations. provide a way to encapsulate processes and package dependencies, making it easier to use DevOps practices and follow cloud native patterns for Windows applications.
Organizations with investments in Windows-based applications and Linux-based applications don't have to look for separate orchestrators to manage their workloads, leading to increased operational efficiencies across their deployments, regardless of operating system.
Windows nodes in Kubernetes
To enable the orchestration of Windows containers in Kubernetes, include Windows nodes in your existing Linux cluster. Scheduling Windows containers in Pods on Kubernetes is similar to scheduling Linux-based containers.
In order to run Windows containers, your Kubernetes cluster must include multiple operating systems. While you can only run the control plane on Linux, you can deploy worker nodes running either Windows or Linux depending on your workload needs.
Windows nodes are supported provided that the operating system is Windows Server 2019.
This document uses the term Windows containers to mean Windows containers with process isolation. Kubernetes does not support running Windows containers with .
Resource management
On Linux nodes, cgroups are used as a pod boundary for resource control. Containers are created within that boundary for network, process and file system isolation. The Linux cgroup APIs can be used to gather CPU, I/O, and memory use statistics.
In contrast, Windows uses a job object per container with a system namespace filter to contain all processes in a container and provide logical isolation from the host. (Job objects are a Windows process isolation mechanism and are different from what Kubernetes refers to as a Job).
There is no way to run a Windows container without the namespace filtering in place. This means that system privileges cannot be asserted in the context of the host, and thus privileged containers are not available on Windows. Containers cannot assume an identity from the host because the Security Account Manager (SAM) is separate.
Memory reservations
Windows does not have an out-of-memory process killer as Linux does. Windows always treats all user-mode memory allocations as virtual, and pagefiles are mandatory (on Linux, the kubelet will by default not start with swap space enabled).
Windows nodes do not overcommit memory for processes running in containers. The net effect is that Windows won't reach out of memory conditions the same way Linux does, and processes page to disk instead of being subject to out of memory (OOM) termination. If memory is over-provisioned and all physical memory is exhausted, then paging can slow down performance.
You can place bounds on memory use for workloads using the kubelet
parameters --kubelet-reserve
and/or --system-reserve
; these account
for memory usage on the node (outside of containers), and reduce
NodeAllocatable.
As you deploy workloads, set resource limits on containers. This also subtracts from
NodeAllocatable
and prevents the scheduler from adding more pods once a node is full.
On Windows, good practice to avoid over-provisioning is to configure the kubelet with a system reserved memory of at least 2GiB to account for Windows, Kubernetes and container runtime overheads.
CPU reservations
To account for CPU use by the operating system, the container runtime, and by Kubernetes host processes such as the kubelet, you can (and should) reserve a percentage of total CPU. You should determine this CPU reservation taking account of to the number of CPU cores available on the node. To decide on the CPU percentage to reserve, identify the maximum pod density for each node and monitor the CPU usage of the system services running there, then choose a value that meets your workload needs.
You can place bounds on CPU usage for workloads using the
kubelet parameters --kubelet-reserve
and/or --system-reserve
to
account for CPU usage on the node (outside of containers).
This reduces NodeAllocatable
.
The cluster-wide scheduler then takes this reservation into account when determining
pod placement.
On Windows, the kubelet supports a command-line flag to set the priority of the
kubelet process: --windows-priorityclass
. This flag allows the kubelet process to get
more CPU time slices when compared to other processes running on the Windows host.
More information on the allowable values and their meaning is available at
.
To ensure that running Pods do not starve the kubelet of CPU cycles, set this flag to ABOVE_NORMAL_PRIORITY_CLASS
or above.
Compatibility and limitations
Some node features are only available if you use a specific container runtime; others are not available on Windows nodes, including:
- HugePages: not supported for Windows containers
- Privileged containers: not supported for Windows containers
- TerminationGracePeriod: requires containerD
Not all features of shared namespaces are supported. See API compatibility for more details.
See Windows OS version compatibility for details on the Windows versions that Kubernetes is tested against.
From an API and kubectl perspective, Windows containers behave in much the same way as Linux-based containers. However, there are some notable differences in key functionality which are outlined in this section.
Comparison with Linux
Key Kubernetes elements work the same way in Windows as they do in Linux. This section refers to several key workload enablers and how they map to Windows.
-
A Pod is the basic building block of Kubernetes–the smallest and simplest unit in the Kubernetes object model that you create or deploy. You may not deploy Windows and Linux containers in the same Pod. All containers in a Pod are scheduled onto a single Node where each Node represents a specific platform and architecture. The following Pod capabilities, properties and events are supported with Windows containers:
- Single or multiple containers per Pod with process isolation and volume sharing
- Pod
status
fields - Readiness and Liveness probes
- postStart & preStop container lifecycle events
- ConfigMap, Secrets: as environment variables or volumes
emptyDir
volumes- Named pipe host mounts
- Resource limits
- OS field:
FEATURE STATE:
Kubernetes v1.23 [alpha]
.spec.os.name
should be set towindows
to indicate that the current Pod uses Windows containers.IdentifyPodOS
feature gate needs to be enabled for this field to be recognized and used by control plane components and kubelet.Note:If the
IdentifyPodOS
feature gate is enabled and you set the.spec.os.name
field towindows
, you must not set the following fields in the.spec
of that Pod: *spec.hostPID
*spec.hostIPC
*spec.securityContext.seLinuxOptions
*spec.securityContext.seccompProfile
*spec.securityContext.fsGroup
*spec.securityContext.fsGroupChangePolicy
*spec.securityContext.sysctls
*spec.shareProcessNamespace
*spec.securityContext.runAsUser
*spec.securityContext.runAsGroup
*spec.securityContext.supplementalGroups
*spec.containers[*].securityContext.seLinuxOptions
*spec.containers[*].securityContext.seccompProfile
*spec.containers[*].securityContext.capabilities
*spec.containers[*].securityContext.readOnlyRootFilesystem
*spec.containers[*].securityContext.privileged
*spec.containers[*].securityContext.allowPrivilegeEscalation
*spec.containers[*].securityContext.procMount
*spec.containers[*].securityContext.runAsUser
*spec.containers[*].securityContext.runAsGroup
Note: In this table, wildcards (*) indicate all elements in a list. For example, spec.containers[*].securityContext refers to the Security Context object for all defined containers. If not, Pod API validation would fail causing admission failures.
-
Workload resources including:
- ReplicaSet
- Deployments
- StatefulSets
- DaemonSet
- Job
- CronJob
- ReplicationController
-
Services See Load balancing and Services for more details.
Pods, workload resources, and Services are critical elements to managing Windows workloads on Kubernetes. However, on their own they are not enough to enable the proper lifecycle management of Windows workloads in a dynamic cloud native environment. Kubernetes also supports:
kubectl exec
- Pod and container metrics
- Horizontal pod autoscaling
- Resource quotas
- Scheduler preemption
Networking on Windows nodes
Networking for Windows containers is exposed through CNI plugins. Windows containers function similarly to virtual machines in regards to networking. Each container has a virtual network adapter (vNIC) which is connected to a Hyper-V virtual switch (vSwitch). The Host Networking Service (HNS) and the Host Compute Service (HCS) work together to create containers and attach container vNICs to networks. HCS is responsible for the management of containers whereas HNS is responsible for the management of networking resources such as:
- Virtual networks (including creation of vSwitches)
- Endpoints / vNICs
- Namespaces
- Policies including packet encapsulations, load-balancing rules, ACLs, and NAT rules.
Container networking
The Windows HNS and vSwitch implement namespacing and can
create virtual NICs as needed for a pod or container. However, many configurations such
as DNS, routes, and metrics are stored in the Windows registry database rather than as
files inside /etc
, which is how Linux stores those configurations. The Windows registry for the container
is separate from that of the host, so concepts like mapping /etc/resolv.conf
from
the host into a container don't have the same effect they would on Linux. These must
be configured using Windows APIs run in the context of that container. Therefore
CNI implementations need to call the HNS instead of relying on file mappings to pass
network details into the pod or container.
The following networking functionality is not supported on Windows nodes:
- Host networking mode
- Local NodePort access from the node itself (works for other nodes or external clients)
- More than 64 backend pods (or unique destination addresses) for a single Service
- IPv6 communication between Windows pods connected to overlay networks
- Local Traffic Policy in non-DSR mode
- Outbound communication using the ICMP protocol via the
win-overlay
,win-bridge
, or using the Azure-CNI plugin.
Specifically, the Windows data plane (- ICMP packets directed to destinations within the same network (such as pod to pod communication via ping) work as expected and without any limitations;
- TCP/UDP packets work as expected and without any limitations;
- ICMP packets directed to pass through a remote network (e.g. pod to external internet communication via ping) cannot be transposed and thus will not be routed back to their source;
- Since TCP/UDP packets can still be transposed, you can substitute
ping <destination>
withcurl <destination>
to get some debugging insight into connectivity with the outside world.
Overlay networking support in kube-proxy is a beta feature. In addition, it requires to be installed on Windows Server 2019.
Network modes
Windows supports five different networking drivers/modes: L2bridge, L2tunnel, Overlay (beta), Transparent, and NAT. In a heterogeneous cluster with Windows and Linux worker nodes, you need to select a networking solution that is compatible on both Windows and Linux. The following out-of-tree plugins are supported on Windows, with recommendations on when to use each CNI:
As outlined above, the
CNI
is also
This plugin supports delegating to one of the reference CNI plugins (win-overlay,
win-bridge), to work in conjunction with Flannel daemon on Windows (Flanneld) for
automatic node subnet lease assignment and HNS network creation. This plugin reads
in its own configuration file (cni.conf), and aggregates it with the environment
variables from the FlannelD generated subnet.env file. It then delegates to one of
the reference CNI plugins for network plumbing, and sends the correct configuration
containing the node-assigned subnet to the IPAM plugin (for example: For Node, Pod, and Service objects, the following network flows are supported for
TCP/UDP traffic: The following IPAM options are supported on Windows: A Kubernetes Service is an abstraction
that defines a logical set of Pods and a means to access them over a network.
In a cluster that includes Windows nodes, you can use the following types of Service: There are known issue with NodePort services on overlay networking, if the target destination node is running Windows Server 2022.
To avoid the issue entirely, you can configure the service with There are known issues with pod to pod connectivity on l2bridge network on Windows Server 2022 with KB5005619 or higher installed.
To workaround the issue and restore pod-pod connectivity, you can disable the WinDSR feature in kube-proxy. Windows container networking differs in some important ways from Linux networking.
The
On Windows, you can use the following settings to configure Services and load
balancing behavior:host-local
).
CNI plugin limitations
IP address management (IPAM)
Load balancing and Services
NodePort
ClusterIP
LoadBalancer
ExternalName
externalTrafficPolicy: Local
.
Feature | Description | Supported Kubernetes version | Supported Windows OS build | How to enable |
---|---|---|---|---|
Session affinity | Ensures that connections from a particular client are passed to the same Pod each time. | v1.20+ | Set service.spec.sessionAffinity to "ClientIP" |
|
Direct Server Return (DSR) | Load balancing mode where the IP address fixups and the LBNAT occurs at the container vSwitch port directly; service traffic arrives with the source IP set as the originating pod IP. | v1.20+ | Windows Server 2019 | Set the following flags in kube-proxy: --feature-gates="WinDSR=true" --enable-dsr=true |
Preserve-Destination | Skips DNAT of service traffic, thereby preserving the virtual IP of the target service in packets reaching the backend Pod. Also disables node-node forwarding. | v1.20+ | Windows Server, version 1903 (or higher) | Set "preserve-destination": "true" in service annotations and enable DSR in kube-proxy. |
IPv4/IPv6 dual-stack networking | Native IPv4-to-IPv4 in parallel with IPv6-to-IPv6 communications to, from, and within a cluster | v1.19+ | Windows Server, version 2019 | See IPv4/IPv6 dual-stack |
Client IP preservation | Ensures that source IP of incoming ingress traffic gets preserved. Also disables node-node forwarding. | v1.20+ | Windows Server, version 2019 | Set service.spec.externalTrafficPolicy to "Local" and enable DSR in kube-proxy |
Session affinity
Setting the maximum session sticky time for Windows services using
service.spec.sessionAffinityConfig.clientIP.timeoutSeconds
is not supported.
DNS
- ClusterFirstWithHostNet is not supported for DNS. Windows treats all names with a
.
as a FQDN and skips FQDN resolution - On Linux, you have a DNS suffix list, which is used when trying to resolve PQDNs. On Windows, you can only have 1 DNS suffix, which is the DNS suffix associated with that pod's namespace (mydns.svc.cluster.local for example). Windows can resolve FQDNs and services or names resolvable with just that suffix. For example, a pod spawned in the default namespace, will have the DNS suffix default.svc.cluster.local. Inside a Windows pod, you can resolve both kubernetes.default.svc.cluster.local and kubernetes, but not the in-betweens, like kubernetes.default or kubernetes.default.svc.
- On Windows, there are multiple DNS resolvers that can be used. As these come with
slightly different behaviors, using the
Resolve-DNSName
utility for name query resolutions is recommended.
IPv6 networking
Kubernetes on Windows does not support single-stack "IPv6-only" networking. However, dual-stack IPv4/IPv6 networking for pods and nodes with single-family services is supported.
You can use IPv4/IPv6 dual-stack networking with l2bridge
networks. See configure IPv4/IPv6 dual stack for more details.
Persistent storage
Windows has a layered filesystem driver to mount container layers and create a copy filesystem based on NTFS. All file paths in the container are resolved only within the context of that container.
- With Docker, volume mounts can only target a directory in the container, and not an individual file. This limitation does not exist with CRI-containerD runtime.
- Volume mounts cannot project files or directories back to the host filesystem.
- Read-only filesystems are not supported because write access is always required for the Windows registry and SAM database. However, read-only volumes are supported.
- Volume user-masks and permissions are not available. Because the SAM is not shared between the host & container, there's no mapping between them. All permissions are resolved within the context of the container.
As a result, the following storage functionality is not supported on Windows nodes:
- Volume subpath mounts: only the entire volume can be mounted in a Windows container
- Subpath volume mounting for Secrets
- Host mount projection
- Read-only root filesystem (mapped volumes still support
readOnly
) - Block device mapping
- Memory as the storage medium (for example,
emptyDir.medium
set toMemory
) - File system features like uid/gid; per-user Linux filesystem permissions
- DefaultMode (due to UID/GID dependency)
- NFS based storage/volume support
- Expanding the mounted volume (resizefs)
Kubernetes volumes enable complex applications, with data persistence and Pod volume sharing requirements, to be deployed on Kubernetes. Management of persistent volumes associated with a specific storage back-end or protocol includes actions such as provisioning/de-provisioning/resizing of volumes, attaching/detaching a volume to/from a Kubernetes node and mounting/dismounting a volume to/from individual containers in a pod that needs to persist data.
The code implementing these volume management actions for a specific storage back-end or protocol is shipped in the form of a Kubernetes volume plugin. The following broad classes of Kubernetes volume plugins are supported on Windows:
In-tree volume plugins
Code associated with in-tree volume plugins ship as part of the core Kubernetes code base. Deployment of in-tree volume plugins do not require installation of additional scripts or deployment of separate containerized plugin components. These plugins can handle provisioning/de-provisioning and resizing of volumes in the storage backend, attaching/detaching of volumes to/from a Kubernetes node and mounting/dismounting a volume to/from individual containers in a pod. The following in-tree plugins support persistent storage on Windows nodes:
FlexVolume plugins
Code associated with FlexVolume plugins ship as out-of-tree scripts or binaries that need to be deployed directly on the host. FlexVolume plugins handle attaching/detaching of volumes to/from a Kubernetes node and mounting/dismounting a volume to/from individual containers in a pod. Provisioning/De-provisioning of persistent volumes associated with FlexVolume plugins may be handled through an external provisioner that is typically separate from the FlexVolume plugins. The following FlexVolume , deployed as PowerShell scripts on the host, support Windows nodes:
CSI plugins
Kubernetes v1.19 [beta]
Code associated with CSI plugins ship as out-of-tree scripts and binaries that are typically distributed as container images and deployed using standard Kubernetes constructs like DaemonSets and StatefulSets. CSI plugins handle a wide range of volume management actions in Kubernetes: provisioning/de-provisioning/resizing of volumes, attaching/detaching of volumes to/from a Kubernetes node and mounting/dismounting a volume to/from individual containers in a pod, backup/restore of persistent data using snapshots and cloning. CSI plugins typically consist of node plugins (that run on each node as a DaemonSet) and controller plugins.
CSI node plugins (especially those associated with persistent volumes exposed as
either block devices or over a shared file-system) need to perform various privileged
operations like scanning of disk devices, mounting of file systems, etc. These
operations differ for each host operating system. For Linux worker nodes, containerized
CSI node plugins are typically deployed as privileged containers. For Windows worker
nodes, privileged operations for containerized CSI node plugins is supported using
For more details, refer to the deployment guide of the CSI plugin you wish to deploy. The behavior of some kubelet command line options behave differently on Windows, as described below: There are no differences in how most of the Kubernetes APIs work for Windows. The
subtleties around what's different come down to differences in the OS and container
runtime. In certain situations, some properties on workload resources were designed
under the assumption that they would be implemented on Linux, and fail to run on Windows. At a high level, these OS concepts are different: Container exit codes follow the same convention where 0 is success, and nonzero is failure.
The specific error codes may differ across Windows and Linux. However, exit codes
passed from the Kubernetes components (kubelet, kube-proxy) are unchanged. The following list documents differences between how Pod container specifications
work between Windows and Linux: The following list documents differences between how Pod specifications work between Windows and Linux: None of the Pod The node problem detector (see
Monitor Node Health)
is not compatible with Windows. In a Kubernetes Pod, an infrastructure or “pause” container is first created
to host the container. In Linux, the cgroups and namespaces that make up a pod
need a process to maintain their continued existence; the pause process provides
this. Containers that belong to the same pod, including infrastructure and worker
containers, share a common network endpoint (same IPv4 and / or IPv6 address, same
network port spaces). Kubernetes uses pause containers to allow for worker containers
crashing or restarting without losing any of the networking configuration. Kubernetes maintains a multi-architecture image that includes support for Windows.
For Kubernetes v1.23 the recommended pause image is Microsoft maintains a different multi-architecture image, with Linux and Windows
amd64 support, that you can find as You need to install a
container runtime
into each node in the cluster so that Pods can run there. The following container runtimes work with Windows: You can use
Learn how to install ContainerD on a Windows node.
See
On Windows nodes, strict compatibility rules apply where the host OS version must
match the container base image OS version. Only Windows containers with a container
operating system of Windows Server 2019 are fully supported. For Kubernetes v1.23, operating system compatibility for Windows nodes (and Pods)
is as follows: The Kubernetes version-skew policy also applies. On Windows, data from Secrets are written out in clear text onto the node's local
storage (as compared to using tmpfs / in-memory filesystems on Linux). As a cluster
operator, you should take both of the following additional measures: RunAsUsername
can be specified for Windows Pods or containers to execute the container
processes as a node-default user. This is roughly equivalent to
RunAsUser. Linux-specific pod security context privileges such as SELinux, AppArmor, Seccomp, or capabilities (POSIX capabilities), and others are not supported. Privileged containers are not supported on Windows. Your main source of help for troubleshooting your Kubernetes cluster should start
with the Troubleshooting
page. Some additional, Windows-specific troubleshooting help is included
in this section. Logs are an important element of troubleshooting
issues in Kubernetes. Make sure to include them any time you seek
troubleshooting assistance from other contributors. Follow the
instructions in the
SIG Windows . How do I know You should see kubelet, kube-proxy, and (if you chose Flannel as your networking
solution) flanneld host-agent processes running on your node, with running logs
being displayed in separate PowerShell windows. In addition to this, your Windows
node should be listed as "Ready" in your Kubernetes cluster. Can I configure the Kubernetes node processes to run in the background as services? The kubelet and kube-proxy are already configured to run as native Windows Services,
offering resiliency by re-starting the services automatically in the event of
failure (for example a process crash). You have two options for configuring these
node components as services. As native Windows Services You can run the kubelet and kube-proxy as native Windows Services using Using You can also always use alternative service managers like
,
leveraging nssm.exe to register kubelet, kube-proxy, and flanneld.exe to run
as Windows services in the background. If the above referenced script is not suitable, you can manually configure
For initial troubleshooting, you can use the following flags in
For additional details, see . My Pods are stuck at "Container Creating" or restarting over and over Check that your pause image is compatible with your OS version. The
assume that both the OS and the containers are version 1803. If you have a later
version of Windows, such as an Insider build, you need to adjust the images
accordingly. See Pause container for more details. My Windows Pods do not have network connectivity If you are using virtual machines, ensure that MAC spoofing is enabled on all
the VM network adapter(s). My Windows Pods cannot ping external resources Windows Pods do not have outbound rules programmed for the ICMP protocol. However,
TCP/UDP is supported. When trying to demonstrate connectivity to resources
outside of the cluster, substitute If you are still facing problems, most likely your network configuration in
deserves some extra attention. You can always edit this static file. The
configuration update will apply to any new Kubernetes resources. One of the Kubernetes networking requirements
(see Kubernetes model) is
for cluster communication to occur without
NAT internally. To honor this requirement, there is an
for all the communication where you do not want outbound NAT to occur. However,
this also means that you need to exclude the external IP you are trying to query
from the My Windows node cannot access Local NodePort access from the node itself fails. This is a known
limitation. NodePort access works from other nodes or external clients. vNICs and HNS endpoints of containers are being deleted This issue can be caused when the With flannel, my nodes are having issues after rejoining a cluster Whenever a previously deleted node is being re-joined to the cluster, flannelD
tries to assign a new pod subnet to the node. Users should remove the old pod
subnet configuration files in the following paths: After launching There are numerous reports of this
My Windows Pods cannot launch because of missing This indicates that Flannel didn't launch correctly. You can either try
to restart My Windows node cannot access my services using the service IP This is a known limitation of the networking stack on Windows. However, Windows Pods can access the Service IP. No network adapter is found when starting the kubelet The Windows networking stack needs a virtual adapter for Kubernetes networking to work. If the following commands return no results (in an admin shell), virtual network creation — a necessary prerequisite for the kubelet to work — has failed: Often it is worthwhile to modify the start-kubelet.ps1 script to see if there are errors during virtual network creation. DNS resolution is not properly working Check the DNS limitations for Windows in this section. This was implemented in Kubernetes 1.15 by including My Kubernetes installation is failing because my Windows Server node is behind a proxy If you are behind a proxy, the following PowerShell environment variables must be defined: If these steps don't resolve your problem, you can get help running Windows containers on Windows nodes in Kubernetes through: If you have what looks like a bug, or you would like to
make a feature request, please use the
.
You can open issues on
If filing a bug, please include detailed information about how to reproduce the problem, such as: It helps if you tag the issue as sig/windows, by commenting on the issue with The kubeadm tool helps you to deploy a Kubernetes cluster, providing the control
plane to manage the cluster it, and nodes to run your workloads.
Adding Windows nodes
explains how to deploy Windows nodes to your cluster using kubeadm. The Kubernetes
For a detailed explanation of Windows distribution channels see the . Information on the different Windows Server servicing channels
including their support models can be found at
.Command line options for the kubelet
--windows-priorityclass
lets you set the scheduling priority of the kubelet process (see CPU resource management)--kubelet-reserve
, --system-reserve
, and --eviction-hard
flags update NodeAllocatable--enforce-node-allocable
is not implemented--eviction-hard
and --eviction-soft
are not implemented--kubelet-reserve
and --system-reserve
do not set limits on
kubelet or processes running on the host. This means kubelet or a process on the host
could cause memory resource starvation outside the node-allocatable and scheduler.MemoryPressure
Condition is not implementedAPI compatibility
/etc/groups
or /etc/passwd
back to UID+GID. Windows uses a larger binary
\
instead of /
. The Go IO
libraries typically accept both and just make it work, but when you're setting a
path or command line that's interpreted inside a container, \
may be needed.
WM_CLOSE
.SERVICE_CONTROL_STOP
control codes.Field compatibility for container specifications
requests.cpu
and requests.memory
- requests are subtracted
from node available resources, so they can be used to avoid overprovisioning a
node. However, they cannot be used to guarantee resources in an overprovisioned
node. They should be applied to all containers as a best practice if the operator
wants to avoid overprovisioning entirely.securityContext.allowPrivilegeEscalation
-
not possible on Windows; none of the capabilities are hooked upsecurityContext.capabilities
-
POSIX capabilities are not implemented on WindowssecurityContext.privileged
-
Windows doesn't support privileged containerssecurityContext.procMount
-
Windows doesn't have a /proc
filesystemsecurityContext.readOnlyRootFilesystem
-
not possible on Windows; write access is required for registry & system
processes to run inside the containersecurityContext.runAsGroup
-
not possible on Windows as there is no GID supportsecurityContext.runAsNonRoot
-
this setting will prevent containers from running as ContainerAdministrator
which is the closest equivalent to a root user on Windows.securityContext.runAsUser
-
use runAsUserName
insteadsecurityContext.seLinuxOptions
-
not possible on Windows as SELinux is Linux-specificterminationMessagePath
-
this has some limitations in that Windows doesn't support mapping single files. The
default value is /dev/termination-log
, which does work because it does not
exist on Windows by default.Field compatibility for Pod specifications
hostIPC
and hostpid
- host namespace sharing is not possible on WindowshostNetwork
- There is no Windows OS support to share the host networkdnsPolicy
- setting the Pod dnsPolicy
to ClusterFirstWithHostNet
is
not supported on Windows because host networking is not provided. Pods always
run with a container network.podSecurityContext
(see below)shareProcessNamespace
- this is a beta feature, and depends on Linux namespaces
which are not implemented on Windows. Windows cannot share process namespaces or
the container's root filesystem. Only the network can be shared.terminationGracePeriodSeconds
- this is not fully implemented in Docker on Windows,
see the .
The behavior today is that the ENTRYPOINT process is sent CTRL_SHUTDOWN_EVENT,
then Windows waits 5 seconds by default, and finally shuts down
all processes using the normal Windows shutdown behavior. The 5
second default is actually in the Windows registry
,
so it can be overridden when the container is built.volumeDevices
- this is a beta feature, and is not implemented on Windows.
Windows cannot attach raw block devices to pods.volumes
emptyDir
volume, you cannot set its volume source to memory
.mountPropagation
for volume mounts as this is not
supported on Windows.Field compatibility for Pod security context
securityContext
fields work on Windows.Node problem detector
Pause container
k8s.gcr.io/pause:3.6
.
The
is available on GitHub.mcr.microsoft.com/oss/kubernetes/pause:3.6
.
This image is built from the same source as the Kubernetes maintained image but
all of the Windows binaries are
Container runtimes
cri-containerd
Kubernetes v1.20 [stable]
Mirantis Container Runtime
Windows OS version compatibility
Security for Windows nodes
Getting help and troubleshooting
Node-level troubleshooting
start.ps1
completed successfully?
sc.exe
.# Create the services for kubelet and kube-proxy in two separate commands
sc.exe create <component_name> binPath= "<path_to_binary> --service <other_args>"
# Please note that if the arguments contain spaces, they must be escaped.
sc.exe create kubelet binPath= "C:\kubelet.exe --service --hostname-override 'minion' <other_args>"
# Start the services
Start-Service kubelet
Start-Service kube-proxy
# Stop the service
Stop-Service kubelet (-Force)
Stop-Service kube-proxy (-Force)
# Query the service status
Get-Service kubelet
Get-Service kube-proxy
nssm.exe
register-svc.ps1 -NetworkMode <Network mode> -ManagementIP <Windows Node IP> -ClusterCIDR <Cluster subnet> -KubeDnsServiceIP <Kube-dns Service IP> -LogDir <Directory to place logs>
# NetworkMode = The network mode l2bridge (flannel host-gw, also the default value) or overlay (flannel vxlan) chosen as a network solution
# ManagementIP = The IP address assigned to the Windows node. You can use ipconfig to find this
# ClusterCIDR = The cluster subnet range. (Default value 10.244.0.0/16)
# KubeDnsServiceIP = The Kubernetes DNS service IP (Default value 10.96.0.10)
# LogDir = The directory where kubelet and kube-proxy logs are redirected into their respective output files (Default value C:\k)
nssm.exe
using the following examples.# Register flanneld.exe
nssm install flanneld C:\flannel\flanneld.exe
nssm set flanneld AppParameters --kubeconfig-file=c:\k\config --iface=<ManagementIP> --ip-masq=1 --kube-subnet-mgr=1
nssm set flanneld AppEnvironmentExtra NODE_NAME=<hostname>
nssm set flanneld AppDirectory C:\flannel
nssm start flanneld
# Register kubelet.exe
# Microsoft releases the pause infrastructure container at mcr.microsoft.com/oss/kubernetes/pause:3.6
nssm install kubelet C:\k\kubelet.exe
nssm set kubelet AppParameters --hostname-override=<hostname> --v=6 --pod-infra-container-image=mcr.microsoft.com/oss/kubernetes/pause:3.6 --resolv-conf="" --allow-privileged=true --enable-debugging-handlers --cluster-dns=<DNS-service-IP> --cluster-domain=cluster.local --kubeconfig=c:\k\config --hairpin-mode=promiscuous-bridge --image-pull-progress-deadline=20m --cgroups-per-qos=false --log-dir=<log directory> --logtostderr=false --enforce-node-allocatable="" --network-plugin=cni --cni-bin-dir=c:\k\cni --cni-conf-dir=c:\k\cni\config
nssm set kubelet AppDirectory C:\k
nssm start kubelet
# Register kube-proxy.exe (l2bridge / host-gw)
nssm install kube-proxy C:\k\kube-proxy.exe
nssm set kube-proxy AppDirectory c:\k
nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --hostname-override=<hostname>--kubeconfig=c:\k\config --enable-dsr=false --log-dir=<log directory> --logtostderr=false
nssm.exe set kube-proxy AppEnvironmentExtra KUBE_NETWORK=cbr0
nssm set kube-proxy DependOnService kubelet
nssm start kube-proxy
# Register kube-proxy.exe (overlay / vxlan)
nssm install kube-proxy C:\k\kube-proxy.exe
nssm set kube-proxy AppDirectory c:\k
nssm set kube-proxy AppParameters --v=4 --proxy-mode=kernelspace --feature-gates="WinOverlay=true" --hostname-override=<hostname> --kubeconfig=c:\k\config --network-name=vxlan0 --source-vip=<source-vip> --enable-dsr=false --log-dir=<log directory> --logtostderr=false
nssm set kube-proxy DependOnService kubelet
nssm start kube-proxy
nssm set <Service Name> AppStdout C:\k\mysvc.log
nssm set <Service Name> AppStderr C:\k\mysvc.log
Network troubleshooting
ping <IP>
with corresponding
curl <IP>
commands.ExceptionList
. Only then will the traffic originating from your Windows
pods be SNAT'ed correctly to receive a response from the outside world. In this
regard, your ExceptionList
in cni.conf
should look as follows:"ExceptionList": [
"10.244.0.0/16", # Cluster subnet
"10.96.0.0/12", # Service subnet
"10.127.130.0/24" # Management (host) subnet
]
NodePort
type Serviceshostname-override
parameter is not passed to
kube-proxy. To resolve
it, users need to pass the hostname to kube-proxy as follows:C:\k\kube-proxy.exe --hostname-override=$(hostname)
Remove-Item C:\k\SourceVip.json
Remove-Item C:\k\SourceVipRequest.json
start.ps1
, flanneld is stuck in "Waiting for the Network to be created"[Environment]::SetEnvironmentVariable("NODE_NAME", "<Windows_Worker_Hostname>")
C:\flannel\flanneld.exe --kubeconfig-file=c:\k\config --iface=<Windows_Worker_Node_IP> --ip-masq=1 --kube-subnet-mgr=1
/run/flannel/subnet.env
flanneld.exe
or you can copy the files over manually from
/run/flannel/subnet.env
on the Kubernetes master to C:\run\flannel\subnet.env
on the Windows worker node and modify the FLANNEL_SUBNET
row to a different
number. For example, if node subnet 10.244.4.1/24 is desired:FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.4.1/24
FLANNEL_MTU=1500
FLANNEL_IPMASQ=true
Get-HnsNetwork | ? Name -ieq "cbr0"
Get-NetAdapter | ? Name -Like "vEthernet (Ethernet*"
kubectl port-forward
fails with "unable to do port forwarding: wincat not found"wincat.exe
in the pause infrastructure container mcr.microsoft.com/oss/kubernetes/pause:3.6
. Be sure to use a supported version of Kubernetes.
If you would like to build your own pause infrastructure container be sure to include
[Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://proxy.example.com:80/", [EnvironmentVariableTarget]::Machine)
[Environment]::SetEnvironmentVariable("HTTPS_PROXY", "http://proxy.example.com:443/", [EnvironmentVariableTarget]::Machine)
Further investigation
Reporting issues and feature requests
kubectl version
/sig windows
. This helps to bring
the issue to a SIG Windows member's attentionWhat's next
Deployment tools
Windows distribution channels