instruction: Create a Dockerfile for storage
output: ```dockerfile
  from in-tree plugins
  
  FEATURE STATE:
  Kubernetes v1.25 [stable]
  
  The CSIMigration feature directs operations against existing in-tree
  plugins to corresponding CSI plugins (which are expected to be installed and configured).
  As a result, operators do not have to make any
  configuration changes to existing Storage Classes, PersistentVolumes or PersistentVolumeClaims
  (referring to in-tree plugins) when transitioning to a CSI driver that supersedes an in-tree plugin.
  Note:Existing PVs created by a in-tree volume plugin can still be used in the future without any configuration
  changes, even after the migration to CSI is completed for that volume type, and even after you upgrade to a
  version of Kubernetes that doesn't have compiled-in support for that kind of storage.
  As part of that migration, you - or another cluster administrator - must have installed and configured
  the appropriate CSI driver for that storage. The core of Kubernetes does not install that software for you.
  
  After that migration, you can also define new PVCs and PVs that refer to the legacy, built-in
  storage integrations.
  Provided you have the appropriate CSI driver installed and configured, the PV creation continues
  to work, even for brand new volumes. The actual storage management now happens through
  the CSI driver.
  
  The operations and features that are supported include:
  provisioning/delete, attach/detach, mount/unmount and resizing of volumes.
  In-tree plugins that support CSIMigration and have a corresponding CSI driver implemented
  are listed in Types of Volumes.
  The following in-tree plugins support persistent storage on Windows nodes:
  
  azureFile
  gcePersistentDisk
  vsphereVolume
  
  flexVolume (deprecated)
  
  FEATURE STATE:
  Kubernetes v1.23 [deprecated]
  
  FlexVolume is an out-of-tree plugin interface that uses an exec-based model to interface
  with storage drivers. The FlexVolume driver binaries must be installed in a pre-defined
  volume plugin path on each node and in some cases the control plane nodes as well.
  Pods interact with FlexVolume drivers through the flexVolume in-tree volume plugin.
  For more details, see the FlexVolume README document.
  The following FlexVolume plugins,
  deployed as PowerShell scripts on the host, support Windows nodes:
  
  SMB
  iSCSI
  
  Note:FlexVolume is deprecated. Using an out-of-tree CSI driver is the recommended way to integrate external storage with Kubernetes.
  Maintainers of FlexVolume driver should implement a CSI Driver and help to migrate users of FlexVolume drivers to CSI.
  Users of FlexVolume should move their workloads to use the equivalent CSI Driver.
  
  Mount propagation
  Caution:Mount propagation is a low-level feature that does not work consistently on all
  volume types. It is recommended to use only with hostPath or in-memory emptyDir
  volumes. See this discussion
  for more context.
  Mount propagation allows for sharing volumes mounted by a container to
  other containers in the same pod, or even to other pods on the same node.
  Mount propagation of a volume is controlled by the mountPropagation field
  in containers[*].volumeMounts. Its values are:
  
  None - This volume mount will not receive any subsequent mounts
  that are mounted to this volume or any of its subdirectories by the host.
  In similar fashion, no mounts created by the container will be visible on
  the host. This is the default mode.
  This mode is equal to rprivate mount propagation as described in
  mount(8)
  However, the CRI runtime may choose rslave mount propagation (i.e.,
  HostToContainer) instead, when rprivate propagation is not applicable.
  cri-dockerd (Docker) is known to choose rslave mount propagation when the
  mount source contains the Docker daemon's root directory (/var/lib/docker).
  
  HostToContainer - This volume mount will receive all subsequent mounts
  that are mounted to this volume or any of its subdirectories.
  In other words, if the host mounts anything inside the volume mount, the
  container will see it mounted there.
  Similarly, if any Pod with Bidirectional mount propagation to the same
  volume mounts anything there, the container with HostToContainer mount
  propagation will see it.
  This mode is equal to rslave mount propagation as described in the
  mount(8)
  
  Bidirectional - This volume mount behaves the same the HostToContainer mount.
  In addition, all volume mounts created by the container will be propagated
  back to the host and to all containers of all pods that use the same volume.
  A typical use case for this mode is a Pod with a FlexVolume or CSI driver or
  a Pod that needs to mount something on the host using a hostPath volume.
  This mode is equal to rshared mount propagation as described in the
  mount(8)
  Warning:Bidirectional mount propagation can be dangerous. It can damage
  the host operating system and therefore it is allowed only in privileged
  containers. Familiarity with Linux kernel behavior is strongly recommended.
  In addition, any volume mounts created by containers in pods must be destroyed
  (unmounted) by the containers on termination.
  
  Read-only mounts
  A mount can be made read-only by setting the .spec.containers[].volumeMounts[].readOnly
  field to true.
  This does not make the volume itself read-only, but that specific container will
  not be able to write to it.
  Other containers in the Pod may mount the same volume as read-write.
  On Linux, read-only mounts are not recursively read-only by default.
  For example, consider a Pod which mounts the hosts /mnt as a hostPath volume. If
  there is another filesystem mounted read-write on /mnt/<SUBMOUNT> (such as tmpfs,
  NFS, or USB storage), the volume mounted into the container(s) will also have a writeable
  /mnt/<SUBMOUNT>, even if the mount itself was specified as read-only.
  Recursive read-only mounts
  
  FEATURE STATE:
  Kubernetes v1.31 [beta] (enabled by default: true)
  
  Recursive read-only mounts can be enabled by setting the
  RecursiveReadOnlyMounts feature gate
  for kubelet and kube-apiserver, and setting the .spec.containers[].volumeMounts[].recursiveReadOnly
  field for a pod.
  The allowed values are:
  
  Disabled (default): no effect.
  
  Enabled: makes the mount recursively read-only.
  Needs all the following requirements to be satisfied:
  
  readOnly is set to true
  mountPropagation is unset, or, set to None
  The host is running with Linux kernel v5.12 or later
  The CRI-level container runtime supports recursive read-only mounts
  The OCI-level container runtime supports recursive read-only mounts.
  It will fail if any of these is not true.
  
  IfPossible: attempts to apply Enabled, and falls back to Disabled
  if the feature is not supported by the kernel or the runtime class.
  
  Example:
  
  storage/rro.yaml
  
  apiVersion: v1
  kind: Pod
  metadata:
   name: rro
  spec:
   volumes:
   - name: mnt
   hostPath:
   # tmpfs is mounted on /mnt/tmpfs
   path: /mnt
   containers:
   - name: busybox
   image: busybox
   args: ["sleep", "infinity"]
   volumeMounts:
   # /mnt-rro/tmpfs is not writable
   - name: mnt
   mountPath: /mnt-rro
   readOnly: true
   mountPropagation: None
   recursiveReadOnly: Enabled
   # /mnt-ro/tmpfs is writable
   - name: mnt
   mountPath: /mnt-ro
   readOnly: true
   # /mnt-rw/tmpfs is writable
   - name: mnt
   mountPath: /mnt-rw
  
  When this property is recognized by kubelet and kube-apiserver,
  the .status.containerStatuses[].volumeMounts[].recursiveReadOnly field is set to either
  Enabled or Disabled.
  Implementations
  Note: This section links to third party projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for these projects, which are listed alphabetically. To add a project to this list, read the content guide before submitting a change. More information.
  The following container runtimes are known to support recursive read-only mounts.
  CRI-level:
  
  containerd, since v2.0
  CRI-O, since v1.30
  
  OCI-level:
  
  runc, since v1.1
  crun, since v1.8.6
  
  What's next
  Follow an example of deploying WordPress and MySQL with Persistent Volumes.
  
  Items on this page refer to third party products or projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for those third-party products or projects. See the CNCF website guidelines for more details.You should read the content guide before proposing a change that adds an extra third-party link.
  
  Feedback
  Was this page helpful?
  Yes
  No
  
   Thanks for the feedback. If you have a specific, answerable question about how to use Kubernetes, ask it on
  
   Stack Overflow.
   Open an issue in the GitHub Repository if you want to
  
   report a problem
   or
  
   suggest an improvement.
  
   Last modified November 23, 2024 at 2:59 PM PST: Fix sample CEL expression in volumes.md (38e7774e77)
  
   Volume API reference
    Create child page
   Create documentation issue
   Print entire section
  
  Background
  Types of volumes
  
  awsElasticBlockStore (deprecated)
  azureDisk (deprecated)
  azureFile (deprecated)
  cephfs (removed)
  cinder (deprecated)
  configMap
  downwardAPI
  emptyDir
  fc (fibre channel)
  gcePersistentDisk (deprecated)
  gitRepo (deprecated)
  glusterfs (removed)
  hostPath
  image
  iscsi
  local
  nfs
  persistentVolumeClaim
  portworxVolume (deprecated)
  projected
  rbd (removed)
  secret
  vsphereVolume (deprecated)
  
  Using subPath
  
  Using subPath with expanded environment variables
  
  Resources
  Out-of-tree volume plugins
  
  csi
  flexVolume (deprecated)
  
  Mount propagation
  Read-only mounts
  
  Recursive read-only mounts
  
  What's next
  
  © 2025 The Kubernetes Authors | Documentation Distributed under CC BY 4.0
  © 2025 The Linux Foundation ®. ICP license: 京ICP备17074266号-3
  ```