Criando um servidor web com docker

Olá!

Você está procurando uma forma de criar um ambiente web fácil e rápido? pois bem, hoje vamos mostrar como criar um ambiente web de maneira rápida e fácil. Nosso ambiente será constituído por 3 containers, sendo eles: Weave, HAProxy e Apache.

Com esse comando estamos criando o nosso container onde vamos colocar nosso apache

docker run -it --name apache centos /bin/bash

Agora já dentro do container vamos executar os seguintes comandos:


yum install wget -y
wget http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm #Estamos utilizando a versão 7 do CentOS em nosso container.
rpm -ivh epel-release-7-5.noarch.rpm

yum install httpd -y
yum install php -y

/usr/sbin/httpd -DFOREGROUND -k start &

vi /var/www/html/index.html #Dentro do arquivo index.php vamos colocar o código abaixo:

<?php
 echo "Mundo Docker";
?>

Feito isso acima agora vamos pressionar CTRL + P + Q assim estamos saindo do container e voltando para o nosso Host. Vamos instalar agora o Weave para conseguir trabalhar com a parte de redes de uma maneira mais simples.


curl -L git.io/weave -o /usr/local/bin/weave
chmod a+x /usr/local/bin/weave

weave attach 192.168.0.2/24 apache #Estamos vinculando o ip 192.168.0.2/24 ao container apache através da rede Weave.

Agora vamos criar o container com o HAProxy.

docker run -it --name haproxy -p 80:80 centos /bin/bash

yum install wget -y
wget http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm #Estamos utilizando a versão 7 do CentOS em nosso container.
rpm -ivh epel-release-7-5.noarch.rpm

yum install haproxy -y
echo "" > /etc/haproxy/haproxy.cfg
vi /etc/haproxy/haproxy.cfg 

Copiar e colar dentro desse arquivo



global
    chroot /var/lib/haproxy
    user haproxy
    group haproxy
    daemon



defaults
    log     global
    mode    http
    option  httplog
    option  dontlognull
    timeout connect 5000
    timeout client  50000
    timeout server  50000

frontend localnodes
    bind *:80
    mode http
    default_backend nodes

backend nodes
    mode http
    balance roundrobin
    option forwardfor
    server web01 192.168.0.2:80 check

Agora vamos iniciar o HAProxy



/usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg &

Feito isso acima agora vamos pressionar CTRL + P + Q para sair do container e vamos anexar um IP para esse container.


weave attach 192.168.0.1/24 haproxy

 

Após isso é só acessar http://seuip e você estará visualizando a sua página.

 

Por hoje era isso pessoal, em nossos próximos posts vamos mostrar como criar um ambiente web com alta disponibilidade, replicação de arquivos e muito mais. Então fique ligado e nos ajude a divulgar o mundodocker.com.br obrigado!.

Docker e Jenkins para build de aplicações

Olá pessoal,

Hoje queremos demonstrar para vocês como podemos utilizar Docker e Jenkins para o build de aplicações de forma rápida e fácil, primeiro vamos entender como é o ambiente de diversas empresas de TI hoje e você que estiver lendo este post possivelmente estará se identificando com isso.

Hoje diversas empresas utilizam a ferramenta Jenkins para build e deploy de aplicações, muitas vezes (Se não forem todas) essa maquina de Jenkins é compartilhada entre diversos times, Java, PHP, Python, Rails e NodeJS acabam utilizando. O que deixa essa máquina com ferramentas desnecessárias para as equipes, sobrecarregando o sistema e qualquer problema acaba parando todas as equipes.

Porém existem alguns casos mais organizados que a maquina onde irá ocorrer o build será uma máquina para cada equipe, o que torna o processo um pouco melhor, porém sempre que sair uma nova versões de softwares alguém precisa ficar atualizando essa máquina, o que pode acabar por muitas vezes impactando em prazos do projeto.

Então existe o que acreditamos que seja a melhor solução que seria a utilização de containers para o build de suas aplicações. mas porque usar containers?

  • Só dependências para aquela aplicação
  • Fácil manutenção
  • Ambiente de produção e local iguais.
  • Escabilidade

Então visto o porque que devemos utilizar containers para realizar o build, vamos mostrar como podemos utilizar essas duas ferramentas em sincronia.

Primeiramente vamos até as configurações do nosso repositório e clicar em “WebHooks & Services:4

Vamos até “Add Service” e adicionar o “Jenkins (Github Plugin)”
5
Agora em nosso servidor com Docker instalado, vamos iniciar o container que terá o Jenkins Master instalado.

############# SERVIDOR1 #################
docker run -p 8080:8080 -p 50000:50000 -d jenkins

Iniciado, agora vamos até o nosso browser e digitar http://ipserver:8080 e vamos fazer a configuração base do Jenkins.

1

Para pegar a senha você irá executar

docker exec idcontainer cat /var/jenkins_home/secrets/initialAdminPassword

Na pŕoxima página você pode escolher a opção de usar os plugins recomendados, então depois irá pedir para você criar um usuário.

2

Feito isso agora estamos na página inicial do jenkins.

3

Esse será nosso servidor de Jenkins Master que sera o responsável por avisar e mandar rodar alguns comandos no nosso servidor onde estará o Docker. Para isso, vamos acessar o servidor 2 e realizar a instalação do Jenkins:

############# SERVIDOR2 #################
sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key
sudo yum install jenkins -y
sudo yum install java -y 
sudo service jenkins start/stop/restart
sudo chkconfig jenkins on
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --reload
sudo yum install java-1.7.0-openjdk -y

Após realizar a instalação do servidor2, vamos até o nosso servidor de Jenkins Master e adicionar o outro nó nele, colocando o IP e a forma pela qual o agente fosse instalado: Para isso você deve ir até “Gerenciar Jenkins” >> “Gerenciar nós”

6

Após isso você irá clicar em novo nó, colocar o ip desse novo servidor e clicar na opção de “Permanent” e OK. Após isso irá aparecer algo parecido com a tela abaixo então, você tera que fazer download do slave.jar, ir até o outro servidor e executar o comando do java que é mostrado na imagem abaixo, porem com as suas configurações.

7

Feito isso, vamos até a tela da esquerda na opção de configurações e configurar parecido com a imagem abaixo: A parte mais importante dessa tela é a configuração do “rótulo” que é o apelido que vamos dar a esse servidor, e também o “uso” que estamos dizendo que vamos executar esse servidor apenas como jobs.

8

Agora vamos até a página inicial do nosso jenkins e então criar o nosso build. Vamos até “Novo Build”

9

Após selecionar “Novo Build” vamos até a opção de configuração:

10

Vamos colocar o nome do nosso servidor de slave na opção de “Restringe onde este projeto pode ser executado”

11

Abaixo vamos colocar o nosso caminho do “GitHub” e também de qual branch irá baixar o código.

12

Vamos marcar  a opção de “Build when a change is pushed to github” e também a opção de quanto em quanto tempo vamos ir consultar o nosso “SCM”.

14

Em nosso ultimo passo, vamos colocar os comandos que iremos executar em nosso servidor. Vamos criar uma imagem a partir do Dockerfile que está em nosso GitHub e após isso vamos iniciar o container com essa imagem.

15

Então por hoje era isso pessoal, espero que tenham gostado do post e gostaríamos que vocês interagissem através de comentários propondo novos posts e arquiteturas que vocês gostariam que a gente fizesse com Docker. Em breve teremos mais posts nesse estilo.

Obrigado!

Referências: https://docker.com/sites/default/files/RA_CI%20with%20Docker_08.25.2015.pdf

: https://jenkins.io/solutions/docker/

: https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins

Sysdig para Ops

Oi Pessoal,

Queremos mostrar para vocês hoje como é possível analisar seu ambiente Docker e ver a saúde de seus containers de forma fácil e bem prática, conheça nesse post o Sysdig. O Sysdig é uma ferramenta escrita em Lua que vem como uma opção, principalmente para quem é de operações, para realizar algum troubleshooting em seu sistema. Ele trás de forma rápida e fácil todas as informações que você precisa saber, não havendo mais a necessidade de executar dois, três comandos para ter uma noção do que está acontecendo, com o Sysdig em um único comando você já terá visibilidade do que é importante você saber e do que pode estar ocorrendo em seu sistema. O Sysdig também é multiplataforma, então é possível instalar ele tanto em Windows, quanto Linux e Mac, e claro, ele suporta containers, ótimo! Veja abaixo um mini tutorial que montamos para você:

1 – Instalação:

Simples, se for em um host Linux você pode utilizar o comando abaixo:

curl -s https://s3.amazonaws.com/download.draios.com/stable/install-sysdig | sudo bash

Você ainda pode baixar os repositório e utilizar sua ferramenta para instalação (yum, apt-get e afins), que saber como? Da uma olhada aqui e veja também como instalar o Sysdi em Windows e Mac.

2 – Utilização:

Mas claro o que nos interessa é saber como mais como está o uso de recursos do meu host, e descobrir qual container está utilizando mais em relação aos outros, ou ainda ver como está a saúde do meu ambiente Docker, mas como o Sysdig faz isso? Ele fica ‘ouvindo’ as chamadas de sistema e com base nessas informações monta os reports para você, veja na imagem abaixo como ele trabalha tanto com Docker quanto com LXC puro:

Perceba que o Kernel envia para o Sysdig todas as informações que foram processadas por ele, seja de acesso a memória, disco, rede, processador, etc. e com base nisso o Sysdig consegue mapear qual processo está vinculado a qual arquivo, ou quanto de trafego está sendo gerado por um container.

Veja abaixo o exemplo de alguns comandos que pode lhe ser muito uteis (existe um lista bem grande disponível, vamos colocar aqui apenas os essenciais e extremamente úteis para fazer um troubleshooting em seu ambiente Docker):

  • Listagem dos containters existentes:
    sysdig -c lscontainers
  • Top por containers que mais utilizam CPU:
    sysdig -c topcontainers_cpu
  • Você ainda por visualizar quais processos estão consumindo mais recursos dentro de cada container, para isso:
    sysdig -pc -c topprocs_cpu

O retorno desse comando será algo parecido com este gif:

 

topproc_cpu

  • Você pode ainda filtrar a saída do comando pelo nome de seu container:
    sysdig -pc -c topprocs_cpu container.name contains wordpress
  • Quer ver quanto de rede um container está utilizando?
    sysdig -pc -c topcontainers_net
  • E qual processo dentro de cada container está utilizando mais rede?
    sysdig -pc -c topprocs_net
  • Quais portas estão trafegando mais?
    sysdig -pc -c topconns
  • Consigo filtrar por nome de container também?
    sysdig -pc -c topconns container name=wordpress
  • Eu consigo saber quais containers estão utilizando mais I/O em meu host?
    sysdig -c topcontainers_file
  • Consigo saber qual processo dentro do container está fazendo isso?
    sysdig -pc -c topprocs_file
  • E quais arquivos realmente estão sendo mais lidos ou escritos?
    sysdig -pc -c topfiles_bytes

 

Ufa, já é um começo certo? Existem muitas outras opções disponíveis, como por exemplo agregar logs de todos os containers em uma única visualização, com o Sysdig isso é simples de se fazer, quer ver mais? Acessa a Wiki dele, ela é rica em informações: http://sysdig.org/wiki

Por hoje era isso, fique por dentro das novidades aqui do Blog e se você ainda não viu, montamos um fórum aqui no blog, acessa o link ai em cima e poste a sua dúvida ou dificuldade, assim tanto nós quantos outras pessoas da comunidade Docker podem te ajudar e claro nos ajude divulgando o MundoDocker, Abraço!

Docker Global Mentor Week

Olá Pessoal!

Para quem não viu ainda, na quinzena final de novembro será realizado uma das maiores ações do Docker para treinamento e troca de experiência entre seus usuários, esse evento foi chamado de Docker Global Mentor Week.

Essa é uma ação coordenada diretamente pela equipe do Docker com a ajuda dos organizadores dos grupos de meetup docker pelo mundo, o objetivo é simples: Dar treinamento técnico de alto nível de maneira abrangente e uniforme, ou seja, o conteúdo abordado em Singapura, é o mesmo no México, na Inglaterra e claro aqui no Brasil :). SIM teremos esse evento ocorrendo aqui no Brasil também, vou deixar abaixo os links desses eventos para que você possa se inscrever.

Mas afinal, esse é apenas mais um encontro do grupo de Meetup? Sim e Não, sim porque os canais utilizados para divulgação desse evento são os grupos de meetup e não porque esse evento tem conteúdo definido pela equipe do Docker e é repassado através de seus Mentors, que são pessoas ativas na comunidade docker e que auxiliam na divulgação de conteúdo, disseminação da tecnologia e enriquecimento da comunidade local. Você encontrará em cada evento no mínimo 1 Mentor, então não deixe de tirar suas dúvidas com ele(s).

Ok Cristiano, gostei, mas e valor? Bom, isso é um problema, por ser um evento oficial realizado no mundo inteiro, o valor para realizar esse treinamento é……. ZERO, sim é evento totalmente de graça, e agora, qual a sua desculpa?

E o conteúdo?

A equipe do Docker definiu uma série de trilhas que podem ser abordadas durante o evento, é claro que todas é impossível de serem realizadas num período de 3 a 4 horas, então cada usuário defini o que deverá ver no evento, e os mentor auxiliaram na execução do treinamento e esclarecimento de dúvidas. Os conteúdos em si vão do básico (criação de containers, Dockerfile, etc) até o avançado (orquestração, serviços, rede, volume, etc).

Onde serão realizados aqui no Brasil?

Temos por enquanto, 4 eventos confirmados aqui no Brasil, são eles:

Docker Global Mentor Week – Goiania – 14/11

http://meetup.com/pt-BR/Docker-Goiania/events/234750966/?eventId=234750966

 

Docker Global Mentor Week – Rio de Janeiro  – 16/11

http://meetup.com/pt-BR/Docker-Rio-de-Janeiro/events/234784863/?eventId=234784863&chapter_analytics_code=UA-48368587-1

 

Docker Global Mentor Week – São Paulo – 19/11

https://meetup.com/pt-BR/Docker-Sao-Paulo/events/235267786/?eventId=235267786&chapter_analytics_code=UA-48368587-1

 

Docker Global Mentor Week – Porto Alegre – 26/11

http://meetup.com/pt-BR/Docker-Porto-Alegre/events/235451287/?eventId=235451287&chapter_analytics_code=UA-48368587-1

 

O MundoDocker estará presente? Claro! Vamos auxiliar o pessoal do grupo de Porto Alegre!

 

Era isso por hoje pessoal, ajude você também divulgando os eventos e claro o blog

 

Grande abraço!

Docker 1.12

Oi Pessoal,
Já vimos aqui no blog algumas ferramentas e soluções, como por exemplo: Docker Compose, Docker Swarm, SwarmkitDocker Network, dentre outros. Bom, o que você sabe sobre elas é essencial para entender a nova versão do Docker, que será lançada em agosto e que está em RC4 atualmente.

A grande novidade no Docker 1.12 é ter a orquestração nativa, sem a necessidade de ter duas ou mais ferramentas para criar seu cluster de Docker, basta apenas que você tenha a engine instalada e a partir dela poderá montar seu ambiente. Outra grande novidade é o conceito de serviço, esse conceito nós já tratamos em Swarmkit, e é algo que foi incorporado ao Docker para facilitar o deploy e escalonamento das aplicações. Vamos ver o que muda?

Orquestração:

Agora para você criar um cluster de Docker, basta rodar:

docker swarm init

Com isso você iniciará o primeiro nó do cluster, para adicionar mais nós ao cluster execute o seguinte comando em outro nó:

docker swarm join IP-DO-MANAGER:2377

Veja na imagem abaixo a sequência de comandos:

docker_swarm

Serviços:

No Docker 1.12 foi introduzido o conceito de serviço, que já existe no Kubernetes, e que agora possibilita a criação, atualização e escalonamento da sua camada de serviço (seja ela de frondend ou backend) de forma muito mais fácil. Por exemplo:

docker service create --replicas 1 --name servico1 alpine echo "Ola Mundo"

Dessa forma você estará criando um serviço com um container de Alpine, você pode aumentar a quantidade de containers que irão atender este serviço, para isso execute:
docker_service

Além de poder criar e escalonar, você pode ainda realizar a atualização de seu ambiente, basta utilizar o comando update, e pode ainda definir uma politica de atualização (por exemplo, executar a atualização em um container por vez, com isso ele removerá um container e iniciará um novo baseado na nova imagem). Você pode ainda, definir um bloco de rede para cada serviço, com isso você isola totalmente os ambientes, veja:

docker service create --replicas 3 --name webservers --network web --publish 80:80/tcp nginx

Dessa forma, serão criados 3 containers (caso você tenha colocar 2 ou mais hosts no cluster de Swarm, será criado um container por host). O mais interessante nesse ambiente é que, se você acessar a porta 80 de qualquer host que esteja no cluster Swarm, seu acesso será redirecionado ao serviço, independente se o container esteja nele ou não, isso por que o Docker garante que o serviço esteja acessível mesmo que um nó venha a falhar. E como o Docker faz isso? Simples, através da 3 feature adicionada nessa versão:

Roteamento:

Quando você criar um cluster via Docker Swarm, o Docker se encarregará de atribuir ao serviço um identificador único dentro do cluster, com isso, quando for solicitado acesso á porta exposta na criação do serviço, o acesso será roteado para o container que é responsável por aquele serviço (ou mais de um é claro), ele faz isso através do algoritmo de routing mesh que está presente na engine, ele identifica quem possuí o container que atende o serviço e redireciona o trafego para ele, por isso é importante que, quando você criar um novo serviço define uma rede também, pois reduzirá o tempo de processamento que a engine precisará para identificar onde encontra-se o container.

Segurança:

Por último e não menos importante, vem a questão de segurança. No Docker 1.12, toda a comunicação do cluster é realizada via tls, e quem garante o rotacionamento desses certificados (renovação e deploy) assim como a criação de certificados para novos nós é o nó manager, que é eleito baseado em uma série de parâmetros (disponibilidade e saúde), mas que de maneira geral é o primeiro nó onde você iniciou o cluster. Os certificados são rotacionados de tempos em tempos, e você pode modificar essa politica também.

Há mais coisas? Claro! Foi adicionado também um sub comando do comando docker plugin que permite você plugar de forma mais fácil os plugins do Docker, quando você realizar um docker plugin install nome_do_plugin, lhe será informado ao que exatamente aquele plugin terá acesso, e poderá assim permitir ou não sua instalação.

Bacana né? Se gostou nos ajude divulgando o blog e caso tenha dúvida nos avise

Grande Abraço!

Docker – API Autenticada

Oi Pessoal,

Uma das grandes vantagens em se utilizar o Docker em vez de LXC puro é a facilidade de se trabalhar utilizando uma API de integração, isso facilita e agiliza a vida tanto de programadores quanto do pessoal de operações. Alguns cuidados devem ser tomados é claro, entre eles em não expor a API de seu host Docker, pois nativamente não há um método de limitar o acesso. Existem soluções para isso? É claro, e hoje o mundodocker.com.br abordará um delas: Docker API com Basic Authentication.

Passo 1:

Primeiramente você deve expor a API do Docker apenas localhost, para isso você deverá editar o arquivo de configuração, no nosso exemplo (CentOS 7) é no /etc/sysconfig/docker, e deixe-o assim:

OPTIONS='-H tcp://127.0.0.1:2376 -H unix:///var/run/docker.sock'

Em seguida reinicie o serviço do Docker:

systemctl restart docker.service

Passo 2:

Agora precisamos instalar e configurar um proxy http (Nginx, Apache, etc), no nosso exemplo vamos utilizar o Nginx, para isso:

yum install nginx -y

Agora precisamos definir as credenciais de acesso, é simples, basta criar .htpasswd e fazer com que o proxy exija usuário e senha em uma determinada url, vamos lá:

htpasswd -c /etc/nginx/.htpasswd USUARIO

Ele solicitará a senha, digite-a duas vezes e está pronto seu arquivo de autenticação.

Agora vamos a configuração do proxy, para isso precisamos editar o arquivo: /etc/nginx/conf.d/default.conf e deixe-o da seguinte forma:

server {
 listen 2375 default_server;
 server_name localhost;
 location / {
 proxy_pass http://127.0.0.1:2376;
 auth_basic_user_file /etc/nginx/.htpasswd;
 auth_basic "Acesso restrito a API do Docker";
 }
}

O que falta? reiniciar o serviço do Nginx:

systemctl restart nginx.service

Testes

Depois de tudo configurado (se fosse não encontrar nenhum erro no caminho também ) basta você testar de uma forma bem simples: http://ipdoservidor:2375/info ele solicitará os dados informados anteriormente via htpasswd e retornará algumas informações do Docker e dos containers que está em execução neste host.

Você pode optar por outro método, que é o certificado SSL diretamente na API do Docker, isso garante que apenas clientes confiáveis tenham acesso ao host (pois deverão tem o certificado client configurado). E claro, você pode configurar para que o Nginx trabalhe sob SSL, isso garante que, além da autenticação com usuário e senha, você ainda tenha todos os seus dados trafegados de forma criptografada (esse sim é um ótimo método).

Por hoje era isso gente, gostaram? Ajudem divulgando o Blog por ai

Abraços!

Docker e Weave

Olá pessoal,

Hoje vou demonstrar através de um vídeo, como podemos utilizar uma aplicação do ecossistema Docker para que se possa trabalhar de uma maneira mais fácil com a parte de rede, Essa ferramenta se chama Weave e você pode fazer download dela a partir do endereço: https://github.com/weaveworks/weave.

 

Ficou dúvida? Curiosidade? Deixe sua dúvida e vamos conversando, divulgue o mundodocker.com.br e nos ajude disseminando conhecimento!

Docker ToolBox

Oi Pessoal,

Você, sim você mesmo, que não tem grandes conhecimentos em Linux mas quer aprender Docker, criar seus containers e montar suas imagens, pois bem, esse post é pra você ;). Queremos mostrar como instalar e utilizar a ferramenta Docker ToolBox, que é um ótimo utilitário para subir seu ambiente Docker dentro de seu Windows ou Mac de forma fácil e rápida, montamos esse vídeo para lhe auxiliar, veja:

Basta você acessar: https://docker.com/docker-toolbox, fazer download da ferramenta e instalar como está ilustrado no vídeo. Ficou com dúvida ou dificuldade? Sem problema, deixa seu comentário ou ainda posta lá no nosso fórum: /forum que vamos lhe ajudando.

Esperamos ter ajudado e nos ajude divulgando o Blog.

Container no Windows Server 2016 TP3

Olá pessoal !

Como já publicado aqui no mundo docker Docker no Windows Server Server 2016, hoje vou explicar como funciona a criação e administração de um container no Windows server 2016 TP3. Mas antes quero deixar dois links para vocês onde há uma explanação mais aprofundada de como o Windows manipula containers, é basicamente uma leitura obrigatória ehehe:

https://msdn.microsoft.com/virtualization/windowscontainers/about/about_overview
http://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/

Requerimentos:
Windows Server 2016 TP3
10GB disponível para imagem sistema operacional de scripts
Permissão de admin na máquina.

Sem mais demora, vamos ao vídeo onde estarei ensinando vocês a criarem containers e acessá-los remotamente:


Gostou do vídeo ou do post? Divulga nosso Blog, ajude-nos a disseminar cada vez mais o conhecimento sobre Docker.

Docker Compose V3

Olá pessoal, tudo bem?

 

Conforme falamos em um post anterior o Docker lançou uma nova versão a 1.13 e nessa nova versão tivemos diversas melhorias e com a entrada dessa nossa versão também tivemos a criação de uma nova versão no Docker Compose que é a v3. Essa nova versão é totalmente compatível com o Docker Swarm que hoje é nativo na mesma engine no Docker, então agora com Docker Compose podemos gerenciar nossos serviços através do Docker Swarm.

Agora com a V3 existe opção chamada deploy que é responsável por realizar as implantações e execução de serviços. Dentro dessa opção temos as seguintes funções:

  • Mode
    • Onde é possível escolher a opção “Global” (Um container por nó de swarm) ou “Replicated” (Onde posso escolher a quantidade de réplicas que estarão distribuídas entre os nós). O padrão é replicated.
    • Replicas
      • replicas: x
    • Global
  • Placement
    • Especifica restrições de posicionamento são elas:
      • node.id = idworker
      • node.hostname = nomeworker
      • node.role = manager ou worker
      • node.lables = nome
      • engine.labels = Sistema Operacional ou Driver
  • Update_config
    • Configura como devem ser as opções de atualizações dos serviços.
    • Parallelism: 5 #O Numero de containers que vão ser atualizados em paralelo.
    • delay: 10s #O tempo entre cada grupo de containers será atualizado
    • failure_action: pause ou continue #O que irá acontecer se a atualização falhar. O padrão é pause.
    • monitor: 0s # Duração após cada atualização para monitorar a falha. O padrão é 0s.
    • max_failure_ratio: #Taxa de falha para atualizar.
  • resources
    • Configura a restrição de recursos
      • limits:
        • cpus: ‘0.5’ # 0.5 representa 50% de um núcleo, porem pode ser 1 ou 1.5 ou 2….
        • memory: ‘512M’ #apenas especificar o prefixo M, G, K….
  • Restart_policy
    • Configura como reiniciar os containers quando eles derem exit.
      • condity: none on-failure any #Por padrão é any
      • delay: 0s #Tempo entre as tentativas de reiniciar o containers #Por padrão é 0s
      • max_attempts: 0 #Quantas vezes irá tentar subir o container antes de desistir #Por padrão é nunca desistir.
      • window: 0s #Quanto tempo demora para decidir se um reinicio foi bem sucedido  #Por padrão é imediatamente,

 

Alem dessas opções, com a entrada da V3 foram descontinuadas as seguintes opções do Docker Compose: volume_driver, volumes_from, cpu_shares, cpu_quota, cpuset, mem_limit, memswap_limit

Agora vamos demonstrar um exemplo de como ficaria o docker-compose.yml com essas opções que mostramos acima.

version: "3"
services:

  redis:
    image: redis
    ports:
      - "6379"
    deploy:
      placement:
        constraints: [node.role == manager]
  nginx:
    image: nginx
    ports:
      - 80:80
    depends_on:
      - redis
    deploy:
      mode: replicated
      replicas: 2
      placement:
        constraints: [node.role == manager]
      resources:
        limits:
          memory: 512M
      restart_policy:
        condition: on-failure
        delay: 10s

Executando o comando docker deploy --compose-file docker-compose.yml nomedastack criamos a stack mencionada acima em nossa estrutura. Após executar esse comando é possível dar um docker stack ls e você poderá ver que a sua stack foi criada, com o nome da sua stack você pode executar o docker stack services nomedastack e poderá ver os serviços criados e qual o seu status.

Então ta pessoal, por hoje era isso, espero que tenham gostado e qualquer dúvida é só deixar um comentário que estaremos felizes em lhe ajudar, nos ajude divulgando o blog obrigado!

 

Portando aplicação para Docker

Oi Pessoal,

Para você que acompanha nosso blog, o mundodocker.com.br, hoje vamos mostrar um pouco mais de prática no Docker, vamos colocar em containers algumas aplicações e ver como é fácil ter seu ambiente totalmente portável. Para você que está começando com Docker, esse post será útil para entender e aprender como você pode começar, em casa mesmo, a mexer com Docker e fazer deploy de aplicações com ele. Já você que conhece Docker e já utiliza ele em seu ambiente, terá a oportunidade de pegar algumas dicas de como pode melhorar seu processo de deploy e criação de imagens.

Vamos lá:

 NodeJS

Vamos montar primeiro uma imagem de nossa aplicação, neste exemplo vamos utilizar o Framework Express do node. Primeiro crie um pasta, neste caso chamamos de app:

mkdir app

Crie dentro dessa pasta dois arquivos, package.json:

{
 "name": "app-node-mundodocker",
 "private": true,
 "version": "0.0.1",
 "description": "Teste App Node em Docker",
 "author": "MundoDocker <[email protected]>",
 "dependencies": {
 "express": "3.2.4"
 }
}

E index.js:

var express = require('express');

// Constants
var PORT = 8080;

// App
var app = express();
app.get('/', function (req, res) {
 res.send('Minha App Noden');
});

app.listen(PORT);
console.log('Running on http://localhost:' + PORT);

Em seguida crie o arquivo Dockerfile:

FROM centos:centos6

# Habilita o repositório epel no CentOS
RUN yum install -y epel-release
# Instala o node e o npm
RUN yum install -y nodejs npm

# Instala as dependências 
COPY package.json /src/package.json
RUN cd /src; npm install

# Copia a app para a pasta src do container
COPY . /src

EXPOSE 8080
CMD ["node", "/src/index.js"]

Agora vamos criar a imagem:

docker build -t mundodocker/app-node-mundodocker .

Fácil né? Agora só criar o container e testar:

docker run -p 9090:8080 -d mundodocker/app-node-mundodocker

Se você acessar: http://seuip:9090 deve aparecer uma página como essa:

NodeApp

Rails

Agora vamos montar uma imagem utilizando uma aplicação em rails, primeiro vamos criar a pasta onde em seguida coloque nela os arquivos da aplicação e crie o Dockerfile:

FROM ruby:latest 
ENV HOME /home/rails/webapp 

# Instala as dependencias
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs 
WORKDIR $HOME 

# Instala as gems necessárias
ADD Gemfile* $HOME/ 
RUN bundle install 

# Adiciona os arquivos a pasta home 
ADD . $HOME 

# Executa o comando
CMD ["rails", "server", "--binding", "0.0.0.0”] 

Vamos criar a imagem:

docker build -t mundodocker/app-rails-mundodocker .

Agora só criar o container e testar:

docker run -p 3000:3000 -d mundodocker/app-rails-mundodocker

Acesse http://seuip:3000 e você deverá ter um retorno desses:

RailsApp

Python

Para uma aplicação python vamos criar uma pasta chamado app e dentro dela criar um arquivo chamado app.py:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
 return 'Minha App em Python!n'

if __name__ == "__main__":
 app.run(host="0.0.0.0", debug=True)

E também um Dockerfile:

FROM orchardup/python:2.7
RUN pip install Flask
ADD . /code
WORKDIR /code
CMD python app.py

Em seguida vamos gerar uma imagem desse ambiente:

docker build -t mundodocker/app-python-mundodocker .

Fácil né? Agora só criar o container e testar:

docker run -d -p 5000:5000 mundodocker/app-python-mundodocker

Se você acessar: http://seuip:5000 deve aparecer uma página como essa:

PythonApp

Baseado nesses exemplos você pode ir modificando e acrescentando o que for necessário para sua aplicação, não esquecendo que você pode criar links entre as aplicações, trazendo maior facilidade e segurança para seu ambiente.

Gostou? Nos ajude divulgando o Blog, grande Abraço!

Docker AUFS

Olá pessoal,

AUFS foi o primeiro controlador de armazenamento em uso com Docker, como beneficio tem uma história longa com Docker. É muito estável, tem grandes implementações no mundo real e possui forte apoio da comunidade, o AUFS possui diversas características que acabam o tornando uma boa escolha para uso com Docker. Entre elas estão:

  • Tempo de inicialização do container rápido
  • Uso eficiente de armazenamento
  • Uso eficiente de memória

Apesar de ter uma ampla capacidade de caracteristicas com Docker, algumas distribuições não possuem suporte ao AUFS, pois ele não está incluído na linha principal do Kernel Linux, no caso do RHEL não é suporte AUFS.

Os tópicos seguintes demonstram algumas características do AUFS e como ele se relaciona com o Docker:

 

Layers de Imagens:

AUFS é um sistema de unificação de arquivos, isso quer dizer que ele leva vários diretórios em um único host linux, colocando um sobre o outro e fornece uma visão unificada desses arquivos para conseguir isso o AUFS usa uma união de montagem.

O AUFS driver de storage do Docker implementa Layers de imagens utilizando usando a união do sistema montado. Abaixo podemos ver um exemplo de Layers, onde para o cliente é apresentado a união de todas elas:

 

layer1

 

Utilizando arquivos:

O Docker utiliza a tecnologia de “AUFS CoW”  para conseguir compartilhar a imagem e minimizar o uso de disco. Como o AUFS trabalha em nível de arquivos então todos os dados são copiados por inteiros para a camada superior mesmo que modificando uma pequena parte do arquivo, isso faz com que dependendo do tamanho de arquivo que será copiado acabe penalizando um pouco o desempenho do container, pois um arquivo muito grande demorará algum tempo para que seja copiado. Ou também a imagem possui uma grande quantidade de camadas e o arquivo que você deseja utilizar está na primeira camada da imagem.

A ordem de procura é de cima para baixo, então caso seja a primeira vez que o usuário irá utilizar aquele arquivo, então o Docker vai procurar esse arquivo nas suas camadas abaixo e copiar todo o seu conteúdo para a camada gravável do container. Porém o arquivo só é copiado na primeira vez, após isso o esse arquivo já está na ultima camada então todas as demais operações são rápidas.

Deletando arquivos:

O driver do AUFS exclui um arquivo de dentro do container colocando um arquivo whiteout na camada gravável do container. O arquivo whiteout obscurece a existência do arquivo nas camadas inferiores de imagem:

 

 

layers2

 

 

Você pode adicionar o driver AUFS no seu daemon docker editando o arquivo de conf do docker e adicionando:

DOCKER_OPTS="--storage-driver=aufs"
systemctl restart docker

 

Então ta pessoal esse é nosso primeiro post dessa série que vai mostrar para vocês os drivers de armazenamento nativos do Docker.

 

Docker Stack e Deploy

Oi Pessoal,

Nós já conversamos sobre o Docker 1.13 aqui, agora vamos explorar um pouco mais sobre essa funcionalidade que saiu do modo experimental e tornou-se parte da engine estável do Docker, sim estamos falando do docker stack/deploy. Mas antes, recomendo fortemente você ler este post aqui sobre docker compose v3, ele é muito, mas muito importante mesmo para os exemplos que veremos neste post.

Agora com o Docker 1.13 é possível você portar suas aplicações do compose para o Swarm, e isso graças a funcionalidade de deploy disponível na engine. Seu funcionamento é bem simples, basta você informar na execução do comando o diretório de onde está o seu arquivo compose, e o nome da aplicação, se lembra que falei que era muito importante olhar esse post? Pois bem, não adianta você ter um compose escrito para a versão 2 e tentar utilizar aqui, será necessário você se altere para as novas regras da versão 3 para que seja possível a criação de sua stack pelo docker deploy. Mas digamos que você já tem seu arquivo pronto na versão 3, vamos pegar o exemplo do outro post, basta executar:

$ docker deploy --compose-file docker-compose.yml app

O retorno desse comando será

$ docker deploy --compose-file docker-compose.yml app
Creating network app_default
Creating service app_nginx
Creating service app_redis

Dessa forma foram criados uma rede e dois serviços, o mesmos definidos no arquivo compose. Para obter mais informações da stack, você pode executar os comandos:

$ docker stack ls
NAME SERVICES
app 2

Com o stack ls, será retornado todas as stacks que você criou, neste caso retornou apenas a “app” e informa também quantos serviços existem para essa stack, com este comando:

$ docker stack ps app
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
xb02xrua71db app_redis.1 redis:latest node1 Running Running 7 minutes ago
lm7k8obhncyl app_nginx.1 nginx:latest node1 Running Running 7 minutes ago
jh65f9scx0cq app_nginx.2 nginx:latest node1 Running Running 7 minutes ago

Você visualizará mais informações sobre a stack, como por exemplo o id de cada container, imagem utilizada, nome do container, nó onde está executando e claro o estado de cada container. Você pode ainda, executar o comando:

$ docker stack services app
ID NAME MODE REPLICAS IMAGE
g3i4f4erympf app_nginx replicated 2/2 nginx:latest
s11w093eraxz app_redis replicated 1/1 redis:latest

Para ter a visualização de sua stack no mesmo formato dos serviços (docker service ls).

O que fizemos até aqui foi portar uma stack do docker-compose para o cluster de swarm.

 

“Ahh mas como assim?”

Bom se você pegar esse mesmo arquivo de compose e executar: docker-compose up -d, ele funcionará também, sem erro, sua stack iniciará e ficará disponível para uso, MAS, não em cluster :), você continuará utilizando o docker-compose da mesma forma que antes, sem os benefícios do Swarm. Apenas com o docker deploy é que você poderá fazer o deploy e gerenciamento de sua stack dentro do cluster de swarm.

“Ok, entendido, mas como eu escalo agora a minha stack? Antes eu executava: docker-compose scale app=3, como faço isso com o docker stack?”, não se preocupe, você continuará tendo a possibilidade de escalar a sua stack, vamos lá: Já sabemos que o docker deploy criar todos os serviços necessários para a stack, certo? Pois bem, para escalar algum componente da sua stack, basta você escalar o serviço, da mesma forma como se você estivesse manipulando um serviço dentro do swarm, veja:

$ docker service ls
ID NAME MODE REPLICAS IMAGE
cnnabnpqkjvy app_redis replicated 1/1 redis:latest
pcn4urntqn8l app_nginx replicated 2/2 nginx:latest

Agora vamos escalar o serviço de nginx da minha stack app:

$ docker service scale app_nginx=4
app_nginx scaled to 4

E o resultado é:

$ docker service ls
ID NAME MODE REPLICAS IMAGE
cnnabnpqkjvy app_redis replicated 1/1 redis:latest
pcn4urntqn8l app_nginx replicated 4/4 nginx:latest

Ou seja, escalei apenas o nginx.

 

“Ok, muito bonito, mas como eu acesso a minha stack?”

Boa pergunta, mas é claro que há uma resposta, e é aqui que vem a parte mais legal ;).

Vamos voltar ao docker-compose.yml que usamos para criar essa stack, veja essas linhas:

nginx:
    image: nginx
    ports:
        - 80:80

Preste atenção no parâmetro: ports, ali você define em qual porta o serviço vai ouvir, neste caso, o nginx estará trabalhando na porta 80, ou seja, o serviço no cluster de swarm estará disponível para acesso através da porta 80, e todos os nós do cluster, quando receberem alguma requisição na porta 80 encaminharão para o container que atende este serviço (utilizando uma das funcionalidade do docker swarm que é a rede de serviço em mesh).
Quando escalamos um serviço, dizemos ao docker para adicionar mais containers para atender as requisições que estarão sendo feitas para o mesmo, ou seja, teremos diversos containers atendendo um único recurso que é o serviço, e o swarm se encarrega de distribuir os acessos para todos os containers.

 

“Ta bom, me convenceu, mas como removo tudo agora pra fazer direito?”

Muito fácil, da mesma forma que o docker service, basta você executar:

$ docker stack rm app
Removing service app_redis
Removing service app_nginx
Removing network app_default

E serão removidos todos os serviços, containers e rede que tenham sido criadas pela sua stack.

Interessante não? Esperamos que tenha sido útil, se ficou com dúvida nos avisa que ajudamos. Por hoje era isso, nos ajude divulgando o blog e fique atento, teremos mais novidades em breve ;).

Abraço!

 

Escalando o MySQL com Docker e MaxScale

Oi Pessoal,

Não, hoje o post não é nosso :). Mas queremos divulgar um ótimo conteúdo criado por um de nossos parceiros, o MySQLBox, que é um dos maiores blogs sobre o SGBD MySQL e é mantido por um grande amigo nosso.

Então não deixe de ler o post: Escalando Mysql com Docker e Maxscale e veja como o Docker pode ajudar a escalar seu ambiente de banco de dados de forma fácil e rápida.

Grande abraço!

Link entre Containers – Parte 2

Olá!

Dando prosseguimento a primeira parte, vou trazer hoje como o Docker cria o tunelamento entre os containers para criar o Link. Como você viu aqui no Blog é possível criar um acesso seguro entre os containers sem a necessidade de expor portas tcp/udp tanto do host quanto do próprio container, para isso basta utilizar o parâmetro “link” e você vinculará dois containers. Mas como o Docker fazer com que esse acesso seja seguro e confiável? Basicamente de duas formas, são elas:

1 – Variáveis de ambiente:

O Docker cria diversas variáveis ​​de ambiente quando você cria um link entre os container. Docker, ele automaticamente as variáveis ​​de ambiente no container de destino com base nos parâmetros –link, ele também irá expor todas as variáveis ​​de ambiente provenientes do container de origem. Essas variáveis podem vir de:

  • Do comando ENV, utilizado na criação da imagem de origem via Dockerfile;
  • Das opções -e, –env e –env-file no comando docker run quando o container de origem é criado.

Essas variáveis ​​de ambiente possibilitam acessar programaticamente as informações do container de origem, ou seja podemos automatizar tarefas de deploy utilizando as variáveis carregadas de um container para o outro..

Aviso: É importante compreender que todas as variáveis ​​de ambiente provenientes de um container são disponibilizados para qualquer outro container que esteja ligado a ele. Isso poderia ter sérias implicações de segurança se dados sensíveis são armazenados nas variáveis de ambiente (como pode exemplo usuário e senha de banco de dados).

O Docker define um <alias>_NAME padrão como variável de ambiente para cada container de destino listado no parâmetro –link. Por exemplo, se um novo container chamado web está ligado a um container de banco de dados chamado db via –link db: webdb, então Docker cria uma variável WEBDB_NAME=/web/ webdb no container web.

Docker também define um conjunto de variáveis ​​de ambiente para cada porta exposta pelo container de origem. Cada variável tem um prefixo único no formulário:

<name>_PORT_<port>_<PROTOCOL>

Os componentes desses prefixos são:

  • O  alias <name> especificado no parâmetro –link (por exemplo, webdb);
  • A <port> exposta no container de origem;
  • O <protocol>, se é TCP ou UDP;

Docker usa este formato de prefixo para definir três variáveis ​​de ambiente distintas:

  • A variável prefix_ADDR contém o endereço IP a partir do URL, por exemplo WEBDB_PORT_5432_TCP_ADDR = 172.17.0.82.
  • A variável prefix_PORT contém apenas o número da porta, por exemplo WEBDB_PORT_5432_TCP_PORT = 5432.
  • A variável prefix_PROTO contém apenas o protocolo, por exemplo WEBDB_PORT_5432_TCP_PROTO = tcp.

Se o container expõe várias portas, uma variável de ambiente é definido para cada porta exposta. Isso significa, por exemplo, se um container expõe 4 portas o Docker cria 12 variáveis ​​de ambiente, 3 para cada porta.

Além disso, Docker cria uma variável de ambiente chamada <alias>_PORT. Esta variável contém do container de origem e a primeira porta exposta. A ‘primeira’ porta exposta é definida como a de menor número. Agora, considere essa variável: WEBDB_PORT=tcp: //172.17.0.82:5432, Se essa porta é usada para TCP e UDP, você deve especificar o protocolo tcp primeiro.

Agora na prática, vamos criar um container chamado site ligado a um container chamado db, veja o retorno do comando env dentro do container web:

    $ docker run --rm --name site --link db:db mundodocker/app env
    . . .
    DB_NAME=/site/db
    DB_PORT=tcp://172.17.0.5:5432
    DB_PORT_5432_TCP=tcp://172.17.0.5:5432
    DB_PORT_5432_TCP_PROTO=tcp
    DB_PORT_5432_TCP_PORT=5432
    DB_PORT_5432_TCP_ADDR=172.17.0.5
    . . .

Você pode ver que Docker criou uma série de variáveis ​​de ambiente com informações úteis sobre o container de origem ‘db‘. Cada variável é prefixado com DB_, que é preenchida a partir do alias especificado acima. Se o alias fosse db1, as variáveis ​​seriam prefixado com DB1_. Você pode usar essas variáveis ​​de ambiente para configurar suas aplicações para se conectar ao banco de dados no container db. A conexão será segura e privada; apenas o container site será capaz de falar com o container db.

Importante sobre variáveis ​​de ambiente Docker
Ao contrário de entradas de host no arquivo /etc/hosts, os endereços IP armazenados nas variáveis ​​de ambiente não são atualizados automaticamente se o container de origem é reiniciado. É recomendado a utilização das entradas de host em /etc/hosts para atualizar automaticamente o endereço IP de containers ligados.

As variáveis ​​de ambiente só são definidas para o primeiro processo no container. Alguns daemons, como sshd, limpará essas variáveis em uma nova conexão.

2 – Atualizando o arquivo / etc / hosts

Além das variáveis ​​de ambiente, o Docker adiciona uma entrada de host para o container de origem no arquivo /etc/hosts do container de destino. Veja como fica o /etc/hosts do container de destion:

$ docker run -t -i --rm --link db:sitedb mundodocker/app /bin/bash
root@aed84ee21bde:/opt/app# cat /etc/hosts
172.17.0.7  aed84ee21bde
. . .
172.17.0.5  sitedb 6e5cdeb2d300 db

Você pode ver duas entradas de host, a primeira é uma entrada para o container site que usa o Container ID como um nome de host. A segunda entrada utiliza o alias para referenciar o endereço IP do container db. Quer testar? Ótimo, do container que você acabou de criar (sitedb), você pode pingar os nomes definidos no link, por exemplo:

root@aed84ee21bde:/opt/app# ping db
PING webdb (172.17.0.5): 48 data bytes
56 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.267 ms
56 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.250 ms
56 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.256 ms

Você pode ver que o nome db responde ao ip do container onde está o seu banco de dados, que resolve para 172.17.0.5. Você pode usar essa entrada do host para configurar um aplicativo para fazer uso de seu container db.

Nota: É possível ligar vários container de destino em um único de origem. Por exemplo, você pode ter vários (com nomes diferentes) containers web conectados ao seu container db.

Se você reiniciar o container db, os containers ligados via /etc/hosts serão atualizados automaticamente com novo endereço IP do container de origem, permitindo que a comunicação continue.

Legal né? a partir disso é possível criar sistemas distribuídos de forma mais fácil, uma utilização bem importante é relacionado a criar link entre containers de aplicação e de volume, isso será tratado em posts futuros.

Estaremos ter ajudado, e tendo dúvidas nos avise, e claro ajude 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!

Cluster Mongo em Docker

Opa!

Hoje o post será mais prático, e queremos trazer para vocês uma forma de criar um cluster de MongoDB utilizando Docker. O próprio Docker tem um tutorial de como você pode criar a sua imagem de mongo e executá-lo dentro do Docker, para quem não viu ainda, segue o link. Para quem não conhece, MongoDB é um tipo de banco de dados orientado a documentos ou seja, utiliza o conceito de dados e documentos auto contidos e auto descritivos, e isso implica que o documento em si já define como ele deve ser apresentado e qual é o significado dos dados armazenados na sua estrutura.

O MongoDB também é chamado de banco de dados NoSql, mas isso é outro assunto . O que veremos neste artigo é como você pode montar um cluster de instâncias do mongo utilizando como backend containers Docker. Isso é possível pois o existe na “caixa” do mongo algumas formas de se construir um cluster, uma delas é utilizando o método de replica set, que consiste em ter instâncias  para onde a informação será replicada, e dessa forma garantir a persistência das informações, abaixo segue uma imagem ilustrativa de como isso funciona:

Dessa forma garantimos a persistência e tolerância a falha dos dados que estão sendo armazenados. Neste post mostraremos como utilizar essa abordagem, não entraremos em detalhes mais fundos do Mongo pois não é este o objetivo.

Vamos lá?

Antes de tudo, é recomendável que os servidores possam ser acessíveis via nome, caso não seja possível, você pode adicionar nos hosts os endereços para que isso seja temporariamente possível.

Em seguida precisamos criar o diretório no host onde será persistido os dados do banco:

$ mkdir /opt/mongo
$ mkdir /opt/mongo/data $ cd /opt/mongo

É importante lembrar que essas pastas devem estar criadas em todos os nós, para que dessa forma seja possível persistir os dados em todos os nós.

Agora você precisa gerar uma chave que será utilizada para realizar a sincronia entre as replicas, e garantir que os dados além de trafegar de forma segura, estejam replicados entre todos os nós, essa chave deve ser copiada para todos os nós também.

$ openssl rand -base64 741 > mongodb-keyfile $ chmod 600 mongodb-keyfile $ chown 999 mongodb-keyfile

Configurado este arquivo, precisamos subir um container para realizar algumas tarefas administrativas, para depois subir o cluster propriamente dito:

$ docker run --name mongo -v /opt/mongo/data:/data/db -v /opt/mongo:/opt/keyfile --hostname="node1" -p 27017:27017 -d mongo:2.6.5 --smallfiles

Vamos as configurações agora:

$ docker exec -it mongo /bin/bash
root@node1:/# mongo
> use admin
db.createUser( {
     user: "admin",
     pwd: "SENHA_DE_ADMIN",
     roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
   });

db.createUser( {
     user: "root",
     pwd: "SENHA_DE_ROOT",
     roles: [ { role: "root", db: "admin" } ]
   });
> exit
root@node1:/# exit

Remova o container para que possamos agora subir o ambiente todo:

$ docker stop mongo
$ docker rm mongo

Agora sim vamos subir o ambiente:

$ docker run --name mongo -v /etc/hosts:/etc/hosts -v /opt/mongo/data:/data/db -v /opt/mongo:/opt/keyfile --hostname="node1" --add-host node1.db:${node1} --add-host node2.db:${node2} --add-host node3.db:${node3} -p 27017:27017 -d mongo:2.6.5 --smallfiles --keyFile /opt/keyfile/mongodb-keyfile --replSet "rs0"

Acesse este container para inicializar o cluster:

$ docker exec -it mongo /bin/bash
root@node1:/# mongo
> use admin
> db.auth("root", "SENHA_DE_ROOT");
> rs.initiate()
{
         "info2" : "no configuration explicitly specified -- making one",
         "me" : "node1.db:27017",
         "info" : "Config now saved locally.  Should come online in about a minute.",
         "ok" : 1
}

> rs0:PRIMARY> rs.conf()
{
        "_id" : "rs0",
        "version" : 1,r
        "members" : [
              {
                  "_id" : 0,
                  "host" : "node1.db:27017"
              }
        ]
}

Nos demais nós, suba os containers da seguinte forma:

Servidor 2

$ docker run --name mongo -v /etc/hosts:/etc/hosts -v /opt/mongo/data:/data/db -v /opt/mongo:/opt/keyfile --hostname="node2" -p 27017:27017 -d mongo:2.6.5 --smallfiles --keyFile /opt/keyfile/mongodb-keyfile --replSet "rs0"

Servidor 3

$ docker run --name mongo -v /etc/hosts:/etc/hosts -v /opt/mongo/data:/data/db -v /opt/mongo:/opt/keyfile --hostname="node3" -p 27017:27017 -d mongo:2.6.5 --smallfiles --keyFile /opt/keyfile/mongodb-keyfile --replSet "rs0"

Volte até o servidor 1, acesse o container de mongo e execute os comandos:

$ docker exec -it mongo /bin/bash
root@node1:/# mongo
> use admin
> db.auth("root", "SENHA_DE_ROOT");
> rs0:PRIMARY> rs.add("node2.db") 
> rs0:PRIMARY> rs.add("node3.db") 
> rs0:PRIMARY> rs.status()

O status devem ser algo parecido com este retorno:

rs0:PRIMARY> rs.status()
{
 "set" : "rs0",
 "date" : ISODate("2017-05-16T15:43:30Z"),
 "myState" : 1,
 "members" : [
 {
 "_id" : 0,
 "name" : "node1:27017",
 "health" : 1,
 "state" : 1,
 "stateStr" : "PRIMARY",
 "uptime" : 578713,
 "optime" : Timestamp(1494371417, 1),
 "optimeDate" : ISODate("2017-05-09T23:10:17Z"),
 "electionTime" : Timestamp(1494371963, 1),
 "electionDate" : ISODate("2017-05-09T23:19:23Z"),
 "self" : true
 },
 {
 "_id" : 1,
 "name" : "node2.db:27017",
 "health" : 1,
 "state" : 2,
 "stateStr" : "SECONDARY",
 "uptime" : 577454,
 "optime" : Timestamp(1494371417, 1),
 "optimeDate" : ISODate("2017-05-09T23:10:17Z"),
 "lastHeartbeat" : ISODate("2017-05-16T15:43:29Z"),
 "lastHeartbeatRecv" : ISODate("2017-05-16T15:43:29Z"),
 "pingMs" : 0,
 "syncingTo" : "node1:27017"
 },
 {
 "_id" : 2,
 "name" : "node3.db:27017",
 "health" : 1,
 "state" : 2,
 "stateStr" : "SECONDARY",
 "uptime" : 577354,
 "optime" : Timestamp(1494371417, 1),
 "optimeDate" : ISODate("2017-05-09T23:10:17Z"),
 "lastHeartbeat" : ISODate("2017-05-16T15:43:29Z"),
 "lastHeartbeatRecv" : ISODate("2017-05-16T15:43:29Z"),
 "pingMs" : 0,
 "syncingTo" : "node1:27017"
 }
 ],
 "ok" : 1
}
rs0:PRIMARY>

Caso tenha ocorrido algum erro na sincronização das informações, você poderá visualizar através deste retorno, e claro terá informações para realizar a correção do caso. Existem muitas maneiras de realizar esse tipo de configuração de cluster, algumas mais complexas e outras mais simples, em nosso teste esta foi a forma onde tivemos mais objetividade e assertividade na configuração, baseado nessas informações você pode montar/adaptar os passos que atendem a sua demanda.

Um ponto muito importante nesse ambiente é a forma como ocorre a recuperação em caso de desastre, pois você pode parar o master (primário) e você poderá ver através do rs.status(); o comportamento do cluster elegendo um novo master, ou seja, dessa forma seu cluster ficará quase que 100% a prova de falhas ;).

Esperamos ter ajudado, e se tiver alguma dificuldade ou dúvida com relação a este ambiente por favor entre em contato conosco para que possamos ajudar o/. E como sempre, nos ajude divulgando o blog, isso é muito importante para nós.

Grande abraço!

Oito dicas sobre Docker

Oi Gente!

Sendo este o primeiro post com conteúdo sobre Docker para o ano de 2017, tivemos a ideia de trazer a vocês algumas dicas e informações que consideramos de muita importância. Para isso fizemos um com uma apresentação sobre essas dicas, explicando cada uma dela e contando um pouco sobre como elas resolvem ou ajudam em determinadas situações. Vamos ao vídeo?

 
Para você que não conseguiu ver o vídeo, disponibilizamos também a apresentação em nosso canal no slideshare, acompanhe:

 

Viu, não deixamos passar nada

Aguarde pois este ano teremos diversas novidades aqui no blog, garanto que vocês vão gostar.

 

Grande abraço!

Alpine – Faça você mesmo

Oi Pessoal,

O MundoDocker trás hoje para você um pequeno tutorial de como é possível criar uma imagem enxuta, somente com o que você precisa e utilizando menos espaço possível. Para isso será necessário utilizar uma das duas imagens mais limpas do Docker, são elas: Alpine ou BusyBox, nesse tutorial vamos focar na Alpine, uma das mais buscadas atualmente.

Para que não conhece, a Alpine é uma distribuição construída com musl libc e BusyBox, que é conhecida como canivete suíço, pois combina versões minúsculas de muitos utilitários comuns no UNIX em um único pequeno executável. Algumas características de Alpine:

Pequena

Enquanto a menor imagem para Docker precisa de cerca de 130MB de espaço em disco, a Alpine precisa de no máximo 8MB, isso faz com que, mesmo você montando todo o seu ambiente, ele nunca terá o mesmo tamanho do que se montando em um imagem tradicional, isso é ótimo, pois deixa o ambiente ainda mais enxuto e simples de migrar.

Simples

Você tem apenas aquilo que é necessário para o funcionamento de sua aplicação, se precisar de mais alguma biblioteca, é só instalar, você não precisa se preocupar em desativar ou remover lixos, eles simplesmente não existem.

Segura

Alpine foi desenvolvida pensando em segurança, e para garantir isso os desenvolvedores se preocuparam aprimorar os recursos de segurança do kernel como grsecurity/PaX, além disso, todos os binários foram compilados em executáveis independente de posição, isso previne alguns uso problemas relacionados a buffer overflow e outros tipos de ataques envolvendo estouro de pilha.

Mãos a obra?

Nosso exemplo consistirá em montarmos uma imagem de com Alpine e Nodejs, e vamos comparar o tamanho da nova imagem que montamos com Alpine e outras distros disponíveis.

A Aplicação:

Será algo bem simples, apenas uma aplicação olá mundo:

var http = require('http');
http.createServer(function(req,res) {
 res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
 res.end('Exemplo Node.js Mundo Docker!');
}).listen(8080);

Colocamos o nome de app.js, não esqueça de criar o package.json com as dependências da aplicação:

{
"name": "docker_web_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "First Last <[email protected]>",
"main": "app.js"
}

Agora criamos nosso Dockerfile:

FROM alpine:3.1
# Update
RUN apk add --update nodejs
# Cria a pasta da app
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Instala as dependencias da app
COPY package.json /usr/src/app/
RUN npm install
# copia a app
COPY . /usr/src/app
EXPOSE 8080
CMD ["node", "/usr/src/app/app.js"]

 

Não é nada muito complexo, basta você informar qual imagem base utilizará, e a diferença está no instalador de dependências, que para o Alpine é o apk. Agora vamos gerar a imagem:

docker build -t alpineteste .

Será gerado uma nova imagem com o nome de alpineteste, agora vamos comparar o tamanho dessa imagem com outras:

Alpine

Lembrando, que utilizamos a imagem base de cada distribuição e em cima dela instalamos o node e subimos essa aplicação, note que a diferença é exorbitante, isso por que a Alpine tem apenas o que é necessário para essa aplicação rodar, nada além disso.

Como podem ver, utilizando essa abordagem seu ambiente fica ainda mais escalável, e claro ainda mais portável, pois quanto menos a sua imagem, melhor é para transitar ela entre os hosts (não é necessário baixar megas e megas da imagem no primeiro deploy por exemplo) .

Gostou? nos ajude divulgando o Blog

Grande abraço!

Docker e .Net

Oi pessoal!

Rodar .Net em container? SIM!! é possível, e vamos mostrar hoje como você pode fazer esse ambiente funcionar e testar sua aplicação. Bem, antes de tudo você precisa entender todo o movimento que a Microsoft vem fazendo para que sua linguagem de programação torne-se cada vez mais utilizada pelos desenvolvedores, para isso eles repensaram tudo que já fizeram, e lançaram uma versão do .Net com features muito parecidas como as encontradas em node e ruby on rails, e a batizaram de ASP.NET Core. Conceitualmente o ASP.NET Core é uma plataforma open source de desenvolvimento leve e eficiente para aplicação escritas em .net, veja abaixo uma lista dos principais pontos do asp.net Core:

  • Suporte integrado para criação e utilização de pacotes NuGet;
  • Pipeline de request mais leve e modular;
  • Ambiente configurado para cloud;
  • Suporte a injeção de dependência;
  • Novas ferramentas que facilitam o desenvolvimento web;
  • Capacidade de hospedar o processo no IIS ou em um Self-Host;
  • Suporte para desenvolvimento de aplicação asp.net em Windows, Linux e Mac;
  • Open Source e com comunidade ativa;
  • Todos os pacotes do .Net no NuGet;
  • .Net Core construido com suporte a versionamento side-by-side;
  • Uma unica Stack para Web UI e Web APIs;

Por que a Microsoft vem tomando esse rumo? Simples, para atrair mais pessoas para o seu produto, tendo em vista que as principais linguagens, ou as que mais crescem tem nativas todas essas features, a melhor alternativa para a Microsoft foi mudar a abordagem e atrair pessoas para melhorar seu produto/serviço e claro, isso consolida ainda mais o Windows Azure, fazendo com o desenvolvimento e deploy de Apps em .net torne-se menos doloroso.

Vamos ver isso rodando em um container?

Simples, tendo o Docker instalado (em qualquer host, seja ele Windows, Linux ou Mac), execute:

docker run -it microsoft/dotnet:latest

Dentro do container, você deve criar sua aplicação, de forma parecida com o que ocorre com o ruby on rails, para isso o .net core disponibiliza um utilitário chamado: dotnet, veja:

mkdir app
cd app
dotnet new

O comando dotnet new criará toda a estrutura necessária para rodar uma aplicação hello world básica, ele criará um arquivo chamado project.json com o seguinte código:

{
 "version": "1.0.0-*",
 "compilationOptions": {
 "emitEntryPoint": true
 },
 "dependencies": {
 "Microsoft.NETCore.Runtime": "1.0.1-beta-*",
 "System.IO": "4.0.11-beta-*",
 "System.Console": "4.0.0-beta-*",
 "System.Runtime": "4.0.21-beta-*"
 },
 "frameworks": {
 "dnxcore50": { }
 }
}

Esse arquivo project.json contém as informações de dependência que sua aplicação precisará para rodar, é fundamental que você informe nesse aquivo todos os pacotes que necessita. Nessa mesma estrutura será criado um arquivo chamado Program.cs com este código:

using System;
namespace ConsoleApplication
{
 public class Program
 {
 public static void Main(string[] args)
 {
 Console.WriteLine("Hello World!");
 }
 }
}

Agora basta realizar a instalação das dependências:

dotnet restore

E pronto, sua aplicação estará pronta para rodar, basta executar o comando:

dotnet run

 Fácil certo? E é possível deixar ainda mais fácil, para isso, basta criar Dockerfile e gerar uma imagem com esse ambiente:

FROM microsoft/dotnet:latest
RUN mkdir /app
WORKDIR /app
RUN ["dotnet", "new"]
RUN ["dotnet", "restore"] 
ENTRYPOINT ["dotnet", "run"]

Agora crie a imagem: docker build -t myapp .

E crie um container baseado nessa nova imagem: docker run -d myapp , quer ver o que retornou nessa execução? docker logs iddocontainer, ele deverá retornar algo desse tipo: Hello World!.

É claro que você pode aprimorar esse ambiente, principalmente se quiser rodar uma aplicação web, mas esse ambiente básico já serve como inicio para seus testes ;).

Gostou? Então nos ajude divulgando o mundodocker.com.br, grande abraço!

Docker 1.13 – O que vem por ai

Eai gente!

Você que é leitor do blog já está acostumado a ver por aqui as principais novidades sobre o Docker e tecnologia associadas, e hoje não será diferente. Queremos trazer uma preview sobre as novas features que serão lançadas na versão 1.13 do Docker, como todos os sabem, o ciclo de desenvolvimento dentro do Docker é algo fora da curva, e a cada nova versão alguma novidade aparece, é possível acompanhar esse ritmo pelo próprio github deles.

Mas se você não quiser esperar a versão estável para brincar com as novidades, pode utilizar a versão experimental do Docker, que obviamente não é recomendado para se colocar em produção, mas que pode ser usada para lab sem problema. Para isso, basta você instalar o Docker com o seguinte comando: curl -sS https://experimental.docker.com | sh, com isso você terá acesso a engine com as modificações mais atuais mas em fase de desenvolvimento ainda.

Bom, chega de papo, vamos a uma pequenas lista das novidades do Docker 1.13:

 

Docker stack

Para quem usa docker-compose ou docker service sabe das diferenças entre essas duas “ferramentas”, e como de certa foram eles deveriam se complementar, não é mesmo? E Essa é uma situação que vinha sendo trabalhada pelos engenheiros do Docker a algum tempo, essa função intermediária vinha sendo testada através do comando docker stack que possibilita criar um serviço dentro do swarm baseado em uma estrutura do docker-compose, ou seja, você conseguirá portar para o cluster de swarm um serviço baseado no docker-compose, isso facilita em muito a administração de seu serviço e claro no deploy do mesmo, pois garante que o serviço esteja rodando independente do nó onde ele está.

Nas versões de teste você tinha que gerar um arquivo .dab (distributed application bundle ou pacote de aplicação distribuída) baseado em seu docker-compose.yml e depois sim você conseguiria fazer deploy dessa stack utilizando o docker. Agora no docker 1.13 isso não é mais necessário, basta você chamar o arquivo docker-compose.yml diretamente no deploy da stack, algo como isso:

# docker stack deploy --compose-file ./docker-compose.yml minhastack

Muito mais simples e rápido não?

 

Gerenciamento de senha

Ou gerenciamento de segredos, essa é uma função básica dentro de qualquer orquestrator, o Kubernetes já possuía esse conceito e aplicação á algum tempo já, e agora o docker também implementa essa funcionalidade.
Mas afinal, onde vou usar isso? Sua aplicação usa senha não usa? Seja para banco, API, etc, qualquer aplicação usa senha de acesso a algum serviço em algum momento, e com você faz hoje com Docker? Provavelmente via variável de ambiente ou compartilhando um arquivo com o container, existem outras formas, como ferramentas as a service de gerenciamento de identidade.

Agora no docker 1.13 você pode definir uma secret que pode ser utilizada pelo seu serviço dentro do swarm, exatamente da mesma forma que o Kubernetes usa. Para isso foram adicionados quatro comandos novos, são eles:

  • docker secret create
  • docker secret inspect
  • docker secret ls
  • docker secret rm

Veja um exemplo de como criar uma secret para ser utilizada dentro de seu serviço

# echo "123456" | docker secret create senha-banco

Agora um exemplo de como utilizar essa secret em seu serviço:

# docker service create --name app --secret senha-banco ubuntu

Dentro do container será criado um arquivo em /run/secrets/senha-banco com a informação da senha, isso é claro apenas dentro do container, sem precisar mapear nada do host para o container.

# docker exec -it app cat /run/secrets/senha-banco
123456

Um detalhe muito importante é: As secrets podem ser utilizadas apenas dentro de serviços, se você criar um container com o docker run, vão não poderá utilizar essa funcionalidade.

 

Novo parâmetro de rede no Swarm

Essa talvez seja uma das melhorias mais importante no core do docker, pois permite que você adicione uma rede do Swarm mesmo se o container for criado fora de um serviço, ou seja, criado da forma tradicional com o docker run.... Mas afinal, por que isso é importante? É importante porque agora é possível adicionar um container a mesma rede do serviço criado no Swarm, isso é muito útil para debugs ou até mesmo testes de ambiente.

E como fica agora então? Simples, veja:

# docker network create --driver overlay --attachable rede-plugavel

Com o comando acima nós criamos uma rede overlay do Swarm, e a diferença agora é o parâmetro –attachable, que permite que essa rede seja plugada em qualquer container criado, e no comando abaixo nós plugamos um container a essa rede:

# docker run --rm -it --net rede-plugavel centos ping google.com

 

Plugins

Finalmente alguns plugins que estavam sendo testados e aprimorados foram disponibilizados como estáveis dentro da engine do Docker. Dentre ele podemos destacar o Flocker e o Weave, que agora tem integração total com docker.

 

Docker Daemon –experimental

Até então para você poder utilizar comandos e opções em desenvolvimento/teste do docker, você teria que instalar a versão experimental ou test da engine, mas agora basta você iniciar o daemon do docker com a opção –experimental, com isso será habilitado em momento de execução as opções da versão experimental, veja:

 

Melhorias no docker service

Essas, na verdade, são algumas das melhorias que a comunidade pediu ao longo do meses, uma delas tem relação com o update da imagem no update do serviço, para quem não notou, quando um serviço é atualizado (até então) você precisava executar um update com alguns parâmetros a mais para poder atualizar o serviço com uma nova imagem, na nova versão esse processo pode ser feito passando o parâmetro –force junto, o docker service update já verificará se há uma versão mais recente da imagem e atualizará o serviço baseado nisso.

 

Novo parâmetro no docker service

Além das melhorias no docker service, foi acrescentado também um novo parâmetro. Hoje nós acessamos um serviço através da porta exposta do mesmo, que você pode definir com o parâmetro –publish, no docker 1.13 será possível você definir de forma mais detalhada essa regra, isso deve-se ao novo parâmetro –port, que, da mesma forma que o –mout, tem sintaxe parecida com csv, onde você define item=valor,item=valor… Veja um exemplo:

# docker service create --name servico_web --port mode=ingress,target=80,published=8080,protocol=tcp

Dessa forma você tem, de forma mais clara, as definições de porta do serviço.

 

Outras novidades

Dentre outras novidades do docker 1.13 podemos destacar ainda algumas que tem bastante relevância para quem o utiliza, como por exemplo:

  • Cache de Layer para o Build: Para que gera muitas imagens, sabe que esse era um problema a ser resolvido, exemplo: geramos um imagem agora com o docker build, caso tenha que modificar essa imagem todas as layers anteriores a alteração não eram buildadas novamente, o docker build usava o cache para elas. Agora digamos que mandamos essa imagem para outro host e queremos fazer outra modificação nela, o que ocorre? Exatamente, todas as layers são buildadas novamente, isso pelo fato do docker não ter naquele host o cache de build dessa imagem. Parece ser trivial, mas quando se quer ganhar tempo, não é. No docker 1.13 você pode especificar na hora do build de onde o docker poderá buscar o cache de build, como por exemplo:
    docker pull imagem:v1.0
    docker build --cache-from imagem:v1.0 -t imagem2:v1.1 .
    

    Dessa forma o build da nova imagem utilizará o cache da imagem original, compilando assim apenas as layers diferentes.

  • A instrução MAINTAINER  foi removida do Dockerfile, agora essa informação deve ser utilizada através de label;
  • Foi adicionado um novo comando, ainda experimental, que é o docker service logs para visualizar os logs do serviço e não do container em si.
  • Outra adição do docker service foi o parâmetro –rollback que tem por objetivo realizar o update do serviço através de uma versão anterior a atual;
  • Remoção de container velhos através do docker system (ainda não há mais informações sobre como esse comando funcionará para remoção de containers antigos, então ficamos ligados no lançamento)

 

Ok Cristiano, e quando será lançada? Não há uma data 100% definida, o que se sabe é que será lançada até inicio de Janeiro de 2017, então pode ser que seja lançada hoje mesmo . Pode haver mais modificações? Claro, sempre há e com certeza as novidades que trouxemos hoje serão melhor explicadas após o lançamento oficial, então o jeito é ficar ligado aqui no blog e claro no site do ofiical do docker.

 

Grande abraço!

 

 

Docker Overlay

Oi Pessoal,

Como vimos nesse post, é possível utilizar plugins diversos para resolver o desafio da rede, e mostramos nesse post um pouco da teoria de como usar o driver de overlay, hoje queremos mostrar isso na prática, e para isso, nada melhor do que colocar a mão na massa, certo?  Claro, mas antes precisamos entender um pouco de teoria, e lá vamos nós.

Se você estiver utilizando o Swarm, não é necessário configurar um serviço de chave-valor externo, pois o próprio Swarm faz o controle e persistência das informações de rede que você utiliza. E você deve ter cuidado, pois se quiser utilizar o Overlay com um serviço externo de chave-valor, o modo de cluster via Swarm fica impossibilitado.

Veja abaixo uma tabela com algumas informações relevantes sobre o funcionamento do Overlay:

Protocolo Porta Descrição
udp 4789 Data plane (VXLAN)
tcp/udp 7946 Control plane

Ou seja, você deve cuidar para que em seus firewalls essas portas estejam liberadas, caso contrario a comunicação entre os nós não ocorrerá, o que impossibilitará o funcionando do Overlay.

Veja abaixo os principais parâmetros que você deve ter atenção:

Opção Descrição
--cluster-store=PROVIDER://URL
Endereço do seu servidor/serviço de chave-valor
--cluster-advertise=HOST_IP|HOST_IFACE:PORT
IP ou interface do host que será utilizado para comunicação do cluster
--cluster-store-opt=KEY-VALUE OPTIONS
Configuração opicional, onde é possível definir regras de monitoramento dos hosts e validação TLS

Ok Cristiano, entendi tudo isso, mas como vamos testar, qual será o ambiente de laboratório que vamos seguir? Vamos lá, para exemplificar como será o ambiente que vamos montar, segue abaixo uma imagem onde ilustra o funcionamento do Docker com o serviço de chave-valor, todos os hosts consultam esse serviço para identificar quais redes existem e qual bloco/ip deve ser alocado por container. Veja:

Engine on each host

Vamos colocar a mão na massa?

Dependências/Configuração

Você deve ter um serviço de chave valor, no qual o Docker persistirá as informações de rede que você criar, em nosso lab utilizamos o Consul dentro de um container Docker, rodando em um server a parte dos que participarão do ambiente multi-host, para isso executamos:

[root@consul ~]# docker run -d  -p "8500:8500"  -h "consul"  progrium/consul -server -bootstrap

Dessa forma iniciamos um container com Consul, mapeando a porta 8500 do host para o container, ou seja, para ter acesso ao serviço do Consul basta acessar ip-do-host:8500. Agora vamos ao nosso ambiente de Docker.

Nos hosts de Docker (obviamente você já tem o Docker instalado, mas se quiser saber como instalar, veja esse post ) você precisará configurar o daemon para consultar o Consul e buscar as informações de rede, em nosso laboratório utilizamos o CentOS, com isso, o arquivo a ser modificado é o: /lib/systemd/system/docker.service, e deixamos da seguinte forma:

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --cluster-advertise=eth0:2376 --cluster-store=consul://ip-do-consul:8500
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process

[Install]
WantedBy=multi-user.target

Feito isso, basta reiniciar o serviço e seguirmos para o próximo passo.

Utilização/Testes

Agora que você já definiu um serviço de chave-valor a ser consultado, basta você criar a sua rede com o driver Overlay, para isso:

[root@docker01 ~]# docker network create --driver overlay rede1

Você pode definir ainda qual o bloco de ip que deseja para essa rede, caso não faça essa definição, o Docker associará um bloco automaticamente para você. Fácil certo? Basta testarmos, para isso vamos validar em todos os hosts se ambos estão visualizando a mesma rede, execute esse comando em qualquer outro host:

[root@docker01 ~]# docker network ls

Será retornando algo como isso:

NETWORK ID          NAME                DRIVER
64507d0be843f        rede1               overlay
d0bdae8fbe7bd        bridge              bridge
1c0eb8f68962d        none                null
3412c2496d0eb        host                host
697102a22e8d2        docker_gwbridge     bridge

 Vamos utilizar essa rede, crie os containers em pelo menos 2 hosts, informando essa nova rede, veja:

[root@docker01 ~]# docker run -it --net=rede1 centos /bin/bash

Agora basta pingar ou acessar os serviços entre os containers que estão nessa mesma rede.

Dessa forma você pode definir uma rede diferente por grupo de containers, e pode ainda isolar essas redes utilizando o método VXLAN, para isso deve passar como parâmetro na criação da rede o seguinte argumento: –opt “com.docker.network.driver.overlay.vxlanid_list=257″, esse parâmetro fará com que essa rede receba uma vlan, ou seja, todo o trafego direcionado a essa rede receberá uma identificação, impossibilitando que outros containers que não estejam nessa vlan tenha acesso a esse trafego. 

Legal né? Se gostou nos ajude divulgando o blog.

Grande abraço!

Docker Run – Avançado

Olá pessoal,

Hoje vamos falar um pouco mais sobre as opções que talvez muitas pessoas não conhecem sobre o Docker run e que podem ajudar você diariamente a subir suas aplicações com mais segurança e também com mais praticidade. A ideia por trás desse post não é mostrar como criar um container, mas sim quais as opções novas e que podemos utilizar em nosso dia a dia.

PID settings (–pid)

Por padrão todos os containers possuem o PID namespace habilitado. O Namespace PID remove o ponto de vista dos processos do sistema e permite ids de processos para ser utilizado. Em alguns casos você pode querer rodar alguma ferramenta de depuração em seu container para que ele consiga visualizar os processos do seu host, então basta iniciar o container com a opção de –pid ativado:

docker run -it --rm --pid=host imagem

É possível também utilizar o –pid para depurar as informações de outro container, para isso vamos iniciar a execução de um container com mongoDB e depois um container para realizar a depuração

docker run --name mongo -d mongodb 
docker run --it --pid=container:mongo imagem

–dns

Por padrão os containers irão compartilhar os mesmos servidores de DNS que estão sendo utilizados em seu host, então na hora de criação de cada container você pode utilizar o parâmetro –dns=”8.8.8.8″ por exemplo.

–add-host

O docker ja cria dentro de cada container em /etc/hosts o arquivo com algumas configurações de rede, como:

172.17.0.2 02ed3f564f1b
127.0.0.1 localhost
fe00::0 ip6-localnet

Porem é possivel na hora da criação do container você adicionar mais uma entrada dentro do arquivo de hosts para isso basta colocar a opção –add-host em seu “docker run”

 docker run -it --add-host entrada:ip -d centos

–security-opt

Nas versões mais recentes do Docker é possível você limitar para que os comandos que exigem privilégios dentro do Docker não sejam mais executado, como: su ou sudo para isso basta executar:

docker run --security-opt no-new-privileges -d centos

–restart

Utilizando essa opção é possível realizar a reinicialização de containers a partir de determinados evento, são esses: on-failure, always, unless-stopped.

  • On-failure: Reinicia somente se o status de saída do container por diferente de 0, é possível limitar o numero de tentativas de reinicialização. O docker irá esperar 100ms na primeira vez que tentar reiniciar o container, caso vá para segunda vez então irá esperar 200ms e depois 400ms e assim dependendo do número de tentativas.
 docker run --restart=on-failure:3 centos
  • Always: Sempre reinicie o container independentemente do status de saída. Na reinicialização do servidor, o container irá subir automaticamente após o serviço do docker ser startado.
 docker run --restart=always centos
  • Unless-Stopped: Inicialize o container independentemente do status de saída, porem na reinicialização do servidor ou do serviço do Docker o container não irá subir automaticamente;
 docker run --restart=unless-stopped centos

O status de saída exibido pelo Docker no docker run pode ser visto utilizando a seguinte opção:

 docker run redis; echo $?

Existem alguns números já conhecidos, 125 (Problema com o docker daemon), 126 (Comando não pode ser invocado), 127 (Comando não pode ser encontrado).

–isolation

Essa opção é útil quando você executar Docker no Windows essa opção define qual tecnologia ira ser usada para o isolamento do container, no caso do linux é default e no Windows temos: process e Hyper-v.

docker run -d --isolation process busybox top

–device

Um dia poderá aparecer a necessidade para que você anexe um disco a seu container, então com essa opção você pode anexar diretamente um disco a seu container:

docker run --device=/dev/sdb:/dev/xvdc -d centos

–rm

Por padrão quando você cria um container sem passar a opção de “–rm” quando esse container acaba parando por algum motivo, ele não é removido do Docker e também nem o seu volume. Porem caso você deseja que remova o container você poderá passar o parâmetro na hora da criação do container.

docker run -it -v /home/container:/home --rm -d centos

Nesse modo de criação de container, quando o container por algum motivo parar o docker irá excluir-lo e também apagar o volume junto. Para que NÃO APAGUE O VOLUME você deve criar um volume com a opção de docker volume create.... e na hora da criação desse container passar o nome do volume.

docker run -it --rm -v volume:/home -d centos

Então ta pessoal, por hoje era isso, espero que tenham gostado, em breve faremos posts mais focados no baixo nível do Docker para que você possa saber como todas as opções funcionam e como utiliza-las. Já sabe, nos ajude divulgando o blog

Link entre containers – Parte 1

Olá pessoal,

Hoje vou mostrar aqui no blog como podemos interligar containers sem precisar expor as portas do nosso host. Mapeamentos de portas não são a única maneira de conectar um container ao outro. Docker também tem um sistema de ligação que permite interligar vários containers juntos e enviar as informações de conexão de um para outro.

A importância de nomear

Para estabelecer os links, o Docker conta com os nomes dos container. Você já viu que cada container que você criar tem um nome criado automaticamente, mas você mesmo pode dar um nome ao container. Esta nomeação fornece duas funções úteis:

1 – Torna-se útil quando você precisa criar containers com funções especificas e precisa lembrar-se deles, por exemplo um container web, ou mysql, etc.

2 – Fica mais fácil fazer o link entre os containers, pois você não precisa decorar um nome que foi gerado aleatoriamente, basta você linkar seu container web com seu container mysql, por exemplo.

Você pode nomear seu recipiente usando o parâmetro –name, por exemplo:

$ docker run -d -P --name web training/webapp python app.py

Isso inicia um novo container e usa o parâmetro –name para nomea-lo como web. Você pode ver o nome do container utilizando o comando docker ps.

$ docker ps -l
CONTAINER ID  IMAGE                  COMMAND        CREATED       STATUS       PORTS                    NAMES
aed84ee21bde  training/webapp:latest python app.py  12 hours ago  Up 2 seconds 0.0.0.0:49154->5000/tcp  web

Você também pode usar docker inspect para retornar o nome do container.

Nota: Os nomes dos containers são únicos, então para reutilizar algum nome você deverá parar o container, remover e criar o container com o nome desejado.

Comunicação via Link

O Link permite que você trafegue informações entre os containers de forma segura, pois quem conhece um container conhece apenas o seu par definido no link. Quando você configurar um link, você cria um elo de ligação entre um container de origem e um container de destino. Para criar um link, você deve utilizar o parâmetro –link. Em primeiro lugar, deve-se criar um container que será origem de dados para outro container, desta vez vamos criar o container de banco de dados:

$ docker run -d --name db training/postgres

Isso criará um novo container chamado db a partir da imagem do postgres, que contém um banco de dados PostgreSQL.

Agora, você precisa excluir o container web criado anteriormente para que você possa substituí-lo por outro vinculado ao db:

$ docker rm -f web

Agora, crie um novo container chamado web e vincule com o seu container db.

$ docker run -d -P --name web --link db:db training/webapp python app.py

Isto irá ligar o novo container web com o container db criado anteriormente. O parâmetro –link fica da seguinte forma:

--link <nome ou id>:alias

Você pode ver que o container web agora está ligado ao container db, o que lhe permitirá coletar as informações do container db e claro do banco de dados que encontra-se lá.

Como pode notar, um link permite que um container de origem forneça informações sobre si próprio e de seus serviços a outro container de destino. No nosso exemplo, o destinatário web, pode acessar informações sobre o banco de dados de origem. Para fazer isto, o Docker cria um túnel seguro entre os container que não precisam expor as portas externamente, você deve ter notado que quando iniciamos o container db nós não usamos o parâmetro -P ou -p,  isso é uma grande vantagem em utilizar o link, nós não precisamos expor o container ou serviço, no nosso exemplo o banco de dados PostgreSQL, para toda a rede.

Na parte 2 desse tutorial veremos como o Docker cria esse túnel e permite a comunicação entre containers, fique atento as novidades aqui no Blog, e nos ajude divulgando o mundodocker.com.br

Abraço!