Microserviços, Containers e o Docker
Estar envolto com uma arquitetura de microserviços criando pequenos serviços com uma necessidade de mecanismos leves, publicação independente, escalabilidade e portabilidade, hoje se torna mais que primordial em grandes projetos de médias e grandes empresas.
Containers são ambientes de execução leves com a maioria dos componentes do núcleo de uma máquina virtual e serviços isolados de um sistema operacional, concebido para fazer o empacotamento fácil e a execução de serviços leves.
Entre as vantagens de se usar o Docker com seu sistema de containers podemos pontuar
Com um container portável entre diferentes plataformas, a portabilidade de uma aplicação pode ser alcançada colocando a aplicação e todas suas dependências dentro do container;
Containers incluem apenas a aplicação e suas dependências que, juntamente com a natureza leve dos containers torna-os mais eficientes na utilização dos recursos;
Os containers podem fornecer ambientes ao usuário com as necessidades de recursos estritamente controladas sem o uso de virtualização;
A tecnologia que faz uso de containers é uma nova tecnologia emergente tendo o Docker como líder e muitas grandes empresas assinaram acordos de parceria com Docker, incluindo empresas gigantescas tanto no ramo de TI, como em variados ramos
A documentação sobre containers já é imensa, e não pretendo me aprofundar aqui na base teórica, portanto nesse artigo focaremos como dar os primeiros passos na criação, aplicação e gerenciamento de containers docker
( Outputs dos comandos também serão mostrados em algumas ocasiões para exemplificar o que está sendo feito, lembrando que todos os comandos devem ser executados com superusuário )
1. Instalar o docker
root@ubuntu:~# curl -fsSL https://get.docker.com/ | sh
# Executing docker install script, commit: 26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c
+ sh -c apt-get update -qq >/dev/null
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null
+ sh -c curl -fsSL "https://download.docker.com/linux/ubuntu/gpg" | apt-key add -qq - >/dev/null
Warning: apt-key output should not be parsed (stdout is not a terminal)
+ sh -c echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable" > /etc/apt/sources.list.d/docker.list
+ sh -c apt-get update -qq >/dev/null
+ [ -n ]
+ sh -c apt-get install -y -qq --no-install-recommends docker-ce >/dev/null
+ sh -c docker version
2. Iniciar o docker
/etc/init.d/docker start ( Ubuntu/Debian )
systemctl start docker ( Centos/Fedora )
3. Verificar a versão do docker
root@ubuntu:/# docker --version
Docker version 19.03.13, build 4484c46d9d
4. Criar um container simples
docker run -ti debian /bin/bash
( Você já cai diretamente dentro do container depois de criado )
[root@localhost keys]# docker run -ti debian /bin/bash
root@e640e827e407:/#
Sair do container matando a sessão do mesmo
ctrl + d
Sair do container deixando ativo a sessão do mesmo
crtl + p + q
5. Verificar containers criados com docker ps
[root@rfnc init.d]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f5cc741db4c5 ubuntu:14.10 "/bin/bash" 13 minutes ago Up 13 minutes happy_meninsky
Voltar para o container se você saiu do mesmo com crtl + p + q, use sempre o CONTAINER ID
docker attach e640e827e40
[root@localhost keys]# docker attach e640e827e407
root@e640e827e407:/#
Agora não se esqueça, se você saiu do container com ctrl + d, somente um attach não irá funcionar, como você pode ver abaixo
root@ubuntu:/# docker attach 7eb3b08dc896
You cannot attach to a stopped container, start it first
Portanto, inicie o container primeiro, use sempre o CONTAINER ID
root@ubuntu:/# docker start 7eb3b08dc896
7eb3b08dc896
Agora attache o container, use sempre o CONTAINER ID
root@ubuntu:/# docker attach 7eb3b08dc896
root@7eb3b08dc896:/#
6. Ver mudanças que foram feitas no container com o comando diff, use sempre o CONTAINER ID
docker diff e640e827e407
[root@localhost keys]# docker diff e640e827e407
C /root
A /root/.bash_history
C /var
C /var/lib
C /var/lib/apt
C /var/lib/apt/lists
A /var/lib/apt/lists/auxfiles
A /var/lib/apt/lists/lock
A /var/lib/apt/lists/partial
7. Depois que você fez mudanças no seu container, seria interessante e de seu agrado comitar a imagem do container para que essas mudanças de tornem duradouras no seu container, para isso use o comando commit ( o nome ao qual voc~e deve dar ao seu container comitado, sempre deve ser em letras minusculas , como você ve no exemplo abaixo, use sempre o CONTAINER ID
[root@localhost keys]# docker commit ad09676a3247 debian
sha256:e84c1542c6de918daec2f06e42bb304f8afcd2ccbfd062aaab0b92114c9bb4b5
Ver images comitadas com o comando docker images
[root@localhost keys]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
debian latest e84c1542c6de 22 seconds ago 114MB
<none> <none> 404e6c9c2e16 11 hours ago 201MB
<none> <none> 43a9f9930dad 12 hours ago 72.9MB
rafael latest 29ae1c5589d1 13 hours ago 137MB
fedora latest b9ef4f2d3b60 5 days ago 201MB
8. Você pode por algum motivo querer parar um container, para isso use o comando abaixo, use sempre o CONTAINER ID
docker stop ad09676a3247
[root@localhost keys]# docker stop ad09676a3247
ad09676a3247
E como você viu anteriormente para iniciar um container, use o seguinte comando, use sempre o CONTAINER ID
docker start ad09676a3247
[root@localhost keys]# docker start ad09676a3247
ad09676a3247
9. Você pode por algum motivo querer executar comandos fora do container, para isso use o comando, use sempre o CONTAINER ID
docker exec ad09676a3247 df -k
[root@localhost keys]# docker exec ad09676a3247 df -k
Filesystem 1K-blocks Used Available Use% Mounted on
overlay 39483560 4491004 34992556 12% /
tmpfs 65536 0 65536 0% /dev
shm 65536 0 65536 0% /dev/shm
/dev/sda5 39483560 4491004 34992556 12% /etc/hosts
tmpfs 999016 0 999016 0% /proc/asound
tmpfs 999016 0 999016 0% /proc/acpi
tmpfs 999016 0 999016 0% /proc/scsi
tmpfs 999016 0 999016 0% /sys/firmware
10. Você pode por algum motivo querer ver informações detalhadas do container, use o comando a seguir, use sempre o CONTAINER ID
docker inspect ad09676a3247
[root@localhost keys]# docker inspect ad09676a3247
[
{
"Id": "ad09676a32474050413f92d6ca1744a820365197bec73d7d405b205e7d9ac60a",
"Created": "2020-10-08T12:10:48.778724562Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Status": "running",
"Running": true,
Você pode por algum motivo querer ver informações estatisticas do container com o comando abaixo, use sempre o CONTAINER ID
docker stats ad09676a3247
[root@localhost keys]# docker stats ad09676a3247
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
ad09676a3247 clever_lehmann 0.00% 0B / 0B 0.00% 1.09kB / 0B 0B / 0B 0
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
ad09676a3247 clever_lehmann 0.00% 0B / 0B 0.00% 1.09kB / 0B 0B / 0B 0
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
Você pode por algum motivo querer ver os processos que estão rodando no container com o comando abaixo, use sempre o CONTAINER ID
root@ubuntu:/# docker top 7eb3b08dc896
UID PID PPID C STIME TTY TIME CMD
root 3816 3796 0 17:50 pts/0 00:00:00 bash
11. Você pode por algum motivo querer remover um container que está ativo usando o CONTAINER ID ( cheque usando o docker ps )
docker rm -f 384ca89d0c63
Remover container que está ativo usando o IMAGE ID ( cheque usando o docker images )
docker rmi -f 29ae1c5589d1
12.Verificar a memória do container com o comando inspect, use sempre o CONTAINER ID
docker inspect a58a569b4a58 | grep -i mem
"Memory": 0,
"CpusetMems": "",
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
Criar container com 512 Megas de memória limitada, depois cheque com o inspect, use sempre o CONTAINER ID
docker run -ti -m 512M debian /bin/bash
[root@localhost ~]# docker inspect 62fbfca22bd1 | grep -i mem
"Memory": 536870912,
"CpusetMems": "",
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": -1,
"MemorySwappiness": null,
Criar container com capacidade de CPU limitada
docker run -ti --cpu-shares 1024 debian /bin/bash ( Pode usar até 50% da CPU do seu host )
docker run -ti --cpu-shares 512 debian /bin/bash ( Pode usar até 25% da CPU do seu host )
Verificar CPU alocada no container, use sempre o CONTAINER ID
docker inspect 6dcaa7b69f3a | grep -i cpu
[root@localhost ~]# docker inspect 6dcaa7b69f3a | grep -i cpu
"CpuShares": 1024,
"NanoCpus": 0,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"CpuCount": 0,
"CpuPercent": 0,
Criar container com capacidade de swap limitada, depois cheque com o inspect, use sempre o CONTAINER ID
[root@localhost ~]# docker run -ti --memory=20m --memory-swap=20m debian /bin/bash
root@ubuntu:~# docker inspect 4fd2c24a2fc5 | grep -i swap
"MemorySwap": 20971520,
"MemorySwappiness": null,
Aumentar ou diminuir recursos no container se assim você o desejar, veja o output abaixo com a memória total alocada
root@b3dfbf40f3b0:/# [root@localhost ~]# docker inspect b3dfbf40f3b0 | grep -i mem
"Memory": 268435456,
"CpusetMems": "",
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": -1,
"MemorySwappiness": null,
Agora mude a alocação de memória com o comando update, depois cheque com novo valor com o comando inspect
[root@localhost ~]# docker update -m 512m b3dfbf40f3b0 ( use sempre o CONTAINER ID )
b3dfbf40f3b0
[root@localhost ~]# docker inspect b3dfbf40f3b0 | grep -i mem
"Memory": 536870912,
"CpusetMems": "",
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": -1,
"MemorySwappiness": null,
13. Fazer o update pra mais nova versão do docker ( No caso abaixo como o docker já estava na última versão, nenhum update foi feito
[root@localhost ~]# curl -fsSL https://get.docker.com/ | sh
# Executing docker install script, commit: 26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c
Warning: the "docker" command appears to already exist on this system.
If you already have Docker installed, this script can cause trouble, which is
why we're displaying this warning and provide the opportunity to cancel the
installation.
If you installed the current Docker package using this script and are using it
again to update Docker, you can safely ignore this message.
You may press Ctrl+C now to abort this script.
+ sleep 20
+ sh -c 'dnf install -y -q dnf-plugins-core'
Criando imagens simples de container com Dockerfiles
14. Criar imagens simples de container com Dockerfiles
Crie o diretório abaixo
mkdir -p Dockerfile/apache
Crie o arquivo chamado Dockerfile e inclua essas informações nele
FROM ubuntu:14.04
MAINTAINER rfnc.com.br
RUN apt-get update && apt-get install -y apache2 && apt-get clean
Faça o build da imagem com o seguinte comando
docker build -t rfnc/apache:1.0 .
Cheque se a imagem foi criada
root@ubuntu:~/apache# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
rfnc/apache 1.0 146941fa2166 14 minutes ago 221MB
ubuntu 14.04 df043b4f0cf1 3 weeks ago 197MB
debian latest f6dcff9b59af 4 weeks ago 114MB
ubuntu 19.10 2f6c85efea61 3 months ago 72.9MB
ubuntu 14.10 a8a2ba3ce1a3 5 years ago 194MB
Inicie o container
docker run -it rfnc/apache:1.0 /bin/bash
Inicie o apache
root@f0ab9fc4ac1f:/# /etc/init.d/apache2 start
* Starting web server apache2
Cheque se o apache está iniciado
root@f0ab9fc4ac1f:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 15:55 pts/0 00:00:00 /bin/bash
root 45 1 0 15:56 ? 00:00:00 /usr/sbin/apache2 -k start
www-data 48 45 0 15:56 ? 00:00:00 /usr/sbin/apache2 -k start
www-data 49 45 0 15:56 ? 00:00:00 /usr/sbin/apache2 -k start
root 107 1 0 15:56 pts/0 00:00:00 ps -ef
Verifique se a porta 80 está disponivel com netstat
root@f0ab9fc4ac1f:/# netstat -atunp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 45/apache2
Verifique se o IP fecha conexão com a porta 80
root@ubuntu:~# telnet 172.17.0.3 80
Trying 172.17.0.3...
Connected to 172.17.0.3.
Escape character is '^]'.
Verifique o IP do container
root@f0ab9fc4ac1f:/# ifconfig -a
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:03
inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:29 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3335 (3.3 KB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Saia do container e use o o curl no shell para verificar se a página está disponível
root@ubuntu:~# curl 172.17.0.3
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or g/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
Modified from the Debian original for Ubuntu
Last updated: 2014-03-19
See: https://launchpad.net/bugs/1288690
15. Criar volumes no container, use o comando abaixo
root@ubuntu:~# docker run -ti -v /volume ubuntu /bin/bash
Verifique se o volume foi criado no container
root@fcc2aafacde2:/# df -k
Filesystem 1K-blocks Used Available Use% Mounted on
overlay 30313412 8811472 19939060 31% /
tmpfs 65536 0 65536 0% /dev
tmpfs 1003460 0 1003460 0% /sys/fs/cgroup
shm 65536 0 65536 0% /dev/shm
/dev/sda5 30313412 8811472 19939060 31% /volume
tmpfs 1003460 0 1003460 0% /proc/asound
tmpfs 1003460 0 1003460 0% /proc/acpi
tmpfs 1003460 0 1003460 0% /proc/scsi
tmpfs 1003460 0 1003460 0% /sys/firmware
Verificar no host onde o volume do container está alocado
docker inspect -f {{.Mounts}} fcc2aafacde2
root@ubuntu:~# docker inspect -f {{.Mounts}} fcc2aafacde2
[{volume 7ca63f0148523c27c9a6f32bc14a33096afe8e3c6bf918e4e0610170775ab039 /var/lib/docker/volumes/7ca63f0148523c27c9a6f32bc14a33096afe8e3c6bf918e4e0610170775ab039/_data /volume local true }]
Criar um ponto de montagem no host e mapea lo para o container, para isso crie um diretório no host
root@ubuntu:~# mkdir /root/primeiro_dockerfile
Mapeie o diretório na criação do container e de o nome do ponto de montagem de sua prefêrencia no container
root@ubuntu:~# docker run -ti -v /root/primeiro_dockerfile:/volume debian
Verifique se o ponto de montagem foi mapeado no container
root@7eb3b08dc896:/# df -k
Filesystem 1K-blocks Used Available Use% Mounted on
overlay 30313412 8811628 19938904 31% /
tmpfs 65536 0 65536 0% /dev
tmpfs 1003460 0 1003460 0% /sys/fs/cgroup
shm 65536 0 65536 0% /dev/shm
/dev/sda5 30313412 8811628 19938904 31% /volume
tmpfs 1003460 0 1003460 0% /proc/asound
tmpfs 1003460 0 1003460 0% /proc/acpi
tmpfs 1003460 0 1003460 0% /proc/scsi
tmpfs 1003460 0 1003460 0% /sys/firmware
Para se certifcar que o mapeamento está funcionando, volte no host e crie um arquivo qualquer no diretório ao qual foi mapeado
root@ubuntu:~# cd /root/primeiro_dockerfile
root@ubuntu:~/primeiro_dockerfile# touch Arquivo
root@ubuntu:~/primeiro_dockerfile# ls -la
total 8
drwxr-xr-x 2 root root 4096 Oct 8 17:14 .
drwx------ 7 root root 4096 Oct 8 17:06 ..
-rw-r--r-- 1 root root 0 Oct 8 17:14 Arquivo
Se certifique no container que o arquivo criado est´disponível no ponto de montagem ao qual você criou e mapeou
root@ubuntu:~/primeiro_dockerfile# docker attach 7eb3b08dc896
root@7eb3b08dc896:/volume# ls -la
total 8
drwxr-xr-x 2 root root 4096 Oct 9 00:14 .
drwxr-xr-x 1 root root 4096 Oct 9 00:07 ..
-rw-r--r-- 1 root root 0 Oct 9 00:14 Arquivo
Verifique pelo inspect se o mapeamento está mesmo correto
root@ubuntu:~/primeiro_dockerfile# docker inspect -f {{.Mounts}} 7eb3b08dc896
[{bind /root/primeiro_dockerfile /volume true rprivate}]