在 Azure Kubernetes 服务 (AKS) 中手动创建和使用 NFS(网络文件系统)Linux 服务器卷Manually create and use an NFS (Network File System) Linux Server volume with Azure Kubernetes Service (AKS)

基于容器的服务和应用程序往往需要在容器之间共享数据。Sharing data between containers is often a necessary component of container-based services and applications. 通常,会有各种 Pod 需要访问外部持久性卷上的相同信息。You usually have various pods that need access to the same information on an external persistent volume.
Azure 文件是一个选项,而在 Azure VM 上创建的 NFS 服务器是持久性共享存储的另一种形式。While Azure files are an option, creating an NFS Server on an Azure VM is another form of persistent shared storage.

本文将介绍如何在 Ubuntu 虚拟机上创建 NFS 服务器。This article will show you how to create an NFS Server on an Ubuntu virtual machine. 另外,将介绍 AKS 容器如何访问此共享文件系统。And also give your AKS containers access to this shared file system.

准备阶段Before you begin

本文假设你已有一个 AKS 群集。This article assumes that you have an existing AKS Cluster. 如果需要 AKS 群集,请参阅 AKS 快速入门使用 Azure CLI使用 Azure 门户If you need an AKS Cluster, see the AKS quickstart using the Azure CLI or using the Azure portal.

AKS 群集需要驻留在 NFS 服务器所在的相同或对等互连的虚拟网络中。Your AKS Cluster will need to live in the same or peered virtual networks as the NFS Server. 该群集必须在现有的 VNET 中创建,该 VNET 可以是 VM 所在的同一 VNET。The cluster must be created in an existing VNET, which can be the same VNET as your VM.

以下文档介绍了使用现有 VNET 进行配置的步骤:在现有 VNET 中创建 AKS 群集通过 VNET 对等互连连接虚拟网络The steps for configuring with an existing VNET are described in the documentation: creating AKS Cluster in existing VNET and connecting virtual networks with VNET peering

本文还假设你已创建一个 Ubuntu Linux 虚拟机(例如 18.04 LTS)。It also assumes you've created an Ubuntu Linux Virtual Machine (for example, 18.04 LTS). 可以使用任意设置和大小,并可以通过 Azure 部署该虚拟机。Settings and size can be to your liking and can be deployed through Azure. 有关 Linux 快速入门,请参阅 Linux VM 管理For Linux quickstart, see Linux VM management.

如果你是首次部署 AKS 群集,在部署 Ubuntu 计算机时,Azure 会自动填充虚拟网络字段,使该计算机驻留在同一 VNET 中。If you deploy your AKS Cluster first, Azure will automatically populate the virtual network field when deploying your Ubuntu machine, making them live within the same VNET. 但是,如果你想要改用对等互连网络,请参阅上述文档。But if you want to work with peered networks instead, consult the documentation above.

将 NFS 服务器部署到虚拟机Deploying the NFS Server onto a Virtual Machine

下面是用于在 Ubuntu 虚拟机中设置 NFS 服务器的脚本:Here is the script to set up an NFS Server within your Ubuntu virtual machine:

#!/bin/bash

# This script should be executed on Linux Ubuntu Virtual Machine

EXPORT_DIRECTORY=${1:-/export/data}
DATA_DIRECTORY=${2:-/data}
AKS_SUBNET=${3:-*}

echo "Updating packages"
apt-get -y update

echo "Installing NFS kernel server"

apt-get -y install nfs-kernel-server

echo "Making data directory ${DATA_DIRECTORY}"
mkdir -p ${DATA_DIRECTORY}

echo "Making new directory to be exported and linked to data directory: ${EXPORT_DIRECTORY}"
mkdir -p ${EXPORT_DIRECTORY}

echo "Mount binding ${DATA_DIRECTORY} to ${EXPORT_DIRECTORY}"
mount --bind ${DATA_DIRECTORY} ${EXPORT_DIRECTORY}

echo "Giving 777 permissions to ${EXPORT_DIRECTORY} directory"
chmod 777 ${EXPORT_DIRECTORY}

parentdir="$(dirname "$EXPORT_DIRECTORY")"
echo "Giving 777 permissions to parent: ${parentdir} directory"
chmod 777 $parentdir

echo "Appending bound directories into fstab"
echo "${DATA_DIRECTORY}    ${EXPORT_DIRECTORY}   none    bind  0  0" >> /etc/fstab

echo "Appending localhost and Kubernetes subnet address ${AKS_SUBNET} to exports configuration file"
echo "/export        ${AKS_SUBNET}(rw,async,insecure,fsid=0,crossmnt,no_subtree_check)" >> /etc/exports
echo "/export        localhost(rw,async,insecure,fsid=0,crossmnt,no_subtree_check)" >> /etc/exports

nohup service nfs-kernel-server restart

服务器将会重启(由于使用了该脚本),你可以将 NFS 服务器装载到 AKS。The server will restart (because of the script) and you can mount the NFS Server to AKS.

重要

请务必将 AKS_SUBNET 替换为群集中的适当子网;如果使用“*”,则会在 NFS 服务器中打开所有端口和连接。Make sure to replace the AKS_SUBNET with the correct one from your cluster or else "*" will open your NFS Server to all ports and connections.

创建 VM 后,将上述脚本复制到某个文件中。After you've created your VM, copy the script above into a file. 然后可以使用以下命令,将该脚本从本地计算机或其所在的任意位置移到 VM 中:Then, you can move it from your local machine, or wherever the script is, into the VM using:

scp /path/to/script_file username@vm-ip-address:/home/{username}

将脚本移到 VM 后,可以通过 SSH 连接到 VM,并通过以下命令执行该脚本:Once your script is in your VM, you can ssh into the VM and execute it via the command:

sudo ./nfs-server-setup.sh

如果脚本由于权限被拒绝错误而执行失败,请通过以下命令设置执行权限:If its execution fails because of a permission denied error, set execution permission via the command:

chmod +x ~/nfs-server-setup.sh

将 AKS 群集连接到 NFS 服务器Connecting AKS Cluster to NFS Server

可以通过预配一个持久性卷,以及一个指定如何访问该卷的持久性卷声明,将 NFS 服务器连接到群集。We can connect the NFS Server to our cluster by provisioning a persistent volume and persistent volume claim that specifies how to access the volume.

必须连接相同或对等互连的虚拟网络中的两个服务。Connecting the two services in the same or peered virtual networks is necessary. 下面提供了有关在同一 VNET 中设置群集的说明:在现有 VNET 中创建 AKS 群集Instructions for setting up the cluster in the same VNET are here: Creating AKS Cluster in existing VNET

将这些服务放入同一虚拟网络(或对等互连的虚拟网络)后,需要在 AKS 群集中预配持久性卷和持久性卷声明。Once they are in the same virtual network (or peered), you need to provision a persistent volume and a persistent volume claim in your AKS Cluster. 然后,容器可将 NFS 驱动器装载到其本地目录。The containers can then mount the NFS drive to their local directory.

下面是持久性卷的示例 Kubernetes 定义(此定义假设群集和 VM 位于同一 VNET 中):Here is an example Kubernetes definition for the persistent volume (This definition assumes your cluster and VM are in the same VNET):

apiVersion: v1
kind: PersistentVolume
metadata:
  name: <NFS_NAME>
  labels:
    type: nfs
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: <NFS_INTERNAL_IP>
    path: <NFS_EXPORT_FILE_PATH>

请将 NFS_INTERNAL_IPNFS_NAMENFS_EXPORT_FILE_PATH 替换为 NFS 服务器信息。Replace NFS_INTERNAL_IP, NFS_NAME and NFS_EXPORT_FILE_PATH with NFS Server information.

还需要一个持久性卷声明文件。You'll also need a persistent volume claim file. 下面是该文件的内容示例:Here is an example of what to include:

重要

"storageClassName" 需保留为空字符串,否则声明不起作用。"storageClassName" needs to remain an empty string or the claim won't work.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: <NFS_NAME>
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 1Gi
  selector: 
    matchLabels:
      type: nfs

故障排除Troubleshooting

如果无法从群集连接到服务器,问题的原因可能是导出的目录或其父级没有足够的权限,因此无法访问服务器。If you can't connect to the server from a cluster, an issue might be the exported directory, or its parent, doesn't have sufficient permissions to access the server.

请检查导出的目录及其父目录是否具有 777 权限。Check that both your export directory and its parent directory have 777 permissions.

可运行以下命令来检查权限,目录应有 'drwxrwxrwx' 权限:You can check permissions by running the command below and the directories should have 'drwxrwxrwx' permissions:

ls -l

详细信息More information

如需完整的演练,或者在调试 NFS 服务器设置时需要帮助,请查看以下深度教程:To get a full walkthrough or to help you debug your NFS Server setup, here is an in-depth tutorial:

后续步骤Next steps

如需相关的最佳做法,请参阅 AKS 中的存储和备份最佳做法For associated best practices, see Best practices for storage and backups in AKS.