在 Compute Engine 中部署内核空间 NFS 缓存代理

Last reviewed 2023-10-03 UTC

本教程介绍如何在 Compute Engine 中部署、配置和测试基于 Linux 的内核空间网络文件系统 (NFS) 缓存代理。本教程中介绍的架构专为以下场景设计:在字节级层将只读数据从 NFS 源文件服务器(如本地 NFS 文件服务器)同步到 Google Cloud,或者按需从一个主要可靠来源同步到多个只读副本。

本教程假定您熟悉以下内容:

  • 构建自定义版本的 Linux 操作系统。
  • 在 Compute Engine 中使用启动脚本安装和配置软件。
  • 配置和管理 NFS 文件系统。

此架构不支持文件锁定。此架构最适合使用唯一文件名来跟踪文件版本的流水线。

架构

本教程中的架构有一个充当 NFS 代理和缓存的内核空间 NFS 守护程序 (KNFSD)。此设置通过在 NFS 客户端请求数据时迁移数据,使您的云端计算节点可以访问本地的快速存储。NFS 客户端节点使用直写缓存将数据直接写回 NFS 源文件服务器。下图展示了此架构:

Google Cloud 中使用 KNFSD 代理的架构。

在本教程中,您将部署和测试 KNFSD 代理系统。您将在 Google Cloud 中创建和配置一个 NFS 服务器、一个 KNFSD 代理和一个 NFS 客户端。

KNFSD 代理系统的工作原理是从 NFS 服务器装载卷并重新导出该卷。NFS 客户端从代理装载重新导出的卷。当 NFS 客户端请求数据时,KNFSD 代理检查其各种缓存表,以确定数据是否位于本地。如果数据已在缓存中,KNFSD 代理会立即传送数据。如果请求的数据不在缓存中,则代理会迁移数据、更新其缓存表,然后传送数据。KNFSD 代理在字节级层缓存文件数据和元数据,因此只有使用的字节会在请求时被传输。

KNFSD 代理具有两层缓存:L1 和 L2。L1 是位于 RAM 中的操作系统的标准块缓存。当数据量超过可用 RAM 时,则使用在磁盘上本地缓存数据的 Linux 内核模块 FS-Cache 实现 L2 缓存。在此部署中,您将使用本地固态硬盘 (SSD) 作为 L2 缓存,但您可以通过多种方式配置系统。

要实现本教程中的架构,请使用与 NFS 版本 2、3 和 4 兼容的标准 NFS 工具。

混合架构中的 KNFSD 部署

在混合架构中,Google Cloud 中运行的 NFS 客户端在需要时请求数据。这些请求发送到 KNFSD 代理,代理会从其本地缓存中传送数据(如果存在)。如果数据不在缓存中,代理会与本地服务器通信。系统可以装载一个或多个 NFS 源服务器。代理管理通过 VPN 或专用互连返回到本地 NFS 源服务器的所有必要通信和数据迁移。下图展示了混合架构中的此 KNFSD 部署:

使用 KNFSD 部署的混合架构。

混合连接不在本教程的探讨范围内。如需了解高级主题,例如部署到混合架构的注意事项、扩缩以获得高性能,以及使用指标和信息中心进行问题排查和调整,请参阅高级工作流主题

目标

  • 部署和测试 KNFSD 代理系统。
  • 在 Google Cloud 中创建和配置以下组件:
    • 自定义磁盘映像
    • KNFSD 代理
    • NFS 服务器
    • NFS 客户端
  • 在 NFS 客户端上装载 NFS 代理。
  • 通过 NFS 代理将文件从 NFS 服务器复制到 NFS 客户端。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

对于您的使用情况,请考虑从 Google Cloud 写回本地存储的数据的网络出站流量费用,以及混合连接费用。

准备工作

在本参考指南中,您需要一个 Google Cloud 项目。您可创建一个新项目,也可选择已创建的项目:

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the Compute Engine API.

    Enable the API

  4. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  5. 在 Cloud Shell 终端中对您的登录进行身份验证:

    gcloud auth application-default login
    

    命令行将指导您完成授权步骤。

  6. 设置环境变量:

    export GOOGLE_CLOUD_PROJECT=PROJECT_NAME
    gcloud config set project $GOOGLE_CLOUD_PROJECT
    

    PROJECT_NAME 替换为您之前创建或选择的项目的名称。

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

下载教程配置文件

  1. 在 Cloud Shell 中,克隆 GitHub 代码库:

    cd ~/
    git clone https://github.com/GoogleCloudPlatform/knfsd-cache-utils.git
    
  2. 将 Git 标记设置为已知良好的版本(在本例中为 v0.9.0):

    cd ~/knfsd-cache-utils
    git checkout tags/v0.9.0
    
  3. 切换到代码库中的 image 目录:

     cd ~/knfsd-cache-utils/image
    

配置您的网络

为简化部署,本教程使用默认 VPC 网络。为了让您使用 SSH 连接到各种资源以进行配置和监控,本教程还部署了外部 IP 地址。

VPC 设计的最佳实践与参考架构不在本教程的探讨范围内。但是,在将这些资源集成到混合环境中时,我们建议您遵循以下最佳实践:

如需配置网络,请执行以下操作:

  • 在 Cloud Shell 中,设置以下环境变量:

    export BUILD_MACHINE_NETWORK=default
    export BUILD_MACHINE_SUBNET=default
    

创建 NFS 代理构建机器

在本部分中,您将创建并登录充当 NFS 代理构建机器的虚拟机。然后,运行提供的安装脚本更新内核版本,并安装 KNFSD 代理系统的所有必要软件。软件安装脚本可能需要运行几分钟时间,但您只需运行一次。

  1. 在 Cloud Shell 中,设置以下环境变量:

    export BUILD_MACHINE_NAME=knfsd-build-machine
    export BUILD_MACHINE_ZONE=us-central1-a
    export IMAGE_FAMILY=knfsd-proxy
    export IMAGE_NAME=knfsd-proxy-image
    
  2. 启动虚拟机实例:

    gcloud compute instances create $BUILD_MACHINE_NAME \
      --zone=$BUILD_MACHINE_ZONE \
      --machine-type=n1-standard-16 \
      --project=$GOOGLE_CLOUD_PROJECT \
      --image=ubuntu-2004-focal-v20220615 \
      --image-project=ubuntu-os-cloud \
      --network=$BUILD_MACHINE_NETWORK \
      --subnet=$BUILD_MACHINE_SUBNET \
      --boot-disk-size=20GB \
      --boot-disk-type=pd-ssd \
      --metadata=serial-port-enable=TRUE
    

    您可能会收到一条指出磁盘大小不符的警告消息。您可以忽略此消息。

  3. 创建要安装的必要软件的 tar 文件,然后将其复制到构建机器:

    tar -czf resources.tgz -C resources .
    gcloud compute scp resources.tgz build@$BUILD_MACHINE_NAME: \
      --zone=$BUILD_MACHINE_ZONE \
      --project=$GOOGLE_CLOUD_PROJECT
    
  4. 虚拟机启动后,打开连接到它的 SSH 隧道:

    gcloud compute ssh build@$BUILD_MACHINE_NAME \
      --zone=$BUILD_MACHINE_ZONE \
      --project=$GOOGLE_CLOUD_PROJECT
    
  5. SSH 隧道建立并且命令行指向 knfsd-build-machine 实例后,运行安装脚本:

    tar -zxf resources.tgz
    sudo bash scripts/1_build_image.sh
    

    该脚本会克隆 Ubuntu 内核代码代码库,更新内核版本,并安装其他软件。由于涉及代码库克隆,因此脚本可能需要较长时间才能完成。

  6. 安装脚本完成并显示 SUCCESS 提示符后,重新启动构建机器:

    sudo reboot
    

    构建机器重新启动时,将显示以下消息:

    WARNING: Failed to send all data from [stdin]
    ERROR: (gcloud.compute.ssh) [/usr/bin/ssh] exited with return code [255]
    

    当 Cloud Shell 从 NFS 代理构建机器恢复到宿主机时,就会发生这些错误。您可以忽略这些错误。

  7. 虚拟机重新启动后,重新打开连接到它的 SSH 隧道:

    gcloud compute ssh $BUILD_MACHINE_NAME \
      --zone=$BUILD_MACHINE_ZONE \
      --project=$GOOGLE_CLOUD_PROJECT
    
  8. SSH 隧道建立并且命令行指向 nfs-proxy-build 实例后,请切换到 Root 并检查操作系统版本:

    uname -r
    

    输出类似于以下内容,表明软件更新成功:

    linux <$BUILD_MACHINE_NAME> 5.13.*-gcp ...
    

    如果输出与上述示例不同,请完成此过程以再次创建 NFS 代理构建机器

  9. 清理本地磁盘并关闭构建机器:

    sudo bash /home/build/scripts/9_finalize.sh
    

    将显示以下警告:

    userdel: user build is currently used by process 1431
    userdel: build mail spool (/var/mail/build) not found
    

    当 Cloud Shell 从 NFS 代理构建机器恢复到宿主机时,就会出现这些警告。您可以忽略这些错误。

创建自定义磁盘映像

在本部分中,您将从实例创建自定义映像。自定义映像存储在位于美国的多区域 Cloud Storage 存储桶中。

  1. 在 Cloud Shell 中,设置以下环境变量:

    export IMAGE_NAME=knfsd-image
    export IMAGE_DESCRIPTION="first knfsd image from tutorial"
    export IMAGE_LOCATION=us
    
  2. 创磁盘映像:

    gcloud compute images create $IMAGE_NAME \
      --project=$GOOGLE_CLOUD_PROJECT \
      --description="$IMAGE_DESCRIPTION" \
      --source-disk=$BUILD_MACHINE_NAME \
      --source-disk-zone=$BUILD_MACHINE_ZONE \
      --storage-location=$IMAGE_LOCATION
    
  3. 磁盘映像创建后,删除实例:

    gcloud compute instances delete $BUILD_MACHINE_NAME \
      --zone=$BUILD_MACHINE_ZONE
    
  4. 当系统提示您继续时,请输入 Y

    删除 $BUILD_MACHINE_NAME 实例时,您会看到一条提示,指出虚拟机上挂接的磁盘将被删除。由于您刚刚保存了自定义映像,因此不再需要此临时磁盘,可以放心地将其删除。

创建 NFS 源服务器

如前所述,此架构旨在将云端资源连接到本地文件服务器。为了简化本教程中的过程,您需要创建在 Google Cloud 项目中运行的替代资源来模拟此连接。将替代资源命名为 nfs-server。软件安装和设置包含在启动脚本中。如需了解详情,请查看脚本 ~/knfsd-cache-utils/tutorial/nfs-server/1_build_nfs-server.sh

  1. 在 Cloud Shell 中,切换到下载的 nfs-server 脚本目录:

    cd ~/knfsd-cache-utils/tutorial
    
  2. 创建替代 NFS 服务器:

    gcloud compute \
      --project=$GOOGLE_CLOUD_PROJECT instances create nfs-server \
      --zone=$BUILD_MACHINE_ZONE \
      --machine-type=n1-highcpu-2 \
      --maintenance-policy=MIGRATE \
      --image-family=ubuntu-2004-lts \
      --image-project=ubuntu-os-cloud \
      --boot-disk-size=100GB \
      --boot-disk-type=pd-standard \
      --boot-disk-device-name=nfs-server \
      --metadata-from-file startup-script=nfs-server-startup.sh
    

    此脚本可能需要几分钟才能完成。您可能会看到一条警告消息,指出您的磁盘大小低于 200 GB。您可以忽略此警告。

创建 NFS 代理

在本部分中,您将创建 NFS 代理。代理启动时,它会配置本地存储,为 NFS 服务器准备装载选项,并导出缓存的结果。提供的启动脚本可编排此工作流的大部分内容。

  1. 在 Cloud Shell 中,设置以下变量:

    export PROXY_NAME=nfs-proxy
    
  2. 创建 nfs-proxy 虚拟机:

    gcloud compute instances create $PROXY_NAME \
      --machine-type=n1-highmem-16 \
      --project=$GOOGLE_CLOUD_PROJECT \
      --maintenance-policy=MIGRATE \
      --zone=$BUILD_MACHINE_ZONE \
      --min-cpu-platform="Intel Skylake" \
      --image=$IMAGE_NAME \
      --image-project=$GOOGLE_CLOUD_PROJECT \
      --boot-disk-size=20GB \
      --boot-disk-type=pd-standard \
      --boot-disk-device-name=$PROXY_NAME \
      --local-ssd=interface=NVME \
      --local-ssd=interface=NVME \
      --local-ssd=interface=NVME \
      --local-ssd=interface=NVME \
      --metadata-from-file startup-script=proxy-startup.sh
    

    您可能会看到一条警告消息,指出您的磁盘大小低于 200 GB。您可以忽略此警告。

    启动脚本会配置 NFS 装载命令,并允许您调整系统。NFS 版本、同步或异步、noctoactimeo 的设置是您可能需要通过启动脚本优化的一些变量。如需详细了解这些设置,请参阅优化 NFS 文件系统

    此步骤中的命令定义了 --metadata-from-file 标志,它会将启动脚本注入您的映像模板。在本教程中,您将使用简单的 proxy-startup.sh 脚本。该脚本包含一些预设的变量,它不包含您在集成到流水线时可能需要使用的许多选项。如需查看更高级的用例,请参阅 knfsd-cache-utils GitHub 代码库

创建 NFS 客户端

在此步骤中,您将创建一个 NFS 客户端(名为 nfs-client)来替代一个规模较大的代管式实例组 (MIG)

  • 在 Cloud Shell 中,创建 NFS 客户端:

    gcloud compute \
      --project=$GOOGLE_CLOUD_PROJECT instances create nfs-client \
      --zone=$BUILD_MACHINE_ZONE \
      --machine-type=n1-highcpu-8 \
      --network-tier=PREMIUM \
      --maintenance-policy=MIGRATE \
      --image-family=ubuntu-2004-lts \
      --image-project=ubuntu-os-cloud \
      --boot-disk-size=10GB \
      --boot-disk-type=pd-standard \
      --boot-disk-device-name=nfs-client
    

    您可能会看到一条警告消息,指出您的磁盘大小低于 200 GB。您可以忽略此警告。

在 NFS 客户端上装载 NFS 代理

在此步骤中,您将在 NFS 客户端上打开单独的 SSH 会话,然后装载 NFS 代理。在下一部分,您将使用这一相同的 shell 来测试系统。

  1. 在 Google Cloud 控制台中,转到虚拟机实例页面。

    转到虚拟机实例

  2. 要连接到 nfs-client,请点击连接列中的 SSH

  3. nfs-client SSH 窗口中,在 nfs-client 上安装必要的 NFS 工具:

    sudo apt-get install nfs-common -y
    
  4. 创建装载点并装载 NFS 代理:

    sudo mkdir /data
    sudo mount -t nfs -o vers=3 nfs-proxy:/data /data
    

测试系统

现在,您的所有资源都已创建完毕。在本部分中您将运行测试,具体做法是通过 NFS 代理将文件从 NFS 服务器复制到 NFS 客户端。首次运行此测试时,数据来自源服务器。此过程可能需要一分钟以上。

第二次运行此测试时,数据会从存储在 NFS 代理的本地 SSD 中的缓存中传送。在这一次传输中,复制数据需要的时间要少得多,这可以验证缓存加快了数据传输速度。

  1. 在上一部分中打开的 nfs-client SSH 窗口中,复制 test 文件并查看相应的输出:

    time dd if=/data/test.data of=/dev/null iflag=direct bs=1M status=progress
    

    输出类似于以下内容,其中包含显示文件大小、传输时长和传输速度的行:

    10737418240 bytes (11 GB, 10 GiB) copied, 88.5224 s, 121 MB/s
    real    1m28.533s
    

    在这一次传输中,文件从 NFS 服务器的永久性磁盘传送,因此受到 NFS 服务器磁盘速度的限制。

  2. 再次运行同一命令:

    time dd if=/data/test.data of=/dev/null iflag=direct bs=1M status=progress
    

    输出类似于以下内容,其中包含显示文件大小、传输时长和传输速度的行:

    10737418240 bytes (11 GB, 10 GiB) copied, 9.41952 s, 948 MB/s
    real    0m9.423s
    

    在这一次传输中,文件从 NFS 代理中的缓存传送,因此完成速度更快。

至此,您已完成 KNFSD 缓存代理的部署和测试。

高级工作流主题

本部分介绍部署到混合架构、扩缩以获得高性能,以及使用指标和信息中心进行问题排查和调整的相关信息。

性能特征和资源大小调整

如前所述,本教程使用单个 KNFSD 代理。因此,对系统进行扩容涉及修改各个代理资源,以针对 CPU、RAM、网络、存储容量或性能进行优化。在本教程中,您在具有以下选项的单个 Compute Engine 虚拟机上部署了 KNFSD:

  • 16 个 vCPU,104 GB RAM (n1-highmem-16)。
    • 具有 16 个 vCPU 和 Sandy Bridge 或更高版本的架构,最大网络速度为 32 Gbps。
  • 10 GB 永久性磁盘作为启动磁盘。
  • 4 个本地 SSD 磁盘。此配置提供了 1.5 TB 的高速文件系统。

虽然本教程并未进行讨论,但您可以通过在 MIG 中创建多个 KNFSD 代理以及使用 TCP 负载均衡器管理 NFS 客户端和 NFS 代理之间的连接来对架构进行扩容。如需了解详情,请参阅 knfsd-cache-utils GitHub 代码库,其中包含 Terraform 脚本、示例部署代码以及涵盖扩缩工作负载的各种常见问题解答。

混合部署的注意事项

在许多部署中,从本地到云端的连接带宽是配置系统时需要考虑的主要因素。混合连接不在本教程的探讨范围内。如需简要了解可用选项,请参阅混合连接文档。如需查看有关最佳实践和设计模式的指导,请参阅使用 Google Cloud 构建混合和多云架构系列文章。

探索指标

信息中心可帮助提供指标反馈,以用于性能调整和整体问题排查。探索指标不在本教程的探讨范围内,但是,当您部署在 knfsd-cache-utils GitHub 代码库中定义的多节点系统时,可以使用指标信息中心。

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

若要避免产生费用,最简单的方法是删除您为本教程创建的项目。

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

后续步骤