

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 为 Linux 配置 NVMe/TCP
<a name="provision-nvme-linux"></a>

FSx for ONTAP 支持基于 TCP 的非易失性存储规范（NVMe/TCP）块存储协议。凭借 NVMe/TCP，您可以使用 ONTAP CLI 配置命名空间和子系统，然后将命名空间映射到子系统，这与配置 LUN 并将其映射到 iSCSI 启动器组（igroup）的方式类似。NVMe/TCP 协议适用于拥有 6 个或更少[高可用性（HA）对](HA-pairs.md)的第二代文件系统。

**注意**  
FSx for ONTAP 文件系统在 iSCSI 和 NVMe/TCP 块存储协议中均使用 SVM 的 iSCSI 端点。

在适用于 NetApp ONTAP 的 Amazon FSx 上配置 NVMe/TCP 有三个主要步骤，这些步骤将在以下过程中进行介绍：

1. 在 Linux 主机上安装和配置 NVMe 客户端。

1. 在文件系统的 SVM 上配置 NVMe。
   + 创建 NVMe 命名空间。
   + 创建 NVMe 子系统。
   + 将命名空间映射到子系统。
   + 将客户端 NQN 添加到子系统。

1. 在 Linux 客户端上挂载 NVMe 设备。

## 开始前的准备工作
<a name="nvme-tcp-linux-byb"></a>

在开始为 NVMe/TCP 配置文件系统之前，需要完成以下各项。
+ 创建 FSx for ONTAP 文件系统。有关更多信息，请参阅 [创建文件系统](creating-file-systems.md)。
+ 在与文件系统相同的 VPC 中创建一个运行 Red Hat Enterprise（RHEL）9.3 的 EC2 实例。这是您配置 NVMe 和使用 Linux 版 NVMe/TCP 访问文件数据所在的 Linux 主机。

  在这些过程的范围之外，如果主机位于其他 VPC 中，则可以使用 VPC 对等连接或 Amazon Transit Gateway 来授予其他 VPC 访问该卷的 iSCSI 端点的权限。有关更多信息，请参阅 [从部署 VPC 外部访问数据](supported-fsx-clients.md#access-from-outside-deployment-vpc)。
+ 配置 Linux 主机的 VPC 安全组，允许入站和出站流量，如 [使用 Amazon VPC 进行文件系统访问控制](limit-access-security-groups.md) 中所述。
+ 获取具有 `fsxadmin` 权限的 ONTAP 用户的凭证，此权限用于访问 ONTAP CLI。有关更多信息，请参阅 [ONTAP 用户和角色](roles-and-users.md)。
+ 您将要为 NVMe 配置并用于访问 FSx for ONTAP 文件系统的 Linux 主机位于同一 VPC 和 Amazon Web Services 账户 中。
+ 我们建议使 EC2 实例与文件系统的首选子网处于同一个可用区。

如果 EC2 实例运行的 Linux AMI 与 RHEL 9.3 不同，则这些过程和示例中使用的某些实用程序可能已安装，并且您可能会使用不同的命令来安装所需的软件包。除了安装软件包外，本节中使用的命令还适用于其他 EC2 Linux AMI。

**Topics**
+ [开始前的准备工作](#nvme-tcp-linux-byb)
+ [在 Linux 主机上安装和配置 NVMe](#configure-nvme-on-rhel93)
+ [在 FSx for ONTAP 文件系统上配置 NVMe](#configure-nvme-on-svm)
+ [在 Linux 客户端上挂载 NVMe 设备。](#add-nvme-on-rhel93-host)

## 在 Linux 主机上安装和配置 NVMe
<a name="configure-nvme-on-rhel93"></a>

**安装 NVMe 客户端**

1. 使用 SSH 客户端连接到 Linux 实例。有关更多信息，请参阅[使用 SSH 从 Linux 或 macOS 连接到 Linux 实例](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/connect-linux-inst-ssh.html)。

1. 使用以下命令安装 `nvme-cli`：

   ```
   ~$ sudo yum install -y nvme-cli
   ```

1. 将 `nvme-tcp` 模块加载到主机上：

   ```
   $ sudo modprobe nvme-tcp
   ```

1. 使用以下命令获取 Linux 主机的 NVMe 限定名称（NQN）：

   ```
   $ cat /etc/nvme/hostnqn
   nqn.2014-08.org.nvmexpress:uuid:9ed5b327-b9fc-4cf5-97b3-1b5d986345d1
   ```

   请记录响应，以便在后续步骤中使用。

## 在 FSx for ONTAP 文件系统上配置 NVMe
<a name="configure-nvme-on-svm"></a>

**在文件系统上配置 NVMe**

在您计划创建 NVMe 设备所在的 FSx for ONTAP 文件系统上连接 ONTAP CLI。

1. 要访问 ONTAP CLI，请运行以下命令，在适用于 NetApp ONTAP 的 Amazon FSx 文件系统或 SVM 的管理端口上建立 SSH 会话。将 `management_endpoint_ip` 替换为文件系统管理端口的 IP 地址。

   ```
   [~]$ ssh fsxadmin@management_endpoint_ip
   ```

   有关更多信息，请参阅 [使用 ONTAP CLI 管理文件系统](managing-resources-ontap-apps.md#fsxadmin-ontap-cli)。

1. 在 SVM 上创建一个新的卷以用于访问 NVMe 接口。

   ```
   ::> vol create -vserver fsx -volume nvme_vol1 -aggregate aggr1 -size 1t
        [Job 597] Job succeeded: Successful
   ```

1. 使用 [https://docs.netapp.com/us-en/ontap-cli-9141/vserver-nvme-namespace-create.html](https://docs.netapp.com/us-en/ontap-cli-9141/vserver-nvme-namespace-create.html) NetApp ONTAP CLI 命令创建 NVMe 命名空间 `ns_1`。命名空间映射到启动器（客户端），并控制哪些启动器（客户端）可以访问 NVMe 设备。

   ```
   ::> vserver nvme namespace create -vserver fsx -path /vol/nvme_vol1/ns_1 -size 100g -ostype linux
   Created a namespace of size 100GB (107374182400).
   ```

1. 使用 [https://docs.netapp.com/us-en/ontap-cli-9141/vserver-nvme-subsystem-create.html](https://docs.netapp.com/us-en/ontap-cli-9141/vserver-nvme-subsystem-create.html) NetApp ONTAP CLI 命令创建 NVMe 子系统。

   ```
   ~$ vserver nvme subsystem create -vserver fsx -subsystem sub_1 -ostype linux
   ```

1. 将命名空间映射至刚才创建的子系统。

   ```
   ::> vserver nvme subsystem map add -vserver fsx -subsystem sub_1 -path /vol/nvme_vol1/ns_1
   ```

1. 使用之前检索到的 NQN 将客户端添加到子系统。

   ```
   ::> vserver nvme subsystem host add -subsystem sub_1 -host-nqn nqn.2014-08.org.nvmexpress:uuid:ec21b083-1860-d690-1f29-44528e4f4e0e -vserver fsx
   ```

   如果要将映射到此子系统的设备供多个主机使用，您可以在逗号分隔列表中指定多个启动程序名称。有关更多信息，请参阅 NetApp ONTAP 文档中的[虚拟服务器 NVMe 子系统主机的添加](https://docs.netapp.com/us-en/ontap-cli-9141/vserver-nvme-subsystem-host-add.html)。

1. 使用 [https://docs.netapp.com/us-en/ontap-cli-9141/vserver-nvme-namespace-show.html](https://docs.netapp.com/us-en/ontap-cli-9141/vserver-nvme-namespace-show.html) 命令确认命名空间存在：

   ```
   ::> vserver nvme namespace show -vserver fsx -instance
   Vserver Name: fsx
               Namespace Path: /vol/nvme_vol1/ns_1
                         Size: 100GB
                    Size Used: 90.59GB
                      OS Type: linux
                      Comment: 
                   Block Size: 4KB
                        State: online
            Space Reservation: false
   Space Reservations Honored: false
                 Is Read Only: false
                Creation Time: 5/20/2024 17:03:08
               Namespace UUID: c51793c0-8840-4a77-903a-c869186e74e3
                     Vdisk ID: 80d42c6f00000000187cca9
         Restore Inaccessible: false
      Inconsistent Filesystem: false
          Inconsistent Blocks: false
                       NVFail: false
   Node Hosting the Namespace: FsxId062e9bb6e05143fcb-01
                  Volume Name: nvme_vol1
                   Qtree Name: 
             Mapped Subsystem: sub_1
               Subsystem UUID: db526ec7-16ca-11ef-a612-d320bd5b74a9               
                 Namespace ID: 00000001h
                 ANA Group ID: 00000001h
                 Vserver UUID: 656d410a-1460-11ef-a612-d320bd5b74a9
                   Vserver ID: 3
                  Volume MSID: 2161388655
                  Volume DSID: 1029
                    Aggregate: aggr1
               Aggregate UUID: cfa8e6ee-145f-11ef-a612-d320bd5b74a9
    Namespace Container State: online
           Autodelete Enabled: false
             Application UUID: -
                  Application: -
     Has Metadata Provisioned: true
     
   1 entries were displayed.
   ```

1. 使用 [https://docs.netapp.com/us-en/ontap-cli-9141/network-interface-show.html](https://docs.netapp.com/us-en/ontap-cli-9141/network-interface-show.html) 命令检索您在其中创建 NVMe 设备的 SVM 的块存储接口的地址。

   ```
   ::> network interface show -vserver svm_name -data-protocol nvme-tcp
               Logical               Status     Network            Current                    Current Is 
   Vserver     Interface             Admin/Oper Address/Mask       Node                       Port    Home
   ----------- ----------            ---------- ------------------ -------------              ------- ----
   svm_name
               iscsi_1               up/up      172.31.16.19/20    FSxId0123456789abcdef8-01  e0e     true
               iscsi_2               up/up      172.31.26.134/20   FSxId0123456789abcdef8-02  e0e     true
   2 entries were displayed.
   ```
**注意**  
`iscsi_1` LIF 对 iSCSI 和 NVMe/TCP 均适用。

   在此示例中，iscsi\$11 的 IP 地址为 172.31.16.19，iscsi\$12 的 IP 地址为 172.31.26.134。

## 在 Linux 客户端上挂载 NVMe 设备。
<a name="add-nvme-on-rhel93-host"></a>

在 Linux 客户端上挂载 NVMe 设备的过程包括三个步骤：

1. 发现 NVMe 节点

1. 对 NVMe 设备进行分区

1. 在客户端上挂载 NVMe 设备

以下过程将详述这些步骤。

**发现目标 NVMe 节点**

1. 在 Linux 客户端上，使用以下命令来发现目标 NVMe 节点。将 *`iscsi_1_IP`* 替换为 `iscsi_1` 的 IP 地址以及 *`client_IP`* 客户端的 IP 地址。
**注意**  
`iscsi_1` 和 `iscsi_2` LIF 对 iSCSI 和 NVMe 存储均适用。

   ```
   ~$ sudo nvme discover -t tcp -w client_IP -a iscsi_1_IP
   ```

   ```
   Discovery Log Number of Records 4, Generation counter 11
   =====Discovery Log Entry 0======
   trtype:  tcp
   adrfam:  ipv4
   subtype: current discovery subsystem
   treq:    not specified
   portid:  0
   trsvcid: 8009
   subnqn:  nqn.1992-08.com.netapp:sn.656d410a146011efa612d320bd5b74a9:discovery
   traddr:  172.31.26.134
   eflags:  explicit discovery connections, duplicate discovery information
   sectype: none
   =====Discovery Log Entry 1======
   trtype:  tcp
   adrfam:  ipv4
   subtype: current discovery subsystem
   treq:    not specified
   portid:  1
   trsvcid: 8009
   subnqn:  nqn.1992-08.com.netapp:sn.656d410a146011efa612d320bd5b74a9:discovery
   traddr:  172.31.16.19
   eflags:  explicit discovery connections, duplicate discovery information
   sectype: none
   ```

1. （可选）要为文件系统的 NVMe 设备带来高于 Amazon EC2 单一客户端最大 5Gbps（约 625MBps）的吞吐量，请按照《适用于 Linux 实例的 Amazon Elastic Compute Cloud 用户指南》中的 [Amazon EC2 实例网络带宽](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/ec2-instance-network-bandwidth.html)描述的过程建立更多的会话。

1. 在控制器断开超时至少达到 1800 秒的情况下，再次使用 `iscsi_1` 的 IP 地址（*`iscsi_1_IP`*）和客户端的 IP 地址（*`client_IP`*）登录目标启动器。NVMe 设备显示为可用磁盘。

   ```
   ~$ sudo nvme connect-all -t tcp -w client_IP -a iscsi_1 -l 1800
   ```

1. 使用以下命令验证 NVMe 堆栈是否已识别并合并多个会话且配置了多路径。如果配置成功，则命令会返回确认 `Y`。

   ```
   ~$ cat /sys/module/nvme_core/parameters/multipath
   Y
   ```

1. 使用以下命令验证相应 ONTAP 命名空间的 NVMe-oF 设置 `model` 是否设置为 `NetApp ONTAP Controller`，负载均衡 `iopolicy` 是否设置为 `round-robin`，以使 I/O 分布在所有可用的路径上

   ```
   ~$ cat /sys/class/nvme-subsystem/nvme-subsys*/model
   Amazon Elastic Block Store              
   NetApp ONTAP Controller
   ~$ cat /sys/class/nvme-subsystem/nvme-subsys*/iopolicy
   numa
   round-robin
   ```

1. 使用以下命令验证是否在主机上创建并正确发现了命名空间。

   ```
   ~$ sudo nvme list
   Node                  Generic               SN                   Model                                    Namespace  Usage                      Format           FW Rev  
   --------------------- --------------------- -------------------- ---------------------------------------- ---------- -------------------------- ---------------- --------
   /dev/nvme0n1          /dev/ng0n1            vol05955547c003f0580 Amazon Elastic Block Store               0x1         25.77  GB /  25.77  GB    512   B +  0 B   1.0     
   /dev/nvme2n1          /dev/ng2n1            lWB12JWY/XLKAAAAAAAC NetApp ONTAP Controller                  0x1        107.37  GB / 107.37  GB      4 KiB +  0 B   FFFFFFFF
   ```

   输出中的新设备为 `/dev/nvme2n1`。根据 Linux 安装情况，此命名方案可能会有所不同。

1. 验证每条路径的控制器状态是否处于活动状态，以及是否具有正确的非对称命名空间访问（ANA）多路径状态：

   ```
   ~$ nvme list-subsys /dev/nvme2n1
   nvme-subsys2 - NQN=nqn.1992-08.com.netapp:sn.656d410a146011efa612d320bd5b74a9:subsystem.rhel
                  hostnqn=nqn.2014-08.org.nvmexpress:uuid:ec2a70bf-3ab2-6cb0-f997-8730057ceb24
                  iopolicy=round-robin
   \
    +- nvme2 tcp traddr=172.31.26.134,trsvcid=4420,host_traddr=172.31.25.143,src_addr=172.31.25.143 live non-optimized
    +- nvme3 tcp traddr=172.31.16.19,trsvcid=4420,host_traddr=172.31.25.143,src_addr=172.31.25.143 live optimized
   ```

   在此示例中，NVMe 堆栈已自动发现了文件系统的备用 `iscsi_2` LIF，即 172.31.26.134。

1. 验证 NetApp 插件是否为每个 ONTAP 命名空间设备显示了正确的值：

   ```
   ~$ sudo nvme netapp ontapdevices -o column
   Device           Vserver                   Namespace Path                                     NSID UUID                                   Size     
   ---------------- ------------------------- -------------------------------------------------- ---- -------------------------------------- ---------
   /dev/nvme2n1     fsx                       /vol/nvme_vol1/ns_1                                1    0441c609-3db1-4b0b-aa83-790d0d448ece   107.37GB
   ```

**对设备进行分区**

1. 使用以下命令验证您的 device\$1name `nvme2n1` 路径是否存在。

   ```
   ~$ ls /dev/mapper/nvme2n1
   /dev/nvme2n1
   ```

1. 使用 `fdisk` 对磁盘进行分区。您需要输入交互式提示。按显示的顺序输入选项。您可以使用小于最后一个扇区的值来创建多个分区（在本例中为 `20971519`）。
**注意**  
`Last sector` 值根据 NVMe 设备的大小（在本例中为 100 GiB）而不同。

   ```
   ~$ sudo fdisk /dev/mapper/nvme2n1
   ```

   开始进行 `fsdisk` 交互式提示。

   ```
   Welcome to fdisk (util-linux 2.37.4). 
   Changes will remain in memory only, until you decide to write them. 
   Be careful before using the write command. 
   
   Device does not contain a recognized partition table. 
   Created a new DOS disklabel with disk identifier 0x66595cb0. 
   
   Command (m for help): n
   Partition type 
      p primary (0 primary, 0 extended, 4 free) 
      e extended (container for logical partitions) 
   Select (default p): p
   Partition number (1-4, default 1): 1 
   First sector (256-26214399, default 256): 
   Last sector, +sectors or +size{K,M,G,T,P} (256-26214399, default 26214399): 20971519
                                       
   Created a new partition 1 of type 'Linux' and of size 100 GiB.
   Command (m for help): w
   The partition table has been altered.
   Calling ioctl() to re-read partition table. 
   Syncing disks.
   ```

   输入 `w` 后，您的新分区 `/dev/nvme2n1` 即变为可用。*partition\$1name* 的格式为 *<device\$1name>**<partition\$1number>*。`1` 已用作上一步 `fdisk` 命令中的分区编号。

1. 使用 `/dev/nvme2n1` 作为创建文件系统的路径。

   ```
   ~$ sudo mkfs.ext4 /dev/nvme2n1
   ```

   系统将使用以下输出做出响应：

   ```
   mke2fs 1.46.5 (30-Dec-2021)
   Found a dos partition table in /dev/nvme2n1
   Proceed anyway? (y,N) y
   Creating filesystem with 26214400 4k blocks and 6553600 inodes
   Filesystem UUID: 372fb2fd-ae0e-4e74-ac06-3eb3eabd55fb
   Superblock backups stored on blocks: 
       32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
       4096000, 7962624, 11239424, 20480000, 23887872
   
   Allocating group tables: done                            
   Writing inode tables: done                            
   Creating journal (131072 blocks): done
   Writing superblocks and filesystem accounting information: done
   ```

**在 Linux 客户端上挂载 NVMe 设备**

1. 创建一个目录 *directory\$1path* 作为 Linux 实例上的文件系统的挂载点。

   ```
   ~$ sudo mkdir /directory_path/mount_point
   ```

1. 使用以下命令挂载文件系统。

   ```
   ~$ sudo mount -t ext4 /dev/nvme2n1 /directory_path/mount_point
   ```

1. （可选）如果要向特定用户授予挂载目录的所有权，请将 *`username`* 替换为拥有者的用户名。

   ```
   ~$ sudo chown username:username /directory_path/mount_point
   ```

1. （可选）验证您是否可以从文件系统读取数据和将数据写入文件系统。

   ```
   ~$ echo "Hello world!" > /directory_path/mount_point/HelloWorld.txt
   ~$ cat directory_path/HelloWorld.txt
   Hello world!
   ```

   您在 Linux 客户端上成功创建并挂载了一个 NVMe 设备。