- Introdução 
- Arquitetura do Docker 
- Instalação do Docker 
- Imagem 
- Container 
- Port Bind 
- Networks 
- Volumes 
- Docker Registry 
- Docker compose 
- Boas práticas 
- Desinstalar o Docker 
1. Introdução
1.1. Stacks para fazer deploy da aplicação
Stack tradicional com vm
hardware → hypervisor → virtual machine → operating system → application
- Na criação de um hardware virtual o kernel é isolado e cada vm tem o seu próprio kernel.
Desvantagem:
- Desperdício de hardware 
- Difícil gerenciamento de libs — Várias aplicações usando a mesma lib pode gerar problema. Atualizações de lib feita pelo próprio OS podem quebrar a aplicação 
- Não é imutável 
Stack com container
hardware → operating system → container engine (docker) → container 1 / container 2 / containter 3
- Docker foi feito para ser usado no linux porque usa primitivas do kernel linux para construir um container (chroot, cgroups) 
- O Docker é instalado como um pacote do linux 
- O container utiliza o mesmo kernel do OS (docker host) e isola as aplicações usando o conceito de namespaces. 
- Os containers são pedaços lógicos isolados compartilhando o mesmo kernel. 
Vantagens:
- Otimização de recursos hardware 
- Empacotamento da aplicação — Acaba com o problema de “funciona na minha máquina mas não funciona na sua” 
- Imutabilidade — Por conta do empacotamento a mesma aplicação pode rodar na minha máquina, no servidor, em cloud e onde mais quiser porque a aplicação não muda, é um objeto. 
- Facilidade no deploy 
1.2. Containers
- Abstração a nível de sistema operacional 
- Agrupa códigos, bibliotecas e dependências para garantir a execução de um aplicativo em um ambiente isolado 
- Parece com as máquinas virtuais mas as máquinas virtuais são uma abstração a nível de hardware com a simulação de servidores dentro de um servidor com um sistema operacional completo. 
- Containers (MB) são mais leves que VMs (GB). 
- Os containers não precisam de um SO completo. 
- Os containers compartilham o mesmo kernel do SO onde estão sendo executados. São como um processo do SO. 
Vantagens do uso:
- Ambiente isolado 
- Idempotência 
- Distribuição facilitada 
Desvantagens:
- Escalabilidade 
- Resiliência 
Ferramentas container:
- Docker 
- Podman 
- ContainerD 
1.3. Docker
- Tecnologia e plataforma open source 
- Para VMs temos o Virtualbox e para containers temos o Docker 
- Otimização muito mais eficiente dos recursos 
- Inicialização muito mais rápida que as VMs 
- Importante para trabalhar numa arquitetura de sistemas distribuídos com microsserviços. 
- Microsserviços são serviços independentes que se comunicam entre si. Uma vantagem de utilizar o microsserviços é utilizar a multilinguagens (um java e outro em node). 
- Usando o Docker para microsserviços a gente garante um ambiente isolado com as dependências específicas para aquele serviço para serem executados em qualquer ambiente ou em qualquer servidor. 
- Facilidade de escalar os containers, os serviços de acordo com a demanda. Facilidade de expandir a aplicação. 
- Orquestração de containers: Docker Swarm e Kubernetes 
1.4. Virtualização X Containerização
Container = combinação de tecnologias do kernell do linux (cgroups + namespaces + overlayfilesystem)
2. Arquitetura do Docker
2.1. Elementos da arquitetura
Docker Daemon — responsável por executar os containers e gerenciar todos os objetos do docker
Docker Client — ferramenta de interação com Docker Daemon
Docker Registry — repositório de imagens docker. dockerhub, azure container registry, elastic container registry
Client
- O client é a linha de comando 
- $ docker ps $ docker pull $ docker run 
- O client se comunica diretamente com o docker daemon do docker host. É possível configurar a linha de comando da minha máquina para se comunicar com outro docker host como o docker host que está na aws, azure, na empresa via vpn, etc. 
Docker Host
- No docker host existe um processo chamado docker daemon que faz a lógica de gerenciar as imagens. 
- Quando baixamos uma imagem o docker daemon coloca em /var/livre/docker 
Registry
- Como uma store das imagens docker 
- Servidor remoto que tem imagens para o docker daemon baixar. 
- Empresas possuem registry privado como o Nexus, Jay Frog ou um provedor de cloud. 
3. Instalação do Docker
Aqui apresento duas possibilidades para instação do Docker.
Opção 1- Seguir a documentação para instalação no Ubuntu https://docs.docker.com/engine/install/ubuntu/
Erro de falta de permissão
Para corrigir
Depois que o Docker é instalado ele cria um grupo. É necessário adicionar o usuário ao grupo Docker.
Para acessar todos os grupos do linux cat /etc/group
Para adicionar o usuário ao grupo sudo usermod -a -G docker
Reiniciar o sistema
Opção 2- Seguir para instalação do docker engine diretamente no wsl2 https://github.com/codeedu/wsl2-docker-quickstart#docker-engine-docker-nativo-diretamente-instalado-no-wsl2
4. Imagem
Imagem:
- Base para executar o processo com o container 
- Template do que vai ser executado em um container 
- Filesytem necessário para executar o container: Executável da aplicação, Instalação da aplicação, Pacotes necessários para executar a aplicação. 
Comandos
docker image ls - lista as imagens
docker image rm $(docker image ls -aq) - remove todas as imagens
docker image prune - remove as imagens que não estão sendo mais utilizadas
docker build -t -f Dockerfile . - cria uma imagem baseada no Dockerfile. Se o Dockerfile estiver no diretório atual não é necessário usar o parâmetro -f. ex. docker build -t ubuntu-curl -f Dockerfile . ou docker build -t ubuntu-curl .
docker build -t . --no-cache - cria uma imagem sem o cache. ex. docker build -t ubuntu-curl . --no-cache
Padrão do nome da imagem
- Na criação da imagem é necessário informar a tag. 
- 
Durante o uso do Docker quando a tag não é inserida é utilizado a tag latest da imagem. docker build -t igorspestana/rotten-potatoes:v1 -f Dockerfile . 
Cache
Imagem
- Sistema de arquivo em camadas 
- A cada execução de um parâmetro é criada uma nova camada. Criando uma pilha de camadas. 
- As camadas criadas na imagem são apenas de leitura (read). 
Container
- O container cria uma camada de leitura e escrita (read and write) sobre a camada de leitura (read) de uma imagem pronta. 
- 
O container é rápido de ser criado e jogado fora porque é apenas uma camada. Pesquisar sobre o overlay file system para entender o modelo de camadas. 
 Quando o docker cria uma container ele usa uma imagem como referência. Dessa forma não é criado uma imagem toda vez que um container novo é criado e isso gera uma economia de recursos, otimiza a construção da imagem e o upload da imagem. O Docker cria um cache para armazenar os dados das imagens de referencia e é reutilizado para cada container.
Dockerfile
Receita para criar imagem.
Processo: Dockerfile → Imagem → Container
- Arquivo de texto enviado para o Docker com as instruções para criar uma imagem. 
- Alguns statements: 
- From: a partir de qual imagem será criado. imagem base com binário e pip. Workdir: Run: comandos que vou executar dentro da imagem. instalar um pacote, permissão de execução para um arquivo, mover um arquivo, etc. comandos executados antes de subir a aplicação. Expose: porta que está exposta. onde a aplicação está recebendo dados. Copy: copiar arquivos de onde esta rodando o docker e vai jogar para dentro da imagem. Env: declarar variáveis de ambiente Cmd: qual comando será executado quando eu der um docker run, quando iniciar o container a partir da imagem. comando para subir a aplicação. 
Statements
FROM -> Inicializa o build de uma imagem a partir de uma imagem base.
RUN -> Executa um comando.
LABEL -> Adiciona metadados a imagem.
CMD -> Define o comando e/ou os parâmetros padrão.
EXPOSE -> Define que o container precisa expor a porta em questão.
ARG -> Define um argumento para ser usado no processo de construção.
ENV -> Define variáveis de ambiente.
ADD -> Copia arquivos ou diretórios ou arquivos remotos e adiciona ao sistema de arquivos da imagem.
COPY -> Copia arquivos ou diretórios e adiciona ao sistema de arquivos da imagem.
ENTRYPOINT -> Ajuda a configurar um container que pode ser executado como executável.
VOLUME -> Define volumes que devem ser definidos.
WORKDIR -> Define o seu diretório corrente.
Exemplo 1 — Criando uma imagem Ubuntu a partir de um Dockerfile
1- Criando o Dockerfile
Dockerfile
FROM ubuntu
RUN apt update
RUN apt install curl --yes
FROM ubuntu
RUN apt update && \\
        apt install curl --yes
        apt install vim --yes
FROM ubuntu
RUN apt update && \\
        apt install curl vim --yes
Importante manter o apt install junto do apt update no mesmo comando.
2- Criando a imagem
docker build -t ubuntu-curl .
5. Container
docker container ls -a - mostra os containers criados. -a parâmetro que mostra também os containers que não estão em execução.
docker - mostra as informações do container
docker container run - inicia o container. ex. docker container run ubuntu
docker container stop - interrompe um container em execução.
docker container start -i - inicia um container existente. -i parâmetro que executa o container de forma interativa. ex. docker container start f06a0ce6cd43 -i
docker container run -it ubuntu /bin/bash - inicia o container. -i parâmetro que executa o container de forma interativa. -t parâmetro que habilita o tty.
docker container run -e - inicia o container. -e parâmetro de variável de ambiente. ex. docker container run -e MONGO_INITDB_ROOT_USERNAME=mongouser -e MONGO_INITDB_ROOT_PASSWORD=mongopwd mongo
docker container rm - remove um container.
docker container rm $(docker container ls -aq) - remove todos os containers.
docker container rm -f $(docker container ls -aq) - remove todos os containers. -f remove mesmo se estiverem em execução
docker inspect - mostra informações do container ex. docker inspect 60037a544848
6. Port Bind
O port bind vincula uma porta local a uma porta do container. Dessa forma não é necessário acessar o container para só então acessar a aplicação. Na imagem ao acessar a porta local 8080 é feito um vínculo com a porta 27017 onde é possível acessar o processo que está rodando nessa porta.
docker container run -p : - inicia o container. -p parâmetro que define o vínculo da porta local com a porta do container.
Exemplo 1 — Criando um servidor http Nginx.
Exemplo 2 — Criando um gerenciador de banco de dados PostgreSQL.
1- Criando o container
Para acessar um banco de dados é necessário definir usuário, senha e definir um banco de dados. Nesse caso a criação do container precisa especificar variáveis de ambiente.
Para ler a documentação: https://hub.docker.com/_/postgres
2- Configurando o DBeaver
Para download do client de db: https://dbeaver.io/download/
Exemplo 3 — Criando um gerenciador de banco de dados MongoDB.
7. Networks
IP
Todo container tem um IP e pode ser visto usando o comando docker container inspect :
Exemplo
Criação do container usando as variáveis do mongo e referenciando o ip 172.17.0.2
docker container run -d -p 5000:5000 -e MONGODB_HOST=172.17.0.2 -e MONGODB_USERNAME=mongouser -e MONGODB_PASSWORD=mongopwd igorspestana/rotten-potatoes:v1
Container não deve ser referenciado por IP porque ele é efêmero e está o tempo todo caindo e subindo um novo com novo IP. A forma correta é usando o Docker Network
Docker Network
docker network create - cria uma network
Exemplo
Criação do container usando as variáveis do mongo e referenciando a network
Criando container com network especificada
docker container run -d -p "27017:27017" -e MONGO_INITDB_ROOT_USERNAME=mongouser -e MONGO_INITDB_ROOT_PASSWORD=mongopwd --name mongodb --network=rotten-network mongo
Criação do container usando as variáveis do mongo e referenciando o host mongodb
Criando container com network especificada
docker container run -d -p 5000:5000 -e MONGODB_HOST=mongodb -e MONGODB_USERNAME=mongouser -e MONGODB_PASSWORD=mongopwd --name rotten-potatoes --network=rotten-network igorspestana/rotten-potatoes:v1
8. Volumes
Existem duas possibilidades para que os dados sejam mapeados: fazendo um bind de diretório ou usando o Docker Engine
O volume deve ser especificado no container para que na situação do container com o banco de dados cair e subir um novo os dados continuem populando a aplicação.
Comandos
docker inspect - mostra informações do volume como o diretório local de armazenamento
docker volume ls - lista os volumes
docker volume rm $(docker volume ls) - remove todos os volumes
Bind de diretório
Cuidado quando for trabalhar com volume gerenciado por você mesmo utilizando o bind, fazendo um vínculo de diretório. A melhor forma de trabalhar com o volume é o docker gerenciando o volume com o Docker Engine.
Exemplo:
docker container run -d -p "27017:27017" -e MONGO_INITDB_ROOT_USERNAME=mongouser -e MONGO_INITDB_ROOT_PASSWORD=mongopwd --name mongodb --network=rotten-network -v "$(pwd)/mongodb:/data/db" mongo
Docker Engine
Criar volume
docker volume create - para criar o volume. ex. docker volume create mongo-vol
docker volume ls - lista os volumes criados.
Backup do volume
9. Docker Registry
Enviar imagem para o docker registry
Comandos
docker login - login no docker
docker logout - logout no docker
docker push - sobe a imagem para o dockerhub ex. docker push igorspestana/rotten-potatoes:v1
docker tag - criar uma imagem com a tag latest. ex. docker tag igorspestana/rotten-potatoes:v1 igorspestana/rotten-potatoes:latest
Boa prática: enviar a imagem latest
10. Docker compose
Receita para criar container
docker network create
docker volume create
docker container run mongo
docker container run app
docker-componse up -d - subir container a partir do compose
docker-compose down - derrubar container a partir do compose
11. Boas práticas
Para garantir a idempotência é necessário informar a tag da imagem base. ex. node:16.15.0 . Especificando apenas node teremos a imagem latest, essa imagem mais atualizada pode ter algum breaking change e comprometer a aplicação. É possível conferir as versões disponíveis no dockerhub.
Nunca use imagens desconhecidas. Use imagens oficiais ou imagens confiáveis.
FROM node:16.15.0
WORKDIR /app
COPY ./package*.json
RUN npm install
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]
Usar COPY separado para arquivo das dependências e arquivo da aplicação. A aplicação constantemente sofre alteração e as dependências não, dessa forma aproveitamos o cache das camadas para otimizar a construção da imagem.
FROM node:16.15.0
WORKDIR /app
COPY ./package*.json
RUN npm install
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]
Usar o .dockerignore para que ignorar diretórios específicos na hora de construir imagens.
Quando o comando npm install roda o diretório node_modules é criado com as dependências especificadas em package-lock.json e package.json.
Usando o .dockerignore com esse diretório especificado a criação desse diretório será ignorada no momento que a imagem for criada. **
12. Desinstalar o Docker
Para desinstalar completamente o Docker:
Passo 1
dpkg -l | grep -i docker
Para identificar qual pacote instalado você tem:
Passo 2
sudo apt-get purge -y docker-engine docker docker.io docker-ce docker-ce-cli docker-compose-plugin
sudo apt-get autoremove -y --purge docker-engine docker docker.io docker-ce docker-compose-plugin
Os comandos acima não removerão imagens, conteineres, volumes ou arquivos de configuração criados pelo usuário em seu host. Se você deseja excluir todas as imagens, contêineres e volumes, execute os seguintes comandos:
sudo rm -rf /var/lib/docker /etc/docker
sudo rm /etc/apparmor.d/docker
sudo groupdel docker
sudo rm -rf /var/run/docker.sock
 
 
              
 
    
Top comments (0)