Containers Docker e Cerveja !

sábado, 5 de maio de 2018

Containers Docker e Cerveja !


E aí galera, tudo tranquilo ?

Faz um tempo que estou querendo fazer estee artigo, mas o tempo não ajudanem as IPA's.
Eu queria fazer esse artigo mais descontraído, justamente por se tratar de um assunto massivo, extenso e muito gigantesco, Docker !
Hoje a gente vai ver um overview sobre os conceitos do Docker e comandos básicos, que podem, e vão, ajudar muito você que quer melhorar o desempenho e rodar muitas coisas sem comprometer seu S.O. principal.




O que é Docker (superficialmente) ?

Mas afinal, o que é Docker ? Para que eu vou usar ele se eu posso virtualizar tradicionalmente, se eu posso entregar em uns 40 minutos um servidor novo de desenvolvimento para meu pessoal programar ?!
A resposta que a maioria do pessoal sabe é: "Pois Docker é mais rápido."
Sem "puxar sardinha", mas realmente Docker é rápido.
Independentemente de qualquer resposta, é necessário entender o porquê de ser mais rápido, explorar ao máximo essa dita "agilidade" que todos dizem.

Começando do começo, Docker se trata sim de um virtualizador, porém de um modo um pouco diferente da virtualização que estamos acostumados à ver. Ele é baseado em um tipo de virtualização, vindo do kernel Linux, chamado LXC.
Este método de virtualização pode ser construído com "programação" (olha aí um dos conceitos de infra ágil e devops, IaC - Infrastructure as Code), você escreve um script (dockerfile/compose) que ordena o Docker à começar a montar uma "máquina virtual" (container) a partir de uma imagem, como se fosse uma ISO, selecionada existente no repositório local (docker images)  ou no docker hub e executar os comandos configurados dentro deste novo container. Assim, dando "vida" ao container com todos os comandos e S.O. da imagem que você escreveu.

Esta virtualização se baseia em dividir recursos em comum com o S.O. hospedeiro (host) e os containers, como recursos de rede, storage, e serviços em comum, até daemons.

O conceito e necessidade que o Docker atende, basicamente é o de entregar somente a aplicação funcionando para o cliente final (geralmente o desenvolvedor a princípio).
"Mas então, como vou entregar várias aplicações dentro de um servidor, mas rodando-as separadamente e sem instalá-las nativamente no S.O. base ?"
Com Docker !

Em comandos, você escreve um dockerfile, roda um "docker build" para gerar uma imagem a partir deste dockerfile, roda um "docker run" para construir um conatiner a partir da imagem gerada, roda um "docker exec" para "entrar" no terminal do container. E se você quiser confirmar que o container está em execução basta rodar um "docker ps", caso o container não esteja sendo executado rode um "docker start".

O mais interessante de Docker é que ele cria e gerencia camadas de network, storage e containers.

Docker Network

O Docker possui uma camada de abstração de network também, onde ele cria uma pseudo-network para seus containers, similar ao que o VirtualBox ou Vmware Workstation fazem.
O firewall nesta network é totalmente controlado pelo serviço Docker, assim como o roteamento entre a rede dos containers (ex.: 10.55.55.0/24) e a rede do hospedeiro (ex.: 192.168.0.0/22) e até as portas que os containers expõem.
O mais interessante, é que o Docker gerencia as portas dos containers e expõe elas como se fossem do host.

Docker Volumes

Como dito antes, o Docker cria e gerencia a camada de storage, mais conhecida como volumes.
Os volumes, nada mais são que pontos de montagem do S.O. principal para dentro do container Docker como um disco/ponto de montagem.

Agora imagine que você tem 2 máquinas físicas, ambas com Docker e rodando apache tomcat, mas os dados que os serviços irão consumir devem ser um só, pois irão compartilhar da mesma configuração.
Não seria mais simples se os dois containers dividissem o mesmo volume de dados ?! Escrevendo simultaneamente.

Com os volumes no Docker é possível ter os arquivos na máquina host/principal montados em ambos os containers, assim, se os serviços forem corrompidos, os dados não serão perdidos, basta subir um novo container com o volume de dados montado novamente.

**Mais tarde, esta camada será um dos maiores desafios encontrados por quem está desbravando a persistência de dados dentro do Docker/Swarm.**


Dê uma olhada na ilustração das camadas de abstração do Docker:

Um Exemplo Prático


Um exemplo prático do porque utilizar Docker e qual a principal vantagem seria:

Pedrinho tem vontade de ter 3 web servers, 2 rodando Apache Tomcat com PHP 5.6 e 7 enquanto o terceiro com NGINX rodando um letsencrypt certbot para fornecer certificados. Acontece que a exigência da empresa é que estes servidores tenham como S.O. o Ubuntu e que eles demorem menos de 2 minutos para estarem no ar e funcionando caso o servidor "caia".
Observações:
Pedrinho tem somente um único servidor para fazer isto e dentro de 2 meses, terá que reimplementar estes servidores na nuvem.
A máquina física existente não pode ser formatada, ela possui serviços em uso e possui CentOS 7 como S.O.

Me respondam vocês, por qual motivo Pedrinho deveria levar:

  • 3 horas para fazer um backup deste servidor
  • 2 horas formatando-o, transformar esta única máquina em um vmware
  • perder mais 2 horas se preocupando se fez backup de tudo
  • perder 40 minutos criando máquinas virtuais
  • perder 1,5 horas restaurando o backup em uma máquina virtual passando via SCP
  • perder 4 horas estudando sobre como subir o serviço do nginx (já que pedrinho só conhece apache)
  • ?!

Não seria mais simples instalar um Docker Community Edition dentro do CentOS 7 já existente e programar 3 ou até 2 Dockerfiles, gerar 3 imagens (docker build) e quantos containers desejar ?!
É esta agilidade que tanto conversamos e falamos quando tratamos de assuntos como Infra ágil e DevOps.

Uma ilustração de outra situação similar à apresentada:


Galera, expediente do trabalho chegou ao final...
A galera do serviço vai ficando animada, sem dor de cabeça com "E se o serviço cair depois das 18?"
Tudo o que o pessoal pensa é "Se cair, é só realizar um docker run denovo, 10 segundos" e todos vão para o happy hour !

Eu vou tomar a minha IPA sem dor de cabeça. Abraços !

SESSÃO EXTRA

Comandos úteis

docker build

Este comando transforma o seu dockerfile em imagem base para containers executarem.
A sintaxe é basicamente a seguinte:
# Gerando uma imagem Docker
docker build -t [repository/image_name:tag]

Argumentos úteis:
-t - O argumento -t define uma tag para sua imagem, caso queira realizar um docker push e publicá-la em seu repositório no dockerhub este argumento irá ajudá-lo.

Referência:
https://docs.docker.com/engine/reference/commandline/build/#options

docker images

Este comando lista todas as imagens geradas e baixadas pelo Docker e pelos Dockerfiles.
A sintaxe é exatamente como comando acima.

docker rmi

Este comando exclui as imagens geradas pelo Docker.
Caso a imagem esteja sendo utilizada por um container, ela apresentará erro e não será deletada. Ou até mesmo se ela for utilizada em outra imagem gerada.

Sintaxe:
# Excluindo uma imagem docker
docker rmi -f [image_id]

Argumentos úteis:
-f - O argumento -f força a exclusão cíclica de dependência entre imagens somente, não força a exclusão de uma imagem quando um container está sendo utilizado.

docker run

O comando docker run cria um container baseado em uma imagem existente no dockerhub ou no repositório local (registry).

Sintaxe:
# Criando um container a partir de uma imagem docker
docker run -p [porta_host]:[porta_container] -d --restart=always --name [nome_container] -v [/pasta_host]:[/pasta_container] [image_id]

Argumentos úteis:
-d - Este argumento executa o container em background, mantendo-o "ligado" após o comando docker run.
--restart - Este argumento, aliado com a sua preferência, sempre que o container "desligar" executará a ação designada. (always = sempre reinicia o container)
--name - define um nome ao container. O Docker irá gerar um nome random (bem leagis por sinal) para o container.
-p - Expõe as portas definidas do container ao host Docker. (Realiza um NAT nas portas do container ao host) - É possível mapear as portas dentro do Dockerfile, porém, não é considerada uma boa prática.
-v - Monta um volume do host Docker dentro do container. "bind mount". Também é possível definir a montagem dos volumes dentro de um Dockerfile.

Referência:
https://docs.docker.com/engine/reference/run/

docker pull

Este comando é simples e é utilizaddo para realizar o download de uma imagem do dockerhub (default) ou de um registry especificado.

Sintaxe:
# Realizando download de uma imagem docker (Default DockerHub)
docker pull [repositório]/[imagem]:[tag_versão]

docker start

Este comando tem como objetivo iniciar um container que está "desligado".

Sintaxe:
# Iniciando um container já existente
docker start [container_id]

docker stop

Este comando "desliga" o container alvo.

Sintaxe:
# "Desligando" um container já existente
docker stop [container_id]


docker ps

Este comando lista os containers existentes no host em execução. Com argumentos é possível listar os conatiners "desligados".
A sintaxe é exatamente conforme acima.

Argumentos úteis:
-a - O argumento -a lista TODOS os containers existentes no host.

docker rm

O comando docker rm é similar ao comando docker rmi, porém, ele serve para excluir containers.
É necessário que o container esteja "desligado" para a exclusão.

Sintaxe:
# Excluindo um container já existente
docker rm [container_id]

docker exec

Este comando é utilizado para acessar o CLI do container e executar comandos diretamente no S.O. do container.

Sintaxe:
# Conectando em um container ativo
docker exec -ti [container_id] [bash_/bin/bash]

Argumentos úteis:
-t - Este argumento faz com que seja alocado um pseudo-terminal no container.
-i - Este argumento transforma o container interativo, necessário para interagir no bash do container por exemplo.

Referência:
https://docs.docker.com/engine/reference/commandline/exec/


0 comentários :

Postar um comentário