Entendendo os benefícios e utilização do Docker
Autor: Reginaldo | Publicado: 2016-11-27T22:30:00-02:00

O que é Docker?
Antes esclarecemos uma dúvida comum aos novatos. Docker não é sistema de virtualização tradicional, pois em um sistema de virtualização tradicional temos um SO completo e isolado, já no Docker temos os recursos isolados que utilizam as bibliotecas do kernel em comum (host e contêiner). O Docker utiliza como backend o LXC.

Figura diferença entre Virtualização e Contêiner de [1] 

Docker é uma plataforma open source escrito em Go, linguagem de programação de alto desempenho da Google, que facilita a criação e administração de ambientes isolados.

Vantagens de usar o Docker 
O Docker permite o empacotamento de uma aplicação ou ambiente completo dentro de um contêiner, e a partir desse momento o ambiente completo torna-se portável para qualquer outro Host que contenha o Docker instalado. 
Assim reduz drasticamente o tempo de deploy de alguma infraestrutura ou até mesmo da aplicação, pois não há necessidade de ajustes de ambiente para o correto funcionamento do serviço, o ambiente sempre é o mesmo, configure uma vez e replique quantas vez  quiser.
Outra facilidade do Docker é poder criar imagens (contêiners prontos para deploy) por meio de arquivos de configuração Dockerfile.


Como o Docker funciona? 
O Docker funciona como cliente e servidor (toda a comunicação entre o Docker Daemon e Docker Client é realizada através da API), basta apenas ter instalado o serviço do Docker e apontar o Docker Client para o servidor. A plataforma Docker utiliza alguns conjuntos de recursos, seja para criação ou administração dos containers. entre esses conjuntos destacamos a biblioteca libcontainer, que é responsável pela comunicação entre o Docker Daemon e o backend utilizado, e ela a responsável pela criação do container e através dela podemos setar os limites de recursos por container.

Instalação do Docker 
Pré-requisitos:  O Docker requer instalação das distros Linux com arquitetura 64 bits independente da versão e além disso, o kernel deve ter no mínimo 3.10. 

No Debian 

# apt-get purge "lxc-docker*" 
#apt-get purge "docker.io*" 
# apt-get install apt-transport-https ca-certificates 
# echo "deb https://apt.dockerproject.org/repo debian-jessie main " > /etc/apt/sources.list.d/docker.list 

#apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D 
 

Debian Wheezy (7) 
# echo "deb https://apt.dockerproject.org/repo debian-wheezy main" >> /etc/apt/sources.list  

Debian Jessie (8)  
# echo "deb https://apt.dockerproject.org/repo debian-jessie main" >> /etc/apt/sources.list  

Debian Stretch/Sid (9) 
# echo "deb https://apt.dockerproject.org/repo debian-stretch main" >> /etc/apt/sources.list 
Atualização do repositório  
# apt-get update  
Instalação do pacote Docker  
# apt-get install docker-engine  
Startar o serviço Docker  
# service docker start 
 

No CentOS 
Adicionar no repositório 

# tee /etc/yum.repos.d/docker.repo <<-'EOF' 
[dockerrepo] 
name=Docker Repository 
baseurl=https://yum.dockerproject.org/repo/main/centos/7/ 
enabled=1 
gpgcheck=1 
gpgkey=https://yum.dockerproject.org/gpg 
EOF 
 

Instalar o pacote Docker 
# yum install docker-engine 
Habilitar o serviço Docker  
# systemctl enable docker.service  
Startar o serviço Docker  
# systemctl start docker  

No Ubuntu 

$ sudo apt-get update 
$ sudo apt-get install apt-transport-https ca-certificates 
$ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D 
 

Precise 12.04 (LTS) deb https://apt.dockerproject.org/repo ubuntu-precise main 
Trusty 14.04 (LTS) deb https://apt.dockerproject.org/repo ubuntu-trusty main  
Wily 15.10 deb https://apt.dockerproject.org/repo ubuntu-wily main  
Xenial 16.04 (LTS) deb https://apt.dockerproject.org/repo ubuntu-xenial main  

Adicione o repositório conforme a versão do Ubuntu, nesse caso adicionei a versão Xenial 16.04 LTS 
$ echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo tee /etc/apt/sources.list.d/docker.list  

Atualiza o repositório 
$ sudo apt-get update  

Instalação da imagem do kernel extra e virtual  
$ sudo apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual  

Instalação do pacote Docker  
$ sudo apt-get install docker-engine  

Start do serviço Docker 
$ sudo service docker start  

Comandos Docker 

Build de uma imagem 
docker build -t    
Lembre que as imagens são compostas de camadas (layers) e que o Docker usa caching para fazer o build somente das camadas que tiveram alguma mudança. Recentemente, o Docker publicou uma Image Specification, que explica como tudo isso funciona. Para buildar uma imagem sem utilizar caching, adicione a opção --no-cache ao comando. 

Executar um container 
docker run -d -p : --name    

Iniciar uma sessão bash em um container que esteja rodando 
docker exec -it  bash  

Pesquisa de imagens 
docker search nome-imagem 

Encontrado a imagem, execute o comando pull para o download 
docker pull nome-imagem 

Remover um imagem 
Localize o ID ou nome do repositório com o comando docker images.

Com o id ou o nome do repositório em mãos, utilize o comando rmi para excluir as imagens. 

docker rmi ID_ou_nome_da_imagem 

Ver os logs de um container 
docker logs   

Ver todas as imagens no host 
docker images 

Ver todos os containers 
docker ps -a 

Remover um container 
docker rm -f  

Remover TODOS os containers 
docker rm -f $(docker ps -a -q)  

Remover uma imagem  
docker rmi -f   

Remover dangling images 
docker rmi $(docker images -q -f dangling=true) 
"Dangling images" são, basicamente, imagens sem uma tag. Se você alguma(s) vez(es) rodou um Dockerfile que falhou, provavelmente você deve ter uma ou mais imagens sem tags. 

Copiar um arquivo do container para o host 
docker cp :/caminho/no/container /caminho/no/host 

Monitoramento de containers 
Visualizar estatísticas de um container 
docker stats  

Visualizar estatísticas de todos os containers executando no host 
docker stats `docker ps | tail -n+2 | awk '{ print $NF }' 

Repositório de imagens prontas do Docker  
O site  https://hub.docker.com/explore/  é onde estão as imagens prontas para usar usando os comandos informados. 

Construindo sua própria imagem para seu ambiente em uma aplicação  
O arquivo de manifesto do Docker é o Dockerfile, nele você coloca as instruções de como você quer que sua imagem seja construída. Você pode na construção da imagem setar outro arquivo com o parâmetro -f. 

Abaixo temos um exemplo de Dockerfile, esse é um exemplo de um app em go já compilado para ubuntu então eu só preciso copiar o arquivo executável elasticpush para dentro do docker:  

FROM debian:jessie 
RUN mkdir /app 
ENV ACCESS_TOKEN abc 
ENV SECRET_TOKEN xyz 
COPY ./bin/elasticpush /app/elasticpush 
ENTRYPOINT [“/app/elasticpush”]
 

Detalhando os comandos utilizados:  

FROM: Este é o comando mais importante, pois ele especifica a imagem base para a construção de uma nova. Na maioria das vezes a imagem especificada vai ser uma distribuição linux, se essa imagem não for encontrada na máquina local, o docker tentará buscar em algum repository. Caso queira, por exemplo, fazer a build do seu app em GO dentro do container, você vai precisar de uma imagem que tenha o GO instalado e configurado. Outra forma também seria criar diversas instruções com o comando RUN para fazer essa instalação. 

RUN:  Esse comando serve para executar outros comandos que a versão do sistema operacional permite. Por exemplo, se for Debian pode instalar apt-get, se for CentOS pode utilizar o yum para pegar as dependências que seu serviço precisa para rodar. Com o RUN você também pode criar arquivos, diretórios, enfim os mesmo comando do que executaria na sua máquina, logo você consegue fazer praticamente tudo, e deixar a sequência de comandos versionada aqui no container. 

ENV:  Serve para setar variáveis de ambiente, assim pode tanto deixar essas variáveis setadas de forma fixa dentro do Dockerfile quanto passá-las dinamicamente na hora que instanciar o container. Para passar essas variáveis de ambiente na instanciação do container basta usar o parâmetro -e. 
Exemplo:  docker run -e ACCESS_TOKEN=abcd [nome da imagem]  

COPY:  O COPY serve para poder copiar arquivos e diretório para dentro da imagem do Docker, nesse exemplo eu copiei o arquivo elasticpush que estava dentro do diretório  bin  na minha máquina local para dentro da pasta /app na imagem do docker. 

ENTRYPOINT:  Com esse parâmetro pode setar se quer que algo seja executado na hora da instanciação do container. Então, quando for executar docker run nessa imagem, ela já vai instanciar e executar o programa que está no caminho que você colocar entre colchetes. No nosso caso queremos que essa imagem execute nossa aplicação do Elasticpush, o mesmo vale para quaisquer outros serviços como Redis, Elasticsearch, Nodejs, etc. 

Após criar o arquivo Dockerfiles do seu ambiente de aplicação, execute: 
docker build -t app/elasticpush  

Considerações finais 
O Docker é uma tecnologia da área de DevOps, sendo utilizada por muitas empresas, como Google, Yahoo, Microsoft e outras, dentro da metodologia ágil. 
O Docker é uma ferramenta leve que permite executar containers de forma equivalente como se fosse máquinas virtuais, mas lembra da diferença de virtualização e containers na figura mencionada no início, então o Docker funciona dessa forma.
Por fim, espero que esse artigo tenha esclarecido sobre Docker e recomendo começar a utilizar nas aplicações de projetos que for desenvolver. 
Referências 
[1] http://www.mundodocker.com.br/o-que-e-docker/  

[2] http://stefanteixeira.com.br/2015/03/17/comandos-essenciais-docker-monitoramento-containers/  

[3] https://woliveiras.com.br/posts/comandos-mais-utilizados-no-docker/  

[4] http://tableless.com.br/iniciando-com-o-docker-criando-suas-proprias-imagens/  

[5] https://docs.docker.com/engine/installation/linux/debian/  

[6] https://docs.docker.com/engine/installation/linux/centos/  

[7] https://docs.docker.com/engine/installation/linux/ubuntulinux/  

Feito!