Tópicos
O que é Docker.
Docker é uma tecnologia de software que fornece containeres, promovido pela empresa Docker, Inc. O Docker fornece uma camada adicional de abstração e automação de virtualização de nível de sistema operacional no Windows e no Linux. O Docker usa as características de isolação de recurso do núcleo do Linux como cgroups e espaços de nomes do núcleo, e um sistema de arquivos com recursos de união, como OverlayFS e outros para permitir “containeres” independentes para executar dentro de uma única instância Linux, evitando a sobrecarga de iniciar e manter máquinas virtuais (VMs).
Também pode ser visto como uma alternativa de virtualização em que o kernel da máquina hospedeira é compartilhado com a máquina virtualizada ou o software em operação, portanto um desenvolvedor pode agregar a seu software a possibilidade de levar as bibliotecas e outras dependências do seu programa junto ao software com menos perda de desempenho do que a virtualização do hardware de um servidor completo. Assim, o docker torna operações em uma infraestrutura como serviços web mais intercambiável, eficientes e flexíveis.
Segundo uma análise da 451 Research, o “docker é uma ferramenta que pode empacotar um aplicativo e suas dependências em um recipiente virtual que pode ser executado em qualquer servidor Linux. Isso ajuda a permitir flexibilidade e portabilidade de onde o aplicativo pode ser executado, quer nas instalações, nuvem pública, nuvem privada, entre outros.
Logo, aquela história de que a aplicação só funciona no computador do desenvolvedor acaba pois a aplicação inteira pode ser colocada dentro de um container e esse container pode ser utilizado em qualquer servidor docker.
Principais componentes do Docker
Elementos principais do Docker
Como Instalar.
Script automatizado
$ curl -fsSL get.docker.com -o get-docker.sh
$ sh get-docker.sh
Repositório Docker.
Isso é bem interessante, existe um repositório chamado de docker hub, você pode visitar clicando aqui. Esse repositório serve basicamente como repositório de imagens. Você pode pesquisar por imagens e então baixar elas e inicar a imagem instantânea da distribuição/serviço.
[docker@srv-docker docker]$ docker search debian
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/ubuntu Ubuntu is a Debian-based Linux operating s... 7701 [OK]
docker.io docker.io/debian Debian is a Linux distribution that's comp... 2577 [OK]
docker.io docker.io/google/debian 52 [OK]
docker.io docker.io/neurodebian NeuroDebian provides neuroscience research... 50 [OK]
docker.io docker.io/arm32v7/debian Debian is a Linux distribution that's comp... 35
docker.io docker.io/armhf/debian Debian is a Linux distribution that's comp... 31
docker.io docker.io/itscaro/debian-ssh debian:jessie 23 [OK]
docker.io docker.io/resin/armv7hf-debian Debian is a Linux distro composed entirely... 18
docker.io docker.io/samueldebruyn/debian-git a minimal docker container with debian and... 17 [OK]
docker.io docker.io/arm64v8/debian Debian is a Linux distribution that's comp... 10
docker.io docker.io/eboraas/debian Debian base images, for all currently-avai... 8 [OK]
docker.io docker.io/i386/debian Debian is a Linux distribution that's comp... 7
docker.io docker.io/rockyluke/debian Docker images of Debian. 5
docker.io docker.io/vergissberlin/debian-development Docker debian image to use for development... 5 [OK]
docker.io docker.io/smartentry/debian debian with smartentry 4 [OK]
docker.io docker.io/vicamo/debian Debian docker images for all versions/arch... 3
docker.io docker.io/ppc64le/debian Debian is a Linux distribution that's comp... 2
docker.io docker.io/s390x/debian Debian is a Linux distribution that's comp... 2
docker.io docker.io/dockershelf/debian Repository for docker images of Debian. Te... 1 [OK]
docker.io docker.io/holgerimbery/debian debian multiarch docker base image 1
docker.io docker.io/vpgrp/debian Docker images of Debian. 1
docker.io docker.io/casept/debian-amd64 A debian image built from scratch. Mostly ... 0
docker.io docker.io/igneoussystems/base-debian-client Base image for debian clients 0
docker.io docker.io/jdub/debian-sources-resource Concourse CI resource to check for updated... 0 [OK]
docker.io docker.io/trollin/debian 0
A preferência dos resultados sempre vão ser os oficiais da distribuição/serviço, você pode adicionar uma tag ao final para procurar por uma versão especifica:
[docker@srv-docker docker]# docker search debian:jessie
Ou até mesmo a ultima liberada pelo mantenedor da imagem:
[docker@srv-docker docker]# docker search debian:latest
Imagens Docker
As imagens docker constituem a base para os containeres docker de onde tudo começa a se formar. Elas são muito similares às imagens de disco padrão de sistema operacional que são utilizadas para executar aplicações em servidores e computadores de mesa.
Tendo essas imagens (por exemplo uma base Ubuntu) permite-se a portabilidade perfeita entre sistemas.
Eles constituem uma base sólida, consistente e confiável com tudo o que é necessário para executar as aplicações. Quando tudo é auto suficiente e o risco de atualizações ou modificações em nível de sistema é eliminado, o container torna-se imune a riscos externos que poderiam colocá-lo fora de ordem - evitando o "inferno de dependências".
Quanto mais camadas (ferramentas, aplicações, etc) são adicionadas em cima da base, novas imagens podem ser formadas aplicando-se estas alterações. Quando um novo container é criado a partir de uma imagem salva (ou seja, com as alterações aplicadas), as coisas continuam de onde pararam. E o sistema de arquivos union, traz todas as camadas juntas como uma entidade única quando você trabalha com um container.
Essas imagens de base podem ser explicitamente declaradas quando se trabalha com o docker CLI para criar diretamente um novo container ou, elas podem ser especificadas dentro de um Dockerfile para construção de imagem automatizada.
Para iniciar com o docker, você pode pesquisar as imagens locais:
[docker@srv-docker docker]# docker images
Então vamos realizar o download de uma imagem,
[docker@srv-docker docker]# docker pull debian:latest
Se buscar novamente as imagens locais, irá encontrar a debian lá!
Para remover imagens, você pode fazer da seguinte forma:
[docker@srv-docker docker]# docker rmi debian
Ela só será removida se não tiver nenhum container dependente dela, irei passar esse tipo de detalhe mais a frente.
Iniciando containers.
Agora que temos nossa imagem, você pode iniciar um container da seguinte forma:
~ docker run debian
Observe que ele irá iniciar e morrer, para evitar que isso ocorra, você pode executar no modo interativo passando um comando, no caso, o bash:
~ docker run --name containerName -it debian /bin/bash
Os containers recebem nomes aleatórios, não definir nomes para o container é ruim pois você vai ter problemas para identificar quem é quem, uma forma de dar nomes à container na hora de inicializar é a seguinte:
~ docker run --name containerName -it debian /bin/bash
Para sair do container, é só dar exit:
root@51f7cb0a8162:/# exit
O container vai constar na lista de containers disponíveis, você pode consultar todos os containers com o comando abaixo:
[docker@srv-docker docker]$ docker ps -a
container ID IMAGE COMMAND CREATED STATUS PORTS NAMES
66b810fdfeae debian "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago admiring_golick
Observe o status do container, está como "Exited", ele pode ser reiniciado pelo nome ou ID simplesmente dando start utilizando o name ou id.
[docker@srv-docker docker]$ docker start -i 66b810fdfeae
Para evitar que o container fique ali no limbo, você pode remover o container assim que sair dele da seguinte forma:
~ docker run --rm --name containerName -it debian /bin/bash
Assim, quando sair do container, ele é removido automaticamente.
Para remover containers, use:
~ docker rm containerNameOrID
Administração de containers/imagens.
Vamos supor que você esteja num container e quer verificar algo no servidor docker, fora do container, você pode utilizar as teclas:
ctrl^P+Q
Uma vez fora do container, você pode parar o container da seguinte forma:
docker stop containerNameOrID
Ou simplesmente matar ele!
docker kill containerNameOrID
Mas, agora, você não quis matar ninguém e já verificou o que queria fora do container, você pode voltar pro container simplesmente digitando:
docker attach containerNameOrID
Para verificar containers que estão em execução, simplesmente utilize o comando ps:
[root@srv-docker docker]# docker ps
container ID IMAGE COMMAND CREATED STATUS PORTS NAMES
66b810fdfeae debian "/bin/bash" 13 minutes ago Up 6 minutes admiring_golick
2cb5618495a6 debian:stretch "/bin/bash" 23 hours ago Up 23 hours 0.0.0.0:4000->80/tcp jekyls
Com base nesses containers que estão em execução, você pode parar eles e depois iniciar. Para iniciar é só utilizar start:
docker start containerNameOrID
Caso queira iniciar o container e já entrar nele, pode utilizar -i:
docker start -i containerNameOrID
Para visualizar containers que não estão em execução porém estão presentes:
docker@N0tEvil:/$ docker ps -a
container ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d4daff4d1c54 ubuntu "/bin/bash" 4 minutes ago Exited (0) 16 minutes ago big_cray
Para remover esses caras, bom, você já aprendeu a usar o rm muitas linhas pra cima.
Até aqui, sabemos que containers são volateis, se você deletar ou ele morrer, já era seu trampo. Existe uma forma de você salvar o seu container, como se fosse tirar um snapshot dele e gerar uma nova imagem em cima da atual, na real não é como, é isso que acontece.
Para persistir mudanças no container:
$ docker commit containerNameOrID svendowideit/testimage:version3
Uma observação é, acima você definiu o repositório como svendowideit, o nome da imagem é testimage e por ultimo é a tag version3. Você pode mandar esse container pro docker hub também, assim você poderá baixar de outros lugares assim como outras pessoas poderão, lembrando que o repositório é público. Se você quiser um privado, você precisa contratar algum serviço privado de repositório docker, porém esse lance não será abordado aqui.
Vai gerar um sha256 -> Hash da camada que foi adicionada em cima, o docker nunca altera a imagem base.
Você poderá então iniciar sua própria imagem gerada anteriormente simplesmente usando docker run, passando os devidos argumentos pro comando, claro.
Para Visualizar alterações entre imagens, você pode executar:
~ docker diff
~ docker diff e46faf784171
Semelhança com git? Talvez. Ele vai mostrar todas as diferenças de dentro do container.
Para executar comandos em um container, você utiliza o exec, pode ser utilizado como substituto do ssh ou do comando que está em operação no container na hora que ele foi construido. Ou seja, supondo que você inicou um container e para que ele não encerre, você deixou ele executando um loop besta, se você der append no container e der ctrl^C para sair do loop, o container para.
~ docker exec -it 3c97a996235f /bin/bash
Então você pode utilizar o docker exec para entrar no container sem parar o processo principal, evitando que o container finalize depois que você saia.
ID=$(docker run -d debian sh -c "while true;do sleep 1; done;"
docker exec $ID /bin/bash
docker exec
Scripting.
Removendo todos os containers interrompidos:
[centos@srv-docker ~]$ docker rm -v $(docker ps -aq -f status=exited)
Parando mais de um container ao mesmo tempo:
~ docker stop $(docker ps -q)
Json
Bom, os containers operam com um json bolado, você pode acessar eles e codar sua própria API se quiser, eu nunca precisei então não irei te mostrar como criar uma API, só irei te mostrar como puxar dados do container.
Verificar mais a fundo o container:
[root@srv-docker docker]# docker inspect admiring_golick
[
{
"Id": "66b810fdfeae735ea2243cb58d06875dc3d59bf4a6c3b26773fbece2f87a4319",
"Created": "2018-05-20T02:39:12.602015871Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 3337,
"ExitCode": 0,
"Error": "",
"StartedAt": "2018-05-20T02:45:46.191810949Z",
"FinishedAt": "2018-05-20T02:39:17.383606751Z"
--- saida omitida ---
Buscando informações mais especificas:
[root@srv-docker docker]# docker inspect admiring_golick | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",
GO, sim a linguagem que eu não faço nem ideia ainda de como funciona
Então, estamos aqui. Você pode utilizar templates em GO para tratar os Json, segue um exemplo:
[docker@srv-docker docker]$ docker inspect --format {{.NetworkSettings.IPAddress}} admiring_golick
172.17.0.3
Monitoramento de containers ( docker stats ).
Eu tive uma briga feia com algumas soluções de monitoramento, acabou que engavetei minha pesquisa e entendi que poderia monitorar apenas com as ferramentas built-in do docker, para monitorar os containers em execução, você pode utilizar:
[docker@srv-docker docker]$ docker stats
container CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
66b810fdfeae 0.00% 480 KiB / 1.796 GiB 0.03% 648 B / 648 B 3.85 MB / 0 B 1
2cb5618495a6 0.00% 692 KiB / 1.796 GiB 0.04% 227 MB / 79.7 MB 148 MB / 1.59 GB 1
Uma forma de ter um output mais userfriend seria empregar os templates GO, segue um exemplo:
$ docker stats $(docker inspect -f {{.Name}} $(docker ps -q))
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
/web3_commandexec 0.01% 6.852 MiB / 1.796 GiB 0.37% 3.3 kB / 648 B 24.3 MB / 12.3 kB 8
/web4_notup2date 0.07% 117.7 MiB / 1.796 GiB 6.40% 2.2 kB / 648 B 82.8 MB / 549 kB 37
/web1_threeparts 0.01% 6.848 MiB / 1.796 GiB 0.37% 3.63 kB / 648 B 24.3 MB / 12.3 kB 8
/web2_passatempo 0.01% 6.848 MiB / 1.796 GiB 0.37% 1.14 kB / 648 B 24.3 MB / 12.3 kB 8
/net2_telnet 0.00% 664 KiB / 1.796 GiB 0.04% 2.45 kB / 648 B 6.89 MB / 12.3 kB 3
A diferença é que ele colocou o nome do caontainer ao invés da ID, fica mais fácil de identificar quem é quem agora!
Dockerfile.
Dockerfiles são scripts contendo uma série sucessiva de instruções, orientações e comandos que devem ser executados para formar uma nova imagem docker. Cada comando executado traduz-se para uma nova camada da cebola, formando o produto final. Elas basicamente substituem o processo de se fazer tudo manualmente e repetidamente. Quando um Dockerfile conclui a execução, você acaba tendo formado uma imagem, que então, você utiliza para iniciar ( ou seja, criar) um novo container.
To cansado de escrever, vou só dar um exemplo de docker file:
Crie um arquivo chamado Dockerfile
FROM debian:stretch
MAINTAINER R3bel
RUN apt-get update && apt-get install telnetd -y && useradd -m -s /bin/bash ENG_Florentino && echo 'batatã' > ~ENG_Florentino/loveme && echo 'ENG_Florentino:diediedie' | chpasswd
Então dê:
docker build -t localrepo/imagename .
Ele aceita várias outras instruções, muitas outras mesmo. Tem que lembrar que cada instrução, dependendo de qual, tipo o COPY vai adicionar uma outra camada à imagem. Outras instuções como CMD só poderá ser executada uma vez. Tem muitas outras instruções mesmo, porém eu n to afim de falar sobre isso agora, se você está lendo isso agora, quer dizer que ainda não tive saco pra melhorar esse doc.
Docker Networking
Abrindo portas externas no host para dentro do container:
~ docker run -it -d -p 8080:80
O comando acima vai redirecionar da porta 8080 do host para dentro do container na porta 80.
Um outro exemplo, que eu tive que utilizar recentemente, eu defini várias interfaces virtuais no meu servidor Docker e queria colocar um contatiner em um IP, para definir isso, você pode fazer da seguinte forma:
docker run -d -p 10.2.3.116:21:21 net02 /etc/init.d/vsftpd start
O comando acima vai iniciar o container net02 como daemon(background) e vai passar o comando de start do serviço vsftpd, redirecionando tudo do endereço ip 10.2.3.116 na porta 21 para o container na porta 21.
Se você for um bom observador, vai ter entendido que o comando acima está cagado pois o FTP não usa só uma porta, ele utiliza duas, para resolver isso, você pode fazer o seguinte:
docker run -d -p 10.2.3.116:20:20 -p 10.2.3.116:21:21 net02 /etc/init.d/vsftpd start
Eu já ia esquecendo de citar, se você usar o -P ao invés do -p, o Docker vai usar uma porta randomica, isso parece nonsense, mas é bem interessante para adotar em plataformas de CTF por exemplo, onde se cria um container para cada equipe.
Agora, para linkar containers entre si?
Os links do Docker são a maneira mais fácil de permitir que containers existentes no mesmo host conversem uns com os outros. Quando o modelo-padrão de rede do Docker é usado, a comunicação entre containeres ocorre por meio de uma rede interna da plataforma Docker, o que significa que as comunicações não são expostas para a rede do host.
O Docker define variáveis de ambiente dentro do container-mestre para facilitar a comunicação com o container conectado. Mas isso ai você descobre por conta, é só dar o comando env dentro do container.
Bom, então como que rola o bag, primeiro você cria o container que será conectado, depois o master, conectando no conectado?
Subindo container que será coenctado:
docker run -d --name badass debian:latest
Subindo container mestre e conectando:
docker run -d --link badass:bad debian:latest
Quando o cabo pluga, o Docker já cria regras no netfilter aka iptables para permitir a comunicação entre os dois. Ele também adiciona no /etc/hosts o container e tal, assim você acessa pelo Hostname, que na verdade é só um alias pro IP.
A estrutura do comando é a seguinte:
--link :alias
Então, eu falei ali do /etc/hosts, no caso, será criado um alias do container badass e dentro do /etc/hosts será adicionado o alias para o container badass com o nome de bad
Compartilhando diretórios
Aqui o naipe é o seguinte, você pode compartilhar diretórios do host com um ou mais containers ou entre containers.
Compartilhando diretórios do host com containers
Aqui você usa a flag -v
docker run -v /home/fulano/app:/data debian
Outro exemplo:
~ docker run -it -d -p 8080:80 -v /que/queeuquero/:/pra/ond
Compartilhando diretórios entre containers
Aqui você usa --volumes-from, essa fica de dever de casa!
Fontes/Recursos
http://www.diego-garcia.info/2015/02/15/docker-por-onde-comecar/
https://get.docker.com/
https://docs.docker.com/engine/reference/commandline/commit/#examples
https://docs.docker.com/network/links/#communication-across-links

One thought on “Docker – Básico”