Melhores praticas Dockerfile

Muitas pessoas pensam que construir uma imagem é apenas iniciar um container, realizar algumas alterações e assim realizar o commit da mesma. Ou até mesmo escrever um Dockerfile do jeito que quiser e pronto a imagem está pronta e agora é só colocar em produção. Com algumas técnicas na criação do Dockerfile é possível fazer o seu Build passar de 10 minutos para apenas 10 segundos.

Baseado nas dúvidas que o pessoal acaba tendo no dia a dia resolvemos a equipe do mundodocker.com.br resolveu dar algumas dicas referentes a como deixar o seu Dockerfile o mais otimizado possível.

Use o .dockerignore

O .dockerignore possui a mesma funcionalidade do .gitignore, fazendo com que você possa gerar a sua imagem excluindo alguns arquivos que estejam no diretório do seu Dockerfile.

Não instale pacotes desnecessários

Para reduzir o tamanho de sua imagem e o tempo de construção dela, não instale pacotes que você acha que poderá usar um dia, instale apenas o necessário para que sua aplicação possa rodar de forma integra e segura. Muitas vezes pacotes desnecessários possuem uma série de dependências o que pode acarretar um tempo maior de construção da imagem.

Construa o minimo de camadas possíveis

Cada comando “RUN”, “COPY”, “ADD” acaba adicionando uma camada a mais em sua imagem, então quanto mais comandos conseguir executar de uma vez só melhor.

Use tags

Quando você for realizar o docker build utilize o parâmetro -t para que você possa organizar melhor sua estrutura de imagens e no desenvolvimento ficará mais fácil para saber o qual release essa imagem representa.
docker build . -t php:56-0-4

apt-get

Nunca utilize apenas apt-get update utilize sempre apt-get update && apt-get install. Por exemplo você tem o seguinte Dockerfile:


FROM UBUNTU
apt-get update
apt-get install wget

Você executa isso e depois de algum tempo você altera o Dockerfile e coloca assim:


FROM UBUNTU
apt-get update
apt-get install wget vim

Ao executar o build o Docker não irá executar o apt-get update fazendo com que o vim esteja desatualizado no momento da instalação.

Nunca mapear a porta pública no Dockerfile

Você NUNCA deve mapear a porta do seu host em seu Dockerfile:


#Não faça isso
EXPOSE 80:8080

#Faça isso
EXPOSE 80

Deixe sempre o que mais será alterado para o final

Como o Dockerfile trabalha com camadas, então você sempre devera deixar para o final a parte que é mais dinâmica em seu Dockerfile, pois ao rodar o seu Dockerfile pela segunda vez, o Docker irá olhar onde foi modificado o arquivo e irá refazer as camadas abaixo da modificação. Então se você tem uma parte que demora algum tempo e você não irá precisar modificar ela constantemente então é melhor você deixar essa parte no topo.


FROM ubuntu
RUN apt-get install -y nodejs
RUN mkdir /var/www
ADD app.js /var/www/app.js

FROM ubuntu
RUN apt-get install -y nodejs
RUN mkdir /var/www
ADD package.json /var/www/package.json

Nessa alteração de Dockerfile o Docker irá apenas refazer a camada do ADD e não irá baixar novamente o node e criar o diretorio /var/ Assim economizando tempo de Build e também tamanho em disco.

Então tá pessoal espero que tenham gostado desse post referente a dicas de como criar melhor o seu Dockerfile. Qualquer dúvida é só deixar um comentário que iremos reponder o mais rápido possível.

Docker API com Python

Oi pessoal!

Hoje, nós do mundodocker.com.br, vamos nos aprofundar um pouco mais na API do Docker, entenda de que forma você pode integra-la com alguma linguagem de programação. Como explicado neste post, o Docker é dividido basicamente em duas partes: Engine e CLI, ou seja, podemos acessar o Docker Engine de qualquer lugar, desde que o mesmo tenha sua API exposta, neste link: https://docs.docker.com/reference/api/remote_api_client_libraries são relacionadas todas as bibliotecas em diversas linguagens que podem ser utilizadas para manipular a API do Docker, ou seja, você não precisa se preocupar, se prefere PHP, há uma biblioteca em PHP, se prefere Java, há uma biblioteca em Java, se prefere GO, bom, há uma biblioteca também, e assim para muitas outras linguagens.

Vamos a prática!

Primeiro você deve instalar a biblioteca Docker no Python, para isso instale o pip.
Se for CentOS 7:

# rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
# yum -y install python-pip

Se for Ubuntu:

# apt-get instal python-pip

Instalado o pip, execute:

# pip install docker-py

Para criar um container você pode utilizar o seguinte script:

import docker
objdocker = docker.Client(base_url="unix://var/run/docker.sock")
container = objdocker.create_container(image=imagem, command=comando, hostname=host+":4500",mem_limit="1000m",name=nome_Container)
objdocker.start(container,port_bindings={port_Container: ('0.0.0.0', port_Host)})
Para saber a utilização de recursos de um container, pode utilizar o script:
import docker
objdocker = docker.Client(base_url="unix://var/run/docker.sock")
objdocker.stats_container = objdocker.stats('nome_Container')
for stat in objdocker.stats_container:
print(stat)
Para saber algumas informações do Docker, pode utilizar:
import docker
objdocker = docker.Client(base_url="unix://var/run/docker.sock")
objdocker.info()
Para remover um container, você pode utilizar:
import docker
objdocker = docker.Client(base_url="unix://var/run/docker.sock")
objdocker.stats_container = objdocker.stop('nome_Container')
Você pode também habilitar a API do Docker para ser acessível remotamente, para isso, basta editar o /etc/sysconfig/docker (CentOS) ou /etc/init/docker.conf (Ubuntu) deixando-o assim:
DOCKER_OPTS='-H tcp://0.0.0.0:PORTA -H unix:///var/run/docker.sock'

 

Reinicie o Docker:

# service docker restart

E pronto, agora você pode manipular esse host de Docker remotamente, pode utilizar os mesmos script acima trocando apenas a base_url, algo parecido com isso:

objdocker=docker.Client(base_url="tcp://host_remoto:PORTA",,version="1.20",timeout=30)

A partir disso é possível realizar algumas automatizações de tarefas, e claro é possível integrar isso em algum dashboard ou ferramenta para poder administrar seus containers de forma mais organizada.

Espero ter ajudado e se gostou ajude divulgando nosso Blog, abraço!

Traefik e Docker Swarm

Opa!

Acreditamos que um dos maiores desafios quando se trabalha com alguma tecnologia de cluster, é a forma como você vai disponibilizar o conteúdo para seu usuário/cliente, obviamente isso pode ser feito de diversas maneiras, e cada uma delas atender a uma necessidade e objetivo.

A intenção hoje é trazer à vocês uma forma simples de se disponibilizar conteúdo web (site, api, etc.) e que tem como backend o Docker Swarm, sim, hoje falaremos do Traefik, um poderoso proxy web dinâmico. Antes disso, temos que responder a seguinte dúvida: Por que diabos preciso de um proxy reverso dinâmico? Simples, por que as implementações atuais de Apache, Haproxy e Nginx foram desenvolvidas para serem estáticos, necessitando de intervenções para que as modificações sejam aplicadas. É claro que existem iniciativas que tratam isso, e são boas alternativas também, como é o caso do docker-flow-proxy e jwilder/nginx mas são presas ao que as tecnologias base oferecerem. No caso do traefik, a situação é bem diferente, ele é um proxy arquitetado e desenvolvimento para ser totalmente dinâmico e orientado a micro-serviços, além disso, ele suporta nativamente diversos tipos de backend, como é o caso do Docker Swarm, Kubernetes, Mesos, Docker apenas, Consul, dentre muitos outros.

Features

Algumas features/benefícios do Traefik, incluem:

  • Veloz.
  • Sem dependência, ele é um binário escrito em go.
  • Existe imagem oficial para Docker.
  • Fornece uma API Rest.
  • Reconfiguração sem a necessidade de reiniciar o processo.
  • Metricas (Rest, Prometheus, Datadog, Statd).
  • Web UI em AngularJS.
  • Suporte a Let’s Encrypt (Com renovação automática).
  • Alta disponibilidade em modo cluster (beta).

O Traefik foi desenvolvido para atender a demanda de requisições web, então ele pode ser utilizado para fazer o roteamento das conexões de um site ou api para o container ou serviço que foi criada para isso. A imagem abaixo é clássica, e explica bem esse comportamento:

Fonte: https://docs.traefik.io

Como pode ser visto, o traefik fica “ouvindo” as ações que ocorrem no orquestrador (independente de qual for) e baseado nessa ações se reconfigura para garantir o acesso ao serviço/container criado. Dessa forma basta você apontar as requisições web (seja http ou https) para o servidor onde o traefik está trabalhando.

Mãos a massa?

Em nosso lab, vamos montar esse ambiente utilizando o Docker Swarm como nosso orquestrador, para isso, tenha pelo menos três hosts, inicialize o Swarm em um deles, e em seguida adicione os demais ao cluster.

Feito isso, precisamos criar um rede do tipo overlay, que será utilizada pelo traefik para enviar o trafego web:

docker network create -d overlay net

Depois de inicializada a rede overlay, basta criar o serviço do traefik:

docker service create --name traefik --constraint 'node.role==manager' --publish 80:80 --publish 8080:8080 --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock --network net traefik:camembert --docker --docker.swarmmode --docker.domain=mundodocker --docker.watch --logLevel=DEBUG --web

Com este comando, será criado um serviço mapeando o socket do Docker para que o traefik possa monitorar o que acontece neste cluster, além disso são expostas as porta 80 (para acesso dos sites/apis) e 8080 (página administrativa do traefik), caso preciso da 443, basta adicionar a lista.

Ok, até agora o que fizemos foi criar o serviço do traefik no cluster para que monitore e se reconfigure baseado nos eventos do cluster. Agora precisamos criar nossos serviços web e ver se tudo funcionará como deveria. Vamos lá:

Blog:

Vamos criar agora uma nova aplicação web, que será responsável por um blog, o processo de criação é bem simples:

docker service create --name traefik --label 'traefik.port=80' --label traefik.frontend.rule="Host:blog.mundodocker.com.br;" --network net ghost

Criamos um serviço com nome de blog, utilizando uma imagem do WordPress e adicionamos na rede “net”, essa mesma rede onde o traefik está, agora vamos detalhar os novos parâmetros:

  • traefik.port = Porta onde a aplicação vai trabalhar, nos caso do wordpress, será na porta 80 mesmo.
  • traefik.frontend.rule = Qual será o virtual host que este serviço atende, com isso o traefik consegue definir que, quando chegar uma requisição para: blog.mundodocker.com.br, encaminhará as requisições para o serviço correto.

Agora basta apontar no DNS a entrada blog.mundodocker.com.br para o servidor do traefik e a mágica estará feita.

Site:

Para ver como é difícil, tudo que você precisa fazer é executar este comando:

docker service create --name site --label 'traefik.port=80' --label traefik.frontend.rule="Host:mundodocker.com.br;" --network net tutum/apache-php

Dessa vez criamos um novo serviço, na mesma rede, mas com alguns parâmetros diferentes, como é o caso do traefik.frontend.rule, onde especificamos um novo endereço, e claro a imagem que vamos utilizar, que agora é a tutum/apache-php.

URLs:

Outra feature muito legal do traefik é a possibilidade de redirecionar URLs para backends diferentes. O que isso quer dizer? Quer dizer que podemos enviar partes de uma aplicação para serviços diversos, por exemplo, na aplicação existe um /compras e um /categoria, podemos enviar essas URLs para serviços distintos, isso apenas informando o traefik, veja:

docker service create --name categoria --label 'traefik.port=3000' --label traefik.frontend.rule="Host:mundodocker.com.br; Path: /categoria/" --network net node

Note que agora temos um novo parâmetro, o “Path” onde especificamos qual URL este serviço vai atender, o resto é semelhante, informamos a porta e imagem que este serviço vai utilizar. Para criar um serviço especifico para outra URL, basta:

docker service create --name compras --label 'traefik.port=3000' --label traefik.frontend.rule="Host:mundodocker.com.br; Path: /compras/" --network -net node

E pronto, sua aplicação estará “quebrada” entre vários serviços, e o mais legal é que você não precisou editar um arquivo de configuração se quer. Além dessas facilidades, o traefik ainda disponibiliza uma interface para visualizar como está a saúde das url, em nosso lab você acessará pela porta 8080, e você visualizará algo assim:

Neste dashboard você poderá visualizar como estão configuradas as suas entradas no proxy. Na aba health você poderá visualizar como está o tempo de resposta das url e saber se está tudo certo com o trafego, veja:

Bonito né? E além de tudo, extremamente funcional , em posts futuros veremos um pouco mais sobre como funciona a API do traefik, como configurar o let’s encrypt, e alguns outros pontos, por enquanto, como post introdutório, era isso que gostaria de trazer a vocês.

Esperemos que tenham gostado, qualquer dúvida/sugestão nos avise

Grande abraço, até mais!

Desenvolvimento com Docker

Oi Pessoal,

A intenção hoje é trazer para vocês um conteúdo mais voltado para as equipes de desenvolvimento, ilustrando como é possível automatizar alguns pontos do seu trabalho utilizando Docker e como ele tornará as equipes mais eficientes naquilo que precisam ser: Entrega de resultado, óbvio.

Neste exemplo abordaremos um pouco sobre como é fácil montar um ambiente de desenvolvimento local utilizando nginx, php e mysql, este será, é claro, o primeiro passo em seu caminho para utilizar docker no seu dia-a-dia. Bom, chega de conversa, mãos a obra :).

Obviamente, nesse post não abordaremos como você deve instalar o Docker, para isso temos esse post que vai lhe ajudar muito, veja também que vamos usar nesse ambiente o docker compose, e claro, levamos em consideração que você está utilizando Docker em seu host de desenvolvimento, seja ele Windows, Linux ou Mac, e não no servidor de produção.

A receita

Ok, atendo a esses requisitos, e agora Cristiano, o que faço?

Primeiramente você deve criar, dentro de seu diretório de trabalho um arquivo para que o Docker Compose possa dar inicio a sua stack, e como você viu no post sobre o docker compose, o formato dele é de um arquivo do tipo Yaml, vamos utilizar a versão 2 do Docker Compose, que trás algumas melhorias, mas que difere um pouco na sintaxe, veja o exemplo que vamos usar nesse post:

# Utilizando sintaxe da versão 2:
version: '2'

volumes:
 database_data:
 driver: local

services:
###########################
# Container Web (Nginx)
###########################
 nginx:
 image: nginx:latest
 ports:
 - 8080:80
 volumes:
 - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
 volumes_from:
 - php

###########################
# Container PHP
###########################
 php:
 build: ./php/
 expose:
 - 9000
 volumes:
 - .:/var/www/html

###########################
# Container de banco de dados (MySQL)
###########################
 mysql:
 image: mysql:latest
 expose:
 - 3306
 volumes:
 - database_data:/var/lib/mysql
 environment:
 MYSQL_ROOT_PASSWORD: senha
 MYSQL_DATABASE: projeto
 MYSQL_USER: projeto
 MYSQL_PASSWORD: projeto

A grande diferença entre a versão 1 e 2 do Docker Compose está relacionado a utilização de algumas tags especiais, entre elas: services e volumes. Essas tags obviamente foram adicionadas por um bom motivo, e esse motivo é você poder ter múltiplos serviços dentro de uma stack, mas ter a flexibilidade de escalonar ou modificar atributos de um único serviço dentro de sua stack, sem precisar mexer em toda ela, isso é muito bom, não?

Outro motivo está relacionado ao uso de volumes para a persistência de dados, você não quer perder todo seu trabalho se seu container for acidentalmente removido, certo? E uma das grandes vantagens nesse caso é que você pode especificar um driver para volume que seja persistente não apenas em seu host, mas distribuído em um cluster de volume, explicamos um pouco sobre isso aqui e aqui, em nosso exemplo vamos usar local mesmo.

 

Inside

Note que nas linhas que referem-se ao container PHP, não há referência para imagem, o motivo é simples, faremos o build da imagem no mesmo momento de subir a stack, ou seja, quando rodarmos o docker-compose up -d o docker realizará o build do Dockerfile que encontra-se dentro da pasta php e utilizará a imagem gerada por esse build para iniciar o container php.

Mas e o que tem nesse Dockerfile? Calma, não íamos deixar isso de lado, veja abaixo como é esse Dockerfile:

FROM php:7.0-fpm 
RUN docker-php-ext-install pdo_mysql  
&& docker-php-ext-install json

Em nosso lab, usaremos como base a imagem do php 7.0 em fpm, e baseado nisso instalaremos algumas extensões, para que posteriormente possamos utilizá-las. Note que não é algo muito elaborado, mas poderia, caso você tenha essa necessidade. Na imagem em questão, há um binário responsável pela instalação das extensões, que é o docker-php-ext-install, ele realiza o download e instalação da extensão e sua ativação no php.ini global.

Note também que definimos expor a porta 9000 do container php para que o container do serviço web possa acessa-lo e assim processar as requisições. O arquivo de configuração do servidor web deve ser assim:

server {

 # Set the port to listen on and the server name
 listen 80 default_server;

 # Set the document root of the project
 root /var/www/html/public;

 # Set the directory index files
 index index.php;

 # Specify the default character set
 charset utf-8;

 # Setup the default location configuration
 location / {
 try_files $uri $uri/ /index.php;
 }

 # Specify the details of favicon.ico
 location = /favicon.ico { access_log off; log_not_found off; }

 # Specify the details of robots.txt
 location = /robots.txt { access_log off; log_not_found off; }

 # Specify the logging configuration
 access_log /var/log/nginx/access.log;
 error_log /var/log/nginx/error.log;

 sendfile off;

 client_max_body_size 100m;

 # Specify what happens when PHP files are requested
 location ~ .php$ {
 fastcgi_split_path_info ^(.+.php)(/.+)$;
 fastcgi_pass php:9000;
 fastcgi_index index.php;
 include fastcgi_params;
 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
 fastcgi_param APPLICATION_ENV development;
 fastcgi_intercept_errors off;
 fastcgi_buffer_size 16k;
 fastcgi_buffers 4 16k;
 }

 # Specify what happens what .ht files are requested
 location ~ /.ht {
 deny all;
 }
}

Veja que na opção: fastcgi_pass definimos como php:9000 ou seja, o nome do container na porta que expomos no docker-compose. Lembrando que você pode ter acesso a stack completa baixando esse exemplo de nosso repositório no gitub.

Para o Container de banco de dados, utilizamos a imagem oficial do MySQL, definimos apenas os dados de acesso e nome do banco de dados que gostaríamos de criar, e claro definimos um volume onde serão persistidos os dados desse banco.

Agora finalmente basta você subir a sua stack, para isso:

docker-compose up -d

Depois do docker compose realizar todo o processo de build da sua stack, basta você acessar o ambiente web pelo endereço: http://localhost:8080 e você terá como retorno a pagina inicial do seu site (que em nosso teste é apenas um phpinfo).

Próximos passos

 Bom, agora você só precisar criar :), quando você ficar alguma modificação na pasta onde está o projeto, elas serão refletidas no site, ou seja, modificando o seu index.php será alterado no site que está rodando nos container, isso porque mapeamos a pasta local como sendo a public do servidor web/php. O mais interessante dessa abordagem é poder movimentar esse ambiente para onde quiser, imagem que isso tudo faz parte de seu código versionado no git, basta chegar em basta e rodar um git clone do seu projeto (ou pull) e você terá o mesmo ambiente de desenvolvimento.

Gostou? Não gostou? Tem dúvida? Deixa nos comentários que vamos conversando! E como sempre, nos ajude divulgando o blog.

Grande abraço!

Serviços Windows em Docker

Oi Pessoal,

Já vimos em alguns posts, por exemplo este, este e este, como é possível ter seu ambiente Windows em Docker, ou Docker para Windows. Pois bem, a intenção hoje é nos aprofundarmos mais em como é possível portar um ambiente já existente para dentro de containers no Windows, ou seja, veremos como migrar sua aplicação .net que atualmente está em uma máquina virtual para um container, isso de forma bem simples e rápida.

 

Do início

Antes de tudo, precisamos nos situarmos sobre o uso de algumas ferramentas, e aqui entra a parte fundamental desse processo, que é entender como funciona o Image2Docker, para quem não o conhece, este é um módulo do powershell que possibilita a criação de arquivo(s) Dockerfile(s) a partir de um VHD, VHDx ou ainda uma imagem WIM. Você não precisa estar com a máquina virtual ligada para realizar esse processo, o Image2Docker inspeciona o disco offline coletando informações sobre o que você tem instalado ali, e claro, ele serve apenas para ambiente Windows, então ele já possui uma tabela pré-determinada de aplicações que devem ser verificadas.

Após finalizado o scan, ele monta um Dockerfile baseado na imagem do Windows Server Core (microsoft/windowsservercore), é claro que ele não portará tudo de seu ambiente, por exemplo, se você tem instalado uma base MySQL na VM Windows que escaneou, essa instalação não será portada para o Dockerfile, e consequentemente terá que ser portada manualmente depois. Aqui está uma lista de softwares/aplicações que o Image2Docker busca, e que são suportados por ele:

  • IIS e aplicações ASP.NET
  • MSMQ
  • DNS
  • DHCP
  • Apache
  • SQL Server

Ou Seja, se dentro de seu VHD você possuir algum desses softwares instalados, o Image2Docker gerará o Dockerfile baseado nisso.

image2docker

 

Instalação

Há duas formas de instalação, Você pode instalar o módulo nativo do Image2Docker, o processo é simples:

Install-Module Image2Docker
Import-Module Image2Docker

Neste caso, se você não tiver todas as dependências instaladas, ele fará essa instalação de forma automática (caso você aprove é claro).
Outro método é você utilizar a última versão diretamente do repositório, neste caso você terá que instalar algumas coisas antes, como por exemplo:

Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201
Install-Module -Name Pester,PSScriptAnalyzer,PowerShellGet

Feito isso, basta agora realizar o download do módulo e importa-lo:

mkdir docker
cd docker
git clone https://github.com/sixeyed/communitytools-image2docker-win.git
cd communitytools-image2docker-win
Import-Module .Image2Docker.psm1

É muito importante ressaltar que ele foi desenvolvido para rodar em versões superiores a 5.0 do Poweshell, então se atende a esse detalhe.

 

Convertendo

Vamos começar as poucos, digamos que você tenha uma máquina virtual com IIS instalado com algumas aplicações e quer porta-la para container Docker, é possível? Sim, o Image2Docker suporta VMs em Windows 2016, 2012, 2008 e 2003, independente da tecnologia utilizada, seja ela ASP.NET WebForms, ASP.NET MVC, ASP.NET WebApi.

Para você rodar Image2Docker, precisará informar alguns parâmetros, dentre eles:

  • ImagePath – Localização do VHD, VHDx ou WIM
  • Artifact – Que tipo de serviço você quer portar para um Dockerfile, deve ser um dos itens da listagem acima.
  • ArtifactParam – Parametro que deve ser utilizado apenas se o artefato for IIS, pois é possível especificar apenas um site a ser portado.
  • OutputPath – Localização de onde você salvará o Dockerfile

Chega de papo, vamos ao trabalho, para converter uma VM com IIS e todos os seus sites para um único Dockerfile, basta executar:

ConvertTo-Dockerfile -ImagePath C:VMSwin-2016-iis.vhd -Artifact IIS -Verbose -OutputPath c:dockeriis

A saída desse comando deve ser algo como isso aqui:

VERBOSE: IIS service is present on the system
VERBOSE: ASP.NET is present on the system
VERBOSE: Finished discovering IIS artifact
VERBOSE: Generating Dockerfile based on discovered artifacts in
:C:UsersmundodockerAppDataLocalTemp287653115-6dbb-40e8-b88a-c0142922d954-mount
VERBOSE: Generating result for IIS component
VERBOSE: Copying IIS configuration files
VERBOSE: Writing instruction to install IIS
VERBOSE: Writing instruction to install ASP.NET
VERBOSE: Copying website files from
C:UsersmundodockerAppDataLocalTemp287653115-6dbb-40e8-b88a-c0142922d954-mountwebsitesaspnet-mvc to
C:dockeriis
VERBOSE: Writing instruction to copy files for aspnet-mvc site
VERBOSE: Writing instruction to create site aspnet-mvc
VERBOSE: Writing instruction to expose port for site aspnet-mvc

Ao final da execução do comando, ele gerará um Dockerfile dentro da pasta c:dockeriis com o seguinte conteúdo:

# Instalar a feature do IIS
RUN Add-WindowsFeature Web-server, NET-Framework-45-ASPNET, Web-Asp-Net45
RUN Enable-WindowsOptionalFeature -Online -FeatureName IIS-ApplicationDevelopment,IIS-ASPNET45,IIS-BasicAuthentication...

# Adicionar o site mvc no IIS
COPY aspnet-mvc /websites/aspnet-mvc
RUN New-Website -Name 'aspnet-mvc' -PhysicalPath "C:websitesaspnet-mvc" -Port 8081 -Force
EXPOSE 8081

# Adicionar o site webapi no IIS
COPY aspnet-webapi /websites/aspnet-webapi
RUN New-Website -Name 'aspnet-webapi' -PhysicalPath "C:websitesaspnet-webapi" -Port 8082 -Force
EXPOSE 8082

Lembrando, no exemplo acima nós portamos todos os sites do IIS para um único Dockerfile, é possível especificar apenas um site, para isso:

ConvertTo-Dockerfile -ImagePath C:VMSwin-2016-iis.vhd -Artifact IIS -ArtifactParam aspnet-webforms -Verbose -OutputPath c:dockeriis

Dessa forma, apenas o site chamado: aspnet-webforms será portado para um Dockerfile.

 

Converti, e agora?

Tendo gerado o Dockerfile, basta você seguir o fluxo normal de criação de imagem Docker, por exemplo:

docker build -t mundodocker/site-webforms .

Dessa forma você criará uma imagem chamada: mundodocker/site-webforms e poderá utiliza-la da mesma forma como as demais, apenas lembrando que essa imagem fará a criação do site e copiará os arquivos do site que havia na VM para dentro do container, vamos rodar:

docker run -d -p 8080:8083 mundodocker/site-webforms

Basta agora, você acessar o endereço de sua aplicação, para isso você terá que saber o ip do container criado, então execute:

docker inspect --format '{{ .NetworkSettings.Networks.nat.IPAddress }}' ID_DO_CONTAINER

Agora sim, basta acessar o ip que esse comando retornará, na porta 8080, algo assim: http://172.28.192.4:8080 e você poderá visualizar a aplicação que você tinha em um VM, agora dentro de um container

 

Dica final

Imagine que você tenha diversos sites dentro do mesmo IIS, e queira portar cada um para um container diferente, qual seria o método normal? Rodar o comando N vezes até ter todos portados, certo? Pois bem, você pode automatizar isso, criar um script em powershell que faça essa “mágica” sem muito esforço. O script pode ser parecido como este:

$sites = @("aspnet-mvc", "aspnet-webapi", "aspnet-webforms", "static")
foreach ($site in $sites) { 
    ConvertTo-Dockerfile -ImagePath C:VMSwin-2016-iis.vhd -Artifact IIS -ArtifactParam $site -Verbose -OutputPath "c:docker$website" -Force
    cd "c:docker$site"
    docker build -t "mundodocker/$site" .
}

Dessa forma ele gerará tanto o Dockerfile para cada site assim como as imagens para cada um.

 

Gostaram? Ficaram com dúvidas? Deixe nos comentários ou no nosso fórum, que tanto nós quanto nossos leitores poderão ajudar. E como sempre, ajude divulgando o blog.

Grande abraço!

Docker e Flannel

Oi Pessoal!

A intenção hoje é chamar a atenção para um dos recursos que está presente no Docker e que as vezes passa despercebido para muitos dos utilizadores dessa tecnologia, que é trabalhar com rede. Já vimos aqui no blog como trabalhar com Docker Network, mas com a ascensão do docker 1.12 ficou ainda mais fácil mudar a forma de como se utilizar rede, você pode integrar o Docker com diversos plugins e tecnologias de rede, hoje veremos como utilizar o Flannel para ser seu backend de rede.

Para quem não conhece, o Flannel é um projeto que foi inicialmente desenvolvido pela CoreOS, mas que atualmente é mantido, além da própria empresa, pela comunidade. Ele utiliza um serviço de chave-valor para persistir as informações sobre alocação de ip entre hosts e containers, por padrão ele utiliza o Etcd (que por coincidência é desenvolvido e mantido pela CoreOS também ), veja abaixo algumas das características do Flannel e a diferença em relação ao Docker Network:

                              Flannel              Docker Overlay Network
Modelo                        VxLAN ou UDP                            VxLAN
Isolamento de aplicação                        CIDR Schema                      CIDR Schema
Protocolos suportados                              Todos                            Todos
Serviço de nome                                Não                              Não
Requer backend externo                                Sim                              Sim
Tipo de encriptação                                TLS                              Não
 vNIC por Container                                Não                              Sim
Restrição de subnet por container                                Não                              Sim

Como podem notar o Flannel tem algumas vantagens e desvantagens em relação ao Docker Network, destacam-se a comunicação encriptada que ele provê e não ter a possibilidade de criar subnet diferente por cliente, ou seja, todos os containers fazem parte da mesma rede. Se você está pensando em utilizar Kubernetes, leve em consideração o Flannel, pois é um dos plugins mais utilizados com esse orquestrador. Vamos colocar a mão na massa?

Instalação e dependências

Servidor Etcd

Nosso exemplo foi baseado no Centos 7 64 bits, mas você pode utilizar em outro S.O sem problema. Vamos lá, primeiramente você deve habilitar o repositório Extras do CentOS, para isso edite o CentOS-Base.repo e coloque habilite-o, veja:

# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

#released updates
[updates]
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/
gpgcheck=1
enable=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus&infra=$infra
#baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

Agora vamos instalar o backend do Flannel, que é o etcd (serviço de chave valor em memória), o etcd é utilizada para armazenar as informações sobre as redes que serão distribuídas entre os containers. Vamos lá:

[root@host-etcd ~]#  yum install etcd

Edite o /etc/etcd/etcd.conf alterando o ETCD_LISTEN_CLIENT_URLS, em nosso teste colocamos 0.0.0.0, ou seja, o etcd estará acessível através de qualquer ip do host, veja:

ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"

Cuide para que a porta 2389 esteja liberado no firewall desse host. Agora vamos aproveitar que estamos no host de etcd e vamos já deixar configurado a rede que será utilizada pelos hosts de Docker. Para isso, crie um arquivo, em nosso lab: rede.json e adicione o seguinte código:

{
 "Network": "192.0.0.0/16",
 "SubnetLen": 22,
 "Backend": {
 "Type": "vxlan",
 "VNI": 1
 }
}

Onde:

  • Network – Bloco de rede que será distribuída para os containers;
  • SubnetLen – Tamanho do bloco alocada para cada host, ou seja, cada host receberá um /22 do bloco 192.0.0.0/16, isso que dizer que poderíamos ter até 1000 containers em 1 host.
  • Type – Tipo do canal que será utilizado, lembra que no Flannel você pode escolher em vxlan ou udp, pois bem, é aqui que você configura isso, por experiência própria, recomendamos utilizar vxlan, pois há menos overhead.

O que faço com isso agora? Importe no etcd ;), lembrando que o etcd trabalha com chave=valor, então execute:

[root@host-etcd ~]# etcdctl set /mundodocker/network/config < rede.json

Onde:

  • /mundodocker/network/config – chave
  • rede.json – valor

Agora vamos ver se essas informações foram persistidas no etcd:

[root@host-etcd ~]#etcdctl get /mundodocker/network/config
{
 "Network": "192.0.0.0/16",
 "SubnetLen": 22,
 "Backend": {
 "Type": "vxlan",
 "VNI": 1
 }
}

 

Servidores Docker

Não esqueça, em todos os hosts temos que ativar o repositório de extras do CentOS, da mesma forma que foi feita acima. Vamos as instalações das dependências, o docker é claro:

[root@host-docker01 ~]# curl -fsSL https://get.docker.com/ | sh

Agora o Flannel:

[root@host-docker01 ~]# yum install flannel -y

Vamos as configurações agora, começamos pelo Flannel, para isso, edite o arquivo: /etc/sysconfig/flanneld, modificando as linhas:

FLANNEL_ETCD = Servidor do Etcd.
FLANNEL_ETCD_KEY = Key definida no Etcd.

Veja como deve ficar:

[root@host-docker01 ~]# cat /etc/sysconfig/flanneld | grep -v ^#
FLANNEL_ETCD="http://host-etcd:2379"
FLANNEL_ETCD_KEY="/mundodocker/network"

Agora inicie o serviço do Flannel:

[root@host-docker01 ~]# systemctl enable flanneld
[root@host-docker01 ~]# systemctl start flanneld

Note que ele criará uma interface de rede chamada flannel.1, que será utilizada para comunicação entre os hosts. Note também que será criado um arquivo dentro de: /run/flannel/subnet.env com as informações sobre a rede que o host assumiu, esse arquivo será utilizado daqui a pouco.

Agora vamos configurar nosso serviço de Docker para utilizar a rede Flannel configurada anteriormente, para isso, edite o arquivo: /lib/systemd/system/docker.service adicionando a linha: EnvironmentFile=-/run/flannel/subnet.env e alterando a forma como o Docker será iniciado, veja como deve ficar:

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target docker.socket
Requires=docker.socket
 
[Service]
Type=notify
EnvironmentFile=-/run/flannel/subnet.env
ExecStart=/usr/bin/docker daemon -H fd:// $OPTIONS $DOCKER_STORAGE_OPTIONS --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
TimeoutStartSec=0
 
[Install]
WantedBy=multi-user.target

Agora basta iniciar/reiniciar o serviço do Docker:

[root@host-docker01 ~]# systemctl enable docker.service
[root@host-docker01 ~]# systemctl start docker.service

Não esqueça de fazer isso em todos os hosts de Docker que você quer colocar nessa rede.

 

Vamos testar?

Basta você criar um container em cada host, em nosso teste criamos um baseado na imagem do CentOS:

Host 1:

[root@host-docker01 ~]# docker run -it centos /bin/bash

Host 2:

[root@host-docker02 ~]# docker run -it centos /bin/bash

Agora basta você pingar de um container para o outro, ou se quiser fazer um teste mais real, você pode instalar um banco de dados ou servidor web em um dos containers e tentar acessar via ip da rede Flannel pelo outro container. Como você deve ter notado esse processo é bem simples e resolve grandes problemas com rede no Docker, como por exemplo a comunicação entre multi-host.

Por hoje era isso, espero que tenha ajudado, e como sempre, nos ajude divulgando o blog

Abraço!

Docker Swarm na Prática

Oi Pessoal!

Fizemos um vídeo mostrando na prática como é possível criar um cluster de Swarm e gerenciar seus serviços com ele, veja também como você pode portar sua stack do Docker Compose para dentro do cluster via o Docker Stack. Veja:

Este é apenas um vídeo de lab, lembramos que você deve se ater a alguns outros pontos nesse ambiente antes de colocar em produção, OK?

Contamos com a ajuda de vocês para divulgação do blog, grande abraço!

Cronjobs com Docker

Oi Pessoal,

Hoje vamos trazer para vocês um forma de resolver algo que é bem recorrente e comum em ambientes de produção, e que talvez acabe de tornando uma porta de entrada para o uso do Docker em maior escala. Dessa vez, você entenderá como é possível realizar o agendamento e execução de script utilizando a crontab dentro de containers Docker o/.

Para quem ainda não sabe, dentro de ambiente like *unix é possível realizar o agendamento de scripts utilizando uma ferramenta chamada Crontab (para quem é do ambiente Microsoft, é o mesmo que o task scheduler, mas com mais poder ), através dela você define o horário de execução para os scripts, usuário que será utilizado para a execução do mesmo, e claro, qual script deve ser executado. Pois bem, sabendo disso, é possível utilizar o Docker para que a execução desses scripts seja realizada dentro de containers.

Mas afinal, quais as vantagens disso?

Bem, a execução de script via crontab, pode gerar alguns desafios, principalmente se não há um controle rigoroso de quais scripts estão sendo agendados, dentre os desafios podemos destacar:

1 – Uso excessivo de recursos: Pode acontecer de algum script ter algum erro e fazer com que haja uso excessivo de recursos (memória, cpu) durante a sua execução, e acredite, isso é mais comum do que imagina. Existe formas de contornar isso, no entanto, nativamente não.

2 – Segurança na execução: Você pode definir qual usuário executará um determinado script, isso funciona muito bem dentro da crontab, no entanto, caso você não especifique, o usuário utilizado para a execução do script  será o mesmo que inicializou o serviço da cron, e geralmente este serviço inicializa com o usuário root, então…

Ok Cristiano, e como o Docker pode me ajudar?

Aeooooo mais um convertido, vamos ver como funciona na prática?

A primeira coisa que faremos é criar os diretório necessários, para isso, defina um diretório de trabalho, e nele crie uma pasta chamada “cron” e outra chamada “scripts”. Em seguida vamos buildar uma imagem Docker apenas com o que precisamos para realizar a execução dos scripts, como imagem base, vamos utilizar uma do NodeJS Alpine, lembrando que, neste caso nossa cron executará um script escrito em node, você deve adaptar a imagem de acordo com a sua necessidade (se seu script é em PHP, então a imagem deve ser PHP, e assim por diante) veja como ficou nosso Dockerfile:

FROM node:8-alpine
RUN apk update && apk add tzdata && 
    cp /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime && 
    echo "America/Sao_Paulo" > /etc/timezone && 
    apk del tzdata && rm -rf /var/cache/apk/*
CMD chown root:root /etc/crontabs/root && /usr/sbin/crond -f

Não preciso explicar este Dockerfile né, você já deve ter lido este post né?  salve-o dentro da pasta “cron”.

Bem, agora precisamos montar o resto do ambiente, para este lab, vamos criar um arquivo chamado cron1 com o seguinte conteúdo:

0 7,19 * * * /usr/local/bin/node /home/mundodocker/hello.js >> /var/log/cronteste/hello.log 2>&1

Neste caso, o script será executado as 7h e as 19h todos os dias, salve-o dentro da pasta “cron” também.

Veja, que neste caso o script que deverá ser executado é o /home/mundodocker/hello.js que contém algo simples em node:

console.log("Hello world");

Salve-o dentro da pasta “scripts”.

Ok, agora estamos quase prontos, pelo menos, tudo que precisamos está pronto, se quisermos podemos utilizar essa estrutura, pois ai já contém tudo que é necessário, obvio que isso não basta, visto que a intenção é deixar tudo automatizado. Para isso, é necessário que você tenha o docker-compose instalado, com isso conseguimos automatizar 100% do ambiente. Como você já sabe, para utilizarmos o docker-compose, precisamos de um arquivo no formato yaml com as definições de nosso ambiente, veja como ficou nosso docker-compose.yml:

version: "3"
services:
    cron:
        build: cron
        container_name: cronteste
        volumes:
            - /var/log/cronteste:/var/log/cronteste
            - ./cron/cron1:/etc/crontabs/root
            - ./sripts:/home/mundodocker

Para validar, você pode executar o comando:

docker-compose up

Com isso ele fará o build da imagem e em seguida iniciará um container com esse agendamento. Além das opções acima, você pode por exemplo limitar os recursos desse container, inclusive definir um valor minimo para o mesmo. Outra possibilidade é iniciar este container com um usuário especifico, dessa forma você não terá problemas com aquela execução com usuário root

Validou? Tudo certo? Agora vamos fazer com que esse mesmo comando seja executado na inicialização do servidor, visto que, ele ficará no somente enquanto o servidor estiver ligado, e obviamente os agendamentos serão perdidos, não queremos isso certo?

Pois bem, em sistema onde você tem o systemd (Ubuntu, RedHat, Fedora, CentOS) você deverá criar um novo service, para isso, crie dentro de: “/lib/systemd/system/” um arquivo com nome de: docker-cron.service com o seguinte conteúdo:

[Unit]
Description=Docker Cron
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/local/bin/docker-compose -f /home/mundodocker/docker-compose.yml up
ExecStop=/usr/local/bin/docker-compose -f /home/mundodocker/docker-compose.yml stop

[Install]
WantedBy=default.target

Criado o arquivo, basta fazer com que o systemctl releia o arquivo e adicione o serviço a sua base:

systemctl daemon-reload

Agora é simples, vamos adicionar este serviço ao startup do servidor:

systemctl enable docker-infra

Dessa forma você pode administrar da mesma forma que um serviço, ou seja, posso iniciar e parar esse agendamento a qualquer momento, e mesmo que o servidor seja reiniciado, o agendamento será persistido.

 

Ok, agora sim temos tudo 100% automático, não precisamos nos preocupar com mais nada, a não ser é claro em estender isso a  outros tipos de agendamento (se for este o seu caso é claro). Bom, por hora era isso, ficou com dúvida? Tem algo a contribuir? Por favor deixe nos comentários e vamos melhorando juntos

 

Obrigado e grande abraço!

Docker Bench Security

Eai pessoal!

Os engenheiros do Docker disponibilizaram uma ferramenta para testes básicos de segurança para o ambiente Docker. Essa ferramenta nada mais é do que um container que executa um script e verifica se as melhores práticas e recomendações de segurança foram seguidas na instalação e configuração do serviço do Docker. Para executar rode o comando:

docker run -it --net host --pid host --cap-add audit_control -v /var/lib:/var/lib -v /var/run/docker.sock:/var/run/docker.sock -v /usr/lib/systemd:/usr/lib/systemd -v /etc:/etc --label docker_bench_security docker/docker-bench-security

Este comando retornará algo parecido com:

BenchDocker

Que é um report sobre como está seu ambiente, a cada procedimento para correção das falhas indicadas por este relatório, você deverá executar novamente o comando, pois ele analisará se a correção surtiu efeito ou não.

Lembrando que é recomendado que você execute esse container na versão 1.6 em diante do Docker.

Todos os testes realizados por esse script foram criados baseados em um estudo realizado pelo CISecurity (Center Of Internet Security), que indicam quais seriam as melhores formas de se proteger e aumentar a segurança de seu ambiente Docker.

Espero que tenha sido útil, tendo dúvidas ou precisando de ajuda para resolver algum ponto nos avise, e ajude divulgando o mundodocker.com.br!

 

Referências:

https://benchmarks.cisecurity.org/tools2/docker/CIS_Docker_1.6_Benchmark_v1.0.0.pdf

https://github.com/docker/docker-bench-security

Understanding Docker Security and Best Practices

Coleta de métricas no Docker Swarm

Oi Pessoal!

Queremos trazer para vocês hoje uma solução para coleta e visualização de métricas para o Docker Swarm. Um dos maiores desafios, principalmente para as equipes de operações, é saber quanto está sendo utilizado por cada container, OK, existem soluções na engine do Docker, como é o caso do docker stats, mas e quando você tem um diversos hosts, e eles estão em cluster e não tem definido quais containers estão em cada host, complicou né?

A intenção com este post é mostrar como é possível ter, de forma fácil, todas as informações de consumo de seu cluster, utilizando soluções simples, e que a maioria de vocês já deve ter visto. Para este lab vamos usar o Cadvisor, Influxdb e Grafana, vamos entender melhor onde cada um irá atuar neste ambiente.

Cadvisor

Como já vimos aqui no blog, o Cadvisor é uma ferramenta desenvolvida justamente para realizar a coleta de recursos de containers/aplicações dentro de um servidor. É possível estender seu uso através de integração com a API que essa ferramenta disponibiliza, e enviar os dados coletados para diversos backends, em nosso lab vamos utilizar o InfluxDB, que você verá logo abaixo o que é e como funciona.

 

InfluxDB

Para quem não conhece, o InfluxDB faz parte de um conjunto de soluções da empresa InfluxData, que tem seus produtos voltadas para analise, monitoramento e armazenamento de informações cronológicas. O InfluxDB é conhecido como um data series database, que serve justamente para armazenar dados em ordem cronológica.

 

Grafana

O Grafana talvez seja uma das mais completas ferramentas para criação e exibição de gráficos, e uma ferramenta extremamente flexível e adaptável, tendo como input diversos tipos de backend, o que facilita ainda mais o nosso lab 😉 . Você pode inclusive ter mais datasources e montar o seu dashboard unindo todas as essas informações, bacana né?

 

Ok, teoria é muito bonita, mas… vamos praticar?

Primeiramente você deve ter em execução o seu cluster, caso não tenha feito isso ainda, faça agora, caso tenha dúvidas, veja este post, onde mostramos na prática como fazer isso 🙂 . Certo agora vamos criar os serviços de coleta para o nosso cluster, para isso, você pode executar o seguinte passo-a-passo:

  •  Crie uma rede do tipo overlay para que seja possível a comunicação entra as ferramentas, e que essa comunicação seja realizada de forma isolada:
$ docker network create -d overlay --attachable coleta
  • Em um dos dos hosts (de preferência o menos utilizado), crie o servidor de Influx, que será utilizado como backend para as informações coletadas:
$ docker run -d --restart=always -v /data:/var/lib/influxdb --network coleta --name influx influxdb
  • Devemos criar a database dentro do influx para que seja possível salvar as informações:
$ docker exec -it influx influx -execute 'CREATE DATABASE cadvisor'
  • Ok, agora basta criar o serviço de coleta no cluster:
$ docker service create --name agentes --network coleta --mode global --mount type=bind,source=/,destination=/rootfs,readonly=true --mount type=bind,source=/var/run,destination=/var/run  --mount type=bind,source=/sys,destination=/sys,readonly=true  --mount type=bind,source=/var/lib/docker,destination=/var/lib/docker,readonly=true google/cadvisor -logtostderr -docker_only -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influx:8086

Se tudo correu bem, você deve terá criado um serviço do tipo global, ou seja, cada host de seu cluster terá um container desse tipo (Cadvisor), e todos eles enviarão os dados para o banco influx. Para ter certeza de que tudo correu bem, você pode executar o comando:

$ docker service ls

Dessa forma você visualizará os serviços que estão em execução, e terá ter certeza de que os containers iniciaram em todos os nós, o retorno do comando deverá ser algo parecido com isso:

$ docker service ls
ID           NAME    MODE   REPLICAS IMAGE                  PORTS
5ras37n3iyu2 agentes global 2/2      google/cadvisor:latest

Viu, tudo certo 🙂 Mas ainda não acabou, continuando:

  • A última etapa é subir nosso serviço de Grafana para podermos visualizar as informações que foram coletadas pelo Cadvisor, e armazenadas no InfluxDB, execute:
$ docker run -d --restart=always -v /data:/var/lib/grafana --network coleta --name grafana -p 80:3000 grafana/grafana

Simples né? Agora temos que acessar a interface do Grafana para podemos configurar e termos os gráficos que desejamos, acesse: http://ip-do-host/login, você visualizará a interface de acesso dele, como ilustrado abaixo:

Os dados de acesso default do Grafana são:

User: admin
Password: admin

Estando dentro da interface do Grafana, vá até “Source” e adicione uma nova fonte de dados, nela informe “InfluxDB”, conforme imagem abaixo:

Após clique em “save & test” para validar o acesso ao seu InfluxDB. Se tudo ocorrer conforme o planejado, você terá sucesso nessa adição, e em seguida deverá montar o gráfico baseado nas informações que estão no banco, para isso existem duas formas, uma mais complexa onde você precisará montar as querys e depois criar o gráfico com essas querys, ou importar um template pronto para isso, e neste caso eu agradeço ao Hanzel Jesheen, pela contribuição a comunidade, em ter criado o template e disponibilizado em seu github . Você pode baixar este arquivo, salvar em seu computador e depois ir até a área de Dashboard de seu Grafana e clicar em import, informe o caminho de onde salvou o template, escolha o source criado anteriormente e depois clique em “import”, conforme imagem abaixo:

Parabéns! Você acaba de montar seu sistema de coleta e visualização de recursos para todo o seu cluster! Indo até Dashboards – Cadvisor você terá uma visualização parecida com esta:

Bacana não?

A partir desse protótipo você pode evoluir seu ambiente para atender a sua demanda, em nosso lab a coleta é realizada pelo Cadvisor e enviada ao InfluxDB a cada 60 segundos, isso quer dizer que o gráfico tem um delay de 1 minuto entre a coleta e a visualização, para alguns isso é problema, para outros não. Outro ponto que você deve se atentar é: Quantos mais containers você tiver, mais poluído ficará o seu gráfico, isso por motivos óbvios, então talvez você precisa alterar o layout do dashboard. Ahhh não esqueça de trocar a senha do usuário admin do Grafana

Por hoje era isso gente, esperamos que isso ajude vocês, e continuaremos com alguns posts mais técnicos trazendo alguns soluções ou implementações legais utilizando Docker. Nos ajude divulgando o blog, e tendo dúvida nos avise!

Grande abraço!