Dateien zwischen Anwendungsservern mit EFS teilen

AWSBeginner
Jetzt üben

Einführung

Eine Upload-Anwendung läuft auf zwei Servern. Beide speichern Dateien auf ihrer eigenen lokalen Festplatte. Ein Upload kann deshalb auf einem Server gelingen und auf dem anderen „nicht gefunden“ liefern. Gib beiden Servern mit Amazon Elastic File System (EFS) eine gemeinsame Dateischnittstelle.

Absolviere zuerst AWS VPC for Beginners und AWS EC2 and EBS for Beginners. Diese unabhängige Umgebung stellt die Anwendung, drei Hosts und ihr Netzwerk bereit. Verwende Terminal für AWS CLI und SSH und AWS View für echte Upload-Antworten. Die CLI ist eingerichtet; ein persönliches AWS-Konto oder Ressourcen aus früheren Übungen sind nicht erforderlich. Hier werden Dateifreigabe und Verbindungen untersucht, keine Produktionsleistung oder Verfügbarkeit.

Bezug zu Zertifizierungen

Zertifizierung Prüfungsaufgabe Praxis
Cloud Practitioner (CLF-C02) Task 3.6 EFS als gemeinsamen Dateidienst erkennen und eine gemountete Dateischnittstelle von getrennten lokalen Upload-Verzeichnissen unterscheiden.

Übersicht

Konzeptdarstellung; die tatsächlichen IDs stehen in deiner frischen Umgebung.

Speicher für die Upload-Anwendung erstellen

In diesem Schritt beobachtest du das lokale Upload-Problem und erstellst dein gemeinsames Dateisystem.

Arbeite in /home/labex/project. Prüfe die konfigurierte Identität, ohne Zugangsdaten auszugeben:

cd /home/labex/project
aws sts \
  get-caller-identity

Die Benutzer-ARN endet auf labex-fs01-operator. resources.json enthält das vorbereitete Subnetz und die Anwendungs-Sicherheitsgruppe. Lade die IDs, damit weitere Befehle die tatsächlichen Ressourcen verwenden:

SUBNET_ID=$(jq -r .subnet_id resources.json)
APP_GROUP_ID=$(jq -r .application_group_id resources.json)
VPC_ID=$(jq -r .vpc_id resources.json)
echo "$SUBNET_ID"
echo "$APP_GROUP_ID"
echo "$VPC_ID"
aws ec2 \
  describe-instances \
  --filters Name=tag:Name,Values=application-a,application-b \
  --query 'Reservations[].Instances[].{Name:Tags[?Key==`Name`].Value|[0],IP:PrivateIpAddress,State:State.Name}'

Beobachte zunächst das lokale Speicherproblem. HTTP PUT speichert einen Upload, HTTP GET liest eine Datei. Diese Adressen erreichen die vorbereiteten Anwendungsserver:

curl -i -X PUT --data-binary 'A local upload' \
  http://127.0.0.1:8081/uploads/local-example.txt
curl -i http://127.0.0.1:8082/uploads/local-example.txt

A antwortet mit 201 Created, B mit 404 Not Found: Sein lokales Verzeichnis enthält andere Dateien. Du kannst denselben Dateinamen auch über die beiden Karten in AWS View schreiben und lesen.

EFS bietet ein gemeinsames Dateisystem. Beide Anwendungen greifen mit NFS, dem Network File System-Protokoll, auf dieselben Dateien und Verzeichnisse zu. Erstelle zuerst das Dateisystem. Das Erstellungstoken identifiziert die Anfrage; das Name-Tag erleichtert Prüfung und Bereinigung. --encrypted aktiviert die Einstellung für Verschlüsselung ruhender Daten. Transportverschlüsselung wird beim Mounten eingerichtet.

FS_ID=$(aws efs \
  create-file-system \
  --creation-token fs01-shared-uploads \
  --encrypted \
  --tags Key=Name,Value=fs01-shared-uploads \
  --query FileSystemId --output text)
echo "$FS_ID"
aws efs \
  describe-file-systems \
  --file-system-id "$FS_ID" \
  --query 'FileSystems[].{ID:FileSystemId,State:LifeCycleState,Encrypted:Encrypted}'

Warte auf available. Die Diensteressource existiert, aber die Anwendungen benötigen noch ein erreichbares Mount Target und einen echten Mount.

Dateisystem mit dem Anwendungssubnetz verbinden

In diesem Schritt stellst du einen erreichbaren NFS-Endpunkt bereit und beschränkst ihn auf die Anwendungsserver.

Ein Mount Target stellt den Netzwerkendpunkt des Dateisystems in einem Subnetz bereit. NFS verwendet TCP 2049. Erstelle eine eigene Speicher-Sicherheitsgruppe und erlaube diesen Port aus der vorbereiteten Anwendungsgruppe. Die Quellgruppenregel erfasst beide Server, ohne NFS für alle Adressen zu öffnen. Der unabhängige Referenzserver gehört zu einer anderen Gruppe und bleibt ausgeschlossen.

EFS_GROUP_ID=$(aws ec2 \
  create-security-group \
  --group-name fs01-efs-access \
  --description 'NFS from the upload application servers' \
  --vpc-id "$VPC_ID" \
  --query GroupId --output text)
echo "$EFS_GROUP_ID"
aws ec2 \
  authorize-security-group-ingress \
  --group-id "$EFS_GROUP_ID" \
  --ip-permissions "IpProtocol=tcp,FromPort=2049,ToPort=2049,UserIdGroupPairs=[{GroupId=$APP_GROUP_ID}]"

Erstelle das Mount Target im vorbereiteten Subnetz und ordne die neue Gruppe zu:

MOUNT_TARGET_ID=$(aws efs \
  create-mount-target \
  --file-system-id "$FS_ID" \
  --subnet-id "$SUBNET_ID" \
  --security-groups "$EFS_GROUP_ID" \
  --query MountTargetId --output text)
echo "$MOUNT_TARGET_ID"
aws efs \
  describe-mount-targets \
  --file-system-id "$FS_ID" \
  --query 'MountTargets[].{ID:MountTargetId,IP:IpAddress,State:LifeCycleState,AZ:AvailabilityZoneName}'
aws efs \
  describe-mount-target-security-groups \
  --mount-target-id "$MOUNT_TARGET_ID"

Warte auf available. Beide Anwendungen liegen in einer Availability Zone; diese Topologie benötigt deshalb nur ein Mount Target. Plane in einer Produktionsregion Mount Targets für die Availability Zones der Clients.

Beide Anwendungen mounten und gemeinsame Dateien prüfen

In diesem Schritt verbindest du beide Anwendungen mit EFS und testest Uploads in beide Richtungen.

Die bereitgestellte ssh_config verbindet dich mit jedem Host. Ein Mountpunkt ist das lokale Verzeichnis für den Zugriff auf ein entferntes Dateisystem. Erstelle auf beiden Hosts /srv/shared und mounte dort die EFS-Wurzel:

ssh -F ssh_config application-a \
  "sudo mkdir -p /srv/shared && sudo mount -t efs -o tls,stunnel,lookupcache=positive ${FS_ID}:/ /srv/shared"
ssh -F ssh_config application-b \
  "sudo mkdir -p /srv/shared && sudo mount -t efs -o tls,stunnel,lookupcache=positive ${FS_ID}:/ /srv/shared"

lookupcache=positive fragt zuvor fehlende Dateinamen erneut beim Server ab, wenn eine andere Anwendung eine neue Datei erstellt. Dadurch werden neue Uploads während dieser kurzen Übung sichtbar. Cacheänderungen für Produktionslasten erfordern eine separate Leistungsbewertung. Siehe Linux-NFS-Optionen für den Verzeichniscache.

-t efs wählt den offiziellen Mount-Helfer. tls verschlüsselt die Verbindung; stunnel wählt seinen unterstützten TLS-Transport. ${FS_ID}:/ bezeichnet die Dateisystemwurzel. Die erforderlichen Client-Werkzeuge sind bereits vorhanden.

Anfangs gehört das neue Verzeichnis root. Bereite ein Upload-Unterverzeichnis für den Anwendungsbenutzer labex vor und richte beide Anwendungen darauf aus:

ssh -F ssh_config application-a \
  'sudo mkdir -p /srv/shared/uploads && sudo chown labex:labex /srv/shared/uploads'
ssh -F ssh_config application-a \
  'printf "{\"upload_directory\":\"/srv/shared/uploads\"}\n" | sudo tee /etc/uploads-app/config.json'
ssh -F ssh_config application-b \
  'printf "{\"upload_directory\":\"/srv/shared/uploads\"}\n" | sudo tee /etc/uploads-app/config.json'

Die Anwendung liest die Konfiguration bei jeder Anfrage; ein Neustart ist nicht nötig. Prüfe die tatsächlichen Mounts:

ssh -F ssh_config application-a 'findmnt -t nfs4 /srv/shared'
ssh -F ssh_config application-b 'findmnt -t nfs4 /srv/shared'

Beide Hosts zeigen NFS 4 unter /srv/shared. Bei TLS kann der Kernel als Quelle 127.0.0.1:/ anzeigen, weil der Helfer NFS durch einen lokalen verschlüsselten Tunnel überträgt.

Lade jetzt über A hoch und lies über B:

curl -i -X PUT --data-binary 'Shared upload version 1' \
  http://127.0.0.1:8081/uploads/shared.txt
curl -i http://127.0.0.1:8082/uploads/shared.txt

B liefert 200 OK und Shared upload version 1. Aktualisiere über B und lies über A, um die Gegenrichtung zu prüfen:

curl -i -X PUT --data-binary 'Shared upload version 2' \
  http://127.0.0.1:8082/uploads/shared.txt
curl -i http://127.0.0.1:8081/uploads/shared.txt
ssh -F ssh_config application-a 'stat -c "%i %u:%g" /srv/shared/uploads/shared.txt'
ssh -F ssh_config application-b 'stat -c "%i %u:%g" /srv/shared/uploads/shared.txt'

Beide Anwendungen lesen Version 2, und die stat-Befehle zeigen dieselbe inode. Unabhängige EFS-Mounts greifen auf dieselbe Datei zu; lokale Verzeichnisse werden nicht kopiert oder synchronisiert. Vergleiche den Upload auch in AWS View.

Gemeinsame Uploads in AWS View

Beide Anwendungen lesen denselben aktualisierten Upload. IDs unterscheiden sich je frischer Umgebung.

Aushängen und eigenen Speicher löschen

In diesem Schritt beendest du die Nutzung des gemeinsamen Verzeichnisses und löschst nur deinen Speicher.

Stelle vor dem Löschen des Netzwerkendpunkts beide Anwendungen auf das bereitgestellte lokale Verzeichnis zurück und hänge EFS aus:

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'

Meldet umount ein belegtes Verzeichnis, verlasse Shells, die /srv/shared verwenden, und versuche es erneut. Prüfe, dass die Mounts verschwunden sind:

ssh -F ssh_config application-a 'findmnt -t nfs4'
ssh -F ssh_config application-b 'findmnt -t nfs4'

Es sollen keine NFS-Mounts verbleiben. Ohne Treffer liefert findmnt Status 1; das ist hier erwartet.

Lösche zuerst das Mount Target, dann das Dateisystem und zuletzt ausschließlich deine eigene Speicher-Sicherheitsgruppe:

aws efs \
  delete-mount-target --mount-target-id "$MOUNT_TARGET_ID"
aws efs \
  describe-mount-targets --file-system-id "$FS_ID"

Warte auf eine leere MountTargets-Liste, bevor du fortfährst:

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==`fs01-shared-uploads`].FileSystemId'
aws ec2 \
  describe-security-groups \
  --filters Name=group-name,Values=fs01-efs-access \
  --query 'SecurityGroups[].GroupId'

Beide Abfragen liefern leere Listen. Nur erfolgreiche autorisierte Abfragen belegen das Löschen; Netzwerk- oder Berechtigungsfehler tun das nicht. Behalte die vorbereiteten Server, ihre Gruppen und das Subnetz.

Führe die Prüfung aus, um das Löschen und den Erhalt der vorbereiteten Ressourcen zu bestätigen. Jede folgende Übung startet mit ihrer eigenen unabhängigen Umgebung.

Zusammenfassung

Du hast zwei Anwendungen über ein Mount Target, eingeschränkten NFS-Zugriff und TLS-Mounts mit demselben EFS-Dateisystem verbunden. Gegenseitige Uploads und dieselbe Dateiidentität belegten echtes Teilen. Anschließend hast du lokale Verzeichnisse wiederhergestellt, Clients ausgehängt und eigene Ressourcen in Abhängigkeitsreihenfolge gelöscht.

Ein gemeinsames Dateisystem trennt Anwendungsverzeichnisse und POSIX-Identitäten nicht automatisch. Die nächste Übung verwendet dafür EFS-Zugriffspunkte.

Weitere Informationen bietet die AWS-Dokumentation: EFS-Mount-Helfer und TLS-Transport; Netzwerkregeln für Clients und Mount-Ziele.