Como atribuir um IP para cada container + backup

Caros,

Em uma conversa no grupo do telegram eu comentei sobre como eu utilizava os meus containers e como surgiu o interesse de saber mais, explico aqui no forum. Basicamente eu tenho um script para cada container/serviço que eu uso e isso facilita fazer o backup do container e subi-lo rapidamente em outra máquina se assim for necessário. Como cada container possui o seu próprio IP dentro minha rede, não importa em que maquina esse container rode, porque o IP vai junto com ele. A minha estratégia não funciona se vc roda o hass-OS e requer um pouco de conhecimento de docker/linux, mas tb não é tão difícil assim :-).

O pré-requisito é uma instalação padrão de Debian + Docker. Feito? vamos lá… O primeiro passo é criar uma “network” do tipo macvlan dentro do docker e é isso que permite que cada container tenha seu próprio IP da sua intranet em vez daquele IP “interno” auto atribuído do docker. Eu vou chamar essa network de “intranet” e ela é criada com o comando abaixo:

docker network create -d macvlan --subnet=192.168.0.0/24 --gateway=192.168.0.1 --ip-range=192.168.0.80/28 -o parent=enp2s0f0 intranet

O prefixo 192.168.0.0/24 é o mesmo utilizado na minha intranet. O comando acima faz uma espécie de “reserva” dos ips 192.168.0.80 até o 192.168.0.95 (Não é uma reserva propriamente dita, mas o docker vai tentar atribuir um ip desse range se vc não dizer explicitamente que ip quer usar). Observem tb que a interface “física” correspondente é a enp2s0f0 da máquina hospedeira (do Debian).

Só esse comando já é o suficiente para vc poder atribuir IPs aos containers, mas tem um “probleminha”: a máquina hospedeira não vai conseguir “pingar”/acessar os containers por conta de como as interfaces/bridges funcionam no linux, então será necessário criar uma “bridge” e adicionar a interface física à essa bridge. Usando o exemplo acima, vamos modificar a configuração da interface enp2s0f0 para permitir isso. Edite o arquivo /etc/network/interfaces e faça as configuração como no exemplo abaixo:

auto enp2s0f0
iface enp2s0f0 inet manual
iface enp2s0f0 inet6 manual

auto intranet
iface intranet inet static
       address 192.168.0.4
       netmask 255.255.255.0
       gateway 192.168.0.1
       pre-up ip link add link enp2s0f0 name intranet type macvlan mode bridge

A primeira parte da config coloca a interface física enp2s0f0 em modo “manual” e a segunda parte cria uma bridge na qual a enp2s0f0 faz parte e uma interface virtual chamada “intranet” atribuindo a ela o ip 192.168.0.4. Reinicie o serviço de rede ou reboote a máquina.

Pronto, agora sim podemos criar containers e atribuir IPs a eles. Eu costumo criar um script meio que “padrão” que baixa a imagem atualizada do container, destrói o container e o cria novamente. Eu tb costumo criar um diretório chamado /docker e para cada container criar um <nome_container>/config que será mapeado para persistir as configurações do container. O script abaixo cria e inicia o meu HA de testes:

#!/bin/bash

docker pull homeassistant/home-assistant:stable

docker stop ha-dev
docker rm ha-dev

docker create --name="ha-dev" -h "home-assistant" -v /docker/ha-dev/clean-config:/config -v /etc/localtime:/etc/localtime:ro  --net=intranet --ip=192.168.0.31  homeassistant/home-assistant:stable

docker start ha-dev

Observem que nesse caso estou mapeando o diretório /docker/ha-dev/clean-config para o /config do container. Se eu quiser fazer um backup desse container, basta fazer o o backup desse diretório e do script acima. Observem tb que estou atribuindo o ip 192.168.0.31 ao container.

Eu tenho mais de uma máquina com docker em casa e usando esse esquema eu posso subir rapidamente qualquer container em qualquer uma das máquinas.

Já que estamos falando de backups também… Eu os faço com o duplicity (apt-get install duplicity). Os debians montam um diretório remoto do meu NAS no “/remote” e eu uso o script abaixo para fazer backup:

#!/bin/bash
#BASE DOCKER DIR
DKDIR="/docker"

#BASE BACKUP DIR
BKDIR="/remote/backups"

#DUPLICITY OPTS
OPTS="--no-encryption"


# CODE
TYPE=$1
CONTAINERDIR=$2

function fullbackup
{
	duplicity full $OPTS $DKDIR/$CONTAINERDIR file://$BKDIR/$CONTAINERDIR
}

function incrbackup
{
	duplicity incr $OPTS $DKDIR/$CONTAINERDIR file://$BKDIR/$CONTAINERDIR
}

function restorebackup
{
	duplicity restore --force  $OPTS file://$BKDIR/$CONTAINERDIR $DKDIR/$CONTAINERDIR
}

function printhelp
{
 echo "use $0 [full|incr|restore] docker_container"
}


case $TYPE in
	full) fullbackup
		;;
	incr)  incrbackup
		;;
	restore) restorebackup
		;;
	*) printhelp
		;;
esac

Ou seja: ./backup.sh full . para fazer um backup completo do containter. E ./backup.sh restore . para baixar o backup. Rode o script de criação do container e pronto! tá o container no ar novamente!

4 Likes