EFS 마운트 연결 복구하기

AWSBeginner
지금 연습하기

소개

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에는 없으며 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"

새 연결은 성공합니다. NFS를 0.0.0.0/0에 개방하거나 파일 시스템을 바꾸지 않고 네트워크를 복구했습니다.

B의 액세스 포인트 마운트 복구하기

이 단계에서는 A의 데이터를 바꾸지 않고 B를 기존 공유 디렉터리에 연결합니다.

마운트 전에 준비된 포인트를 조회합니다.

aws efs \
  describe-access-points \
  --access-point-id "$AP_ID" \
  --query 'AccessPoints[].{ID:AccessPointId,Root:RootDirectory.Path,User:PosixUser}'

루트는 /uploads이고 숫자 신원은 준비된 애플리케이션 사용자입니다. 같은 업로드를 공유하려면 양쪽이 같은 포인트를 선택해야 합니다. 새 파일 시스템을 만들거나 A 파일을 B의 로컬 디스크로 복사하지 마세요.

공식 도우미와 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"

연결은 0이 아닌 종료 상태로 실패해야 합니다. 이는 의도된 접근 경계이며 다른 애플리케이션 장애가 아닙니다. 참조 서버의 독립된 업로드가 유지되는지 확인합니다.

curl -i http://127.0.0.1:8083/uploads/reference.txt

200 OK와 Unrelated reference upload remains unchanged를 반환합니다. 복구된 애플리케이션과 참조 서비스는 다른 네트워크 범위를 유지합니다.

AWS View의 복구된 업로드

양쪽이 같은 새 공유 업로드를 읽습니다. 식별자는 환경마다 다릅니다.

저장소 해제하기

이 단계에서는 복구 테스트 후 임시 저장소를 삭제하고 준비된 호스트와 네트워크를 보존합니다.

두 애플리케이션을 로컬 디렉터리로 복원하고 마운트를 해제합니다.

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'

저장소 목록이 비어 있어야 합니다. 서버, 원래 그룹, 서브넷과 참조 업로드를 유지합니다. 권한 있는 조회가 가능한 동안 정리 검사를 실행하세요.

요약

리소스 가용성, TCP 도달성, 마운트 선택과 파일 권한을 나눠 진단했습니다. 애플리케이션 그룹으로 규칙을 복구하고 B의 원본 접근과 새 공유 업로드를 확인하며 참조 클라이언트를 제외했습니다. 마지막으로 종속성 순서로 저장소를 삭제했습니다.

자세한 내용은 AWS 공식 문서를 참고하세요: 클라이언트 및 마운트 대상 네트워크 규칙; 마운트 시간 초과 및 액세스 실패 진단.