Olá, me chamo André Pereira, e esse é o meu primeiro post aqui no dev.to. Geralmente atuo como fullstack nos projetos que desenvolvo e por conta da responsabilidade que isso me traz, acabo não tendo oportunidade de trabalhar com infraestrutura.
Porém, recentemente eu resolvi fazer uma tarefa referente a infraestrutura de um projeto. A ideia era programar o Crontab da instância de produção para copiar os dados para uma instância de backup, ambas hospedadas no GCP. Aparentemente é uma tarefa simples, mas pode se tornar complicada para inexperientes em infraestrutura ou GCP.
Sem mais delongas, vamos ao telão:
Sumário
(Caso você já tenha uma instância de produção pronta comece a partir do item 3)
1. Criando a instância de produção
2. Criando o banco de dados na instância de produção
3. Criando a instância de backup
4. Conectando as duas instâncias via SSH
5. Criando os shell scripts de backup
6. Entendendo e configurando o Crontab
7. Adicionando o shell script de expurgo
1. Criando a instância de produção
Como eu havia introduzido utilizaremos o Google Cloud Platform para hospedar nossos servidores. Lembre-se, eu não irei ensinar a fazer deploy da sua aplicação, essa instância será apenas para simular um backup. Caso você ainda não tenha uma conta, acesse Google Cloud Platform, clique "Comece a usar gratuitamente" e conclua o cadastro. Perceba que o cadastro irá requerer um cartão de crédito para confirmação, mas não se preocupe, nada será cobrado.
Após o cadastro você será levado para uma página de primeiros passos com algumas apresentações. Você pode configurar um projeto no menu superior se preferir. Por padrão o GCP te coloca no "My First Project", e por questões de agilidade utilizaremos esse projeto mesmo.
Para ir até o gerenciamento de instâncias clique no menu de navegação no canto superior esquerdo, procure a opção "Google Compute Engine", e selecione "Instâncias de VM"
Agora iremos criar nossa instância de produção. Clique em "Criar" e nos deparamos com um formulário.
Escolha um nome para a instância, defina a região (Para um melhor tempo de resposta escolha southamerica-east1) e a zona de acordo com suas necessidades. Na parte de configuração da máquina podemos deixar a série "N1", e o tipo de máquina "n1-standard-1", mas caso você esteja configurando uma instância para a sua aplicação, você deve avaliar qual máquina satisfaz melhor as necessidades da hospedagem.
Um pouco mais abaixo encontraremos a seção de "Disco de inicialização" onde escolheremos o tamanho do disco da nossa instância, e qual OS será instalado na mesma. Por padrão o Google nos traz um disco de 10GB com Debian 9. Para este tutorial utilizaremos Ubuntu 18.04, então vamos mudar isso clicando no botão "Alterar".
Na tela de configuração do disco de inicialização, selecionamos menu de "Imagens públicas", o sistema operacional "Ubuntu", e a versão "Ubuntu 18.04 LTS". Logo abaixo no Tipo de disco de inicialização, selecionamos "Disco permanente padrão", e o tamanho fica a critério do usuário. Neste tutorial usarei 20GB.
Podemos confirmar a configuração do disco, e de volta no formulário de criação da instância clicaremos em "Criar". Estas são as configurações mínimas necessárias para simular o nosso banco de produção.
Note que ao longo do formulário de criação um valor no canto superior direito simulava o gasto mensal que seria necessário para manter essa instância funcionando. Mas como você deve ter lido ao se cadastrar, o Google disponibiliza U$300 para novos usuários, o que convertido em reais na cotação atual nos dá cerca de R$1350, que é mais do que o necessário para estudos como esses.
Agora ao acessar a aba de "Instâncias de VM", conseguimos ver nossa instância na listagem funcionando.
2. Criando o banco de dados na instância de produção
Agora que temos nossa instância pronta para uso. Vamos acessá-la usando a própria conexão SSH do GCP, e para isso basta clicar no botão SSH no final da tabela de instâncias.
Uma janela será aberta e após a conexão temos acesso direto à instância com o nosso usuário do GCP. Aqui instalaremos os pacotes necessários para criar o nosso banco de dados. Neste tutorial utilizaremos PostgreSQL em um container Docker para agilizar o processo.
Instalando o Docker via Snap:
$ sudo snap install docker
Criando container Docker com PostgreSQL:
$ sudo docker run --name prod_database -e POSTGRES_PASSWORD=docker -p 5432:5432 -d postgres
Após isso, basta rodar sudo docker ps
para verificar se o container já está ativo. Caso o comando retorne uma tabela vazia significa que o container está inativo, portanto rode sudo docker start prod_database
, e repita o processo de verificação para prosseguir.
Agora iremos acessar o container e popular o banco com alguns dados para o backup.
Acessando o container:
$ sudo docker exec -it prod_database bash
A aparência do terminal irá mudar pois estamos logados no container como usuário root (#).
Acessando o PostgreSQL:
# psql -U postgres
Iremos utilizar o banco "postgres" que vem por padrão no PostgreSQL, para uma melhor visualização disso, basta digitar \l
e serão retornados os bancos existentes. Até o momento seu terminal estará parecido com isso:
Conectando ao banco:
\c postgres
Criando tabela users
:
CREATE TABLE users (
id serial PRIMARY KEY,
name VARCHAR (255) NOT NULL,
email VARCHAR (255) UNIQUE NOT NULL
);
Criando tabela users
com alguns dados:
INSERT INTO users(name, email)
VALUES
('Andre Pereira', 'contato.andrepsf@gmail.com'),
('Maria Silva', 'mariasilva@email.com'),
('João Paulo', 'joaopaulo@email.com');
Verificando se os dados foram cadastrados corretamente:
SELECT * FROM users;
O retorno deverá ser o seguinte:
Feito. Agora temos uma servidor com dados armazenados e podemos prosseguir para o próximo passo.
3. Criando a instância de backup
Aqui repetiremos um passo-a-passo muito semelhante ao da primeira parte deste tutorial. Já logado na sua conta do Google que administra o GCP vá até a listagem de instâncias de VM (help), e no menu superior clique em criar instância.
Defina um nome para a instância, selecione a região, e defina as configurações da máquina. Minhas configurações ficaram da seguinte forma:
Logo abaixo na seção do disco de inicialização clique em alterar. também iremos manter a mesma configuração utilizada no início do tutorial (help), no entanto, podemos alocar bem mais espaço no disco. A depender do tamanho do seu banco, eu recomendaria pelo menos 500GB. Então, temos:
Por fim, podemos clicar em "Criar" no fim do formulário e prosseguir para a próxima parte.
4. Conectando as duas instâncias via SSH
Agora que temos as duas instâncias prontas para uso, precisamos conectá-las via SSH para enviar dados para a instância de backup.
Caso você não saiba como o protocolo SSH funciona, sugiro que procure fontes confiáveis e leia sobre, pois trataremos esse assunto de forma bem rasa ao longo deste guia.
Para que a conexão seja feita, precisamos gerar um par de chaves SSH no servidor de produção e autorizá-la no servidor de backup. Para fazer isso, primeiro vá até a listagem instâncias de VM e clique no botão "SSH" da instância de produção.
Uma janela será aberta e após a conexão temos acesso ao servidor de produção. Para gerar uma novo par de chaves SSH utilizaremos o comando:
$ ssh-keygen -t rsa -b 4096
Após isso será pedido que você selecione uma pasta destino para as chaves. Basta pressionar enter
para que elas sejam criadas no diretório padrão ~/.ssh/
. Depois será pedido uma passphrase, basta deixar o campo em branco e confirmar com enter
duas vezes.
Pronto, para confirmar se as chaves foram realmente criadas, basta rodar:
$ ls ~/.ssh/
E verificar se na pasta existem os arquivos id_rsa
e id_rsa.pub
. Caso contrário, repita o processo indicando que quer suas chaves no diretório ~/.ssh
.
Explicando esses dois arquivos rapidamente, temos id_rsa
como chave privada e id_rsa.pub
como chave pública. Essa última será compartilhada com o servidor de backup. Por questões de segurança recomendo que mude as permissões na chave privada para somente leitura do usuário dono com o comando:
$ chmod 400 ~/.ssh/id_rsa
Prosseguindo com o acesso ao servidor de backup, primeiro você deve obter o valor de sua chave pública:
$ cat ~/.ssh/id_rsa.pub
O comando cat
retornará o valor da chave. Copie-o e cole em um editor de texto de sua preferência e feche a janela de acesso ao servidor de produção. A ideia aqui é eliminar as quebras de linha presentes na chave pública utilizando backspace
, caso contrário ela será invalidada. Essas foram as quebras de linha presentes no meu arquivo:
Após eliminar as quebras de linha, copie o conteúdo, e vá novamente até a listagem de instâncias de VM e clique na instância "backup".
Agora, no menu de detalhamento da instância clique em editar no menu superior.
Desça até a seção "Chaves SSH", clique em "Mostrar e editar" e insira a chave pública no campo. Perceba que caso a chave tenha sido validada corretamente, o nome do seu usuário aparecerá à esquerda do campo.
Desça até o final da página e clique em "Salvar", volte até a listagem de instâncias, e abra o acesso ao servidor de produção novamente.
Caso tudo tenha corrido bem até aqui, para acessar a instância de backup através da instância de produção basta rodar:
$ ssh <nome-da-instancia-de-backup>
No meu caso:
$ ssh backup
Pronto! Agora as duas máquinas estão conectadas. Para voltar para a máquina de produção basta rodar o comando exit
.
5. Criando os shell scripts de backup
Para configurar os shells scripts você deve voltar a instância de produção, então caso ainda não o tenha feito, rode exit
.
Iremos criar algumas pastas para armazenar backups temporários ainda nessa máquina antes de passá-los para a outra instância. As pastas serão criadas na raiz /
com o seguinte comando:
$ sudo mkdir -p /backups_tmp/databases/postgres
Após isso iremos mudar usuário dono dessas pastas para o nosso ao invés do root.
$ sudo chown $USER:$USER -R /backups_tmp/
Navegaremos até a pasta /backups_tmp
:
$ cd /backups_tmp
E iremos começar escrever o nosso shell script. Eu utilizarei o nano, mas sinta-se à vontade para utilizar outro editor como o Vim.
$ nano backup.sh
Cole o seguinte script dentro do arquivo.
#!/bin/sh
# backup.sh
DATE=$(/bin/date +%Y%m%d%H%M%S)
POSTGRES_NAME="prod_database"
POSTGRES_USER="postgres"
POSTGRES_DATABASE="postgres"
sudo docker exec -t $POSTGRES_NAME pg_dumpall -c -U $POSTGRES_USER > /backups_tmp/databases/postgres/$POSTGRES_DATABASE-$DATE
rsync -avzhe ssh /backups_tmp/databases/ backup:~/backups/databases/
Aqui definimos quatro variáveis que são utilizadas ao longo do script. O primeiro comando roda o comando pg_dumpall
gerando um backup no container onde está o nosso banco de dados.
O retorno desse comando é inserido em um arquivo na pasta databases/postgres/
, que é composto pelo nome do banco de dados seguido de um hífen e a data em que o backup foi gerado.
O segundo comando é onde acontece o envio do arquivo para o servidor de backup. Utilizamos rsync
para sincronizar os dados do backup temporário com o servidor de backup.
Após o parâmetro ssh
é informado o diretório dos arquivos ou pastas a serem enviados: /backups_tmp/databases
. Em seguida informamos o destino dos arquivos neste formato <nome-ou-ip-do-servidor>:/diretorio/alvo
, que no meu caso ficou como: backup:~/backups/databases
Pressione CTRL+O
para salvar e CTRL+X
para fechar o nano, sempre confirmando com enter
.
Agora basta dar permissão de execução para o arquivo:
$ chmod +x backup.sh
Antes de executar o arquivo e passarmos para a próxima parte do tutorial, execute ssh backup
para ir até a instância de backup, e rode o comando para criar os diretórios.
$ mkdir -p ~/backups/databases/postgres/
Volte a instância de produção, e execute o shell script que criamos.
$ ./backup.sh
O backup será gerado, armazenado na pasta postgres
e enviado para a pasta postgres
do servidor de backup. O retorno deverá ser semelhante ao seguinte:
Sugiro que você verifique os arquivos no servidor de backup antes de prosseguir para a próxima parte, caso algo não esteja como esperado, revise o seu script e repita os passos.
6. Entendendo e configurando o Crontab
Agora iremos programar o Crontab para rodar o nosso script de backup e remover arquivos antigos periodicamente. Mas antes entenda como o Crontab funciona.
Para configurá-lo iremos fazer alterações no arquivo /etc/crontab
, portanto:
$ sudo nano /etc/crontab
Ao abrir o arquivo você irá se deparar com o seguinte conteúdo:
Para configurar novas tarefas iremos alterar somente a tabela ao fim do arquivo. Ela funciona da seguinte forma:
m
-> minuto (0 - 59)h
-> hora do dia (0 - 23)dom
-> Dia do mês (1 - 31)mon
-> Mês (1 - 12)dow
-> Dia da semana começando pelo domingo (0 - 7)user
-> Usuário que executará a tarefacommand
-> O comando da tarefa
Então caso precisássemos criar o arquivo example.txt
com o usuário john
todo dia 15 do mês e aos domingos às 18:47h, adicionaríamos a seguinte linha ao Crontab:
47 21 15 * 0 john touch ~/example.txt
Se desejar fazer mais testes, sugiro que acesse o Crontab Guru.
Perceba que adicionei +3 à hora, pois o Crontab segue o horário do sistema, que por padrão é UTC. Você pode verificar o horário com o comando date
.
Caso seja necessário que uma tarefa seja executada todo dia em determinado horário, basta preencher a hora exigida e as colunas de dias com *
.
Agora que Sabemos como o Crontab funciona, vamos configurar nossas tarefas de backup. A primeira será a execução do arquivo de backup, a segunda será a limpeza total dos dados na máquina de produção a cada 7 dias na segunda-feira.
30 6 * * * contato_andrepsf /backups_tmp/backup.sh
15 6 * * 1 contato_andrepsf rm -rf /backups_tmp/databases/postgres/*
Dessa forma já temos nosso Crontab totalmente pronto. Caso você queira testar, basta definir um horário próximo e esperar que o Crontab execute as tarefas.
7. Adicionando o shell script de expurgo
Por fim, iremos adicionar um script de expurgo na instância de backup. O script será executado todo dia pelo Crontab eliminando os dados com 7 dias desde a data de criação.
Para começar acesse a máquina de backup com ssh backup
. Logo em seguida iremos criar o arquivo backup_purge.sh
.
$ nano backup_purge.sh
Cole o seguinte script dentro do arquivo.
#!/bin/sh
# backup_purge.sh
DATE=$(/bin/date -d "-7day" +%Y%m%d)
rm -rf ~/backups/databases/postgres/postgres-"$DATE"*
Salve o arquivo, feche o nano, e dê permissão de execução.
$ chmod +x backup_purge.sh
Abra o crontab.
$ sudo nano /etc/crontab
E adicione uma linha ao arquivo para a execução do script todo dia.
15 6 * * * contato_andrepsf ~/backup_purge.sh
Feito! Agora o nosso script diariamente irá expurgar os arquivos de backup diariamente.
Conclusão
Com isso está pronta a nossa rotina de backup no GCP. Vale lembrar que a localização dos arquivos é totalmente personalizável e você pode organizar da forma que achar mais adequado.
Obrigado por ler até aqui, fico aberto a qualquer sugestão ou dúvida. Espero ter ajudado :).
Bibliografia
https://cloud.google.com/compute/docs/instances/
https://www.openssh.com/
https://hub.docker.com/_/postgres
http://www.bosontreinamentos.com.br/linux/10-exemplos-do-comando-rsync-para-backup-e-sincronismo-de-arquivos-no-linux/
Top comments (0)