docker footer

Atualmente é quase impossível falar de virtualização sem falar de Docker – e calma! Ainda que Docker não seja sobre virtualização (e eu sei disso) ele é a ferramenta do momento para usarmos quando desejarmos este tipo de solução. Vamos entender um pouco melhor o que é o Docker, como instalar, alguns comandos básicos e a execução de alguns conteineres 😉

O que é Docker?

logo docker

Docker é não apenas uma tecnologia mas também uma solução e um padrão de mercado para a criação, manutenção, entrega e execução de conteineres de aplicações.

Um container é basicamente um set de uma máquina Linux que roda sobre um (outro) Kernel Linux, qualquer que seja ele.

A grosso modo no Linux existem features que permitem isolar todo um conjunto de serviços e acesso a recursos de máquinas, de forma nativa. Docker faz uso disso para executar um outro sistema Linux (que chamamos de container). Toda a automatização, criação e execução disso fica a cargo do Docker, que acho que eu não preciso falar é uma tecnologia open source 😉

Lá no começo eu cometi a heresia de dizer que quando se fala em virtualização a palavra do momento é Docker. Heresia por que o que o Docker faz não é o que as máquinas virtuais fazem, poderíamos dizer que no fim o resultado é o mesmo, mas os meios para isso são mais elegantes, sustentáveis, eficientes e baratos (sim, são muitos benefícios!).

A imagem abaixo ilustra de forma simples essa diferença:
docker vs vm

Reparem que no caso das máquinas virtuais temos além do SO host (por exemplo Windows) temos vários SOs guest sendo instalados e executados sobre esta máquina. Cada um destes servidores possui suas necessidades de Rede, Memória, Disco, etc. Tudo isso para mantermos nossas aplicações isoladas. Então se para rodar uma aplicação Web precisamos de um servidor com 4 GB e queremos criar 4 instâncias desta aplicação precisamos de 16 GB, possivelmente 40GB de disco (por que cada SO vai usar uma boa parte disso), etc. Ainda que deixemos de ter várias máquinas físicas (o que já é um grande avanço) temos um grande desperdício de recursos, pois na grande maioria dos casos tudo que queremos é ter um ambiente isolado para cada uma de nossas aplicações.

No caso de conteineres isso não acontece, basicamente por que temos apenas um SO e em cima dele estamos rodando versões bastante reduzidas de outros SOs. Não precisamos de uma instalação completa (ainda que seja mínima) de um SO. Um conteiner é um pequeno set, embora completamente funcional, compartilhando o Kernel de um Linux que já está instalado e executando. É este fato também que torna a criação e execução de conteineres algo tão simples, rápido e prático. Executar um container, colocá-lo em produção por exemplo, é extremamente simples e rápido. Desta forma sem desperdício de recursos (tempo e dinheiro) temos ambientes isolados para a execução de nossas aplicações.

Instalando Docker

O processo de instalação do Docker é bastante simples e pode ser realizado em Windows, OSX (Mac) e em diversas distribuições Linux. Acho que vale mais a pena correr aqui e seguir o precesso deles:

Instalando Docker no Windows
Instalando Docker no Mac OSX
Instalando Docker no Ubuntu

Ao final de tudo vocês devem conseguir executar isso aqui no console:

➜  ~  docker -v
Docker version 1.9.1, build a34a1d5

Caso algo tenha dado errado, confirmem os passos e os requerimentos nas respectivas páginas de instalação.

Comandos Básicos

Docker funciona em um padrão client/server. Basicamente o Docker client pede informações e executa comandos contra o Docker server.

Para vermos isso de forma simples basta digitarmos

➜  ~  docker version
Client:
 Version:      1.9.1
 API version:  1.21
 Go version:   go1.4.3
 Git commit:   a34a1d5
 Built:        Fri Nov 20 17:56:04 UTC 2015
 OS/Arch:      darwin/amd64

Server:
 Version:      1.9.1
 API version:  1.21
 Go version:   go1.4.3
 Git commit:   a34a1d5
 Built:        Fri Nov 20 17:56:04 UTC 2015
 OS/Arch:      linux/amd64

Reparem que tanto meu Docker client quanto server estão na mesma versão, usam a API com a mesma versão, etc. Mas reparem que meu client está rodando em Mac enquanto que o meu server está respondendo como Linux 😉

Listando conteiners

A forma mais simples de listarmos nossos containers é usando o comando docker ps (que exibe apenas os conteiners em execução):

➜  ~  docker ps

Para listarmos todos os conteineres:

➜  ~  docker ps -a

E para listarmos apenas o mais recente:

➜  ~  docker ps -l

E se você ainda não tem nenhum conteiner verá um output apenas com o nome das colunas.

Criando um novo container

Que tal criar um container Ubuntu? Sério isso é muito simples e fácil, tudo feito via usando o comando docker create [nome imagem]:

➜  ~  docker create ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu

fcee8bcfe180: Pull complete 
4cdc0cbc1936: Pull complete 
d9e545b90db8: Pull complete 
c4bea91afef3: Pull complete 
Digest: sha256:b53bb7b0d18842214ac7472c2a8801e8682c247d30f1ba4bab0083a2e2e091ea
Status: Downloaded newer image for ubuntu:latest
3ab94dab41907b3b3c79cf5cd3ba6527714969120dbc0472d29ac316595d3023

O Docker por padrão procura suas imagens no Docker Hub, que é o respositório oficial de imagens Docker, onde você pode encontrar imagens oficiais para alguns produtos e tecnologias, bem como imagens mantidas pela comunidade.

O que aconteceu acima é que o Docker viu que eu não tinha nenhuma imagem para Ubuntu localmente, e fez o pull/download disso direto do Docker Hub.

Se executarmos agora um docker ps -a veremos que temos um container de Ubuntu criado, porém não está rodando:

➜  ~  docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
f05e6f45fe0b        ubuntu              "/bin/bash"         1 seconds ago       Created                                 ecstatic_lamarr

Repare também que o Docker sempre dá um nome para o container (o que às vezes pode ser bem engraçado 😛 )

O ponto aqui é que nosso container está apenas criado, não está executando. Se tentarmos iniciar o mesmo perceberemos que ele inicia e encerra, imediatamente. Isso acontece pois o conteiner “morre” assim que o seu processo principal termina. Vamos então apagar este container e criar um novo, que não faça isso.

Apagando containers

Para apagarmos este conteiner:

➜  ~  docker rm ecstatic_lamarr

Iniciando containers

Vamos rodar praticamente o mesmo comando para a criação, exceto que desta vez vamos informar dois parâmetros adicionais o parâmetro -i diz para o container manter manter o STDIN aberto mesmo que o container esteja executando em plano de fundo. Já o parâmetro -t informa ao conteiner para atribuit um pseud-TTY, basicamente um psudo-terminal.

➜  ~  docker create -it ubuntu               
88b23361fc843e6b04468cb5b6809b6c39a82060d774d419ac27e637e71aa707
➜  ~  docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
88b23361fc84        ubuntu              "/bin/bash"         2 seconds ago       Created                                 naughty_hypatia
➜  ~  docker start naughty_hypatia
naughty_hypatia
➜  ~  docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
88b23361fc84        ubuntu              "/bin/bash"         19 seconds ago      Up 2 seconds                            naughty_hypatia

Aqui estamos criando nosso container na linha 1. Depois listamos todos os containers na Linha 3. Na linha 6 iniciarmos nosso container e na linha 8 listamos novamente e na linha 10 observamos o status Up 2 seconds informando que ele está rodando há 2 segundos.

Atachando a containers

Se quisermos brincar dentro de um container que tenhamos executando podemos fazer isso atachando-nos ao container, para isso fazemos:

➜  ~  docker attach naughty_hypatia
root@88b23361fc84:/# 

Repare que na linha 2 estamos dentro do shell do nosso container Ubuntu. Podemos verificar isso claramente:

➜  ~  docker attach naughty_hypatia
root@88b23361fc84:/# uname -a
Linux 88b23361fc84 4.1.13-boot2docker #1 SMP Fri Nov 20 19:05:50 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

Isso nos mostra que estamos dentro de um Ubuntu com Kernel modificado na versão 4.1.13-bootdocker, o que provavelmente significa que esta versão tem otimizações para rodar em um container Docker 🙂

Conclusão

Vimos aqui como é simples fazer o setup e interagir com containeres dentro do Docker. Vimos como é simples criar um container, apagar, criar outro, iniciar e entrar dentro do container criado.

Existem muitas outras coisas que podem ser feitas, obviamente rodar aplicações dentro de containers, mas por hoje, para que não sejamos inundados com informações sem tempo para digerir, vamos ficar por aqui. Voltarei em breve com mais informações sobre como subir um container executando uma aplicação (web site, banco de dados, etc), futuramente como comunicar duas aplicações em containeres distintos e em breve falaremos sobre Docker e Azure, ou Docker e deploy para ambientes de produção.

Se você ainda não está completamente convencido do poder desta tecnologia dê uma olhada neste artigo.

Abraços, e quaisquer dúvidas/críticas/sugestões baixa deixar um comentário 😉

Vinicius Quaiato