# 卷

LLMS index: [llms.txt](/llms.txt)

---

<!--
reviewers:
- jsafrane
- saad-ali
- thockin
- msau42
title: Volumes
api_metadata:
- apiVersion: ""
  kind: "Volume"
content_type: concept
weight: 10
-->

<!-- overview -->

<!--
Kubernetes _volumes_ provide a way for containers in a <a class='glossary-tooltip' title='Pod 表示你的集群上一组正在运行的容器。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/workloads/pods/' target='_blank' aria-label='Pod'>Pod</a>
to access and share data via the filesystem. There are different kinds of volume that you can use for different purposes,
such as:
-->
Kubernetes **卷**为 <a class='glossary-tooltip' title='Pod 表示你的集群上一组正在运行的容器。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/workloads/pods/' target='_blank' aria-label='Pod'>Pod</a>
中的容器提供了一种通过文件系统访问和共享数据的方式。存在不同类别的卷，你可以将其用于各种用途，例如：

<!--
- populating a configuration file based on a <a class='glossary-tooltip' title='ConfigMap 是一种 API 对象，用来将非机密性的数据保存到键值对中。使用时可以用作环境变量、命令行参数或者存储卷中的配置文件。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/tasks/configure-pod-container/configure-pod-configmap/' target='_blank' aria-label='ConfigMap'>ConfigMap</a>
  or a <a class='glossary-tooltip' title='Secret 用于存储敏感信息，如密码、 OAuth 令牌和 SSH 密钥。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/configuration/secret/' target='_blank' aria-label='Secret'>Secret</a>
- providing some temporary scratch space for a Pod
- sharing a filesystem between two different containers in the same Pod
- sharing a filesystem between two different Pods (even if those Pods run on different nodes)
- durably storing data so that it stays available even if the Pod restarts or is replaced
-->
- 基于 <a class='glossary-tooltip' title='ConfigMap 是一种 API 对象，用来将非机密性的数据保存到键值对中。使用时可以用作环境变量、命令行参数或者存储卷中的配置文件。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/tasks/configure-pod-container/configure-pod-configmap/' target='_blank' aria-label='ConfigMap'>ConfigMap</a> 或
  <a class='glossary-tooltip' title='Secret 用于存储敏感信息，如密码、 OAuth 令牌和 SSH 密钥。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/configuration/secret/' target='_blank' aria-label='Secret'>Secret</a> 填充配置文件
- 为 Pod 提供一些临时的涂销空间
- 在同一个 Pod 中的两个不同容器之间共享文件系统
- 在两个不同的 Pod 之间共享文件系统（即使这些 Pod 运行在不同的节点上）
- 持久化存储数据，这样即使 Pod 重启或被替换，存储的数据仍然可用
<!--
- passing configuration information to an app running in a container, based on details of the Pod
  the container is in
  (for example: telling a <a class='glossary-tooltip' title='在 Pod 的整个生命期内保持运行的辅助容器。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/workloads/pods/sidecar-containers/' target='_blank' aria-label='sidecar container'>sidecar container</a>
  what namespace the Pod is running in)
- providing read-only access to data in a different container image
-->
- 基于容器所在 Pod 的详细信息，将配置信息传递给运行在容器中的应用
  （例如告诉<a class='glossary-tooltip' title='在 Pod 的整个生命期内保持运行的辅助容器。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/workloads/pods/sidecar-containers/' target='_blank' aria-label='边车容器'>边车容器</a>：Pod 运行在哪个命名空间）
- 以只读权限访问另一个容器镜像中的数据

<!--
Data sharing can be between different local processes within a container, or between different containers,
or between Pods.
-->
数据共享可以发生在容器内不同本地进程之间，或在不同容器之间，或在多个 Pod 之间。

<!--
## Why volumes are important

- **Data persistence:** On-disk files in a container are ephemeral, which presents some problems for
  non-trivial applications when running in containers. One problem occurs when
  a container crashes or is stopped, the container state is not saved, so all of the
  files that were created or modified during the lifetime of the container are lost.
  After a crash, kubelet restarts the container with a clean state.
-->
## 为什么卷很重要   {#why-volumes-are-important}

- **数据持久性：** 容器中的文件在磁盘上是临时存放的，这给在容器中运行较重要的应用带来一些问题。
  当容器崩溃或被停止时，容器的状态不会被保存，因此在容器生命期内创建或修改的所有文件都将丢失。
  在崩溃之后，kubelet 会以干净的状态重启容器。

<!--
- **Shared storage:** Another problem occurs when multiple containers are running in a `Pod` and
  need to share files. It can be challenging to set up
  and access a shared filesystem across all of the containers.

The Kubernetes <a class='glossary-tooltip' title='包含可被 Pod 中容器访问的数据的目录。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/storage/volumes/' target='_blank' aria-label='volume'>volume</a> abstraction
can help you to solve both of these problems.
-->
- **共享存储：** 当多个容器在一个 Pod 中运行并需要共享文件时，会出现另一个问题。
  那就是在所有容器之间设置和访问共享文件系统可能会很有难度。

Kubernetes <a class='glossary-tooltip' title='包含可被 Pod 中容器访问的数据的目录。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/storage/volumes/' target='_blank' aria-label='卷（Volume）'>卷（Volume）</a>
这一抽象概念能够解决这两个问题。

<!--
Before you learn about volumes, PersistentVolumes, and PersistentVolumeClaims, you should read up
about <a class='glossary-tooltip' title='Pod 表示你的集群上一组正在运行的容器。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/workloads/pods/' target='_blank' aria-label='Pods'>Pods</a> and make sure that you understand how
Kubernetes uses Pods to run containers.
-->
在你学习卷、持久卷（PersistentVolume）和持久卷申领（PersistentVolumeClaim）之前，
你应该先了解 <a class='glossary-tooltip' title='Pod 表示你的集群上一组正在运行的容器。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/workloads/pods/' target='_blank' aria-label='Pod'>Pod</a>，
确保你理解 Kubernetes 如何使用 Pod 来运行容器。

<!-- body -->

<!--
## How volumes work
-->
## 卷是如何工作的   {#how-volumes-work}

<!--
Kubernetes supports many types of volumes. A <a class='glossary-tooltip' title='Pod 表示你的集群上一组正在运行的容器。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/workloads/pods/' target='_blank' aria-label='Pod'>Pod</a>
can use any number of volume types simultaneously.
[Ephemeral volume](/docs/concepts/storage/ephemeral-volumes/) types have a lifetime linked to a specific Pod,
but [persistent volumes](/docs/concepts/storage/persistent-volumes/) exist beyond
the lifetime of any individual pod. When a Pod ceases to exist, Kubernetes destroys ephemeral volumes;
however, Kubernetes does not destroy persistent volumes.
For any kind of volume in a given Pod, data is preserved across container restarts.
-->
Kubernetes 支持很多类型的卷。
<a class='glossary-tooltip' title='Pod 表示你的集群上一组正在运行的容器。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/workloads/pods/' target='_blank' aria-label='Pod'>Pod</a> 可以同时使用任意数目的卷类型。
[临时卷](/zh-cn/docs/concepts/storage/ephemeral-volumes/)类型将生命期关联到特定的 Pod，
但[持久卷](/zh-cn/docs/concepts/storage/persistent-volumes/)可以比任意独立 Pod 的生命期长。
当 Pod 不再存在时，Kubernetes 也会销毁临时卷；不过 Kubernetes 不会销毁持久卷。
对于给定 Pod 中任何类型的卷，在容器重启期间数据都不会丢失。

<!--
At its core, a volume is a directory, possibly with some data in it, which
is accessible to the containers in a pod. How that directory comes to be, the
medium that backs it, and the contents of it are determined by the particular
volume type used.
-->
卷的核心是一个目录，其中可能存有数据，Pod 中的容器可以访问该目录中的数据。
所采用的特定的卷类型将决定该目录如何形成的、使用何种介质保存数据以及目录中存放的内容。

<!--
To use a volume, specify the volumes to provide for the Pod in `.spec.volumes`
and declare where to mount those volumes into containers in `.spec.containers[*].volumeMounts`.
-->
使用卷时, 在 `.spec.volumes` 字段中设置为 Pod 提供的卷，并在
`.spec.containers[*].volumeMounts` 字段中声明卷在容器中的挂载位置。

<!--
When a Pod is launched, a process in the container sees a filesystem view composed from the initial contents of
the <a class='glossary-tooltip' title='镜像（Image）是保存的容器实例，它打包了应用运行所需的一组软件。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/reference/glossary/?all=true#term-image' target='_blank' aria-label='container image'>container image</a>, plus volumes
(if defined) mounted inside the container.
The process sees a root filesystem that initially matches the contents of the container image.
Any writes to within that filesystem hierarchy, if allowed, affect what that process views
when it performs a subsequent filesystem access.
Volumes are mounted at [specified paths](#using-subpath) within the container filesystem.
For each container defined within a Pod, you must independently specify where
to mount each volume that the container uses.
-->
当 Pod 被启动时，容器中的进程看到的文件系统视图是由它们的<a class='glossary-tooltip' title='镜像（Image）是保存的容器实例，它打包了应用运行所需的一组软件。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/reference/glossary/?all=true#term-image' target='_blank' aria-label='容器镜像'>容器镜像</a>
的初始内容以及挂载在容器中的卷（如果定义了的话）所组成的。
其中根文件系统同容器镜像的内容相吻合。
任何在该文件系统下的写入操作，如果被允许的话，都会影响接下来容器中进程访问文件系统时所看到的内容。
卷被挂载在镜像中的[指定路径](#using-subpath)下。
Pod 配置中的每个容器必须独立指定各个卷的挂载位置。

<!--
Volumes cannot mount within other volumes (but see [Using subPath](#using-subpath)
for a related mechanism). Also, a volume cannot contain a hard link to anything in
a different volume.
-->
卷不能挂载到其他卷之上（不过存在一种[使用 subPath](#using-subpath) 的相关机制），
也不能与其他卷有硬链接。

<!--
## Types of volumes {#volume-types}

Kubernetes supports several types of volumes.
-->
## 卷类型  {#volume-types}

Kubernetes 支持下列类型的卷：

### configMap

<!--
A [ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap/)
provides a way to inject configuration data into Pods.
The data stored in a ConfigMap can be referenced in a volume of type
`configMap` and then consumed by containerized applications running in a Pod.
-->
[`configMap`](/zh-cn/docs/tasks/configure-pod-container/configure-pod-configmap/)
卷提供了向 Pod 注入配置数据的方法。
ConfigMap 对象中存储的数据可以被 `configMap` 类型的卷引用，然后被 Pod 中运行的容器化应用使用。

<!--
When referencing a ConfigMap, you provide the name of the ConfigMap in the
volume. You can customize the path to use for a specific
entry in the ConfigMap. The following configuration shows how to mount
the `log-config` ConfigMap onto a Pod called `configmap-pod`:
-->
引用 configMap 对象时，你可以在卷中通过它的名称来引用。
你可以自定义 ConfigMap 中特定条目所要使用的路径。
下面的配置显示了如何将名为 `log-config` 的 ConfigMap 挂载到名为 `configmap-pod`
的 Pod 中：

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod
spec:
  containers:
    - name: test
      image: busybox:1.28
      command: ['sh', '-c', 'echo "The app is running!" && tail -f /dev/null']
      volumeMounts:
        - name: config-vol
          mountPath: /etc/config
  volumes:
    - name: config-vol
      configMap:
        name: log-config
        items:
          - key: log_level
            path: log_level.conf
```

<!--
The `log-config` ConfigMap is mounted as a volume, and all contents stored in
its `log_level` entry are mounted into the Pod at path `/etc/config/log_level.conf`.
Note that this path is derived from the volume's `mountPath` and the `path`
keyed with `log_level`.
-->
`log-config` ConfigMap 以卷的形式挂载，并且存储在 `log_level`
条目中的所有内容都被挂载到 Pod 的 `/etc/config/log_level.conf` 路径下。
请注意，这个路径来源于卷的 `mountPath` 和 `log_level` 键对应的 `path`。


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
* You must [create a ConfigMap](/docs/tasks/configure-pod-container/configure-pod-configmap/#create-a-configmap)
  before you can use it.

* A ConfigMap is always mounted as `readOnly`.

* A container using a ConfigMap as a [`subPath`](#using-subpath) volume mount will not
  receive updates when the ConfigMap changes.
  
* Text data is exposed as files using the UTF-8 character encoding.
  For other character encodings, use `binaryData`.
-->
<ul>
<li>你必须先<a href="/zh-cn/docs/tasks/configure-pod-container/configure-pod-configmap/#create-a-configmap">创建 ConfigMap</a>，
才能使用它。</li>
<li>ConfigMap 总是以 <code>readOnly</code> 的模式挂载。</li>
<li>某容器以 <a href="#using-subpath"><code>subPath</code></a> 卷挂载方式使用 ConfigMap 时，
若 ConfigMap 发生变化，此容器将无法接收更新。</li>
<li>文本数据挂载成文件时采用 UTF-8 字符编码。如果使用其他字符编码形式，可使用
<code>binaryData</code> 字段。</li>
</ul>
</div>


### downwardAPI {#downwardapi}

<!--
A `downwardAPI` volume makes <a class='glossary-tooltip' title='将 Pod 和容器字段值暴露给容器中运行的代码的机制。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/workloads/pods/downward-api/' target='_blank' aria-label='downward API'>downward API</a>
data available to applications. Within the volume, you can find the exposed
data as read-only files in plain text format.
-->
`downwardAPI` 卷用于为应用提供 <a class='glossary-tooltip' title='将 Pod 和容器字段值暴露给容器中运行的代码的机制。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/workloads/pods/downward-api/' target='_blank' aria-label='downward API'>downward API</a> 数据。
在这类卷中，所公开的数据以纯文本格式的只读文件形式存在。


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
A container using the downward API as a [`subPath`](#using-subpath) volume mount does not
receive updates when field values change.
-->
<p>容器以 <a href="#using-subpath">subPath</a> 卷挂载方式使用 downward API 时，
在字段值更改时将不能接收到它的更新。</p></div>


<!--
See [Expose Pod Information to Containers Through Files](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/)
to learn more.
-->
更多详细信息请参考[通过文件将 Pod 信息呈现给容器](/zh-cn/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/)。

### emptyDir {#emptydir}

<!--
For a Pod that defines an `emptyDir` volume, the volume is created when the Pod is assigned to a node.
As the name says, the `emptyDir` volume is initially empty. All containers in the Pod can read and write the same
files in the `emptyDir` volume, though that volume can be mounted at the same
or different paths in each container. When a Pod is removed from a node for
any reason, the data in the `emptyDir` is deleted permanently.
-->
对于定义了 `emptyDir` 卷的 Pod，在 Pod 被指派到某节点时此卷会被创建。
就像其名称所表示的那样，`emptyDir` 卷最初是空的。尽管 Pod 中的容器挂载 `emptyDir`
卷的路径可能相同也可能不同，但这些容器都可以读写 `emptyDir` 卷中相同的文件。
当 Pod 因为某些原因被从节点上删除时，`emptyDir` 卷中的数据也会被永久删除。


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
A container crashing does *not* remove a Pod from a node. The data in an `emptyDir` volume
is safe across container crashes.
-->
<p>容器崩溃并<strong>不</strong>会导致 Pod 被从节点上移除，因此容器崩溃期间 <code>emptyDir</code> 卷中的数据是安全的。</p></div>


<!--
Some uses for an `emptyDir` are:

* scratch space, such as for a disk-based merge sort
* checkpointing a long computation for recovery from crashes
* holding files that a content-manager container fetches while a webserver
  container serves the data
-->
`emptyDir` 的一些用途：

* 缓存空间，例如基于磁盘的归并排序。
* 为耗时较长的计算任务提供检查点，以便任务能方便地从崩溃前状态恢复执行。
* 在 Web 服务器容器服务数据时，保存内容管理器容器获取的文件。

<!--
The `emptyDir.medium` field controls where `emptyDir` volumes are stored. By
default `emptyDir` volumes are stored on whatever medium that backs the node
such as disk, SSD, or network storage, depending on your environment. If you set
the `emptyDir.medium` field to `"Memory"`, Kubernetes mounts a tmpfs (RAM-backed
filesystem) for you instead. While tmpfs is very fast, be aware that, unlike
disks, files you write count against the memory limit of the container that wrote them.
-->
`emptyDir.medium` 字段用来控制 `emptyDir` 卷的存储位置。
默认情况下，`emptyDir` 卷存储在该节点所使用的介质上；
此处的介质可以是磁盘、SSD 或网络存储，这取决于你的环境。
你可以将 `emptyDir.medium` 字段设置为 `"Memory"`，
以告诉 Kubernetes 为你挂载 tmpfs（基于 RAM 的文件系统）。
虽然 tmpfs 速度非常快，但是要注意它与磁盘不同，
并且你所写入的所有文件都会计入容器的内存消耗，受容器内存限制约束。

<!--
A size limit can be specified for the default medium, which limits the capacity
of the `emptyDir` volume. The storage is allocated from
[node ephemeral storage](/docs/concepts/storage/ephemeral-storage/#setting-requests-and-limits-for-local-ephemeral-storage).
If that is filled up from another source (for example, log files or image overlays),
the `emptyDir` may run out of capacity before this limit.
If no size is specified, memory-backed volumes are sized to node allocatable memory.
-->
你可以通过为默认介质指定大小限制，来限制 `emptyDir` 卷的存储容量。
此存储是从[节点临时存储](/zh-cn/docs/concepts/storage/ephemeral-storage/#setting-requests-and-limits-for-local-ephemeral-storage)中分配的。
如果来自其他来源（如日志文件或镜像分层数据）的数据占满了存储，`emptyDir`
可能会在达到此限制之前发生存储容量不足的问题。

<!--
If no size is specified, memory backed volumes are sized to node allocatable memory.
-->
如果未指定大小，内存支持的卷将被设置为节点可分配内存的大小。

<div class="alert alert-caution" role="note"><h4 class="alert-heading">注意：</h4><!--
Please check [here](/docs/concepts/configuration/manage-resources-containers/#memory-backed-emptydir)
for points to note in terms of resource management when using memory-backed `emptyDir`.
-->
<p>使用内存作为介质的 <code>emptyDir</code> 卷时，
请查阅<a href="/zh-cn/docs/concepts/configuration/manage-resources-containers/#memory-backed-emptydir">此处</a>，
了解有关资源管理方面的注意事项。</p></div>


<!--
#### emptyDir configuration example
-->
#### emptyDir 配置示例

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 500Mi
```

<!--
#### emptyDir memory configuration example
-->
#### emptyDir 内存配置示例

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 500Mi
      medium: Memory
```

<!--
### fc (fibre channel) {#fc}

An `fc` volume type allows an existing fibre channel block storage volume
to be mounted in a Pod. You can specify single or multiple target world wide names (WWNs)
using the parameter `targetWWNs` in your Volume configuration. If multiple WWNs are specified,
targetWWNs expect that those WWNs are from multi-path connections.
-->
### fc（光纤通道） {#fc}

`fc` 卷类型允许将现有的光纤通道块存储卷挂载到 Pod 中。
可以使用卷配置中的参数 `targetWWNs` 来指定单个或多个目标 WWN（World Wide Names）。
如果指定了多个 WWN，targetWWNs 期望这些 WWN 来自多路径连接。


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
You must configure FC SAN Zoning to allocate and mask those LUNs (volumes) to the target WWNs
beforehand so that Kubernetes hosts can access them.
-->
<p>你必须配置 FC SAN Zoning，以便预先向目标 WWN 分配和屏蔽这些 LUN（卷），这样
Kubernetes 主机才可以访问它们。</p></div>


<!--
### gcePersistentDisk (deprecated) {#gcepersistentdisk}

In Kubernetes 1.36, all operations for the in-tree `gcePersistentDisk` type
are redirected to the `pd.csi.storage.gke.io` <a class='glossary-tooltip' title='容器存储接口 （CSI）定义了存储系统暴露给容器的标准接口。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/storage/volumes/#csi' target='_blank' aria-label='CSI'>CSI</a> driver.
-->
### gcePersistentDisk（已弃用） {#gcepersistentdisk}

在 Kubernetes 1.36 中，所有针对树内 `gcePersistentDisk`
类型的操作都会被重定向到 `pd.csi.storage.gke.io` <a class='glossary-tooltip' title='容器存储接口 （CSI）定义了存储系统暴露给容器的标准接口。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/storage/volumes/#csi' target='_blank' aria-label='CSI'>CSI</a> 驱动。

<!--
The `gcePersistentDisk` in-tree storage driver was deprecated in the Kubernetes v1.17 release
and then removed entirely in the v1.28 release.
-->
`gcePersistentDisk` 源代码树内卷存储驱动在 Kubernetes v1.17 版本中被弃用，
在 v1.28 版本中被完全移除。

<!--
The Kubernetes project suggests that you use the
[Google Compute Engine Persistent Disk CSI](https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver)
third party storage driver instead.
-->
Kubernetes 项目建议你转为使用
[Google Compute Engine Persistent Disk CSI](https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver)
第三方存储驱动插件。

<!--
### gitRepo (disabled) {#gitrepo}
-->
### gitRepo（已禁用）   {#gitrepo}

<div class="alert alert-danger" role="note"><h4 class="alert-heading">警告：</h4><!--
Kubernetes 1.36 does *not* include the `gitRepo` volume
driver. The last version that provided a way to use this driver was Kubernetes
v1.35, and it has been deprecated since the [v1.11](/releases/1.11) minor
release.

To provision a Pod that has a Git repository mounted, you can mount an
[`emptyDir`](#emptydir) volume into an [init container](/docs/concepts/workloads/pods/init-containers/)
that clones the repo using Git, then mount the [EmptyDir](#emptydir) into the Pod's container.
-->
<p>Kubernetes 1.36 <strong>不</strong>包含 <code>gitRepo</code> 卷驱动。
提供使用此驱动方法的最后一个版本是 Kubernetes v1.35，
并且自从 <a href="/zh-cn/releases/1.11">v1.11</a> 小版本发布以来，它已被弃用。</p>
<p>如果需要制备已挂载 Git 仓库的 Pod，你可以将
<a href="#emptydir">EmptyDir</a> 卷挂载到
<a href="/zh-cn/docs/concepts/workloads/pods/init-containers/">Init 容器</a>中，
使用 Git 命令完成仓库的克隆操作，然后将 <a href="#emptydir">EmptyDir</a> 卷挂载到 Pod 的容器中。</p>
<hr>
<!--
You can restrict the use of `gitRepo` volumes in your cluster using
[policies](/docs/concepts/policy/), such as
[ValidatingAdmissionPolicy](/docs/reference/access-authn-authz/validating-admission-policy/).
You can use the following Common Expression Language (CEL) expression as
part of a policy to reject use of `gitRepo` volumes:
-->
<p>你可以使用 <a href="/zh-cn/docs/reference/access-authn-authz/validating-admission-policy/">ValidatingAdmissionPolicy</a>
这类<a href="/zh-cn/docs/concepts/policy/">策略</a>来限制在你的集群中使用 <code>gitRepo</code> 卷。
你可以使用以下通用表达语言（CEL）表达式作为策略的一部分，以拒绝使用 <code>gitRepo</code> 卷：</p>
<pre tabindex="0"><code class="language-cel" data-lang="cel">!has(object.spec.volumes) || !object.spec.volumes.exists(v, has(v.gitRepo))
</code></pre></div>


### hostPath {#hostpath}

<!--
A `hostPath` volume mounts a file or directory from the host node's filesystem
into your Pod. This is not something that most Pods will need, but it offers a
powerful escape hatch for some applications.
-->
`hostPath` 卷能将主机节点文件系统上的文件或目录挂载到你的 Pod 中。
虽然这不是大多数 Pod 需要的，但是它为一些应用提供了强大的逃生舱。

<div class="alert alert-danger" role="note"><h4 class="alert-heading">警告：</h4><!-- 
Using the `hostPath` volume type presents many security risks.
If you can avoid using a `hostPath` volume, you should. For example,
define a [`local` PersistentVolume](#local), and use that instead.

If you are restricting access to specific directories on the node using
admission-time validation, that restriction is only effective when you
additionally require that any mounts of that `hostPath` volume are
**read only**. If you allow a read-write mount of any host path by an
untrusted Pod, the containers in that Pod may be able to subvert the
read-write host mount.
-->
<p>使用 <code>hostPath</code> 类型的卷存在许多安全风险。如果可以，你应该尽量避免使用 <code>hostPath</code> 卷。
例如，你可以改为定义并使用 <a href="#local"><code>local</code> PersistentVolume</a>。</p>
<p>如果你通过准入时的验证来限制对节点上特定目录的访问，这种限制只有在你额外要求所有
<code>hostPath</code> 卷的挂载都是<strong>只读</strong>的情况下才有效。如果你允许不受信任的 Pod
以读写方式挂载任意主机路径，则该 Pod 中的容器可能会破坏可读写主机挂载卷的安全性。</p>
<hr>
<!--
Take care when using `hostPath` volumes, whether these are mounted as read-only
or as read-write, because:
-->
<p>无论 <code>hostPath</code> 卷是以只读还是读写方式挂载，使用时都需要小心，这是因为：</p>
<!--
* Access to the host filesystem can expose privileged system credentials (such as for the kubelet) or privileged APIs
  (such as the container runtime socket) that can be used for container escape or to attack other
  parts of the cluster.
* Pods with identical configuration (such as created from a PodTemplate) may
  behave differently on different nodes due to different files on the nodes.
* `hostPath` volume usage is not treated as ephemeral storage usage.
  You need to monitor the disk usage by yourself because excessive `hostPath` disk
  usage will lead to disk pressure on the node.
-->
<ul>
<li>访问主机文件系统可能会暴露特权系统凭证（例如 kubelet 的凭证）或特权 API（例如容器运行时套接字），
这些可以被用于容器逃逸或攻击集群的其他部分。</li>
<li>具有相同配置的 Pod（例如基于 PodTemplate 创建的 Pod）可能会由于节点上的文件不同而在不同节点上表现出不同的行为。</li>
<li><code>hostPath</code> 卷的用量不会被视为临时存储用量。
你需要自己监控磁盘使用情况，因为过多的 <code>hostPath</code> 磁盘使用量会导致节点上的磁盘压力。</li>
</ul>
</div>


<!--
Some uses for a `hostPath` are:

* running a container that needs access to node-level system components
  (such as a container that transfers system logs to a central location,
  accessing those logs using a read-only mount of `/var/log`)
* making a configuration file stored on the host system available read-only
  to a <a class='glossary-tooltip' title='静态 Pod（Static Pod）是指由特定节点上的 kubelet 守护进程直接管理的 Pod。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/tasks/configure-pod-container/static-pod/' target='_blank' aria-label='static Pod'>static Pod</a>;
  unlike normal Pods, static Pods cannot access ConfigMaps
-->
`hostPath` 的一些用法有：

* 运行一个需要访问节点级系统组件的容器
  （例如一个将系统日志传输到集中位置的容器，使用只读挂载 `/var/log` 来访问这些日志）
* 让存储在主机系统上的配置文件可以被<a class='glossary-tooltip' title='静态 Pod（Static Pod）是指由特定节点上的 kubelet 守护进程直接管理的 Pod。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/tasks/configure-pod-container/static-pod/' target='_blank' aria-label='静态 Pod'>静态 Pod</a>
  以只读方式访问；与普通 Pod 不同，静态 Pod 无法访问 ConfigMap。

<!--
#### `hostPath` volume types

In addition to the required `path` property, you can optionally specify a
`type` for a `hostPath` volume.

The available values for `type` are:
-->
#### `hostPath` 卷类型

除了必需的 `path` 属性外，你还可以选择为 `hostPath` 卷指定 `type`。

`type` 的可用值有：

<!-- empty string represented using U+200C ZERO WIDTH NON-JOINER -->

<!--
| Value | Behavior |
|:------|:---------|
| `‌""` | Empty string (default) is for backward compatibility, which means that no checks will be performed before mounting the `hostPath` volume. |
| `DirectoryOrCreate` | If nothing exists at the given path, an empty directory will be created there as needed with permission set to 0755, having the same group and ownership with Kubelet. |
| `Directory` | A directory must exist at the given path. |
| `FileOrCreate` | If nothing exists at the given path, an empty file will be created there as needed with permission set to 0644, having the same group and ownership with Kubelet. |
| `File` | A file must exist at the given path. |
| `Socket` | A UNIX socket must exist at the given path. |
| `CharDevice` | _(Linux nodes only)_ A character device must exist at the given path. |
| `BlockDevice` | _(Linux nodes only)_ A block device must exist at the given path. |
-->
| 取值  | 行为     |
|:------|:---------|
| `‌""` | 空字符串（默认）用于向后兼容，这意味着在安装 hostPath 卷之前不会执行任何检查。 |
| `DirectoryOrCreate` | 如果在给定路径上什么都不存在，那么将根据需要创建空目录，权限设置为 0755，具有与 kubelet 相同的组和属主信息。 |
| `Directory` | 在给定路径上必须存在的目录。|
| `FileOrCreate` | 如果在给定路径上什么都不存在，那么将在那里根据需要创建空文件，权限设置为 0644，具有与 kubelet 相同的组和所有权。|
| `File` | 在给定路径上必须存在的文件。|
| `Socket` | 在给定路径上必须存在的 UNIX 套接字。|
| `CharDevice` | **（仅 Linux 节点）** 在给定路径上必须存在的字符设备。|
| `BlockDevice` | **（仅 Linux 节点）** 在给定路径上必须存在的块设备。|

<div class="alert alert-caution" role="note"><h4 class="alert-heading">注意：</h4><!--
The `FileOrCreate` mode does **not** create the parent directory of the file. If the parent directory
of the mounted file does not exist, the Pod fails to start. To ensure that this mode works,
you can try to mount directories and files separately, as shown in the
[`FileOrCreate` example](#hostpath-fileorcreate-example) for `hostPath`.
-->
<p><code>FileOrCreate</code> 模式<strong>不会</strong>创建文件的父目录。如果挂载文件的父目录不存在，Pod 将启动失败。
为了确保这种模式正常工作，你可以尝试分别挂载目录和文件，如
<code>hostPath</code> 的 <a href="#hostpath-fileorcreate-example"><code>FileOrCreate</code> 示例</a>所示。</p></div>


<!--
Some files or directories created on the underlying hosts might only be
accessible by root. You then either need to run your process as root in a
[privileged container](/docs/tasks/configure-pod-container/security-context/)
or modify the file permissions on the host to read from or write to a `hostPath` volume.
-->
下层主机上创建的某些文件或目录只能由 root 用户访问。
此时，你需要在[特权容器](/zh-cn/docs/tasks/configure-pod-container/security-context/)中以
root 身份运行进程，或者修改主机上的文件权限，以便能够从 `hostPath`
卷读取数据（或将数据写入到 `hostPath` 卷）。

<!--
#### hostPath configuration example
-->
#### hostPath 配置示例

<ul class="nav nav-tabs" id="tabs-hostpath-examples" role="tablist"><li class="nav-item"><a data-bs-toggle="tab" class="nav-link active" href="#tabs-hostpath-examples-0" role="tab" aria-controls="tabs-hostpath-examples-0" aria-selected="true">Linux 节点</a></li>
	  
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-hostpath-examples-1" role="tab" aria-controls="tabs-hostpath-examples-1">Windows 节点</a></li></ul>

<div class="tab-content" id="tabs-hostpath-examples-content"><div class="tab-body tab-pane fadeshow active"
        id="tabs-hostpath-examples-0" role="tabpanel" aria-labelledby="tabs-hostpath-examples-0-tab" tabindex="hostpath-examples"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># 此清单将主机上的 &#34;/data/foo&#34; 目录挂载为 hostpath-example-linux Pod 中运行的单个容器内的 &#34;/foo&#34; 目录</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># 容器中的挂载是只读的</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Pod</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">hostpath-example-linux</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">os</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">linux }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">nodeSelector</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kubernetes.io/os</span><span class="p">:</span><span class="w"> </span><span class="l">linux</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">containers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">example-container</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">registry.k8s.io/test-webserver</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumeMounts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="l">/foo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">example-volume</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">readOnly</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">example-volume</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># 挂载 &#34;/data/foo&#34;，但仅当该目录已经存在时</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">hostPath</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/data/foo</span><span class="w"> </span><span class="c"># 主机上的目录位置</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">Directory</span><span class="w"> </span><span class="c"># 此字段可选</span><span class="w">
</span></span></span></code></pre></div></div><div class="tab-body tab-pane fade"
        id="tabs-hostpath-examples-1" role="tabpanel" aria-labelledby="tabs-hostpath-examples-1-tab" tabindex="hostpath-examples"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># 此清单将主机上的 &#34;C:\Data\foo&#34; 目录挂载为 hostpath-example-windows Pod</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># 中运行的单个容器内的 &#34;C:\foo&#34; 目录</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c">#</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c"># 容器中的挂载是只读的</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Pod</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">hostpath-example-windows</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">os</span><span class="p">:</span><span class="w"> </span>{<span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">windows }</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">nodeSelector</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">kubernetes.io/os</span><span class="p">:</span><span class="w"> </span><span class="l">windows</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">containers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">example-container</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">microsoft/windowsservercore:1709</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumeMounts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">example-volume</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;C:\\foo&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">readOnly</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># 从主机挂载 &#34;C:\Data\foo&#34;，但仅当该目录已经存在时</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">example-volume</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">hostPath</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;C:\\Data\\foo&#34;</span><span class="w"> </span><span class="c"># 主机上的目录位置</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">Directory      </span><span class="w"> </span><span class="c"># 此字段可选</span><span class="w">
</span></span></span></code></pre></div></div></div>


<!--
#### hostPath FileOrCreate configuration example {#hostpath-fileorcreate-example}
-->
#### hostPath FileOrCreate 配置示例  {#hostpath-fileorcreate-example}

<!--
The following manifest defines a Pod that mounts `/var/local/aaa`
inside the single container in the Pod. If the node does not
already have a path `/var/local/aaa`, the kubelet creates
it as a directory and then mounts it into the Pod.
-->
以下清单定义了一个 Pod，将 `/var/local/aaa` 挂载到 Pod 中的单个容器内。
如果节点上还没有路径 `/var/local/aaa`，kubelet 会创建这一目录，然后将其挂载到 Pod 中。

<!--
If `/var/local/aaa` already exists but is not a directory,
the Pod fails. Additionally, the kubelet attempts to make
a file named `/var/local/aaa/1.txt` inside that directory
(as seen from the host); if something already exists at
that path and isn't a regular file, the Pod fails.

Here's the example manifest:
-->
如果 `/var/local/aaa` 已经存在但不是一个目录，Pod 会失败。
此外，kubelet 还会尝试在该目录内创建一个名为 `/var/local/aaa/1.txt` 的文件（从主机的视角来看）；
如果在该路径上已经存在某个东西且不是常规文件，则 Pod 会失败。

以下是清单示例：

<!--
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-webserver
spec:
  os: { name: linux }
  nodeSelector:
    kubernetes.io/os: linux
  containers:
  - name: test-webserver
    image: registry.k8s.io/test-webserver:latest
    volumeMounts:
    - mountPath: /var/local/aaa
      name: mydir
    - mountPath: /var/local/aaa/1.txt
      name: myfile
  volumes:
  - name: mydir
    hostPath:
      # Ensure the file directory is created.
      path: /var/local/aaa
      type: DirectoryOrCreate
  - name: myfile
    hostPath:
      path: /var/local/aaa/1.txt
      type: FileOrCreate
```
-->
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-webserver
spec:
  os: { name: linux }
  nodeSelector:
    kubernetes.io/os: linux
  containers:
  - name: test-webserver
    image: registry.k8s.io/test-webserver:latest
    volumeMounts:
    - mountPath: /var/local/aaa
      name: mydir
    - mountPath: /var/local/aaa/1.txt
      name: myfile
  volumes:
  - name: mydir
    hostPath:
      # 确保文件所在目录被创建成功。
      path: /var/local/aaa
      type: DirectoryOrCreate
  - name: myfile
    hostPath:
      path: /var/local/aaa/1.txt
      type: FileOrCreate
```

### image








  <div class="feature-state-notice feature-stable" title="特性门控： ImageVolume">
              <span class="feature-state-name">特性状态：</span> 
              <code>Kubernetes v1.36 [stable]</code>（默认启用）</div>


<!--
An `image` volume source represents an OCI object (a container image or
artifact) which is available on the kubelet's host machine.

An example of using the `image` volume source is:
-->
`image` 卷源代表一个在 kubelet 主机上可用的 OCI 对象（容器镜像或工件）。

使用 `image` 卷源的一个例子是：


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/zh-cn/examples/pods/image-volumes.yaml" download="pods/image-volumes.yaml"><code>pods/image-volumes.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('pods-image-volumes-yaml')" title="复制 pods/image-volumes.yaml 到剪贴板"></img></div>
    <div class="includecode" id="pods-image-volumes-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Pod</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">image-volume</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">containers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">shell</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;sleep&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;infinity&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">debian</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumeMounts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">volume</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="l">/volume</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">volume</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">reference</span><span class="p">:</span><span class="w"> </span><span class="l">quay.io/crio/artifact:v2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">pullPolicy</span><span class="p">:</span><span class="w"> </span><span class="l">IfNotPresent</span><span class="w">
</span></span></span></code></pre></div></div>
</div>

<!--
The volume is resolved at pod startup, depending on which `pullPolicy` value is
provided:

`Always`
: The kubelet always attempts to pull the reference. If the pull fails,
  the kubelet sets the Pod to `Failed`.
-->
此卷在 Pod 启动时基于提供的 `pullPolicy` 值进行解析：

`Always`
: kubelet 始终尝试拉取此引用。如果拉取失败，kubelet 会将 Pod 设置为 `Failed`。

<!--
`Never`
: The kubelet never pulls the reference and only uses a local image or artifact.
  The Pod becomes `Failed` if any layers of the image aren't already present locally,
  or if the manifest for that image isn't already cached.

`IfNotPresent`
: The kubelet pulls if the reference isn't already present on disk. The Pod becomes
  `Failed` if the reference isn't present and the pull fails.
-->
`Never`
: kubelet 从不拉取此引用，仅使用本地镜像或工件。
  如果本地没有任何镜像层存在，或者该镜像的清单未被缓存，则 Pod 会变为 `Failed`。

`IfNotPresent`
: 如果引用在磁盘上不存在，kubelet 会进行拉取。
  如果引用不存在且拉取失败，则 Pod 会变为 `Failed`。

<!--
The volume gets re-resolved if the Pod gets deleted and recreated, which means
that new remote content will become available on Pod recreation. A failure to
resolve or pull the image during Pod startup will block containers from starting
and may add significant latency. Failures will be retried using normal volume
backoff and will be reported on the Pod reason and message.
-->
如果 Pod 被删除并重新创建，此卷会被重新解析，这意味着在 Pod 重新创建时将可以访问新的远程内容。
在 Pod 启动期间解析或拉取镜像失败将导致容器无法启动，并可能显著增加延迟。
如果失败，将使用正常的卷回退进行重试，并输出 Pod 失败的原因和相关消息。

<!--
The types of objects that may be mounted by this volume are defined by the
container runtime implementation on a host machine. At a minimum, they must include
all valid types supported by the container image field. The OCI object gets
mounted in a single directory (`spec.containers[*].volumeMounts[*].mountPath`)
and will be mounted read-only.
-->
此卷可以挂载的对象类型由主机上的容器运行时实现负责定义，至少必须包含容器镜像字段所支持的所有有效类型。
OCI 对象将以只读方式被挂载到单个目录（`spec.containers[*].volumeMounts[*].mountPath`）中。

<!--
Besides that:

- [`subPath`](/docs/concepts/storage/volumes/#using-subpath) or
  [`subPathExpr`](/docs/concepts/storage/volumes/#using-subpath-expanded-environment)
  mounts for containers (`spec.containers[*].volumeMounts[*].subPath`, `spec.containers[*].volumeMounts[*].subPathExpr`)
  are only supported from Kubernetes v1.33.
- The field `spec.securityContext.fsGroupChangePolicy` has no effect on this
  volume type.
- The [`AlwaysPullImages` Admission Controller](/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages)
  does also work for this volume source like for container images.
-->
此外：

- 从 Kubernetes v1.33 开始，才支持容器的
  [`subPath`](/zh-cn/docs/concepts/storage/volumes/#using-subpath) 或
  [`subPathExpr`](/zh-cn/docs/concepts/storage/volumes/#using-subpath-expanded-environment)
  挂载（`spec.containers[*].volumeMounts[*].subPath`、`spec.containers[*].volumeMounts[*].subPathExpr`）。
- `spec.securityContext.fsGroupChangePolicy` 字段对这种卷没有效果。
- [`AlwaysPullImages` 准入控制器](/zh-cn/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages)也适用于此卷源，
  就像适用于容器镜像一样。

<!--
The following fields are available for the `image` type:
-->
`image` 类型可用的字段如下：

<!--
`reference`
: Artifact reference to be used. For example, you could specify
  `registry.k8s.io/conformance:v1.36.0` to load the
  files from the Kubernetes conformance test image. Behaves in the same way as
  `pod.spec.containers[*].image`. Pull secrets will be assembled in the same way
  as for the container image by looking up node credentials, service account image
  pull secrets, and Pod spec image pull secrets. This field is optional to allow
  higher level config management to default or override container images in
  workload controllers like Deployments and StatefulSets.
  [More info about container images](/docs/concepts/containers/images).
-->
`reference`
: 要使用的工件引用。例如，你可以指定 `registry.k8s.io/conformance:v1.36.0`
  来加载 Kubernetes 合规性测试镜像中的文件。其行为与 `pod.spec.containers[*].image` 相同。
  拉取 Secret 的组装方式与容器镜像所用的方式相同，即通过查找节点凭据、服务账户镜像拉取 Secret
  和 Pod 规约镜像拉取 Secret。此字段是可选的，允许更高层次的配置管理在 Deployment 和
  StatefulSet 这类工作负载控制器中默认使用或重载容器镜像。
  参阅[容器镜像更多细节](/zh-cn/docs/concepts/containers/images)。

<!--
`pullPolicy`
: Policy for pulling OCI objects. Possible values are: `Always`, `Never`, or
  `IfNotPresent`. Defaults to `Always` if `:latest` tag is specified, or
  `IfNotPresent` otherwise.

See the [_Use an Image Volume With a Pod_](/docs/tasks/configure-pod-container/image-volumes)
example for more details on how to use the volume source.
-->
`pullPolicy`
: 拉取 OCI 对象的策略。可能的值为：`Always`、`Never` 或 `IfNotPresent`。
  如果指定了 `:latest` 标记，则默认为 `Always`，否则默认为 `IfNotPresent`。

有关如何使用卷源的更多细节，请参见
[**Pod 使用镜像卷**](/zh-cn/docs/tasks/configure-pod-container/image-volumes)示例。

<!--
#### Pod status and `image` volumes {#image-volume-pod-status}
-->
#### Pod 状态与 `image` 卷    {#image-volume-pod-status}








  <div class="feature-state-notice feature-alpha" title="特性门控： ImageVolumeWithDigest">
              <span class="feature-state-name">特性状态：</span> 
              <code>Kubernetes v1.35 [alpha]</code>（默认禁用）</div>


<!--
If the `ImageVolumeWithDigest` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
is enabled in your cluster,
then whenever you specify an `image` volume for a Pod,
the kubelet updates the Pod status to record the _digest_
of the container image that's being used as a volume source.

Here's a simplified example of a running Pod, represented as YAML, including the status update.
Note the new `ImageRef` field under `volumeMounts` in the container status.
-->
如果在你的集群中启用了 `ImageVolumeWithDigest`
[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)，
那么每当你为 Pod 指定一个 `image` 卷时，kubelet 都会更新 Pod 状态，
记录作为卷来源使用的容器镜像的**摘要**（digest）。

下面是一个正在运行的 Pod 的简化示例，以 YAML 表示，其中已包含状态更新。
请注意容器状态中 `volumeMounts` 下新增的 `ImageRef` 字段。

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: default
spec:
  containers:
  - name: shell
    command: ["sleep", "infinity"]
    image: docker.io/library/debian:12
    volumeMounts:
    - name: artifact
      mountPath: /data
  volumes:
  - name: artifact
    image:
      reference: quay.io/crio/artifact:v2
      pullPolicy: IfNotPresent
status:
  containerStatuses:
  - containerID: containerd://examplecontainerid1234567890abcdef
    image: docker.io/library/debian:12
    imageID: docker-pullable://docker.io/library/debian@sha256:3f1d6c17773a45c97bd8f158d665c9709d7b29ed7917ac934086ad96f92e4510
    volumeMounts:
    - name: artifact
      mountPath: /data
      readOnly: true
      imageRef: quay.io/crio/artifact@sha256:abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890
```

### iscsi

<!--
An `iscsi` volume allows an existing iSCSI (SCSI over IP) volume to be mounted
into your Pod. Unlike `emptyDir`, which is erased when a Pod is removed, the
contents of an `iscsi` volume are preserved, and the volume is merely
unmounted. This means that an iscsi volume can be pre-populated with data, and
that data can be shared between Pods.
-->
`iscsi` 卷能将 iSCSI（基于 IP 的 SCSI）卷挂载到你的 Pod 中。
不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除，`iscsi`
卷的内容在删除 Pod 时会被保留，卷只是被卸载。
这意味着 `iscsi` 卷可以被预先填充数据，并且这些数据可以在 Pod 之间共享。


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
You must have your own iSCSI server running with the volume created before you can use it.
-->
<p>在使用 iSCSI 卷之前，你必须拥有自己的 iSCSI 服务器，并在上面创建卷。</p></div>


<!--
A feature of iSCSI is that it can be mounted as read-only by multiple consumers
simultaneously. This means that you can pre-populate a volume with your dataset
and then serve it in parallel from as many Pods as you need. Unfortunately,
iSCSI volumes can only be mounted by a single consumer in read-write mode.
Simultaneous writers are not allowed.
-->
iSCSI 的一个特点是它可以同时被多个用户以只读方式挂载。
这意味着你可以用数据集预先填充卷，然后根据需要在尽可能多的 Pod 上使用它。
不幸的是，iSCSI 卷只能由单个使用者以读写模式挂载。不允许同时写入。

### local

<!--
A `local` volume represents a mounted local storage device such as a disk,
partition or directory.

Local volumes can only be used as a statically created PersistentVolume. Dynamic
provisioning is not supported.
-->
`local` 卷所代表的是某个被挂载的本地存储设备，例如磁盘、分区或者目录。

`local` 卷只能用作静态创建的持久卷。不支持动态配置。

<!--
Compared to `hostPath` volumes, `local` volumes are used in a durable and
portable manner without manually scheduling Pods to nodes. The system is aware
of the volume's node constraints by looking at the node affinity on the PersistentVolume.
-->
与 `hostPath` 卷相比，`local` 卷能够以持久和可移植的方式使用，而无需手动将 Pod
调度到节点。系统通过查看 PersistentVolume 的节点亲和性配置，就能了解卷的节点约束。

<!--
However, `local` volumes are subject to the availability of the underlying
node and are not suitable for all applications. If a node becomes unhealthy,
then the `local` volume becomes inaccessible to the pod. The Pod using this volume
is unable to run. Applications using `local` volumes must be able to tolerate this
reduced availability, as well as potential data loss, depending on the
durability characteristics of the underlying disk.

The following example shows a PersistentVolume using a `local` volume and
`nodeAffinity`:
-->
然而，`local` 卷仍然取决于底层节点的可用性，并不适合所有应用程序。
如果节点变得不健康，那么 `local` 卷也将变得不可被 Pod 访问。使用它的 Pod 将不能运行。
使用 `local` 卷的应用程序必须能够容忍这种可用性的降低，以及因底层磁盘的耐用性特征而带来的潜在的数据丢失风险。

下面是一个使用 `local` 卷和 `nodeAffinity` 的持久卷示例：

```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: example-pv
spec:
  capacity:
    storage: 100Gi
  volumeMode: Filesystem
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete
  storageClassName: local-storage
  local:
    path: /mnt/disks/ssd1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - example-node
```

<!--
You must set a PersistentVolume `nodeAffinity` when using `local` volumes.
The Kubernetes scheduler uses the PersistentVolume `nodeAffinity` to schedule
these Pods to the correct node.
-->
使用 `local` 卷时，你需要设置 PersistentVolume 对象的 `nodeAffinity` 字段。
Kubernetes 调度器使用 PersistentVolume 的 `nodeAffinity` 信息来将使用 `local`
卷的 Pod 调度到正确的节点。

<!--
PersistentVolume `volumeMode` can be set to "Block" (instead of the default
value "Filesystem") to expose the local volume as a raw block device.
-->
PersistentVolume 对象的 `volumeMode` 字段可被设置为 `"Block"`
（而不是默认值 `"Filesystem"`），以将 `local` 卷作为原始块设备暴露出来。

<!--
When using local volumes, it is recommended to create a StorageClass with
`volumeBindingMode` set to `WaitForFirstConsumer`. For more details, see the
local [StorageClass](/docs/concepts/storage/storage-classes/#local) example.
Delaying volume binding ensures that the PersistentVolumeClaim binding decision
will also be evaluated with any other node constraints the Pod may have,
such as node resource requirements, node selectors, Pod affinity, and Pod anti-affinity.
-->
使用 `local` 卷时，建议创建一个 StorageClass 并将其 `volumeBindingMode` 设置为
`WaitForFirstConsumer`。要了解更多详细信息，请参考
[local StorageClass 示例](/zh-cn/docs/concepts/storage/storage-classes/#local)。
延迟卷绑定的操作可以确保 Kubernetes 在为 PersistentVolumeClaim 作出绑定决策时，会评估
Pod 可能具有的其他节点约束，例如：如节点资源需求、节点选择器、Pod 亲和性和 Pod 反亲和性。

<!--
An external static provisioner can be run separately for improved management of
the local volume lifecycle. Note that this provisioner does not support dynamic
provisioning yet. For an example on how to run an external local provisioner, see the
[local volume provisioner user guide](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner).
-->
你可以在 Kubernetes 之外单独运行静态驱动以改进对 `local` 卷的生命周期管理。
请注意，此驱动尚不支持动态配置。
有关如何运行外部 `local` 卷驱动，请参考
[`local` 卷驱动用户指南](https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner)。


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
The local PersistentVolume requires manual cleanup and deletion by the
user if the external static provisioner is not used to manage the volume
lifecycle.
-->
<p>如果不使用外部静态驱动来管理卷的生命周期，用户需要手动清理和删除 <code>local</code> 类型的持久卷。</p></div>


### nfs

<!--
An `nfs` volume allows an existing NFS (Network File System) share to be
mounted into a Pod. Unlike `emptyDir`, which is erased when a Pod is
removed, the contents of an `nfs` volume are preserved, and the volume is merely
unmounted. This means that an NFS volume can be pre-populated with data, and
that data can be shared between Pods. NFS can be mounted by multiple
writers simultaneously.
-->
`nfs` 卷能将 NFS（网络文件系统）挂载到你的 Pod 中。
不像 `emptyDir` 那样会在删除 Pod 的同时也会被删除，`nfs` 卷的内容在删除 Pod
时会被保存，卷只是被卸载。
这意味着 `nfs` 卷可以被预先填充数据，并且这些数据可以在 Pod 之间共享。

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /my-nfs-data
      name: test-volume
  volumes:
  - name: test-volume
    nfs:
      server: my-nfs-server.example.com
      path: /my-nfs-volume
      readOnly: true
```


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
You must have your own NFS server running with the share exported before you can use it.

Also note that you can't specify NFS mount options in a Pod spec. You can either set mount options server-side or
use [/etc/nfsmount.conf](https://man7.org/linux/man-pages/man5/nfsmount.conf.5.html).
You can also mount NFS volumes via PersistentVolumes, which do allow you to set mount options.
-->
<p>在使用 NFS 卷之前，你必须运行自己的 NFS 服务器并将目标 share 导出备用。</p>
<p>还需要注意，不能在 Pod 规约中指定 NFS 挂载可选项。
可以选择设置服务端的挂载可选项，或者使用
<a href="https://man7.org/linux/man-pages/man5/nfsmount.conf.5.html"><code>/etc/nfsmount.conf</code></a>。
此外，还可以通过允许设置挂载可选项的持久卷挂载 NFS 卷。</p>
</div>


### persistentVolumeClaim {#persistentvolumeclaim}

<!--
A `persistentVolumeClaim` volume is used to mount a
[PersistentVolume](/docs/concepts/storage/persistent-volumes/) into a Pod. PersistentVolumeClaims
are a way for users to "claim" durable storage (such as an iSCSI volume)
without knowing the details of the particular cloud environment.
-->
`persistentVolumeClaim` 卷用来将[持久卷](/zh-cn/docs/concepts/storage/persistent-volumes/)（PersistentVolume）挂载到 Pod 中。
持久卷申领（PersistentVolumeClaim）是用户在不知道特定云环境细节的情况下“申领”持久存储（例如 iSCSI 卷）的一种方法。

<!--
See the information about [PersistentVolumes](/docs/concepts/storage/persistent-volumes/) for more
details.
-->
更多详情请参考[持久卷](/zh-cn/docs/concepts/storage/persistent-volumes/)。

<!--
### portworxVolume (deprecated) {#portworxvolume}
-->
### portworxVolume（已弃用） {#portworxvolume}








  <div class="feature-state-notice feature-deprecated">
      <span class="feature-state-name">特性状态：</span>
      <code>Kubernetes v1.25 [deprecated]</code>
    </div>
  



<!--
A `portworxVolume` is an elastic block storage layer that runs hyperconverged with
Kubernetes. [Portworx](https://portworx.com/use-case/kubernetes-storage/) fingerprints storage
in a server, tiers based on capabilities, and aggregates capacity across multiple servers.
Portworx runs in-guest in virtual machines or on bare metal Linux nodes.
-->
`portworxVolume` 是一个可伸缩的块存储层，能够以超融合（hyperconverged）的方式与 Kubernetes 一起运行。
[Portworx](https://portworx.com/use-case/kubernetes-storage/)
支持对服务器上存储的指纹处理、基于存储能力进行分层以及跨多个服务器整合存储容量。
Portworx 可以以 in-guest 方式在虚拟机中运行，也可以在裸金属 Linux 节点上运行。

<!--
A `portworxVolume` can be dynamically created through Kubernetes, or it can also
be pre-provisioned and referenced inside a Pod.
Here is an example Pod referencing a pre-provisioned Portworx volume:
-->
`portworxVolume` 类型的卷可以通过 Kubernetes 动态创建，也可以预先配备并在 Pod 内引用。
下面是一个引用预先配备的 Portworx 卷的示例 Pod：

<!--
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-portworx-volume-pod
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /mnt
      name: pxvol
  volumes:
  - name: pxvol
    # This Portworx volume must already exist.
    portworxVolume:
      volumeID: "pxvol"
      fsType: "<fs-type>"
```
-->
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-portworx-volume-pod
spec:
  containers:
  - image: registry.k8s.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /mnt
      name: pxvol
  volumes:
  - name: pxvol
    # 此 Portworx 卷必须已经存在
    portworxVolume:
      volumeID: "pxvol"
      fsType: "<fs-type>"
```


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
Make sure you have an existing PortworxVolume with the name `pxvol`
before using it in the Pod.
-->
<p>在 Pod 中使用 portworxVolume 之前，你要确保有一个名为 <code>pxvol</code> 的 PortworxVolume 存在。</p></div>


<!--
#### Portworx CSI migration
-->
#### Portworx CSI 迁移








  <div class="feature-state-notice feature-stable" title="特性门控： CSIMigrationPortworx">
              <span class="feature-state-name">特性状态：</span> 
              <code>Kubernetes v1.33 [stable]</code>（默认启用）</div>


<!--
In Kubernetes 1.36, all operations for the in-tree
Portworx volumes are redirected to the `pxd.portworx.com` 
Container Storage Interface (CSI) Driver by default. 
[Portworx CSI Driver](https://docs.portworx.com/portworx-enterprise/operations/operate-kubernetes/storage-operations/csi)
must be installed on the cluster.
-->
在 Kubernetes 1.36 中，默认情况下，
所有针对树内 Portworx 卷的操作都会被重定向到 
`pxd.portworx.com` 容器存储接口（CSI）驱动。
[Portworx CSI 驱动程序](https://docs.portworx.com/portworx-enterprise/operations/operate-kubernetes/storage-operations/csi)必须安装在集群上。

<!--
### projected

A projected volume maps several existing volume sources into the same
directory. For more details, see [projected volumes](/docs/concepts/storage/projected-volumes/).
-->
### 投射（projected）   {#projected}

投射卷能将若干现有的卷来源映射到同一目录上。
更多详情请参考[投射卷](/zh-cn/docs/concepts/storage/projected-volumes/)。

### secret

<!--
A `secret` volume is used to pass sensitive information, such as passwords, to
Pods. You can store secrets in the Kubernetes API and mount them as files for
use by Pods without coupling to Kubernetes directly. `secret` volumes are
backed by tmpfs (a RAM-backed filesystem), so they are never written to
non-volatile storage.
-->
`secret` 卷用来给 Pod 传递敏感信息，例如密码。你可以将 Secret 存储在 Kubernetes
API 服务器上，然后以文件的形式挂载到 Pod 中，无需直接与 Kubernetes 耦合。
`secret` 卷由 tmpfs（基于 RAM 的文件系统）提供存储，因此它们永远不会被写入非易失性（持久化的）存储器。


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
* You must create a Secret in the Kubernetes API before you can use it.

* A Secret is always mounted as `readOnly`.

* A container using a Secret as a [`subPath`](#using-subpath) volume mount will not
  receive Secret updates.
-->
<ul>
<li>使用前你必须在 Kubernetes API 中创建 Secret。</li>
<li>Secret 总是以 <code>readOnly</code> 的模式挂载。</li>
<li>容器以 <a href="#using-subpath"><code>subPath</code></a> 卷挂载方式使用 Secret 时，将无法接收 Secret 的更新。</li>
</ul>
</div>


<!--
For more details, see [Configuring Secrets](/docs/concepts/configuration/secret/).
-->
更多详情请参考[配置 Secret](/zh-cn/docs/concepts/configuration/secret/)。

<!--
## Using subPath {#using-subpath}

Sometimes, it is useful to share one volume for multiple uses in a single Pod.
The `volumeMounts[*].subPath` property specifies a sub-path inside the referenced volume
instead of its root.
-->
## 使用 subPath  {#using-subpath}

有时，在单个 Pod 中共享卷以供多方使用是很有用的。
`volumeMounts[*].subPath` 属性可用于指定所引用的卷内的子路径，而不是其根路径。

<!--
The following example shows how to configure a Pod with a LAMP stack (Linux, Apache, MySQL, PHP)
using a single, shared volume. This sample `subPath` configuration is not recommended
for production use.

The PHP application's code and assets map to the volume's `html` folder and
the MySQL database is stored in the volume's `mysql` folder. For example:
-->
下面例子展示了如何配置某包含 LAMP 堆栈（Linux、Apache、MySQL、PHP）的 Pod 使用同一共享卷。
此示例中的 `subPath` 配置不建议在生产环境中使用。
PHP 应用的代码和相关数据映射到卷的 `html` 文件夹，MySQL 数据库存储在卷的 `mysql` 文件夹中：

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-lamp-site
spec:
    containers:
    - name: mysql
      image: mysql
      env:
      - name: MYSQL_ROOT_PASSWORD
        value: "rootpasswd"
      volumeMounts:
      - mountPath: /var/lib/mysql
        name: site-data
        subPath: mysql
    - name: php
      image: php:7.0-apache
      volumeMounts:
      - mountPath: /var/www/html
        name: site-data
        subPath: html
    volumes:
    - name: site-data
      persistentVolumeClaim:
        claimName: my-lamp-site-data
```

<!--
### Using subPath with expanded environment variables {#using-subpath-expanded-environment}
-->
### 使用带有扩展环境变量的 subPath  {#using-subpath-expanded-environment}








  <div class="feature-state-notice feature-stable">
      <span class="feature-state-name">特性状态：</span>
      <code>Kubernetes v1.17 [stable]</code>
    </div>
  



<!--
Use the `subPathExpr` field to construct `subPath` directory names from
downward API environment variables.
The `subPath` and `subPathExpr` properties are mutually exclusive.
-->
使用 `subPathExpr` 字段可以基于 downward API 环境变量来构造 `subPath` 目录名。
`subPath` 和 `subPathExpr` 属性是互斥的。

<!--
In this example, a `Pod` uses `subPathExpr` to create a directory `pod1` within
the `hostPath` volume `/var/log/pods`.
The `hostPath` volume takes the `Pod` name from the `downwardAPI`.
The host directory `/var/log/pods/pod1` is mounted at `/logs` in the container.
-->
在这个示例中，`Pod` 使用 `subPathExpr` 来 `hostPath` 卷 `/var/log/pods` 中创建目录 `pod1`。
`hostPath` 卷采用来自 `downwardAPI` 的 Pod 名称生成目录名。
宿主机目录 `/var/log/pods/pod1` 被挂载到容器的 `/logs` 中。

<!--
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: container1
    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
    image: busybox:1.28
    command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
    volumeMounts:
    - name: workdir1
      mountPath: /logs
      # The variable expansion uses round brackets (not curly brackets).
      subPathExpr: $(POD_NAME)
  restartPolicy: Never
  volumes:
  - name: workdir1
    hostPath:
      path: /var/log/pods
```
-->
```yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: container1
    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
    image: busybox:1.28
    command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
    volumeMounts:
    - name: workdir1
      mountPath: /logs
      # 包裹变量名的是小括号，而不是大括号
      subPathExpr: $(POD_NAME)
  restartPolicy: Never
  volumes:
  - name: workdir1
    hostPath:
      path: /var/log/pods
```

<!--
## Resources

The storage medium (such as Disk or SSD) of an `emptyDir` volume is determined by the
medium of the filesystem holding the kubelet root dir (typically
`/var/lib/kubelet`). There is no limit on how much space an `emptyDir` or
`hostPath` volume can consume, and no isolation between containers or
Pods.
-->
## 资源   {#resources}

`emptyDir` 卷的存储介质（例如磁盘、SSD 等）是由保存 kubelet
数据的根目录（通常是 `/var/lib/kubelet`）的文件系统的介质确定。
Kubernetes 对 `emptyDir` 卷或者 `hostPath` 卷可以消耗的空间没有限制，容器之间或
Pod 之间也没有隔离。

<!--
To learn about requesting space using a resource specification, see
[how to manage resources](/docs/concepts/configuration/manage-resources-containers/).
-->
要了解如何使用资源规约来请求空间，
可参考[如何管理资源](/zh-cn/docs/concepts/configuration/manage-resources-containers/)。

<!--
## Out-of-tree volume plugins

The out-of-tree volume plugins include
<a class='glossary-tooltip' title='容器存储接口 （CSI）定义了存储系统暴露给容器的标准接口。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/storage/volumes/#csi' target='_blank' aria-label='Container Storage Interface'>Container Storage Interface</a> (CSI), and also
FlexVolume (which is deprecated). These plugins enable storage vendors to create custom storage plugins
without adding their plugin source code to the Kubernetes repository.
-->
## 树外（Out-of-Tree）卷插件    {#out-of-tree-volume-plugins}

Out-of-Tree 卷插件包括<a class='glossary-tooltip' title='容器存储接口 （CSI）定义了存储系统暴露给容器的标准接口。' data-bs-toggle='tooltip' data-bs-placement='top' href='/zh-cn/docs/concepts/storage/volumes/#csi' target='_blank' aria-label='容器存储接口（CSI）'>容器存储接口（CSI）</a>和
FlexVolume（已弃用）。它们使存储供应商能够创建自定义存储插件，而无需将插件源码添加到
Kubernetes 代码仓库。

<!--
Previously, all volume plugins were "in-tree". The "in-tree" plugins were built, linked, compiled,
and shipped with the core Kubernetes binaries. This meant that adding a new storage system to
Kubernetes (a volume plugin) required checking code into the core Kubernetes code repository.
-->
以前，所有卷插件（如上面列出的卷类型）都是“树内（In-Tree）”的。
“树内”插件是与 Kubernetes 的核心组件一同构建、链接、编译和交付的。
这意味着向 Kubernetes 添加新的存储系统（卷插件）需要将代码合并到 Kubernetes 核心代码库中。

<!--
Both CSI and FlexVolume allow volume plugins to be developed independently of
the Kubernetes code base, and deployed (installed) on Kubernetes clusters as
extensions.

For storage vendors looking to create an out-of-tree volume plugin, please refer
to the [volume plugin FAQ](https://github.com/kubernetes/community/blob/main/sig-storage/volume-plugin-faq.md).
-->
CSI 和 FlexVolume 都允许独立于 Kubernetes 代码库开发卷插件，并作为扩展部署（安装）在
Kubernetes 集群上。

对于希望创建树外（Out-Of-Tree）卷插件的存储供应商，
请参考[卷插件常见问题](https://github.com/kubernetes/community/blob/main/sig-storage/volume-plugin-faq.md)。

### CSI

<!--
[Container Storage Interface](https://github.com/container-storage-interface/spec/blob/master/spec.md)
(CSI) defines a standard interface for container orchestration systems (like
Kubernetes) to expose arbitrary storage systems to their container workloads.
-->
[容器存储接口](https://github.com/container-storage-interface/spec/blob/master/spec.md)（CSI）
为容器编排系统（如 Kubernetes）定义标准接口，以将任意存储系统暴露给它们的容器工作负载。

<!--
Please read the [CSI design proposal](https://git.k8s.io/design-proposals-archive/storage/container-storage-interface.md)
for more information.
-->
更多详情请阅读
[CSI 设计方案](https://git.k8s.io/design-proposals-archive/storage/container-storage-interface.md)。


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
Support for CSI spec versions 0.2 and 0.3 is deprecated in Kubernetes
v1.13 and will be removed in a future release.
-->
<p>Kubernetes v1.13 废弃了对 CSI 规范版本 0.2 和 0.3 的支持，并将在以后的版本中删除。</p></div>



<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
CSI drivers may not be compatible across all Kubernetes releases.
Please check the specific CSI driver's documentation for supported
deployment steps for each Kubernetes release and a compatibility matrix.
-->
<p>CSI 驱动可能并非兼容所有的 Kubernetes 版本。
请查看特定 CSI 驱动的文档，以了解各个 Kubernetes 版本所支持的部署步骤以及兼容性列表。</p></div>


<!--
Once a CSI-compatible volume driver is deployed on a Kubernetes cluster, users
may use the `csi` volume type to attach or mount the volumes exposed by the
CSI driver.

A `csi` volume can be used in a Pod in three different ways:
-->
一旦在 Kubernetes 集群上部署了 CSI 兼容卷驱动程序，用户就可以使用
`csi` 卷类型来挂接、挂载 CSI 驱动所提供的卷。
  
`csi` 卷可以在 Pod 中以三种方式使用：

<!--
* through a reference to a [PersistentVolumeClaim](#persistentvolumeclaim)
* with a [generic ephemeral volume](/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes)
* with a [CSI ephemeral volume](/docs/concepts/storage/ephemeral-volumes/#csi-ephemeral-volumes)
  if the driver supports that
-->
* 通过 [PersistentVolumeClaim](#persistentvolumeclaim) 对象引用
* 使用[一般性的临时卷](/zh-cn/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes)
* 使用 [CSI 临时卷](/zh-cn/docs/concepts/storage/ephemeral-volumes/#csi-ephemeral-volumes)，
  前提是驱动支持这种用法

<!--
The following fields are available to storage administrators to configure a CSI
persistent volume:
-->
存储管理员可以使用以下字段来配置 CSI 持久卷：

<!--
* `driver`: A string value that specifies the name of the volume driver to use.
  This value must correspond to the value returned in the `GetPluginInfoResponse`
  by the CSI driver as defined in the
  [CSI spec](https://github.com/container-storage-interface/spec/blob/master/spec.md#getplugininfo).
  It is used by Kubernetes to identify which CSI driver to call out to, and by
  CSI driver components to identify which PV objects belong to the CSI driver.
-->
* `driver`：指定要使用的卷驱动名称的字符串值。
  这个值必须与 CSI 驱动程序在 `GetPluginInfoResponse` 中返回的值相对应；该接口定义在
  [CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#getplugininfo)中。
  Kubernetes 使用所给的值来标识要调用的 CSI 驱动程序；CSI
  驱动程序也使用该值来辨识哪些 PV 对象属于该 CSI 驱动程序。

<!--
* `volumeHandle`: A string value that uniquely identifies the volume. This value
  must correspond to the value returned in the `volume.id` field of the
  `CreateVolumeResponse` by the CSI driver as defined in the
  [CSI spec](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume).
  The value is passed as `volume_id` in all calls to the CSI volume driver when
  referencing the volume.
-->
* `volumeHandle`：唯一标识卷的字符串值。
  该值必须与 CSI 驱动在 `CreateVolumeResponse` 的 `volume_id` 字段中返回的值相对应；接口定义在
  [CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume)中。
  在所有对 CSI 卷驱动程序的调用中，引用该 CSI 卷时都使用此值作为 `volume_id` 参数。

<!--
* `readOnly`: An optional boolean value indicating whether the volume is to be
  "ControllerPublished" (attached) as read-only. Default is false. This value is passed
  to the CSI driver via the `readonly` field in the `ControllerPublishVolumeRequest`.
-->
* `readOnly`：一个可选的布尔值，指示通过 `ControllerPublished`
  关联该卷时是否设置该卷为只读。默认值是 `false`。
  该值通过 `ControllerPublishVolumeRequest` 中的 `readonly` 字段传递给 CSI 驱动。

<!--
* `fsType`: If the PV's `VolumeMode` is `Filesystem`, then this field may be used
  to specify the filesystem that should be used to mount the volume. If the
  volume has not been formatted and formatting is supported, this value will be
  used to format the volume.
  This value is passed to the CSI driver via the `VolumeCapability` field of
  `ControllerPublishVolumeRequest`, `NodeStageVolumeRequest`, and
  `NodePublishVolumeRequest`.
-->
* `fsType`：如果 PV 的 `VolumeMode` 为 `Filesystem`，那么此字段指定挂载卷时应该使用的文件系统。
  如果卷尚未格式化，并且支持格式化，此值将用于格式化卷。
  此值可以通过 `ControllerPublishVolumeRequest`、`NodeStageVolumeRequest` 和
  `NodePublishVolumeRequest` 的 `VolumeCapability` 字段传递给 CSI 驱动。

<!--
* `volumeAttributes`: A map of string to string that specifies static properties
  of a volume. This map must correspond to the map returned in the
  `volume.attributes` field of the `CreateVolumeResponse` by the CSI driver as
  defined in the [CSI spec](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume).
  The map is passed to the CSI driver via the `volume_context` field in the
  `ControllerPublishVolumeRequest`, `NodeStageVolumeRequest`, and
  `NodePublishVolumeRequest`.
-->
* `volumeAttributes`：一个字符串到字符串的映射表，用来设置卷的静态属性。
  该映射必须与 CSI 驱动程序返回的 `CreateVolumeResponse` 中的 `volume.attributes`
  字段的映射相对应；
  [CSI 规范](https://github.com/container-storage-interface/spec/blob/master/spec.md#createvolume)中有相应的定义。
  该映射通过 `ControllerPublishVolumeRequest`、`NodeStageVolumeRequest` 和
  `NodePublishVolumeRequest` 中的 `volume_context` 字段传递给 CSI 驱动。

<!--
* `controllerPublishSecretRef`: A reference to the secret object containing
  sensitive information to pass to the CSI driver to complete the CSI
  `ControllerPublishVolume` and `ControllerUnpublishVolume` calls. This field is
  optional, and may be empty if no secret is required. If the Secret
  contains more than one secret, all secrets are passed.
-->
* `controllerPublishSecretRef`：对包含敏感信息的 Secret 对象的引用；
  该敏感信息会被传递给 CSI 驱动来完成 CSI `ControllerPublishVolume` 和
  `ControllerUnpublishVolume` 调用。
  此字段是可选的；在不需要 Secret 时可以是空的。
  如果 Secret 包含多个 Secret 条目，则所有的 Secret 条目都会被传递。

<!--
* `nodeExpandSecretRef`: A reference to the secret containing sensitive
  information to pass to the CSI driver to complete the CSI
  `NodeExpandVolume` call. This field is optional and may be empty if no
  secret is required. If the object contains more than one secret, all
  secrets are passed. When you have configured secret data for node-initiated
  volume expansion, the kubelet passes that data via the `NodeExpandVolume()`
  call to the CSI driver. All supported versions of Kubernetes offer the
  `nodeExpandSecretRef` field, and have it available by default. Kubernetes releases
  prior to v1.25 did not include this support.
* Enable the [feature gate](/docs/reference/command-line-tools-reference/feature-gates-removed/)
  named `CSINodeExpandSecret` for each kube-apiserver and for the kubelet on every
  node. Since Kubernetes version 1.27, this feature has been enabled by default
  and no explicit enablement of the feature gate is required.
  You must also be using a CSI driver that supports or requires secret data during
  node-initiated storage resize operations.
-->
* `nodeExpandSecretRef`：对包含敏感信息的 Secret 对象的引用，
  该信息会传递给 CSI 驱动以完成 CSI `NodeExpandVolume` 调用。
  此字段是可选的，如果不需要 Secret，则可能是空的。
  如果 Secret 包含多个 Secret 条目，则传递所有 Secret 条目。
  当你为节点初始化的卷扩展配置 Secret 数据时，kubelet 会通过 `NodeExpandVolume()`
  调用将该数据传递给 CSI 驱动。所有受支持的 Kubernetes 版本都提供 `nodeExpandSecretRef` 字段，
  并且默认可用。Kubernetes v1.25 之前的版本不包括此支持。

  为每个 kube-apiserver 和每个节点上的 kubelet 启用名为 `CSINodeExpandSecret`
  的[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates-removed/)。
  自 Kubernetes 1.27 版本起，此特性已默认启用，无需显式启用特性门控。
  在节点初始化的存储大小调整操作期间，你还必须使用支持或需要 Secret 数据的 CSI 驱动。

<!--
* `nodePublishSecretRef`: A reference to the secret object containing
  sensitive information to pass to the CSI driver to complete the CSI
  `NodePublishVolume` call. This field is optional and may be empty if no
  secret is required. If the secret object contains more than one secret, all
  secrets are passed.
-->
* `nodePublishSecretRef`：对包含敏感信息的 Secret 对象的引用。
  该信息传递给 CSI 驱动来完成 CSI `NodePublishVolume` 调用。
  此字段是可选的，如果不需要 Secret，则可能是空的。
  如果 Secret 对象包含多个 Secret 条目，则传递所有 Secret 条目。

<!--
* `nodeStageSecretRef`: A reference to the secret object containing
  sensitive information to pass to the CSI driver to complete the CSI
  `NodeStageVolume` call. This field is optional and may be empty if no secret
  is required. If the Secret contains more than one secret, all secrets
  are passed.
-->
* `nodeStageSecretRef`：对包含敏感信息的 Secret 对象的引用，
  该信息会传递给 CSI 驱动以完成 CSI `NodeStageVolume` 调用。
  此字段是可选的，如果不需要 Secret，则可能是空的。
  如果 Secret 包含多个 Secret 条目，则传递所有 Secret 条目。

<!--
#### CSI raw block volume support
-->
#### CSI 原始块卷支持    {#csi-raw-block-volume-support}








  <div class="feature-state-notice feature-stable">
      <span class="feature-state-name">特性状态：</span>
      <code>Kubernetes v1.18 [stable]</code>
    </div>
  



<!--
Vendors with external CSI drivers can implement raw block volume support
in Kubernetes workloads.
-->
具有外部 CSI 驱动程序的供应商能够在 Kubernetes 工作负载中实现原始块卷支持。

<!--
You can set up your
[PersistentVolume/PersistentVolumeClaim with raw block volume support](/docs/concepts/storage/persistent-volumes/#raw-block-volume-support)
as usual, without any CSI-specific changes.
-->
你可以和以前一样，
安装自己的[带有原始块卷支持的 PV/PVC](/zh-cn/docs/concepts/storage/persistent-volumes/#raw-block-volume-support)，
采用 CSI 对此过程没有影响。

<!--
#### CSI ephemeral volumes
-->
#### CSI 临时卷   {#csi-ephemeral-volumes}








  <div class="feature-state-notice feature-stable">
      <span class="feature-state-name">特性状态：</span>
      <code>Kubernetes v1.25 [stable]</code>
    </div>
  



<!--
You can directly configure CSI volumes within the Pod
specification. Volumes specified in this way are ephemeral and do not
persist across Pod restarts. See
[Ephemeral Volumes](/docs/concepts/storage/ephemeral-volumes/#csi-ephemeral-volumes)
for more information.
-->
你可以直接在 Pod 规约中配置 CSI 卷。采用这种方式配置的卷都是临时卷，
无法在 Pod 重新启动后继续存在。
进一步的信息可参阅[临时卷](/zh-cn/docs/concepts/storage/ephemeral-volumes/#csi-ephemeral-volumes)。

<!--
For more information on how to develop a CSI driver, refer to the
[kubernetes-csi documentation](https://kubernetes-csi.github.io/docs/)
-->
有关如何开发 CSI 驱动的更多信息，请参考 [kubernetes-csi 文档](https://kubernetes-csi.github.io/docs/)。

<!--
#### Windows CSI proxy
-->
#### Windows CSI 代理  {#windows-csi-proxy}








  <div class="feature-state-notice feature-stable">
      <span class="feature-state-name">特性状态：</span>
      <code>Kubernetes v1.22 [stable]</code>
    </div>
  



<!--
CSI node plugins need to perform various privileged
operations like scanning of disk devices and mounting of file systems. 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 are supported using
[csi-proxy](https://github.com/kubernetes-csi/csi-proxy), a community-managed,
stand-alone binary that needs to be pre-installed on each Windows node.

For more details, refer to the deployment guide of the CSI plugin you wish to deploy.
-->
CSI 节点插件需要执行多种特权操作，例如扫描磁盘设备和挂载文件系统等。
这些操作在每个宿主机操作系统上都是不同的。对于 Linux 工作节点而言，容器化的 CSI
节点插件通常部署为特权容器。对于 Windows 工作节点而言，容器化 CSI
节点插件的特权操作是通过 [csi-proxy](https://github.com/kubernetes-csi/csi-proxy)
来支持的。csi-proxy 是一个由社区管理的、独立的可执行二进制文件，
需要被预安装到每个 Windows 节点上。

要了解更多的细节，可以参考你要部署的 CSI 插件的部署指南。

<!--
#### Migrating to CSI drivers from in-tree plugins
-->
#### 从树内插件迁移到 CSI 驱动程序  {#migrating-to-csi-drivers-from-in-tree-plugins}








  <div class="feature-state-notice feature-stable">
      <span class="feature-state-name">特性状态：</span>
      <code>Kubernetes v1.25 [stable]</code>
    </div>
  



<!--
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.
-->
`CSIMigration` 特性针对现有树内插件的操作会被定向到相应的 CSI 插件（应已安装和配置）。
因此，操作员在过渡到取代树内插件的 CSI 驱动时，无需对现有存储类、PV 或 PVC（指树内插件）进行任何配置更改。


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
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.
-->
<p>即使你针对这种卷完成了 CSI 迁移且你升级到不再内置对这种存储类别的支持的 Kubernetes 版本，
现有的由树内卷插件所创建的 PV 在未来无需进行任何配置更改就可以使用，</p>
<p>作为迁移的一部分，你或其他集群管理员<strong>必须</strong>安装和配置适用于该存储的 CSI 驱动。
Kubernetes 不会为你安装该软件。</p>
<hr>
<!--
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.
-->
<p>在完成迁移之后，你也可以定义新的 PVC 和 PV，引用原来的、内置的集成存储。
只要你安装并配置了适当的 CSI 驱动，即使是全新的卷，PV 的创建仍然可以继续工作。
实际的存储管理现在通过 CSI 驱动来进行。</p>
</div>


<!--
The operations and features that are supported include:
provisioning/delete, attach/detach, mount/unmount, and resizing of volumes.
-->
所支持的操作和特性包括：配备（Provisioning）/删除、挂接（Attach）/解挂（Detach）、
挂载（Mount）/卸载（Unmount）和调整卷大小。

<!--
In-tree plugins that support `CSIMigration` and have a corresponding CSI driver implemented
are listed in [Types of Volumes](#volume-types).
-->
上面的[卷类型](#volume-types)节列出了支持 `CSIMigration` 并已实现相应 CSI
驱动程序的树内插件。

<!--
### flexVolume (deprecated)   {#flexvolume}
-->
### flexVolume（已弃用）   {#flexvolume}








  <div class="feature-state-notice feature-deprecated">
      <span class="feature-state-name">特性状态：</span>
      <code>Kubernetes v1.23 [deprecated]</code>
    </div>
  



<!--
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.
-->
FlexVolume 是一个使用基于 exec 的模型来与驱动程序对接的树外插件接口。
用户必须在每个节点上的预定义卷插件路径中安装 FlexVolume
驱动程序可执行文件，在某些情况下，控制平面节点中也要安装。

Pod 通过 `flexvolume` 树内插件与 FlexVolume 驱动程序交互。

<!--
The following FlexVolume [plugins](https://github.com/Microsoft/K8s-Storage-Plugins/tree/master/flexvolume/windows),
deployed as PowerShell scripts on the host, support Windows nodes:
-->
下面的 FlexVolume
[插件](https://github.com/Microsoft/K8s-Storage-Plugins/tree/master/flexvolume/windows)以
PowerShell 脚本的形式部署在宿主机系统上，支持 Windows 节点：

* [SMB](https://github.com/microsoft/K8s-Storage-Plugins/tree/master/flexvolume/windows/plugins/microsoft.com~smb.cmd)
* [iSCSI](https://github.com/microsoft/K8s-Storage-Plugins/tree/master/flexvolume/windows/plugins/microsoft.com~iscsi.cmd)


<div class="alert alert-info" role="note"><h4 class="alert-heading">说明：</h4><!--
FlexVolume is deprecated. Using an out-of-tree CSI driver is the recommended way to integrate external storage with Kubernetes.

Maintainers of the 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.
-->
<p>FlexVolume 已被弃用。推荐使用树外 CSI 驱动来将外部存储整合进 Kubernetes。</p>
<p>FlexVolume 驱动的维护者应开发一个 CSI 驱动并帮助用户从 FlexVolume 驱动迁移到 CSI。
FlexVolume 用户应迁移工作负载以使用对等的 CSI 驱动。</p>
</div>


<!--
## Mount propagation
-->
## 挂载卷的传播   {#mount-propagation}

<div class="alert alert-caution" role="note"><h4 class="alert-heading">注意：</h4><!--
Mount propagation is a low-level feature that does not work consistently on all
volume types. The Kubernetes project recommends only using mount propagation with `hostPath`
or memory-backed `emptyDir` volumes. See
[Kubernetes issue #95049](https://github.com/kubernetes/kubernetes/issues/95049)
for more context.
-->
<p>挂载卷的传播是一项底层功能，不能在所有类型的卷中以一致的方式工作。
建议只在 <code>hostPath</code> 或基于内存的 <code>emptyDir</code> 卷中使用。
详情请参考<a href="https://github.com/kubernetes/kubernetes/issues/95049">讨论</a>。</p></div>


<!--
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:
-->
挂载卷的传播能力允许将容器安装的卷共享到同一 Pod 中的其他容器，甚至共享到同一节点上的其他 Pod。

卷的挂载传播特性由 `containers[*].volumeMounts` 中的 `mountPropagation` 字段控制，
它的值包括：

<!--
* `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 a 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)`](https://man7.org/linux/man-pages/man8/mount.8.html)

  However, the CRI runtime may choose `rslave` mount propagation (i.e.,
  `HostToContainer`) 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`).
-->
* `None` - 此卷挂载将不会感知到主机后续在此卷或其任何子目录上执行的挂载变化。
  类似的，容器所创建的卷挂载在主机上是不可见的。这是默认模式。

  该模式等同于 [`mount(8)`](https://man7.org/linux/man-pages/man8/mount.8.html) 中描述的
  `rprivate` 挂载传播选项。

  然而，当 `rprivate` 传播选项不适用时，CRI 运行时可以转为选择 `rslave` 挂载传播选项
  （即 `HostToContainer`）。当挂载源包含 Docker 守护进程的根目录（`/var/lib/docker`）时，
  cri-dockerd（Docker）已知可以选择 `rslave` 挂载传播选项。

<!--
* `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)`](https://man7.org/linux/man-pages/man8/mount.8.html)
-->
* `HostToContainer` - 此卷挂载将会感知到主机后续针对此卷或其任何子目录的挂载操作。

  换句话说，如果主机在此挂载卷中挂载任何内容，容器将能看到它被挂载在那里。

  类似的，配置了 `Bidirectional` 挂载传播选项的 Pod 如果在同一卷上挂载了内容，挂载传播设置为
  `HostToContainer` 的容器都将能看到这一变化。

  该模式等同于 [`mount(8)`](https://man7.org/linux/man-pages/man8/mount.8.html)
  中描述的 `rslave` 挂载传播选项。

<!--
* `Bidirectional` - This volume mount behaves the same as 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)`](https://man7.org/linux/man-pages/man8/mount.8.html)
-->
* `Bidirectional` - 这种卷挂载和 `HostToContainer` 挂载表现相同。
  另外，容器创建的卷挂载将被传播回至主机和使用同一卷的所有 Pod 的所有容器。

  该模式的典型用例是带有 FlexVolume 或 CSI 驱动的 Pod，或者需要通过
  `hostPath` 卷在主机上挂载某些东西的 Pod。

  该模式等同于 [`mount(8)`](https://man7.org/linux/man-pages/man8/mount.8.html) 中描述的
  `rshared` 挂载传播选项。

  <div class="alert alert-danger" role="note"><h4 class="alert-heading">警告：</h4><!--
  `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.
  -->
<p><code>Bidirectional</code> 形式的挂载传播可能比较危险。
它可以破坏主机操作系统，因此它只被允许在特权容器中使用。
强烈建议你熟悉 Linux 内核行为。
此外，由 Pod 中的容器创建的任何卷挂载必须在终止时由容器销毁（卸载）。</p></div>


<!--
## 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.
-->
## 只读挂载   {#read-only-mounts}

通过将 `.spec.containers[*].volumeMounts[*].readOnly` 字段设置为 `true` 可以使挂载只读。
这不会使卷本身只读，但该容器将无法写入此卷。
Pod 中的其他容器可以以读写方式挂载同一个卷。

<!--
On Linux, read-only mounts are not recursively read-only by default.
For example, consider a Pod that 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.
-->
在 Linux 上，只读挂载默认不会以递归方式只读。
假如有一个 Pod 将主机的 `/mnt` 挂载为 `hostPath` 卷。
如果在 `/mnt/<SUBMOUNT>` 上有另一个以读写方式挂载的文件系统（如 tmpfs、NFS 或 USB 存储），
即使挂载本身被指定为只读，挂载到容器中的卷 `/mnt/<SUBMOUNT>` 也是可写的。

<!--
### Recursive read-only mounts
-->
### 递归只读挂载    {#recursive-read-only-mounts}








  <div class="feature-state-notice feature-stable" title="特性门控： RecursiveReadOnlyMounts">
              <span class="feature-state-name">特性状态：</span> 
              <code>Kubernetes v1.33 [stable]</code>（默认启用）</div>


<!--
Recursive read-only mounts can be enabled by setting the
`RecursiveReadOnlyMounts` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
for kubelet and kube-apiserver, and setting the `.spec.containers[*].volumeMounts[*].recursiveReadOnly`
field for a Pod.
-->
通过为 kubelet 和 kube-apiserver 设置 `RecursiveReadOnlyMounts`
[特性门控](/zh-cn/docs/reference/command-line-tools-reference/feature-gates/)，
并为 Pod 设置 `.spec.containers[*].volumeMounts[*].recursiveReadOnly` 字段，
递归只读挂载可以被启用。

<!--
The allowed values are:

* `Disabled` (default): no effect.
-->
允许的值为：

* `Disabled`（默认）：无效果。

<!--
* `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](/docs/concepts/architecture/cri) 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.
-->
* `Enabled`：使挂载递归只读。需要满足以下所有要求：

  * `readOnly` 设置为 `true`
  * `mountPropagation` 不设置，或设置为 `None`
  * 主机运行 Linux 内核 v5.12 或更高版本
  * [CRI 级别](/zh-cn/docs/concepts/architecture/cri)的容器运行时支持递归只读挂载
  * OCI 级别的容器运行时支持递归只读挂载

  如果其中任何一个不满足，递归只读挂载将会失败。

<!--
* `IfPossible`: attempts to apply `Enabled`, and falls back to `Disabled`
  if the feature is not supported by the kernel or the runtime class.

Example:
-->
* `IfPossible`：尝试应用 `Enabled`，如果内核或运行时类不支持该特性，则回退为 `Disabled`。

示例：


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/zh-cn/examples/storage/rro.yaml" download="storage/rro.yaml"><code>storage/rro.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('storage-rro-yaml')" title="复制 storage/rro.yaml 到剪贴板"></img></div>
    <div class="includecode" id="storage-rro-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Pod</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">rro</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">mnt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">hostPath</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># tmpfs 被挂载到 /mnt/tmpfs 上</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/mnt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">containers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">busybox</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">busybox</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;sleep&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;infinity&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">volumeMounts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># /mnt-rro/tmpfs 不可写入</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">mnt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="l">/mnt-rro</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">readOnly</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">mountPropagation</span><span class="p">:</span><span class="w"> </span><span class="l">None</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">recursiveReadOnly</span><span class="p">:</span><span class="w"> </span><span class="l">Enabled</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># /mnt-ro/tmpfs 可写入</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">mnt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="l">/mnt-ro</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">readOnly</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># /mnt-rw/tmpfs 可写入</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">mnt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="l">/mnt-rw</span><span class="w">
</span></span></span></code></pre></div></div>
</div>

<!--
When this property is recognized by kubelet and kube-apiserver,
the `.status.containerStatuses[*].volumeMounts[*].recursiveReadOnly` field is set to either
`Enabled` or `Disabled`.

#### Implementations {#implementations-rro}
-->
当此属性被 kubelet 和 kube-apiserver 识别到时，
`.status.containerStatuses[*].volumeMounts[*].recursiveReadOnly` 字段将被设置为
`Enabled` 或 `Disabled`。

#### 实现   {#implementations-rro}

<div class="alert alert-secondary callout third-party-content" role="note"><strong>说明：</strong>&puncsp;本部分链接到提供 Kubernetes 所需功能的第三方项目。Kubernetes 项目作者不负责这些项目。此页面遵循<a href="https://github.com/cncf/foundation/blob/main/policies-guidance/website-guidelines.md" target="_blank">CNCF 网站指南</a>，按字母顺序列出项目。要将项目添加到此列表中，请在提交更改之前阅读<a href="/zh-cn/docs/contribute/style/content-guide/#third-party-content">内容指南</a>。</div>


<!--
The following container runtimes are known to support recursive read-only mounts.

CRI-level:

- [containerd](https://containerd.io/), since v2.0
- [CRI-O](https://cri-o.io/), since v1.30

OCI-level:

- [runc](https://runc.io/), since v1.1
- [crun](https://github.com/containers/crun), since v1.8.6
-->
以下容器运行时已知支持递归只读挂载。

CRI 级别：

- [containerd](https://containerd.io/)，自 v2.0 起
- [CRI-O](https://cri-o.io/)，自 v1.30 起

OCI 级别：

- [runc](https://runc.io/)，自 v1.1 起
- [crun](https://github.com/containers/crun)，自 v1.8.6 起

## 接下来

<!--
Follow an example of [deploying WordPress and MySQL with Persistent Volumes](/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/).
-->
参考[使用持久卷部署 WordPress 和 MySQL](/zh-cn/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/)
示例。
