Persistindo dados – Flocker

Olá,

Hoje, no terceiro post da série: Persistindo dados, vamos abordar mais uma forma de como você pode persistir os dados de sua aplicação, garantindo maior disponibilidade para seu ambiente, hoje o assunto é sobre o Flocker.

 A proposta do Flocker é muito parecida com demais soluções para sistema de arquivos distribuídos, a grande diferença esta no foco que a ClusterHQ (desenvolvedora da solução) está dando para o projeto, pois o objetivo tem sido tornar o Flocker cada vez mais especializado em Docker, ou seja, o objetivo do Flocker não é atender a qualquer tipo de problema, mas sim, atender muito bem uma das deficiências que há no Docker , que é a persistência de dados, tanto que o Flocker em si já é um plugin de volumes oficial do Docker. Veja abaixo uma imagem que ilustra muito bem o que o Flocker se propõem a atender:

Fonte: https://clusterhq.com/flocker/introduction/

Atualmente, quando você instância um container em outro host, você precisa cuidar se o volume de onde está sua aplicação também tem mapeamento nesse novo host, o objetivo do Flocker abstrair esse tipo de preocupação, e garantir que, quando um container for movido de um lado para o outro, os dados que estavam mapeados nele também acompanhem esse movimento.

Veja abaixo como é a arquitetura dessa plugin:

Fonte: https://clusterhq.com/flocker/introduction/

Note que, diferentemente do GlusterFS, você precisa ter um ambiente mais complexo, envolvendo basicamente 3 camadas: Flocker Plugin, que é responsável pela comunicação entre o Docker e o Flocker; Flocker Conrol, responsável pelo monitoramento dos volumes, e controle sob o funcionamento do ambiente; Flocker Agent, responsável por executar as ações de criação, remoção e demais ações do Flocker no host que faz parte do ambiente.

Novamente, e o Docker?

Como já falamos em posts anteriores, a intenção não é mostrar a vocês como realizar a instalação e configuração do cluster de Flocker, e sim, seu uso final, juntamente com o Docker, talvez daqui a pouco possamos montar um material com isso ;).

Mãos a massa:

Primeiro vamos criar o volume Docker utilizando o plugin do Flocker, para isso:

$ docker volume create --name volume-1 -d flocker

Agora basta mapear esse volume criado aos containers que desejar:

$ docker run -v volume-1:/data -it centos /bin/bash

Basta criar algum arquivo ou pasta no diretório /data do container e essa informação será salva no volume Flocker que você criou, para ter certeza de que o dado estará nesse volume, crie outro container mapeando esse volume, e você verá que no /data desse novo container estará o arquivo/pasta que você criou no primeiro.

Fácil né? O mais interessante no Flocker é que você não perde os dados caso dê algum problema no host, o volume será criado no cluster Flocker que você montou, e isso é o que garante a disponibilidade da informação.

Por hoje era isso, espero que tenham gostado e tendo dúvidas nos avisem, e claro ajudem divulgando o Blog 😉

Abraço!

Persistindo dados – GlusterFS

Oi Pessoal,

Seguindo na sequência de posts sobre persistência de dados no Docker, hoje vamos ver como podemos utilizar um sistema de arquivos distribuídos para garantir a disponibilidade de sua aplicação dentro de containers.

Para quem não conhece, o GlusterFS é um sistema de arquivos distribuídos desenvolvido pela RedHat e mantido pela comunidade GlusterFS. Como ele funciona? O Gluster permite que você defina volumes compartilhados entre os hosts, isso faz com que os dados sejam distribuídos entre os nós que fazem parte desse volume, existem basicamente duas formas de distribuir os dados com o GlusterFS:

Distributed Glusterfs Volume

Nesse Formato, o GlusterFS distribuí os dados do volume entre todos os nós, isso quer dizer que cada nó terá apenas uma parte da informação, essa arquitetura é muito útil quando você deseja que a leitura seja muito rápida, pois o acesso é feito simultaneamente em todos os nós, mas não garante disponibilidade dos dados, pois caso um dos nós falhe, as informações que ele continha ficarão inacessíveis. Veja abaixo o desenho ilustrativo:

distributed_volume

Fonte: http://gluster.readthedocs.org/en/latest/Quick-Start-Guide/Architecture

Neste exemplo, quando for solicitado os arquivos File 1 e File 3, o Gluster consultará todos os nós e retornará a informação solicitada, como esse acesso é simultâneo, o tempo de resposta é reduzido.

Replicated Glusterfs Volume

No caso de se utilizar o método de replicação, os dados serão armazenados em todos os nóss, isso é claro aumenta o tempo de gravação do arquivo, pois o tempo de resposta será baseado no nó mais lento, mas garante disponibilidade da informação em caso de falha de algum outro nó. Veja abaixo como é esse tipo de arquitetura:

replicated_volume

Fonte: http://gluster.readthedocs.org/en/latest/Quick-Start-Guide/Architecture

Como ser visto, os arquivos são salvos sempre em todos os demais nós, a consulta é feita sempre no nó com menos latência, ou seja, o mais próximo do ponto de origem da requisição.

Há ainda uma forma mista de trabalho, onde é possível garantir que o dados seja replicado e que seja escrito em diversos nós, chama-se:

Distributed Replicated Glusterfs Volume

Dessa forma os dados são escritos em um volume distribuído, que possui ainda sub-volumes replicados, ou seja, você tem maior velocidade de leitura, e ainda garante que os dados estejam em vários nós ao mesmo tempo. Veja como isso funciona:

distributed_replicated_volume

Fonte: http://gluster.readthedocs.org/en/latest/Quick-Start-Guide/Architecture

Note que quando for salvo algum arquivo no ponto de montagem, ele salvará o arquivo no volume distribuído, e esse volume contém os sub-volumes replicados. Para todos os efeitos, o retorno da operação de gravação é realizado pelo volume distribuído, mas o dado será replicado entre os demais nós que fazem parte do volume replicado.

Ok, mas e o Docker?

O objetivo desse post não é ensiná-los a como instalar ou configurar o Gluster, mas sim, como utilizá-lo para garantir disponibilidade de seus dados. Pensando nisso, queremos mostrar para vocês como pode ser utilizado um plugins do Docker que provê suporte a GlusterFS, tenha em mente, antes de tudo, que você já deve ter seu cluster de GlusterFS montando e funcionando, independente da arquitetura escolhida ou ponto de montagem.

Passo 1:

Instale o plugin para administração dos volumes GlusterFS:

$ go get github.com/calavera/docker-volume-glusterfs
Passo 2:

Monte seu ambiente, informando quais servidores fazem parte do cluster que atenderá a demanda de volume, informe também em qual porta o serviço executará, caso esteja utilizando uma porta alternativa:

$ docker-volume-glusterfs -servers server1:server2:server3

É importante enfatizar que você precisará realizar esse procedimento em todos os hosts com Docker aos quais deseja utilizar esse plugin.

Passo 3:

Agora use!

$ docker run --volume-driver glusterfs --volume datastore:/teste centos touch /teste/ola

Inicie outro container, informando esses dados de volume e veja que foi criado um arquivo ola dentro da pasta teste:

$ docker run --volume-driver glusterfs --volume datastore:/teste centos /bin/bash
$ ls -la /teste/
$ -rw-r-xr-- 1 root root 1115 Apr 11 ola

O mais interessante é que nesse caso, você não precisa fazer com que os containers se falem diretamente, basta que nos hosts de Docker você inicie o plugin informando quais os hosts de GlusterFS que serão utilizados, feito isso é só mapear para o container e pronto, seus dados estarão sendo vistos por qualquer container que utilizar esse mesmo volume.

Gostou? Ajude divulgando o Blog 😉

Grande Abraço!

Persistindo dados -BTSync

Olá,

Hoje o mundodocker.com.br dará inicio a uma série de posts que tem por objetivo trazer soluções práticas para a persistência de dados no ambiente Docker.

Uma das premissas de se utilizar Docker é de que seu container é descartável, sim, isso pode parecer um tanto quanto radical, mas container em si foi desenvolvido para atender um processo durante um tempo determinado, e não para servir como um servidor virtual, nesse sentido, um cuidado que se deve ter é persistir os dados importantes de sua aplicação em um volume, ou até mesmo em um sistema de arquivo distribuído, dessa forma um container pode morrer, sem que sua aplicação morra junto.

Vamos ver nessa série, algumas alternativas para isso, e começamos com a mais simples delas: BTSync. Para quem não conhece o BTSync é uma ferramenta que utiliza o protocolo do Bittorrent para sincronismo de dados, através dele é possível sincronizar pastas e arquivos entre diferentes plataformas (desde que tenha o Sync instalado), de forma segura e rápida. No nosso exemplo vamos simular a sincronização de dados entre containers, dessa forma você pode fazer com que diversos containers tenha os dados de sua aplicação, garantindo assim maior disponibilidade. Mãos a obra então:

Como vocês já sabem, vamos criar um Dockerfile para gerarmos uma imagem e carrega-la para onde quisermos, esse é um bom exemplo:

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y curl
RUN curl -o /usr/bin/btsync.tar.gz http://download-lb.utorrent.com/endpoint/btsync/os/linux-x64/track/stable; cd /usr/bin && tar -xzvf btsync.tar.gz && rm btsync.tar.gz
RUN mkdir -p /btsync/.sync; mkdir -p /var/run/btsync; mkdir -p /data

EXPOSE 8888
EXPOSE 55555

ADD start.sh /usr/bin/start.sh

RUN chmod +x /usr/bin/start.sh

VOLUME ["/data"]

ENTRYPOINT ["start.sh"]

 

Na mesma pasta onde está esse Dockerfile, crie um arquivo chamado: start.sh com o seguinte código:

#!/bin/bash
SECRET="${@}"
: ${SECRET:=`btsync --generate-secret`}

echo "Starting btsync with secret: $SECRET"

echo "{
 \"device_name\": \"Sync Server\",
 \"listening_port\": 55555,
 \"storage_path\": \"/btsync/.sync\",
 \"pid_file\": \"/var/run/btsync/btsync.pid\",
 \"check_for_updates\": false,
 \"use_upnp\": false,
 \"download_limit\": 0,
 \"upload_limit\": 0,
 \"shared_folders\": [
 {
 \"secret\": \"$SECRET\",
 \"dir\": \"/data\",
 \"use_relay_server\": true,
 \"use_tracker\": true,
 \"use_dht\": false,
 \"search_lan\": true,
 \"use_sync_trash\": false
 }
 ]
}" > /btsync/btsync.conf

btsync --config /btsync/btsync.conf --nodaemon

Explicando: Você pode definir, via arquivo de configuração, algumas variáveis para o btsync trabalhar, como por exemplo chave para estabelecer comunicação, diretório que será sincronizado e limites de transferência, é claro que em nosso teste não vamos definir algumas delas, apenas alterei o “dir” para que seja sincronizado o diretório /data, você pode definir qualquer um. Por padrão, a porta de comunicação é a 55555, você pode modificá-la sem problema, e não é necessário você mapear portas do host para o container ;).

Então, criado o Dockerfile e o start.sh, vamos gerar a imagem:

docker build -t bt_mundodocker .

Agora é simples, basta você iniciar o primeiro container:

docker run -d --name repl1 bt_mundodocker

Você deve capturar a chave gerada na inicialização desse container, ela será útil para quando você iniciar o segundo container, pois será a chave que permitirá estabilizar a conexão entre os peers do btsync:

docker logs repl1

A saída desse comando, será algo parecido com isso:

Starting btsync with secret: ANDHOU5F7NHNR3EBPFYBPFJJMKATGLBEK
[20160329 21:23:04.194] total physical memory 536870912 max disk cache 2097152
[20160329 21:23:04.195] My PeerID: 102D9BFD720DF686F77DD0BC7FE5FDC98C767930
[20160329 21:23:04.683] LC: license expired
[20160329 21:23:05.291] LC: license renewal

Basta você inicializar o segundo container, passando essa chave como parâmetro:

docker run -d --name repl2 bt_mundodocker ANDHOU5F7NHNR3EBPFYBPFJJMKATGLBEK

Veja agora o retorno do comando docker logs desse container:

Starting btsync with secret: ANDHOU5F7NHNR3EBPFYBPFJJMKATGLBEK
[20160329 21:27:07.480] total physical memory 536870912 max disk cache 2097152
[20160329 21:27:07.482] My PeerID: 1015FC44C961E6AB9B77AD3951437CC69C6D357A
[20160329 21:27:07.756] LC: license expired
[20160329 21:27:08.084] LC: license renewal
[20160329 21:27:08.090] PeerConnection[0x00007fe9bc001170] incoming connection from 172.17.0.42:57871
[20160329 21:27:08.143] PeerConnection[0x00007fe9bc001170] incoming connection from 172.17.0.42:57871
[20160329 21:27:09.260] PeerConnection[0x00007fe9bc20a1c0] incoming connection from 172.17.0.42:55555

Para testar, acesse os containers (docker exec -it repl1/repl2 /bin/bash), crie arquivos dentro da pasta /data e veja que eles serão sincronizados entre os containers, mesmo se você tiver mais de dois containers. Legal né? Todo o trafego entre os containers (mesmo os que não sejam locais) é criptografado, e apenas peers (containers) que iniciaram com a chave mencionada é que entram na replicação. Claro, nem tudo são flores, quanto maior a latência entre os containers, mais lento será essa replicação, então pense bem antes de sair utilizando ele para qualquer coisa 🙂

Fácil, simples e muito eficiente, essa foi a apresentação da primeira solução para persistência de dados entre os containers, fique atento aos próximos. Se gostou, ajude divulgando o Blog.

Grande Abraço!