介绍
应用 A 可以读取共享上传内容,但应用 B 无法连接同一 EFS 存储。诊断连接失败,恢复 B 的挂载,并将访问保持在预期应用服务器范围内。
请先完成前两个 EFS 引导实验。本新环境提供故障所需的已有文件系统、访问点、原始上传和应用主机。使用配置好的 AWS CLI、SSH 连接和 AWS View,无需之前 VM 的资源或个人 AWS 账号。
认证关联
| 认证 | 考纲任务 | 实践 |
|---|---|---|
| Cloud Practitioner (CLF-C02) | Task 3.5;Task 3.6 | 将文件服务连接与 VPC 安全组访问关联,区分网络可达性和存储资源可用状态。 |

概念示意图;实际标识符以你的新环境为准。
诊断并修复 NFS 网络规则
本步骤定位连接失败的层次,修复存储安全组。
在 /home/labex/project 中操作。resources.json 记录本实验的存储和应用标识符:
cd /home/labex/project
aws sts \
get-caller-identity
FS_ID=$(jq -r .fault.filesystem_id resources.json)
MOUNT_TARGET_ID=$(jq -r .fault.mount_target_id resources.json)
AP_ID=$(jq -r .fault.access_point_id resources.json)
EFS_GROUP_ID=$(jq -r .fault.storage_group_id resources.json)
APP_GROUP_ID=$(jq -r .application_group_id resources.json)
APP_A_IP=$(jq -r '.clients["application-a"].ip' resources.json)
echo "$FS_ID"
echo "$MOUNT_TARGET_ID"
echo "$AP_ID"
echo "$EFS_GROUP_ID"
echo "$APP_GROUP_ID"
echo "$APP_A_IP"
通过两个应用读取已有上传:
curl -i http://127.0.0.1:8081/uploads/original-upload.txt
curl -i http://127.0.0.1:8082/uploads/original-upload.txt
A 返回 200 OK 和 Original upload from application A,B 返回 404 Not Found。查看挂载:
ssh -F ssh_config application-a 'findmnt -t nfs4 /srv/shared'
ssh -F ssh_config application-b 'findmnt -t nfs4 /srv/shared'
A 有 NFS 挂载,B 没有,B 的 findmnt 返回状态 1。更改路径或权限前,先确认 B 能否连接网络端点:
MOUNT_IP=$(aws efs \
describe-mount-targets \
--mount-target-id "$MOUNT_TARGET_ID" \
--query 'MountTargets[0].IpAddress' --output text)
echo "$MOUNT_IP"
ssh -F ssh_config application-b "nc -zvw2 $MOUNT_IP 2049"
连接失败。nc 在不创建挂载的情况下测试 TCP 可达性。错误的访问点路径或 POSIX 身份可能阻止已建立连接后的文件访问,但不能解释这次 TCP 测试失败。
确认挂载目标可用,并查看绑定的安全组:
aws efs \
describe-mount-targets \
--mount-target-id "$MOUNT_TARGET_ID" \
--query 'MountTargets[].{ID:MountTargetId,State:LifeCycleState,Subnet:SubnetId}'
aws efs \
describe-mount-target-security-groups \
--mount-target-id "$MOUNT_TARGET_ID"
aws ec2 \
describe-security-groups \
--group-ids "$EFS_GROUP_ID" \
--query 'SecurityGroups[].IpPermissions'
NFS 入站规则用 /32 CIDR,仅允许 A 的私有地址访问 TCP 2049,排除了 B。用提供的应用安全组规则替换该地址规则:
aws ec2 \
revoke-security-group-ingress \
--group-id "$EFS_GROUP_ID" \
--protocol tcp \
--port 2049 \
--cidr "$APP_A_IP/32"
允许应用组的两个成员:
aws ec2 \
authorize-security-group-ingress \
--group-id "$EFS_GROUP_ID" \
--ip-permissions "IpProtocol=tcp,FromPort=2049,ToPort=2049,UserIdGroupPairs=[{GroupId=$APP_GROUP_ID}]"
ssh -F ssh_config application-b "nc -zvw2 $MOUNT_IP 2049"
新连接成功。你修复了网络层,没有向 0.0.0.0/0 开放 NFS,也没有替换文件系统。
恢复 B 的访问点挂载
本步骤将应用 B 连接到已有共享上传目录,不替换 A 的数据。
挂载前查看提供的访问点:
aws efs \
describe-access-points \
--access-point-id "$AP_ID" \
--query 'AccessPoints[].{ID:AccessPointId,Root:RootDirectory.Path,User:PosixUser}'
根目录是 /uploads,数字身份对应准备好的应用用户。两个应用需要相同上传内容,因此应选择同一访问点。不要创建新文件系统,也不要将 A 的文件复制到 B 的本地磁盘。
使用官方 EFS 助手和 TLS 在 B 上挂载:
ssh -F ssh_config application-b \
"sudo mkdir -p /srv/shared && sudo mount -t efs -o tls,stunnel,lookupcache=positive,accesspoint=${AP_ID} ${FS_ID}:/ /srv/shared"
ssh -F ssh_config application-b 'findmnt -t nfs4 /srv/shared'
挂载使用 lookupcache=positive:当另一台应用创建之前不存在的文件时,再次向服务器查询该文件名,让短时间内的上传结果可见。生产工作负载的缓存调整还需要单独评估性能。参见 Linux NFS 目录缓存选项。
B 现在在 /srv/shared 显示 NFS 4 挂载。应用已配置为使用该目录,因此下一次请求直接读取 EFS:
curl -i http://127.0.0.1:8082/uploads/original-upload.txt
ssh -F ssh_config application-a 'stat -c "%i %u:%g" /srv/shared/original-upload.txt'
ssh -F ssh_config application-b 'stat -c "%i %u:%g" /srv/shared/original-upload.txt'
B 返回原始内容,两个主机报告相同 inode 和所有者。修复恢复了对已有文件的访问,而不是另建副本。
验证新上传和访问边界
本步骤证明 B 可写入共享文件,无关客户端仍被排除。
通过 B 上传新文件,再通过 A 读取:
curl -i -X PUT --data-binary 'Shared upload after connection repair' \
http://127.0.0.1:8082/uploads/shared.txt
curl -i http://127.0.0.1:8081/uploads/shared.txt
B 返回 201 Created,A 返回 200 OK 和相同内容。在 AWS View 使用文件名 shared.txt,从两个应用卡片读取。
参考服务器属于不同安全组。确认它无法建立新的 NFS 连接:
ssh -F ssh_config reference-c "nc -zvw2 $MOUNT_IP 2049"
连接应失败并返回非零状态。这是预期的访问边界,不是另一个应用故障。确认参考服务器的无关上传仍然可用:
curl -i http://127.0.0.1:8083/uploads/reference.txt
响应是 200 OK 和 Unrelated reference upload remains unchanged。修复后的应用与参考服务仍有不同的网络访问范围。

连接修复后,两台应用读取同一份新上传内容。标识符以每次新环境为准。
释放实验存储
本步骤在测试修复后删除临时存储,保留准备好的应用和网络资源。
将两个上传应用恢复为本地目录,并卸载共享存储:
ssh -F ssh_config application-a \
'printf "{\"upload_directory\":\"/srv/uploads\"}\n" | sudo tee /etc/uploads-app/config.json'
ssh -F ssh_config application-b \
'printf "{\"upload_directory\":\"/srv/uploads\"}\n" | sudo tee /etc/uploads-app/config.json'
ssh -F ssh_config application-a 'sudo umount /srv/shared'
ssh -F ssh_config application-b 'sudo umount /srv/shared'
存储标识符来自 resources.json,只删除这些确切资源。先删除访问点和挂载目标:
aws efs \
delete-access-point \
--access-point-id "$AP_ID"
aws efs \
delete-mount-target \
--mount-target-id "$MOUNT_TARGET_ID"
aws efs \
describe-mount-targets \
--file-system-id "$FS_ID"
等待 MountTargets 为空,再删除文件系统和存储安全组:
aws efs \
delete-file-system \
--file-system-id "$FS_ID"
aws ec2 \
delete-security-group \
--group-id "$EFS_GROUP_ID"
通过成功的响应确认列表为空:
aws efs \
describe-file-systems \
--query 'FileSystems[?Name==`fs03-shared-uploads`].FileSystemId'
aws ec2 \
describe-security-groups \
--filters Name=group-name,Values=fs03-efs-access \
--query 'SecurityGroups[].GroupId'
存储列表应为空。保留应用服务器、原有安全组、子网和参考上传内容。在环境仍可进行授权读取时运行清理检查。
总结
你在诊断 EFS 连接时区分了资源可用性、TCP 可达性、挂载选择和文件权限。使用应用安全组修复受限规则,恢复 B 对原始文件的访问,测试跨服务器的新上传,并继续排除参考客户端。最后按依赖顺序删除实验存储。
进一步阅读 AWS 官方资料:客户端与挂载目标网络规则; 诊断挂载超时与访问失败。



