recorded decision · public · no signup
Support for CSI Plugins on Windows Nodes
What was chosen
- CSI Node Plugins will interact with csi-proxy.exe using named pipes because Windows blocks containerized processes from host domain sockets.adr ↗
- A new privileged proxy binary, csi-proxy.exe, is chosen to be developed and maintained by the Kubernetes CSI community.adr ↗
- csi-proxy.exe will run as a native Windows Service on Windows nodes to perform privileged storage operations.adr ↗
- A host OS proxy is chosen to execute privileged operations on the Windows host OS on behalf of a container.adr ↗
- The CSI Proxy API will be introduced as v1alpha1 and will graduate to v1beta1 and v1 following Kubernetes conventions.adr ↗
What was ruled out· 3
- Support for CSI plugins requiring special kernel mode drivers on Windows hosts (e.g., FCoE, NFS) is rejected.adr ↗
- Support for CSI Controller Plugin operations from Windows nodes is not an immediate priority and is rejected for this KEP.adr ↗
- Support for privileged operations from Windows containers beyond CSI Node Plugins is rejected for this KEP.adr ↗
Constraints
The recorded why
Support for CSI Plugins on Windows Nodes
§ Table of Contents
<!-- toc -->- Release Signoff Checklist
- Summary
- Motivation
- Proposal
- Design Details
- Production Readiness Review Questionnaire
- Implementation History
- Drawbacks
- Alternatives
- Infrastructure Needed
§ Release Signoff Checklist
- kubernetes/enhancements issue in release milestone, which links to KEP (this should be a link to the KEP location in kubernetes/enhancements, not the initial KEP PR)
- KEP approvers have set the KEP status to
implementable - Design details are appropriately documented
- Test plan is in place, giving consideration to SIG Architecture and SIG Testing input
- Graduation criteria is in place
- Production readiness review completed
- Production readiness review approved
- "Implementation History" section is up-to-date for milestone
- User-facing documentation has been created in [kubernetes/website], for publication to [kubernetes.io]
- Supporting documentation e.g., additional design documents, links to mailing list discussions/SIG meetings, relevant PRs/issues, release notes
§ Summary
Container Storage Interface (CSI) is a modern GRPC based standard for implementing external storage plugins (maintained by storage vendors, cloud providers, etc.) for container orchestrators like Kubernetes. Persistent storage requirements of containerized workloads can be satisfied from a diverse array of storage systems by installing and configuring the CSI plugins supported by the desired storage system. This KEP covers the enhancements necessary in Kubernetes core and CSI related out-of-tree components (specific to Kubernetes) to support CSI plugins for Windows nodes in a Kubernetes cluster. With the enhancements proposed in this KEP, Kubernetes operators will be able to leverage modern CSI plugins to satisfy the persistent storage requirements of Windows workloads in Kubernetes.
§ Motivation
Support for containerized Windows workloads on Windows nodes in a Kubernetes cluster reached GA status in v1.14. For persistent storage requirements, Windows workloads today depend on: (1) Powershell based FlexVolume plugins maintained by Microsoft that support mounting remote storage volumes over SMB and iSCSI protocols and (2) In-tree plugins in Kubernetes core (kubernetes/kubernetes repository) for popular cloud environments that support formatting and mounting direct attached disks on Windows nodes.
Support for CSI in Kubernetes reached GA status in v1.13. CSI plugins provide several benefits to Linux workloads in Kubernetes today over plugins whose code lives in kubernetes/kubernetes as well as plugins that implement the Flexvolume plugin interface. Some of these benefits are:
-
The GRPC based CSI interface allow CSI plugins to be distributed as containers and fully managed through standard Kubernetes constructs like StatefulSets and DaemonSets. This is a superior mechanism compared to the exec model used by the Flexvolume interface where the plugins are distributed as scripts or binaries that need to be installed on each node and maintained.
-
CSI offers a rich set of volume management operations (although not at a GA state in Kubernetes yet): resizing of volumes, backup/restore of volumes using snapshots and cloning besides the basic volume life-cycle operations (GA since v1.13): provisioning of storage volumes, attaching/detaching volumes to a node and mounting/dismounting to/from a pod.
-
CSI plugins are maintained and released independent of the Kubernetes core. This allows features and bug fixes in the CSI plugins to be delivered in a more flexible schedule relative to Kubernetes releases. Transitioning the code for existing in-tree plugins (especially those targeting specific cloud environments or vendor-specific storage systems) to external CSI plugins can also help reduce the volume of vendor-ed code that needs to be maintained in Kubernetes core.
Given the above context, the main motivations for this KEP are:
-
Enable Windows nodes to support CSI plugins so they can surface the above mentioned benefits of CSI plugins to Windows workloads that have persistent storage requirements. CSI Node Plugins today need to execute several privileged operations like scanning for newly provisioned disks, creating partitions on the disks, formatting the partitions with the desired file system as well as resize the filesystem, staging the partitions at a unique path on the host and propagating the staging path to workload containers. However, Windows does not support privileged operations from inside a container today. This KEP describes a host OS proxy to execute privileged operations on the Windows host OS on behalf of a container. The host OS proxy enables: [a] ease of distribution of CSI Node Plugins as containers for both Windows and Linux, [b] execution of CSI Node Plugins on Windows hosts in a manner similar to Linux hosts - from inside a container and [c] management of the CSI Node Plugin containers through Kubernetes constructs like Pods and DaemonSets.
-
The CSI migration initiative (planned to reach beta state in v1.16) aims to deprecate the code associated with several in-tree storage plugins and pave the path for the ultimate removal of that code from Kubernetes core in favor of CSI plugins that implement the same functionality. Windows workloads need to be aligned with the CSI migration effort and cannot depend on environment specific in-tree plugins to satisfy persistent storage needs.
Goals
-
Support all CSI Node Plugin operations: NodeStageVolume/NodeUnstageVolume, NodePublishVolume/NodeUnPublishVolume, NodeExpandVolume, NodeGetVolumeStats, NodeGetCapabilities and NodeGetInfo on Windows nodes.
-
Support CSI plugins associated with a variety of external storage scenarios: block storage surfaced through iSCSI as well as directly attached disks (e.g. in cloud environments) as well as remote volumes over SMB.
-
Ability to distribute CSI Node Plugins targeting Windows nodes as containers that can be deployed using DaemonSets in a Kubernetes cluster comprising of Windows nodes.
Non-Goals
-
Support CSI Controller Plugin operations from Windows nodes: This may be considered in the future but not an immediate priority. Note that this does not require support for privileged operations on a Windows node as required by CSI Node Plugins and thus orthogonal to this KEP around CSI Node Plugins for Windows. If all the worker nodes in the cluster are Windows nodes and Linux master nodes have scheduling disabled then CSI controller plugins cannot be scheduled for now.
-
Support privileged operations from Windows containers beyond CSI Node Plugins: This KEP introduces a host based "privileged proxy" process that may be used for executing privileged operations on the host on behalf of a Windows container. While a similar mechanism may be used for other use cases like containerized CNI plugins (for executing HNS operations), we leave that for a separate KEP. Scoping down the set of actions allowed by the API exposed by by the privileged proxy process to a minimal set simplifies multiple versions of the API as well as reduces the scope for abuse.
-
Support for CSI plugins associated with external storage that requires a special file or block protocol kernel mode driver installed and configured on Windows hosts: e.g. FCoE (Fibre Channel over Ethernet), NFS volumes on Windows and Dokany based filesystems (https://github.com/dokan-dev/dokany) like SSHFS, etc.
§ Proposal
In this KEP, we propose a set of enhancements in pre-existing components to support CSI Node Plugins on Windows nodes.
The following enhancements are necessary in existing Kubernetes community managed code:
- Ability to handle Windows file paths in the Kubelet plugin watcher for domain sockets on Windows nodes.
- Refactor code in the CSI Node Driver Registrar so that it can be compiled for Windows.
- Build official CSI Node Driver Registrar container images based on Windows base images and publish them in official CSI community container registry.
The following enhancements are necessary in CSI plugins maintained by CSI plugin authors:
- Refactor code in existing CSI Node Plugins to support Windows. All privileged operations will need to be driven through an API exposed by a "privileged proxy" binary described below. Details around this will be documented in a plugin developer guide.
- Build CSI Node Plugin container images based on Windows base images.
- Create DaemonSet YAMLs referring to official CSI Node Driver Registrar container images and CSI Node Plugin container images targeting Windows.
Besides the above enhancements, a new "privileged proxy" binary, named csi-proxy.exe is a key aspect of this KEP. csi-proxy.exe will run as a native Windows process on the Windows nodes configured as a Windows Service. csi-proxy.exe will expose an API (through GRPC over a named pipe) for executing privileged storage related operations on Windows hosts on behalf of Windows containers like CSI Node Plugins.
User Stories
With the KEP implemented, administrators should be able to deploy CSI Node Plugins that support staging, publishing and other storage management operations on Windows nodes. Operators will be able to schedule Windows workloads that consume persistent storage surfaced by CSI plugins on Windows nodes.
Deploy CSI Node Plugin DaemonSet targeting Windows nodes
An administrator should be able to deploy a CSI Node Plugin along with the CSI Node Driver Registrar container targeting Windows nodes with a DaemonSet YAML like the following:
kind: DaemonSet
apiVersion: apps/v1
metadata:
name: csi-gce-pd-node-win
spec:
selector:
matchLabels:
app: gcp-compute-persistent-disk-csi-driver-win
template:
metadata:
labels:
app: gcp-compute-persistent-disk-csi-driver-win
spec:
serviceAccountName: csi-node-sa
tolerations:
- key: "node.kubernetes.io/os"
operator: "Equal"
value: "win1809"
effect: "NoSchedule"
nodeSelector:
kubernetes.io/os: windows
containers:
- name: csi-driver-registrar
image: gke.gcr.io/csi-node-driver-registrar:win-v1
args:
- "--v=5"
- "--csi-address=unix://C:\\csi\\csi.sock"
- "--kubelet-registration-path=C:\\var\\lib\\kubelet\\plugins\\pd.csi.storage.gke.io\\csi.sock"
env:
- name: KUBE_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- name: plugin-dir
mountPath: C:\csi
- name: registration-dir
mountPath: C:\registration
- name: gce-pd-driver
image: gke.gcr.io/gcp-compute-persistent-disk-csi-driver:win-v1
args:
- "--v=5"
- "--endpoint=unix:/csi/csi.sock"
volumeMounts:
- name: kubelet-dir
mountPath: C:\var\lib\kubelet
- name: plugin-dir
mountPath: C:\csi
- name: csi-proxy-volume-v1beta1
mountPath: \\.\pipe\csi-proxy-volume-v1beta1
- name: csi-proxy-filesystem-v1beta1
mountPath: \\.\pipe\csi-proxy-filesystem-v1beta1
- name: csi-proxy-disk-v1beta2
mountPath: \\.\pipe\csi-proxy-disk-v1beta2
volumes:
- name: csi-proxy-disk-v1beta2
hostPath:
path: \\.\pipe\csi-proxy-disk-v1beta2
type: ""
- name: csi-proxy-volume-v1beta1
hostPath:
path: \\.\pipe\csi-proxy-volume-v1beta1
type: ""
- name: csi-proxy-filesystem-v1beta1
hostPath:
path: \\.\pipe\csi-proxy-filesystem-v1beta1
type: ""
- name: registration-dir
hostPath:
path: C:\var\lib\kubelet\plugins_registry\
type: Directory
- name: kubelet-dir
hostPath:
path: C:\var\lib\kubelet\
type: Directory
- name: plugin-dir
hostPath:
path: C:\var\lib\kubelet\plugins\pd.csi.storage.gke.io\
type: DirectoryOrCreate
Note that references to GCE PD CSI Plugin is used as an example above based on a prototype port of GCE PD CSI plugin with the enhancements in this KEP. Controller pods for the CSI plugin can be deployed on Linux nodes in the cluster in the same manner as it is done today.
Deploy Windows workloads that consume persistent storage managed by a CSI plugin
An operator should be able to deploy a Windows workload like SQL Server that consumes dynamically provisioned Persistent Volumes managed by a CSI plugin using:
A storage class like:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-gce-pd
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-standard
with a PVC like:
apiVersion: v1
metadata:
name: sqlpvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: csi-gce-pd
resources:
requests:
storage: 100Gi
and a Pod like:
apiVersion: v1
kind: Pod
metadata:
name: sqlserver1
spec:
tolerations:
- key: "node.kubernetes.io/os"
operator: "Equal"
value: "win1809"
effect: "NoSchedule"
nodeSelector:
beta.kubernetes.io/os: windows
containers:
- name: sqlpod
image: ddebroy/sqlsrv:latest
volumeMounts:
- name: csi-sql-vol
mountPath: C:\Data
env:
- name: ACCEPT_EULA
value: "y"
- name: sa_password
value: "*****"
volumes:
- name: csi-sql-vol
persistentVolumeClaim:
claimName: sqlpvc
Implementation Details
CSI Node Plugins listen on domain sockets and respond to CSI API requests sent over GRPC from a container orchestrator like Kubernetes. They are responsible all storage management operations scoped around a specific node that are typically necessary after a CSI Controller Plugin has finished provisioning a Persistent Volume and attached it to the node. In Kubernetes, the CSI Node API calls are invoked by the CSI In-tree Plugin in the kubelet as well as the CSI Node Driver Registrar. The CSI Node Driver Registrar interacts with the Kubelet Plugin Watcher and it is maintained by the Kubernetes CSI community as a side-car container for deployment in CSI Node Plugin pods.

Support for Unix Domain Sockets has been introduced in Windows Server 2019 and works across containers as well as host and container as long as the processes running in containers are listening on the socket. If a process from within a container wishes to connect to a domain socket that a process on the host OS is listening on, Windows returns a permission error. This scenario however does not arise in the context of interactions between Kubelet, CSI Node Driver Registrar and CSI Node Plugin as these involve a process in a container listening on a domain socket (CSI Node Driver Registrar or CSI Node Plugin) that a process on the host (Kubelet) connects to.
Golang supports domain socket operations for Windows since go version 1.12. It was found that in Windows, os.ModeSocket is not set on the os.FileMode associated with domain socket files in Windows. This issue is tracked here. Therefore determining whether a file is a domain socket file using os.ModeSocket does not work on Windows right now. We can potentially work around this by sending down a FSCTL to the file and evaluating the Windows reparse points to determine if the file is backed by a domain socket.
Based on the above, we can conclude that some of the fundamental support in the OS and compiler with regards to domain sockets in the context of CSI plugin discovery and a channel for API invocation is present in a stable state in Windows Server 2019 today. Although there are some observed limitations with respect to domain sockets in Windows Server 2019, they are not major blockers in the context of CSI Node Plugins. In the section below, we call out the components in the context of CSI Node Plugins in Kubernetes that will need to be enhanced to properly account for Windows paths and make use of domain sockets in Windows in a manner very similar to Linux.
CSI Node Plugins need to execute certain privileged operations at the host level as well as propagate mount points in response to the CSI API calls. Such operations involve: scanning disk identities to map the
Excerpt — the full document is at the cited source: keps/sig-windows/1122-windows-csi-support/README.md ↗