Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Montagem Automática de Volumes NFS em uma Instância 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 日本語.

Algumas semanas atrás, esbarrei no que, na hora, achei que fosse um caso de uso bem incomum 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á-los no sistema de arquivos local do dispositivo onde rodavam. Uso bastante NFS na minha rede para compartilhar arquivos entre vários dispositivos, pela simplicidade e pelo amplo suporte que ele oferece.

Depois de colocar tudo isso de pé no home lab, percebi que esse caso de uso não era tão incomum assim, justamente pelo tanto que o NFS é usado por aí. Dá para usá-lo em ambientes de nuvem para montar um compartilhamento NFS on-premise e puxar dados, dar acesso a processos para leitura ou escrita em um compartilhamento NFS, montar diretórios home de usuários a partir de NFS, e em incontáveis outros cenários.

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

Primeiro fui pelo caminho que eu conhecia melhor: o fstab, que uso de tempos em tempos há algumas décadas. Mas logo descobri que ele não estava montando 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 esbarrei em um pacote do Linux chamado autofs. Colocá-lo para funcionar deu bastante trabalho, porque a maioria dos guias online estava desatualizada ou deixava de fora detalhes importantíssimos. Este guia vai direto ao ponto, para você não perder meio dia tentando descobrir como fazer — afinal, tempo é o que menos sobra para quem trabalha na área.

No fundo, o autofs é só um daemon que monta e desmonta compartilhamentos automaticamente, conforme necessário, em segundo plano. Diferente do fstab, ele faz isso sob demanda, então pode atuar 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 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 compartilhamento NFS que você quer adicionar. Às vezes eles não são exatamente o que você imagina, então confira com atenção. Por exemplo, em NAS Synology o nome do volume vem como prefixo, no formato /volume1/share_path.

Vou usar comandos específicos para distribuições derivadas do Debian, ou seja, deve funcionar em Debian, Ubuntu, Kali, etc. Em cada seção, incluirei também o comando equivalente para distribuições derivadas do Red Hat, para quem usa RHEL ou CentOS não precisar ficar traduzindo.

Importante: neste guia não vou abordar práticas de segurança em NFS, porque é um tópico bem extenso. Isso adicionaria um nível de complexidade que poderia facilmente dobrar o tamanho do material, então estou deixando de fora. Não me entenda mal: é MUITO importante, mas está fora do escopo deste artigo. Recomendo que você se aprofunde no assunto e incorpore essas práticas à configuração da forma que melhor atender à sua organização. Se quiser saber mais, sugiro começar por este ótimo artigo da Red Hat sobre o básico de segurança em NFS, disponível aqui.

O processo

  1. Instale o pacote autofs executando 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 preferido.

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

    /- /etc/auto.share -nosuid,noowners (Se preferir, 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 ficam em /etc e seguem o formato auto.[nome_do_share]. Então, para cada linha auto.share adicionada acima, abra o arquivo correspondente no seu editor de texto preferido para criá-lo. Dentro dele, coloque esta linha, substituindo pelo seu nome de compartilhamento (a minha preferência pessoal é manter tudo em /mnt, mas fique à vontade para adaptar), nome do servidor e caminho do compartilhamento:

    /mnt/[nome_do_share] -fstyle=nfs,user,nolock,nosuid,rw [nome_do_servidor]:[caminho_do_share] (De novo: se preferir, adicione mais espaços para melhorar a legibilidade. E se quiser que o compartilhamento 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, vamos garantir que o serviço subiu corretamente e que não houve erros de sintaxe, de rede ou qualquer outro durante a inicialização. Execute 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. Caso contrário, ela vai mostrar as últimas linhas do log para ajudar você a depurar o problema. No final do artigo também incluí uma seção com alguns passos básicos de depuração.

  8. A esta altura, você pode usar o comando cd para entrar nos diretórios definidos nos arquivos acima e acessar os compartilhamentos. Não precisa criar esses diretórios — o daemon autofs cria todos 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 filtrar só as criadas pelo autofs é executar mount | grep autofs.

  10. A partir daqui, as montagens vão carregar automaticamente no sistema e se reconectar sempre que necessário.

  11. Neste ponto, recomendo fortemente que você se aprofunde em segurança do NFS e proteja suas montagens, implementando o melhor método de segurança para o seu uso.

Depurando problemas comuns

Ao longo desse aprendizado, esbarrei em alguns obstáculos que quero listar aqui, junto com a forma como os resolvi.

O primeiro foi o daemon disparando vários erros de falha de conexão com o NFS. No fim das contas, era porque o Synology coloca o número do volume na frente do nome do compartilhamento, algo que eu não sabia na época. Diagnostiquei isso tentando montar manualmente o compartilhamento NFS em uma pasta dentro do meu diretório home com o comando mkdir tmp_mnt && sudo mount -v -r -o user,nolock,nosuid [nome_do_servidor]:[caminho_do_share] tmp_mnt, que monta o compartilhamento em um diretório local. Isso retorna um sucesso ou um erro indicando o que está acontecendo. Para desmontar, basta rodar sudo umount tmp_mnt.

Outro erro que tive foi o servidor não ser acessível pelo hostname. Esse problema acabou sendo de DNS interno: o hostname não estava sendo resolvido. Diagnostiquei conseguindo acessar o compartilhamento pelo IP e depois rodando nslookup hostname, o que confirmou que ele não estava traduzindo o IP para o hostname. Observação: para isso, talvez você precise instalar o pacote bind-utils (no Red Hat: sudo yum -y install bind-utils) ou dnsutils (no Debian: sudo apt install -y dnsutils).

O último problema que enfrentei é específico do Kubernetes. Eu não conseguia acessar nenhum serviço externo, incluindo compartilhamentos NFS, fora do cluster, a partir de qualquer pod dentro dele. Era porque o cluster não conseguia resolver o hostname via DNS, já que ele não tinha conhecimento do meu servidor DNS interno, que ficava fora do cluster. A teoria por trás disso tudo foge do escopo deste guia, então vou só dar 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 vai abrir um editor de texto com o arquivo yaml do CoreDNS. Dentro dele há uma seção chamada Corefile, com um bloco yaml que começa com .:53.
  3. Identifique o seu domínio interno. Ele depende de como o seu servidor DNS interno está configurado. Se você não tiver um servidor DNS interno, é só usar local.
  4. Identifique 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 abaixo (substituindo pelas suas informações) logo após o anterior, em uma nova linha (atenção: use espaços, não tabs!), salve e saia do editor:
[nome_do_dominio]:53 {
                errors
                cache 30
                forward . [servidor_dns]
}

Mais informações sobre por que isso funciona estão disponíveis aqui.