Como montar um bucket Amazon S3 como filesystem local

January 28th, 2014

Category: Administracao e Suporte, Cloud, Unix

Tagged with: , , , ,

amazon-s3O Amazon Simple Storage Service, cujas iniciais dão origem à sigla S3, é um serviço de armazenamento em nuvem da Amazon Web Services – AWS – que oferece redundância e flexibilidade.
Mas talvez as características mais interessantes para nós, micro empresas e free-lancers, sejam o pay-as-you-go e a escalabilidade praticamente ilimitada. Pay-as-you-go significa que você paga pela área ocupada apenas. Como S3 não é aluguel de discos ou volumes, você não é obrigado a contratar mais espaço do que precisa. Em um volume tradicional, obviamente você sempre precisa ter uma área de folga para evitar problemas resultantes de disk full. O S3 é um grande pool de armazenamento, no qual você paga por GB ocupado, resultando em um baixo custo quando comparado a VPS tradicionais.

A escalabilidade ilimitada advém da mesma origem. Como nessa solução não tem sentido falar em volumes, também não tem sentido falar em área disponível. Você não tem as informações de área livre versus ocupada, que está acostumado a procurar nos seus filesystems locais. Tem apenas a área ocupada. Não há limite teórico, pois novos recursos entram e saem da nuvem o tempo todo, fazendo a área real flutuar de acordo com os recursos de gerenciamento em nuvem. A você isso não importa, apenas vai colocando arquivos (na verdade o termo usado é objeto), e pagando por eles. Em tempo, os dados são gravados com redundância e podem ser criptografados.
Aqui veremos como acessar dados no Amazon S3 como se fosse um filesystem tradicional, no qual podemos executar comandos linux ou abrir esses arquivos com aplicativos usuais, como o vi. Isso pode salvar várias horas de trabalho, dado que normalmente o acesso e envio de arquivos para o S3 é feito através do uso de API próprias, o que pode tornar complexa uma solução para um problema simples.
Vamos usar uma solução baseada no FUSE, chamada S3FS. Veja aqui o projeto oficial: S3FS-FUSE.
Assume-se que você já tem alguma experiência com os serviços da Amazon Web Services, principalmente o EC2 e S3 e, claro, tem uma conta e uma instância disponível para executar o lab, com o ubuntu instalado. Outras distribuições podem exigir pequenas adaptações.

Instalação

Você deve primeiro instalar os seguintes pacotes, que são pré-requisito para o S3FS:

  • sudo apt-get install linux-source;
  • sudo apt-get install build-essential
  • sudo apt-get install libfuse-dev
  • sudo apt-get install fuse-utils
  • sudo apt-get install libcurl4-openssl-dev
  • sudo apt-get install libxml2-dev
  • sudo apt-get install mime-support

Provavelmente alguns deles já estarão instalados no seu sistema, mas rode os comandos para ter certeza.
Em seguida, baixamos e compilamos o s3fs:

wget https://github.com/s3fs-fuse/s3fs-fuse/archive/v1.76.tar.gz
--2014-01-28 00:44:05-- https://github.com/s3fs-fuse/s3fs-fuse/archive/v1.76.tar.gz
Resolving github.com (github.com)... 192.30.252.129
Connecting to github.com (github.com)|192.30.252.129|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/s3fs-fuse/s3fs-fuse/tar.gz/v1.76 [following]
--2014-01-28 00:44:06-- https://codeload.github.com/s3fs-fuse/s3fs-fuse/tar.gz/v1.76
Resolving codeload.github.com (codeload.github.com)... 192.30.252.147
Connecting to codeload.github.com (codeload.github.com)|192.30.252.147|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/x-gzip]
Saving to: `v1.76.tar.gz'

[ <=> ] 92,962 --.-K/s in 0.008s

2014-01-28 00:44:06 (10.7 MB/s) - `v1.76.tar.gz' saved [92962]

Verifique o último release aqui para atualizar o link no comando wget.
Descompacte o arquivo (no seu home mesmo):

tar xzvf v1.76.tar.gz
s3fs-fuse-1.76/
s3fs-fuse-1.76/.gitignore
s3fs-fuse-1.76/AUTHORS
s3fs-fuse-1.76/COPYING
s3fs-fuse-1.76/ChangeLog
s3fs-fuse-1.76/INSTALL
s3fs-fuse-1.76/Makefile.am
...
s3fs-fuse-1.76/test/mergedir.sh
s3fs-fuse-1.76/test/require-root.sh
s3fs-fuse-1.76/test/sample_ahbe.conf
s3fs-fuse-1.76/test/sample_delcache.sh
s3fs-fuse-1.76/test/small-integration-test.sh

E rode os comandos para compilação:

cd s3fs-fuse-1.76
~/s3fs-fuse-1.76$ ./autogen.sh
~/s3fs-fuse-1.76$ ./configure --prefix=/usr

Se nesse ponto você receber as mensagens:

configure: error: Package requirements (fuse >= 2.8.4 libcurl >= 7.0 libxml-2.0 >= 2.6 libcrypto >= 0.9) were not met:

No package 'fuse' found
No package 'libcurl' found
No package 'libxml-2.0' found
No package 'libcrypto' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Deve ser porque você está usando uma instância baseada em uma AMI bitnami, que usa normalmente o /opt para instalação de vários pacotes. Basta você acrescentar os caminhos /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ao PATH no seu arquivo .bashrc. Recarregue o arquivo ou simplesmente saia e logue novamente para a variável PATH ser carregada novamente. Eu prefiro fazer isso ao invés de um simples export, para ter certeza de que editei corretamente o arquivo e de que a mudança vai funcionar permanentemente.
Uma vez que o configure funcionou corretamente, vamos seguir em frente com os comandos para a compilação:

~/s3fs-fuse-1.76$ make
~/s3fs-fuse-1.76$ sudo make install

Configuração

Neste ponto, caso você não tenha ainda um bucket criado no S3, faça-o agora. Além disso, para acessa-lo você vai precisar de seu par de chaves ACCESS KEY e SECRET KEY que você pode gerar na management console do AWS.
Há vários métodos de informar o par de chaves para o S3FS. Eu prefiro usar um arquivo /etc/passwd-s3fs, pois fica uma configuração system wide, ou seja, válida para o sistema e não apenas um usuário. Assim, seu web server vai poder acessar seu bucket, por exemplo.

Abra o vi e crie esse arquivo:

sudo vi /etc/passwd-s3fs

Coloque as chaves no formato bucketName:accessKeyId:secretAccessKey. Configure as permissões desse arquivo da seguinte forma:

sudo chmod 640 /etc/passwd-s3fs

Acesso

O comando para montar o bucket é mostrado abaixo, onde /bucket é o ponto de montagem.

sudo /usr/bin/s3fs my-bucket /bucket

Crie um arquivo de teste e confira na aws management console se o arquivo aparece na seção S3.

sudo touch /bucket/teste
sudo ls -l /bucket
total 1
-rw-r--r-- 1 root root 0 Jan 28 12:10 teste

Para desmontar use o comando regular do linux.

sudo umount /bucket

Para permitir que outros usuário escrevam no bucket, monte-o com a opção allow_other.

sudo /usr/bin/s3fs -o allow_other my-bucket /bucket

Para montar pelo fstab, inclua a linha:

s3fs#my-bucket /bucket fuse allow_other 0 0

Aí, para montar basta:

sudo mount /bucket


Helder Garcia

11 comments

  • Gostei muito da explicação. É clara e objetiva. Parabéns!

    Gostaria de alguma idéia em outro sentido:

    Tenho vários clientes na Amazon. Para cada cliente, eu costumo ter um bucket para receber os backups. Criei um utilitário em C# que faz o envio do mesmo. Para linux, tenho um shell script no cron que sempre faz depois do backup.

    Tenho um servidor com Nagios, na conta Amazon da Empresa e gostaria que este servidor tivesse acesso aos buckets de backup dos clientes. A idéia é que eu acesse no linux /buckets e já tenha: clienteX, clienteY, etc…

    É possível?

    Desde já agradeço qualquer ajuda.

    • Olá André,

      O modo mais simples seria criar um mount point para cada cliente, assim:
      ClienteX: mount point /buckets/ClienteX
      ClienteY: mount point /buckets/ClienteY
      e assim por diante. E montar um s3fs para cada um deles.

      Um problema é que isso não fica uma solução dinâmica. Quando você tiver outro cliente para acrescentar, por exemplo, ClienteZ, você deve manualmente criar o mount point e a entrada para ele no fstab.
      Para ter uma solução dinâmica, você poderia criar um script, usando as APIs da AWS, para pegar a lista de buckets existentes e verificar se há algum bucket novo. Nesse caso, o script faria a criação do mount point e alteraria o fstab, além de montar o novo filesystem. É claro que esse esforço só vale a pena se a frequência de inclusão de novos clientes for alta.

      Lembre-se também que um bucket não tem um tamanho máximo real (pelo menos não no sentido estrito). Não sei como o Nagios vai se comportar nesse caso. Pode ser que a informação gerada por ele seja errônea, se você buscar por ocupação de disco em percentual.

      • Obrigado pela resposta.

        Eu entendi a parte de criar um mount point. No arquivo “/etc/passwd-s3fs” posso colocar quantas linhas de buckets e chaves de acesso que eu quiser que o fuse aceita?

        Não tenho a intenção, realmente, neste caso, que a montagem seja dinâmica. Diria que fará parte do processo de criação de ambientes aos clientes, e neste caso, não é algo que possa atrapalhar o processo.

        Vou testar e depois comento mais.

        Obrigado pela ajuda!

        • Sim, havia esquecido de comentar que o passwd-s3fs também precisa ser atualizado.
          Não testei com vários buckets. Compartilhe seu resultado aqui depois ok? Mas de acordo com a documentação não haverá problemas em ter várias linhas.

          • Funcionou com vários buckets diferentes de 5 clientes diferentes. Basca colocar tudo no arquivo de senhas que o fuse se resolve.

            Excelente funcionalidade.

            Obrigado por toda ajuda. Precisando, é só falar.

  • Outra coisa, o Nagios só foi dito para ilustrar o tipo de servidor descrito. Não espero que ele verifique os pontos de montagem com o fuse. (É claro que poderia ser uma… hehehe.. mas não é o foco)

  • Criei assim:

    /buckets/bucket1Cliente1
    /buckets/bucket2Cliente1
    /buckets/bucket1Cliente2

    (…)

    $chown -R
    $chgrp -R

    $montar_buckets.sh # Script de montagem

    Quando monta, todos ficam com privilégios de root:

    root@ip-10-252-115-21:/sites/buckets# ls -l sounerdbkt/
    total 9011030
    ———- 1 root root 11629920 Jan 6 16:03 arquivo1.rar
    ———- 1 root root 11644103 Jan 6 16:06 arquivo2.rar
    -rw-rw—- 1 root root 6543562240 Mar 18 20:50 arquivo3.bak
    ———- 1 root root 51742208 Mar 18 05:30 arquivo4.bak
    ———- 1 root root 37409647 Jan 6 16:11 arquivo5.rar
    ———- 1 root root 2571304448 Mar 18 04:41 arquivo6.bak

    Tenho uma conta de FTP no PROFTPD que lista o raiz /sites.

    Me conecto no servidor de FTP, mas quando vou transferir do bucket para o host de origem, por exemplo o arquivo “arquivo6.bak”, dá acesso negado.

    Como será que eu conseguiria fazer esta transferência?

    Obrigado!

    • André, você colocou a opção allow_other no fstab? Lembrou de desmontar e montar de novo para que essa opção passe a valer?

      • Sim. Acabei até descobrindo que para usar a opção allow_other, tem que descomentar a linha “user_allow_other” no arquivo /etc/fuse.conf.

        Só que pelo que vi, o parâmetro serve para permitir que outros usuários do linux, que não o root, montem o repositório.

        Pelo teste que fiz, se eu estiver com um usuário chamado usrSouNerd e montar, na hora que rodar o “ls -l” o conteúdo é exibido indicando que tanto o grupo como usuário dono do arquivo é o root. Tentei até incluir o usuário usrSouNerd no grupo root mas mesmo assim não consegui fazer o download pelo ftp.

  • André, provavelmente o script que cria os backups roda como root, por isso o arquivo vem com esse owner. Você pode alterar o script para ele fazer um chgrp no arquivo após sua criação, colocando o grupo dos usuários comuns.
    Outra coisa que faria seria isolar as variáveis do problema. Será problema de permissão simples, ou tem alguma coisa a ver com o FTP? Para tirar essa dúvida você pode tentar, no shell (via ssh) com o usuário comum, copiar um arquivo desses para o home desse usuário. Se funcionar significa que o problema aparece apenas quando o acesso é via FTP.


  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>