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

本教程介绍如何在 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. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  2. 确保您的 Cloud 项目已启用结算功能。了解如何检查项目是否已启用结算功能

  3. 启用 Compute Engine API。

    启用 API

  4. 在控制台中,激活 Cloud Shell。

    激活 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.6.4):

    cd ~/knfsd-cache-utils
    git checkout tags/v0.6.4
    
  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-family=ubuntu-2004-lts \
      --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 源服务器

如前所述,此架构旨在将云端资源连接到本地文件服务器。为了简化本教程中的过程,您需要创建在 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. 在控制台中,转到虚拟机实例页面。

    转到虚拟机实例

  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 脚本、示例部署代码以及涵盖扩缩工作负载的各种常见问题解答。

混合部署的注意事项

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

探索指标

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

清理

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

删除项目

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

  1. 在控制台中,打开管理资源页面。

    打开“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

后续步骤