Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Montagem automática de NFS em instâncias Linux

By Sayle MatthewsJul 20, 20208 min read

Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.

1 fl0wtntavgxuf3yqbi5owg

Algumas semanas atrás, me deparei com o que parecia, na época, um caso de uso bem específico ao migrar várias VMs do meu home lab para Kubernetes: montar automaticamente um volume NFS em uma máquina Linux ou container Docker.

A ideia era migrar o backing store do InfluxDB, MySQL e Grafana para o meu NAS, em vez de deixá-lo no sistema de arquivos local do dispositivo onde cada um rodava. Uso bastante NFS na minha rede para compartilhar arquivos entre vários dispositivos, pela simplicidade e pelo amplo suporte.

Depois de configurar tudo no meu home lab, percebi que esse caso de uso não era tão específico assim, dada a enorme quantidade de cenários em que o NFS é utilizado pelo mundo. Dá para usá-lo em um ambiente de nuvem para montar um share NFS on-premise e puxar dados, permitir que processos acessem um share NFS para leitura ou escrita, montar diretórios home de usuários a partir do NFS e inúmeros outros casos.

O problema (e a chave para fazer a montagem automática funcionar)

Comecei pelo caminho que conhecia melhor: o fstab, que venho usando de tempos em tempos nas últimas décadas. Mas logo percebi que ele não montava o NFS rápido o suficiente para os daemons de banco de dados reconhecerem o volume, e isso estava causando problemas sérios.

Foi aí que descobri um pacote Linux chamado autofs. Colocá-lo para funcionar exigiu bastante experimentação, já que muitos guias online estavam desatualizados ou deixavam passar detalhes importantes da configuração. Este guia vai direto ao ponto, para você não precisar perder meio dia decifrando — porque tempo é o que menos sobra para quem trabalha na área.

Em essência, o autofs é um daemon que monta e desmonta shares automaticamente, conforme a necessidade, em segundo plano. Diferente do fstab, ele faz isso sob demanda, ou seja, consegue montar durante o boot sem você precisar se preocupar com a ordem de inicialização dos daemons.


Pré-requisitos

Para simplificar, neste exercício vou supor que você já tem um servidor NFS configurado no seu NAS ou em uma máquina Linux, ou que está usando algo como o Filestore do Google Cloud no papel de NAS.

Tenha em mãos os caminhos completos de cada NFS share que pretende adicionar. Às vezes eles não são o que parecem, então confira duas vezes. Em NASes Synology, por exemplo, o volume aparece como prefixo, no formato /volume1/share_path.

Também vou usar comandos específicos de distribuições derivadas do Debian — então deve funcionar no Debian, Ubuntu, Kali etc. — e, em cada seção, indicarei o comando equivalente para distribuições derivadas do Red Hat, para que quem usa RHEL ou CentOS não precise ficar traduzindo na hora.

Observação: neste guia não vou abordar práticas de segurança em NFS, porque é um tema bem extenso. Isso adicionaria um nível de complexidade que poderia facilmente dobrar o tamanho deste guia, então estou deixando de fora. É MUITO importante, não me entenda mal, mas não vou tratar disso aqui. Recomendo que você estude o assunto e incorpore essas práticas a esta configuração da forma que melhor atender à sua organização. Se quiser se aprofundar, sugiro começar por este ótimo artigo da Red Hat cobrindo o básico aqui.


O processo

  1. Instale o pacote autofs rodando os comandos abaixo, conforme a sua distribuição:

    Ubuntu: `sudo apt -y install nfs-common autofs

    Red Hat: sudo yum -y install nfs-common autofs`

  2. Abra o arquivo /etc/auto.master no seu editor favorito.

  3. Vá até o final do arquivo e adicione uma linha como esta para cada montagem que quiser incluir, trocando a palavra share em auto.share pelo nome de sua preferência para o share:

    `/- /etc/auto.share -nosuid,noowners

    `(Se quiser, adicione mais espaços entre os elementos para facilitar a leitura. O Medium não permite mais de um espaço em um bloco de código dentro de uma lista numerada.)

  4. Em seguida, você precisa criar cada arquivo referenciado no passo anterior. Todos eles ficam em /etc e seguem o formato auto.[share_name]. Então, para cada linha auto.share que você adicionou acima, abra o arquivo correspondente no seu editor de texto favorito para criá-lo. Lá dentro, coloque a linha abaixo, substituindo pelo nome do seu share (minha preferência pessoal é manter tudo em /mnt, mas você pode ajustar como quiser), pelo nome do servidor e pelo caminho do share:

    `/mnt/[share_name] -fstyle=nfs,user,nolock,nosuid,rw [server_name]:[share_path]

    `(De novo, se preferir, coloque mais espaços para facilitar a leitura. E se quiser que o share seja somente leitura, em vez de leitura e escrita, troque o rw acima por ro.)

  5. Feito isso, é hora de reiniciar o serviço autofs com o seguinte comando:

    Ubuntu: sudo service autofs restart

    Red Hat: sudo systemctl restart autofs

  6. Agora confirme que o serviço subiu corretamente e que não houve erros de sintaxe, rede ou outros na inicialização. Rode o comando abaixo para ver o status:

    Ubuntu: sudo service autofs status

    Red Hat: sudo systemctl status autofs

  7. Na saída do passo anterior, o status deve aparecer como running e tudo certo. Se não, a saída mostra as últimas linhas dos logs para ajudar você a depurar o problema. Também incluí uma seção ao final com algumas etapas básicas de depuração.

  8. Neste ponto, basta usar o comando cd para acessar os diretórios indicados nos arquivos acima e chegar aos shares. Você não precisa criar esses diretórios — o daemon autofs cria automaticamente para você.

  9. Uma última verificação possível é rodar o comando mount, que lista todas as montagens da instância. Uma forma fácil de encontrar as criadas pelo autofs é executar mount | grep autofs.

  10. Daqui em diante, as montagens são carregadas automaticamente pelo sistema e religadas sempre que necessário.

  11. Neste ponto, recomendo fortemente que você estude segurança em NFS, proteja suas montagens e implemente o método de segurança mais adequado para o seu cenário.


Depurando problemas comuns

Ao longo desse aprendizado, esbarrei em alguns percalços que quero listar aqui, junto com a forma como os depurei.

O primeiro foi o daemon cuspindo todo tipo de erro sobre não conseguir se conectar ao NFS. Acabei descobrindo que a Synology adiciona o número do volume antes do nome do share — algo que eu não sabia na época. Cheguei a esse diagnóstico tentando montar manualmente o NFS share em uma pasta dentro do meu diretório home com o comando mkdir tmp_mnt && sudo mount -v -r -o user,nolock,nosuid [server_name]:[share_path] tmp_mnt, que monta o share em um diretório local. Isso retorna sucesso ou um erro indicando o que está acontecendo. Para desmontar, rode sudo umount tmp_mnt.

Outro erro que apareceu foi o servidor não estar acessível pelo hostname. Acabou sendo um problema de DNS interno, que não resolvia o hostname. Cheguei a esse diagnóstico ao conseguir acessar o share pelo endereço IP e, depois, rodar nslookup hostname para confirmar que ele não conseguia traduzir o IP para o hostname. Para isso, talvez você precise instalar os pacotes bind-utils (no Red Hat: sudo yum -y install bind-utils) ou dnsutils (no Debian: sudo apt install -y dnsutils).

O último problema é específico de Kubernetes. Eu não conseguia acessar nenhum serviço externo — incluindo NFS shares — que ficasse fora do cluster, a partir de qualquer pod dentro dele. O motivo era que não dava para resolver o hostname via DNS, já que o cluster não conhecia o meu servidor DNS interno, que ficava fora dele. A teoria por trás disso foge bastante do escopo deste guia, então vou apenas apresentar a solução e um link para você se aprofundar.

  1. Edite o configmap do CoreDNS com o comando kubectl edit configmap coredns -n kube-system.
  2. Isso abre um editor de texto com o arquivo yaml do CoreDNS. Lá dentro há uma seção chamada Corefile, com um bloco yaml que começa com .:53.
  3. Identifique seu domínio interno. Ele é definido pela configuração do seu servidor DNS interno; se você não tiver um, use apenas local.
  4. Identifique o endereço IP do seu servidor DNS. Se você não tiver um, provavelmente será o IP do seu roteador.
  5. Adicione o bloco de código a seguir, substituindo pelas suas informações, abaixo desse trecho em uma nova linha (atenção: use espaços, não tabs!), salve e saia do editor:

[domain_name]:53 { errors cache 30 forward . [dns_server] }

Para entender melhor por que isso funciona, dá uma olhada aqui.