Separar diretórios de aplicações com pontos de acesso

AWSBeginner
Pratique Agora

Introdução

Duas aplicações precisam de armazenamento compartilhado, mas cada uma deve trabalhar em seu próprio diretório. Configure pontos de acesso EFS com uma raiz e uma identidade POSIX para cada montagem e observe os arquivos e proprietários reais.

Conclua primeiro Compartilhar arquivos entre servidores de aplicações com EFS. Esta VM independente fornece novos hosts e uma sub-rede, sem reutilizar o sistema anterior. Use Terminal para AWS CLI e SSH e AWS View para comparar respostas. Não é necessária uma conta AWS pessoal.

Relação com certificações

Certificação Tarefa do exame Prática
Cloud Practitioner (CLF-C02) Task 3.6 Explorar EFS e comparar diretórios e permissões de arquivos com armazenamento de objetos.

Visão geral

Diagrama conceitual; confira os identificadores no novo ambiente.

Preparar um sistema compartilhado e uma conexão NFS

Nesta etapa, crie o armazenamento e o ponto de conexão restrito das aplicações.

Trabalhe em /home/labex/project e identifique a rede preparada. AWS CLI já está configurada:

cd /home/labex/project
aws sts \
  get-caller-identity
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"

Crie um novo EFS. As aplicações usarão o mesmo recurso; os pontos de acesso selecionarão diretórios distintos:

FS_ID=$(aws efs \
  create-file-system \
  --creation-token fs02-application-files \
  --encrypted \
  --tags Key=Name,Value=fs02-application-files \
  --query FileSystemId --output text)
echo "$FS_ID"

Crie um grupo de armazenamento dedicado:

EFS_GROUP_ID=$(aws ec2 \
  create-security-group \
  --group-name fs02-efs-access \
  --description 'NFS for the upload application servers' \
  --vpc-id "$VPC_ID" \
  --query GroupId --output text)
echo "$EFS_GROUP_ID"

Permita TCP 2049 a partir do grupo das aplicações. A regra permite conexões NFS, mas não escolhe diretório ou identidade de usuário:

aws ec2 \
  authorize-security-group-ingress \
  --group-id "$EFS_GROUP_ID" \
  --ip-permissions "IpProtocol=tcp,FromPort=2049,ToPort=2049,UserIdGroupPairs=[{GroupId=$APP_GROUP_ID}]"

Crie o destino na sub-rede preparada:

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"

Inspecione os estados e espere ambos os recursos ficarem available:

aws efs \
  describe-file-systems \
  --file-system-id "$FS_ID" \
  --query 'FileSystems[].{ID:FileSystemId,State:LifeCycleState}'
aws efs \
  describe-mount-targets \
  --file-system-id "$FS_ID" \
  --query 'MountTargets[].{ID:MountTargetId,IP:IpAddress,State:LifeCycleState}'

Criar pontos de acesso específicos para aplicações

Nesta etapa, defina a raiz e a identidade das operações de cada montagem.

Um ponto de acesso é uma entrada EFS específica para a aplicação. Sua raiz se torna / dentro da montagem e seu usuário POSIX substitui a identidade das operações do cliente. POSIX usa UID numérico para usuários e GID para grupos.

Crie o ponto de A:

AP_A_ID=$(aws efs \
  create-access-point \
  --file-system-id "$FS_ID" \
  --posix-user Uid=2001,Gid=2001 \
  --root-directory 'Path=/app-a,CreationInfo={OwnerUid=2001,OwnerGid=2001,Permissions=700}' \
  --tags Key=Name,Value=fs02-app-a \
  --query AccessPointId --output text)
echo "$AP_A_ID"

Se /app-a não existir, CreationInfo fornece proprietário e permissões. 700 dá ao proprietário leitura, escrita e travessia do diretório sem conceder isso aos outros usuários. O UID/GID do ponto corresponde ao proprietário.

Crie outro ponto com raiz e identidade diferentes:

AP_B_ID=$(aws efs \
  create-access-point \
  --file-system-id "$FS_ID" \
  --posix-user Uid=2002,Gid=2002 \
  --root-directory 'Path=/app-b,CreationInfo={OwnerUid=2002,OwnerGid=2002,Permissions=700}' \
  --tags Key=Name,Value=fs02-app-b \
  --query AccessPointId --output text)
echo "$AP_B_ID"

Inspecione as duas definições:

aws efs \
  describe-access-points \
  --file-system-id "$FS_ID" \
  --query 'AccessPoints[].{ID:AccessPointId,Root:RootDirectory.Path,User:PosixUser,Creation:RootDirectory.CreationInfo}'

As raízes são /app-a e /app-b, com identidades 2001:2001 e 2002:2002. A próxima etapa testa o comportamento real; a configuração sozinha não comprova o limite.

O ponto limita raiz e identidade da montagem que o seleciona. Sozinho, não impede um cliente autorizado de escolher outro ponto. Em produção, IAM e políticas do sistema podem restringir os pontos permitidos. Aqui o foco é diretórios e comportamento POSIX.

Observar diretórios separados e propriedade imposta

Nesta etapa, monte os pontos e prove que nomes iguais representam arquivos diferentes.

Monte o ponto de A em A. Montagens com ponto de acesso exigem TLS:

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

lookupcache=positive consulta novamente nomes antes ausentes quando outra aplicação cria um arquivo. Isso mantém o exercício curto observável; ajustes de cache em produção precisam de avaliação de desempenho separada. Veja as opções de cache NFS do Linux.

Monte o ponto de B em B:

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

Ambos usam /srv/shared, mas em A ele representa /app-a e em B /app-b. Configure cada aplicação para usar diretamente a raiz de seu ponto:

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

Escreva private.txt por A e tente ler por B:

curl -i -X PUT --data-binary 'Private upload for application A' \
  http://127.0.0.1:8081/uploads/private.txt
curl -i http://127.0.0.1:8082/uploads/private.txt

A retorna 201 Created e B 404 Not Found. Agora crie o arquivo próprio de B com o mesmo nome:

curl -i -X PUT --data-binary 'Private upload for application B' \
  http://127.0.0.1:8082/uploads/private.txt
curl -i http://127.0.0.1:8081/uploads/private.txt
curl -i http://127.0.0.1:8082/uploads/private.txt

A continua retornando seu conteúdo e B retorna o seu. Use private.txt e Read upload nos dois cartões AWS View.

Inspecione as montagens e identidades reais:

ssh -F ssh_config application-a 'findmnt -t nfs4 /srv/shared; stat -c "%i %u:%g" /srv/shared/private.txt'
ssh -F ssh_config application-b 'findmnt -t nfs4 /srv/shared; stat -c "%i %u:%g" /srv/shared/private.txt'

Os inodes são diferentes e os proprietários são 2001:2001 e 2002:2002. A aplicação executa como labex, mas o servidor aplica a identidade do ponto.

Mesmo uma escrita de root pela montagem de A usa a identidade selecionada:

ssh -F ssh_config application-a \
  'printf "Access-point identity also applies to root callers\n" | sudo tee /srv/shared/root-caller.txt; stat -c "%u:%g" /srv/shared/root-caller.txt'

O proprietário é 2001:2001. EFS aplica identidades numéricas sem precisar de contas locais chamadas 2001 e 2002.

A montagem de A expõe /app-a, não a raiz EFS inteira. O diretório irmão de B não é um subdiretório dessa montagem:

ssh -F ssh_config application-a 'ls -a /srv/shared'
ssh -F ssh_config application-a 'cat /srv/shared/app-b/private.txt'

O último comando retorna No such file or directory, embora o arquivo de B exista e possa ser lido por sua aplicação. As raízes independentes e os conteúdos diferentes demonstram separação. .. no ponto local leva ao diretório pai local, não ao diretório irmão EFS.

Diretórios separados em AWS View

O mesmo nome possui conteúdos diferentes em duas raízes. Os identificadores variam entre ambientes.

Remover pontos de acesso e armazenamento

Nesta etapa, libere as montagens e exclua somente seu armazenamento.

Restaure os diretórios locais antes de desmontar:

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'

Exclua os dois pontos e confirme que nenhum permanece:

aws efs \
  delete-access-point \
  --access-point-id "$AP_A_ID"
aws efs \
  delete-access-point \
  --access-point-id "$AP_B_ID"
aws efs \
  describe-access-points \
  --file-system-id "$FS_ID"

AccessPoints deve ficar vazio. Excluir um ponto remove sua definição, não os arquivos do diretório. Agora você removerá todo o sistema descartável e seus dados:

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

Espere MountTargets ficar vazio antes de continuar:

aws efs \
  delete-file-system \
  --file-system-id "$FS_ID"
aws ec2 \
  delete-security-group \
  --group-id "$EFS_GROUP_ID"

Confirme respostas bem-sucedidas e vazias para seus recursos nomeados:

aws efs \
  describe-file-systems \
  --query 'FileSystems[?Name==`fs02-application-files`].FileSystemId'
aws ec2 \
  describe-security-groups \
  --filters Name=group-name,Values=fs02-efs-access \
  --query 'SecurityGroups[].GroupId'

As duas listas são vazias. Preserve os servidores, grupos e sub-rede preparados e execute a verificação.

Resumo

Dois pontos de acesso selecionaram raízes e identidades POSIX distintas no mesmo EFS. Nomes iguais continham dados diferentes e o servidor impôs a propriedade inclusive a clientes root. Depois você desmontou e removeu os pontos, o destino e o sistema descartável.

Acessibilidade da rede, seleção da montagem e permissões são camadas diferentes. O próximo exercício usa essas camadas para diagnosticar uma conexão EFS.

Para aprofundar o tema, consulte a documentação da AWS: Raízes, identidades e escopo de autorização dos pontos de acesso.