Um Sysadmin Cansado
DOCKER, CONTAINER, CONTÊINER, RCLONE, NUVEM

Volume in the sky with Docker - Apertem os cintos, o contêiner subiu!

Introdução

O mundo ama Docker, não é mesmo? Existe por ai uma tonelada de alternativas a ele, inclusive meu queridinho. Eu devo alguns postes sobre o Podman e o ambiente de contêineres que não seja ambiente dev e também não seja um cluster Kubernetes inteiro e hoje eu venho fazer um pouco de justiça neste ponto.

Muitas aplicações não precisam ser convertidas em microsserviços e não precisam da distribuição que um ambiente distribuído tem. Ainda não precisando, podem se beneficiar de algumas comodidades dos contêineres, como consistência de ambiente e configuração, facilidade de operação e facilidade de recovery caso algo exploda em um ambiente de produção.

Hoje apresento mais um motivo pra colocar nesta lista: A possibilidade de gerenciar automaticamente volumes remotos dentro dos contêineres usando docker-volume-rclone.

Rclone

O Rclone é um programa de linha de comando para gerenciar arquivos em armazenamento em nuvem. Esta auto descrição pode levantar suspeitas sobre a necessidade deste poste, principalmente quando o leitor descobrir que ele é capaz de montar volumes mas não se enganem, ainda será mais prático manter a sintaxe habitual de volumes do Docker Compose. Aconselho a todos os aventureiros nuvenáuticos que se apoderem dessa ferramenta - até mesmo como substituição para rsync/sftp/ftp/mount.cifs e tantas outras ferramentas que temos por ai.

Aos que ainda não se convenceram do poder do Rclone, há duas ferramentas do Rclone - hasher e compress - que podem ser aninhadas em qualquer outro endpoint (E aninhadas entre si também - como faremos adiante), adicionando algum poder a protocolos mais restritos, como o ftp.

Docker plugin

O Docker tem uma plataforma de plugins bem mais interessante que os plugins do podman em termos de facilidade de deploy de novas expansões. Não avaliei se o podman é capaz de rodar a mesma estrutura da plugin API do Docker - deixando a sugestão ao leitor a possibilidade de buscar esta possibilidade - e quem sabe a publicar também. Esta plataforma de plugins será utilizada para mapear em volumes Docker qualquer serviço suportado pelo Rclone.

Bora passar raiva? Booooooooraa!

Pré-requisitos

Para o procedimento, o pacote fuse se faz necessário. Nas duas bases mais comuns, o processo de instalação costuma ser o mesmo:

Também é necessária a criação de duas pastas para armazenar o cache e a configuração 1:

sudo mkdir -p /var/lib/docker-plugins/rclone/config
sudo mkdir -p /var/lib/docker-plugins/rclone/cache

Instalação do plugin

Atendidos os pré-requisitos, hora de instalar o plugin!

docker plugin install rclone/docker-volume-rclone:amd64 \
args="-v" --alias rclone --grant-all-permissions

E ver se tudo está instalado como deveria:

docker plugin list

É esperado um resultado como o seguinte:

$ docker plugin list
ID             NAME            DESCRIPTION                       ENABLED
c0ef4f512e4f   rclone:latest   Rclone volume plugin for Docker   true

Voa passarinho, voa

Vou deixar propositalmente os dois passos que já estão documentados pela equipe do Rclone de fora deste texto. O cenário mais simples que cria manualmente o volume pode ser compreendido partindo da leitura deste texto - mesmo sem conhecimento da língua inglesa. O cenário envolvendo docker-compose está ilustrado, mas devo trazer uma visão um pouco mais prática de como chegar a um ponto de uso útil da ferramenta - ilustrando um backup simples de MySQL como exemplo.

Configurando os serviços

A pasta onde o Rclone instala seu arquivo de config é a /var/lib/docker-plugins/rclone/config/ e a configuração do Rclone é gerada pelo comando rclone config. Juntando as duas coisas com um contêiner pra configurar o Rclone (Afinal, pra que motivo iremos instalar via gerenciador de pacotes?), fica da seguinte forma:

# Contêiner para configurar o Rclone

docker run -it --rm --name rclone_config -v /var/lib/docker-plugins/rclone/config/:/config/rclone rclone/rclone config

Nesta altura do campeonato, já fica posto que é possível usar variações do comando acima para fazer qualquer operação fora dos contêineres envolvendo os serviços configurados para os volumes do Docker, como por exemplo:

# Vamos listar os arquivos do serviço brasil_bagunca:
# E não podemos esquecer do dois-pontos no final!

docker run -it --rm --name rclone_config -v /var/lib/docker-plugins/rclone/config/:/config/rclone rclone/rclone ls brasilbagunca:

E assim deverá ser criada toda as configurações para que o Rclone possa operar e vou deixar um exemplo que demonstra um dos poderes interessantes do Rclone:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[brasilbagunca]
type = ftp
host = senhoresselva.com.br
user = cristiano
pass = seu_lixo
explicit_tls = true

[brasilbagunca_compress]
type = compress
remote = brasilbagunca:

[brasilbagunca_compress_hash]
type = hasher
remote = brasilbagunca_compress:

Criamos um perfil de acesso chamado brasilbagunça que se conecta em um FTP. Como não tem como fazer hash e compressão no FTP, criamos um novo perfil de acesso chamado brasilbagunca_compress que comprime os arquivos em gzip e envia para o remote brasilbagunca.

AVISO: O Rclone diz explicitamente que é possível acessar os arquivos e que modificá-los é perigoso! Não altere os arquivos gerados no destino! No lugar disso, veja acima o exemplo que usamos com rclone ls.

E como FTP também não suporta hash remoto, adotamos o componente hasher em cima do componente compress. O hasher gera arquivos .json para cada arquivo enviado com o hash local e verifica este hash em funções como copy, sync e etc.

No final das contas, com uma configuração destas, é possível enviar dados para o FTP com um hash e compressão dos arquivos, o que facilita bastante a vida ao utilizar sistemas legados. Como a configuração é aninhada, usaremos a configuração que contempla os três sistemas, como no exemplo abaixo:

# Vamos listar os arquivos do serviço brasil_bagunca após a compressão e o hashing:
# E novamente não podemos esquecer do dois-pontos no final!

docker run -it --rm --name rclone_config -v /var/lib/docker-plugins/rclone/config/:/config/rclone rclone/rclone ls brasilbagunca_compress_hash:

Forjando um docker-compose.yml

E chega a hora de juntar isso em uma configuração útil. Para manter os serviços o mais modular possível, utilizei o agendador Ofelia - um sistema construído em Go que permite utilizar labels do Docker para parametrizar o agendador. O contêiner MariaDB é padrão e só tem a mais uma pasta de backup que será mapeada para o volume criado com o driver rclone. As rotinas e configurações do job-exec podem ser consultadas aqui. Para os entendidos de cron e mysql, os comandos serão intuitivos e não explicados neste artigo para não desviar do tema do artigo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
version: '3.8'
name: fora_do_brasil

services:
  ofelia:
    image: mcuadros/ofelia:latest
    command: daemon --docker
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  mariadb:
    image: mariadb:latest
    restart: unless-stopped
    labels:
      ofelia.enabled: true
      ofelia.job-exec.mysql-optimize-fora_do_brasil.schedule: "@daily"
      ofelia.job-exec.mysql-optimize-fora_do_brasil.command: "mysqlcheck -uroot -ppiano_caindo -o --all-databases"
      ofelia.job-exec.mysql-backup-fora_do_brasil.schedule: "@daily"
      ofelia.job-exec.mysql-backup-fora_do_brasil.command: 'bash -c "mysqldump -uroot -ppiano_caindo --all-databases >> /backup/$(date +%Y%m%d-%H%M%S).sql"'
      ofelia.job-exec.mysql-clean-fora_do_brasil.schedule: "@daily"
      ofelia.job-exec.mysql-clean-fora_do_brasil.command: 'bash -c "find /backup -type f -mtime +7 -print0 | xargs -r0 rm -v --"'
    environment:
      - MYSQL_ROOT_PASSWORD=piano_caindo
    volumes:
      - backup:/backup

volumes:
  backup:
    driver: rclone
    driver_opts:
      remote: 'brasilbagunca_compress_hash:vejam/voces/percebem/a/loucura/'
      allow_other: 'true'
      vfs_cache_mode: full
      poll_interval: 0

Pode chamar atenção do leitor mais cuidadoso a opção allow_other que é mandatória: Esta opção permite que mais de um volume no mesmo remote seja lançado. Caso esta opção não seja utilizada, somente um volume será montado para cada remote.

A opção vfs_cache_mode está explicada neste link e resumidamente se comporta da seguinte forma: É preciso escolher um modo de cache para qualquer operação que não seja sequencial e que contemple as limitações que cada uma das opções de cache oferece (off, minimal, writes e full). O uso da opção full considerando que é um cenário de backup é adequada, porém cada cenário poderá exigir uma configuração diferente.

A opção poll_interval determina o tempo que o Rclone irá atualizar a lista local com a lista remota. No caso deixei em 0 porque é fundamentalmente um sistema de somente escrita, então não vejo razão para carregar o remoto com polling. Entretanto - conforme sinalizado em outros casos - a situação pode demandar mudanças.

Recomendo a leitura da página de informações sobre o rclone mount pois as opções desta página se aplicam para a montagem dos volumes também.

Conclusão

Este artigo visa mostrar o poder dos plugins do Docker e também indicar o poderoso Rclone. Os dois juntos podem ser uma excelente ferramenta para quem está convertendo estruturas on premisse legadas para contêineres em qualquer formato - sem necessariamente mudar os paradigmas da solução existente.

Caso tenha dúvidas, sugestões ou alguma observação, dá um toque nos comentários abaixo ou nas redes sociais no menu acima!

E nunca se esqueça, se for fultonar um contêiner, segure-se bem e aproveite a viagem!

Metal Gear Auto Extração via Fulton

  1. O comando sudo será indicativo - salvo por outra necessidade - de que há necessidade de execução como root. Poderia indicar usando # e $, porém acredito que esta forma é mais verbosa e compreensível.