Abílio Azevedo.

Docker

Cover Image for Docker
Abílio Azevedo
Abílio Azevedo

O Docker surgiu em 2013 como uma ferramenta open source para facilitar a criação e implantação de aplicações em containers, solucionando muitos problemas comuns relacionados à consistência e portabilidade em ambientes de desenvolvimento e produção.

Antes do Docker, era muito difícil garantir que um ambiente de desenvolvimento fosse idêntico ao ambiente de produção. Isso causava os famosos problemas de "funciona na minha máquina". Além disso, levantar novos ambientes e provisionar máquinas era lento e trabalhoso. Docker Born

O Docker resolve esses problemas empacotando aplicações junto com suas dependências em containers isolados e portáteis. Isso garante consistência e rapidez na implantação, permitindo que desenvolvedores trabalhem localmente da mesma forma que a aplicação é implantada na produção.

A empresa Docker cria produtos para monetizar em volta do ecossistema Docker.

Docker Engine

  • Montar as Imagens - Docker Build (Build Kit)
  • Distribuir as Imagens
  • Rodar os Containers - Containerd (Docker Runtime)
  • Comunicação entre os Containers - Network
  • Compartilhamento de Arquivos - Volumes
  • Orquestramento entre Containers Docker Engine

Essa Engine roda através da aplicação Docker Desktop que foi feita para Linux. Então no Mac e Windows ela sobre uma máquina virtual do Linux para rodar a Docker Engine.

Mas também é possível rodar atráves de outras aplicações como o colima.

Máquinas Virtuais

Máquinas virtuais (VMs) são uma abstração de hardware físico que transforma um servidor em vários servidores. O hipervisor permite que várias VMs sejam executadas em uma única máquina. Cada VM inclui uma cópia completa de um sistema operacional, o aplicativo, os binários e bibliotecas necessários – ocupando dezenas de GBs. As VMs também podem demorar para inicializar e manter (atualizações) é mais custoso. Maquinas Virtuais

Container

Os contêineres são uma evolução/otimização das máquinas virtuais. Pois são uma abstração na camada do aplicativo que empacota código e dependências. Vários contêineres podem ser executados na mesma máquina e compartilhar o kernel do sistema operacional com outros contêineres, cada um executando como processos isolados no espaço do usuário. Os contêineres ocupam menos espaço que as VMs (as imagens dos contêineres geralmente têm dezenas de MBs), podem lidar com mais aplicativos e exigem menos VMs e sistemas operacionais. Containers

Rodar um novo container

docker run -p <hostPort>:<containerPort> image-name

Mostra todos os containers que estão rodando e com a flag "-a" (all) mostra também os que não estão rodando no momento.

docker ps -a

Docker PS -a

Rodar um comando dentro do container de forma iterativa (flag -i), com interface de comunicação (flag -t de terminal teletype ou tty) e usando o usuário root (flag -u)

docker run -it -u root ubuntu bash

Baixar imagens do Docker Hub:

docker pull nginx

Redirecionar portas do container para portas da sua máquina:

docker run -p 8080:80 nginx

OBS: Usando portas mais altas do computador para não ter que rodar comando SUDO de administrador. A primeira porta é a exposta ao computador e a segunda é a do container.

Executar um comando em um container que esteja rodando:

docker exec container_name ls

A flag --rm no Docker é usada para remover automaticamente o contêiner quando ele sai. Aqui está um exemplo executando um contêiner Docker com --rm:

docker run --rm ubuntu echo "Olá, mundo"

docker run

  • Executa um comando em um novo container. Isso cria uma nova instância de container a partir da imagem fornecida e prepara para executar o comando fornecido. Quando o comando termina, o container para.
  • Essencialmente, o docker run executa um novo container temporário para rodar o comando especificado. O container é removido após a execução.

docker exec

  • Executa um comando em um container existente em execução. Isso permite executar comandos adicionais ou um novo shell interativo dentro de um container em execução.
  • O container continua em execução após o comando docker exec ser concluído. Ele não cria um novo container, simplesmente permite emitir mais comandos para um container já em execução.

Volumes

Quando um container morre a gente perde as alterações dentro dele, porque quando ele é montado novamente, ele segue as especificações da imagem. Para contornar isso, usamos os volumes compartilhados.

Compartilha volumes entre o container (/usr/share/nginx/html) e sua máquina (pasta_atual/html):

docker docker run -p 8080:80 -v $(pwd)/html:/usr/share/nginx/html nginx

Dockerfile

O Dockerfile é uma receita para construir imagens automáticas do Docker. Ele permite definir um ambiente padronizado e imutável para aplicações, garantindo que elas sempre sejam executadas da mesma maneira, independentemente de onde são implantadas. Sempre partimos de uma imagem base. Quanto maior sua imagem mais lento vai demorar para subir seu container. DockerFile

Podemos adicionar um stage nas etapas de build:

# Base image
FROM node:16-alpine AS base

# Install dependencies apenas nesta etapa
WORKDIR /app 
COPY package*.json ./
RUN npm install

# Stage de build
FROM base AS build
COPY . .
RUN npm run build

# Stage de produção 
FROM node:16-alpine 
WORKDIR /app

# Copia apenas o necessário 
COPY --from=build /app/package*.json ./
COPY --from=build /app/dist ./dist  

# Use o usuário padrão node
USER node

CMD [ &quot;node&quot;, &quot;dist/index.js&quot; ]

E executar com a flag --target build para irmos até o stage desejado:

docker build --target build

É importante definir o USER para restringirmos permissões do usuário da imagem. Se houver sincronismo de volumes é bom setar o mesmo USER que você usa em desenvolvimento na sua máquina com o USER do container para não precisar alterar arquivos com o SUDO.

Imagem

É a maquete do container, é o descritivo da instância do container. É como se fosse uma classe (especificação) do container.

Buildar uma imagem com base no Docker File:

docker build -t kibolho/nginx:latest .

Docker Hub

O Docker Hub é um registro público de imagens Docker. Ele permite que desenvolvedores compartilhem e reutilizem componentes já construídos por outros, evitando a necessidade de criar tudo do zero. É possível puxar imagens existentes ou enviar suas próprias imagens criadas localmente. Use sempre imagens confiáveis/verificadas.

Enviar uma imagem para o Docker Hub

docker push kibolho/nginx:latest

Docker Compose

O Docker Compose facilita a definição e execução de aplicações Docker de vários containers (orquestrador). Com o Compose, é possível configurar seus serviços em arquivos YAML e implantar toda a sua pilha com um único comando. Isso acelera os workflows de desenvolvimento e implantação.

O arquivo docker-compose.yml que orquestra um container MySQL:

version: '3'

services: 
  mysql:
    image: mysql:8
    container_name: mysql 
    restart: always 
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: app
    ports:
      - 3306:3306
    volumes:
      - ./mysql:/var/lib/mysql

Podemos mapear uma pasta de volume de contêiner para uma pasta do host:

volumes:
   - ./mysql:/var/lib/mysql  

Ou podemos apenas persistir no contêiner sem vincular a uma pasta do host (volume anônimo):

volumes:
   - /opt/node_app/app/node_modules

Também podemos usar uma flag :delegated que informa ao Docker para delegar o gerenciamento deste volume montado para o tempo de execução do contêiner ao invés do próprio Docker. Isso permite algumas otimizações de desempenho.

volumes:
      - ./app:/opt/node_app/app:delegated

Para rodar os containers descritos no arquivo docker-compose.yml em background (flag -d background e em modo detachado/desconectado):

docker compose up -d

Para parar os containers descritos no arquivo docker-compose.yml:

docker compose stop

Para destruir os containers descritos no arquivo docker-compose.yml:

docker compose down

Problemas de Compartibilidade

Mesmo se emulado, algumas imagens x86 têm problemas de compatibilidade, por conter instruções x86 que não podem ser executadas no silicone da Apple com base em ARM. Isso depende do comportamento do aplicativo específico.

O ecossistema ainda está colocando em dia as imagens com variantes arm64.

Uma solução temporária é o uso da chave platform no docker-compose.yml, pois permite que você defina imagens alternativas compatíveis com arm64 especificamente para dispositivos M1. Isso evita problemas de emulação e arquitetura.

version: '3'
services:

  app:
    image: mysql:8
    platform: linux/amd64

Ferramentas para gerar imagens

Podemos usar Buildpacks para gerar as imagens automaticamente.

Kubernetes

Kubernetes é uma plataforma de orquestração de contêineres de código aberto que foi originalmente desenvolvida pelo Google e agora é mantida pela Cloud Native Computing Foundation (CNCF). Ela é usada para automatizar a implantação, dimensionamento e gerenciamento de aplicativos em contêineres em vários hosts.

Kubernetes se tornou uma ferramenta essencial no desenvolvimento e operação de aplicativos modernos. Algumas das principais razões pelas quais o Kubernetes é tão importante incluem:

  1. Escalabilidade e alta disponibilidade: O Kubernetes fornece recursos avançados de dimensionamento automático e balanceamento de carga, permitindo que aplicativos sejam rapidamente dimensionados para cima ou para baixo conforme a demanda muda. Isso ajuda a garantir a alta disponibilidade dos serviços.

  2. Gerenciamento simplificado de contêineres: O Kubernetes abstrai a complexidade do gerenciamento de contêineres, como o provisionamento de hosts, a alocação de recursos e o monitoramento da saúde dos contêineres. Isso permite que os desenvolvedores se concentrem mais no desenvolvimento de aplicativos do que na infraestrutura subjacente.

  3. Portabilidade e consistência: O Kubernetes fornece uma plataforma consistente para implantar aplicativos em diferentes ambientes, como local, nuvem pública ou nuvem privada. Isso ajuda a garantir a portabilidade dos aplicativos e reduz os custos de manutenção.

  4. Resiliência e recuperação de desastres: O Kubernetes fornece recursos avançados de autoreparo, como reinicialização automática de contêineres com falha e redistribuição de cargas de trabalho. Isso melhora a resiliência dos aplicativos e facilita a recuperação de desastres.

  5. Gerenciamento de configuração e segurança: O Kubernetes fornece recursos robustos de gerenciamento de configuração e segurança, incluindo controle de acesso baseado em função, criptografia de dados em repouso e em trânsito, e separação de preocupações entre aplicativos e infraestrutura.

No geral, o Kubernetes se tornou uma plataforma essencial para a implantação e operação de aplicativos modernos, especialmente aqueles baseados em contêineres. Sua capacidade de simplificar o gerenciamento de contêineres, fornecer escalabilidade e alta disponibilidade, e garantir a portabilidade e a resiliência dos aplicativos o torna uma escolha popular entre equipes de desenvolvimento e operações.

Learn more

Amazon EKS (Elastic Kubernetes Service)

O Amazon EKS é um serviço gerenciado de Kubernetes fornecido pela Amazon Web Services (AWS). Ele remove a necessidade de instalar, operar e manter seu próprio cluster Kubernetes, simplificando significativamente o provisionamento e a operação de um cluster Kubernetes na AWS. Algumas das principais vantagens do EKS incluem:

  • Gerenciamento do plano de controle: O AWS cuida do provisionamento e da operação do plano de controle Kubernetes, incluindo a atualização e o dimensionamento do cluster.
  • Integração com outros serviços AWS: O EKS se integra bem com outros serviços da AWS, como o Elastic Load Balancing, o Amazon VPC e o AWS Identity and Access Management (IAM).
  • Alta disponibilidade e resiliência: O EKS fornece alta disponibilidade e resiliência para seu cluster Kubernetes, com redundância em várias zonas de disponibilidade.
  • Segurança: O EKS fornece recursos de segurança, como criptografia de dados em repouso e em trânsito, além de integração com o AWS IAM para controle de acesso.

Google Kubernetes Engine (GKE)

O Google Kubernetes Engine (GKE) é um serviço gerenciado de Kubernetes fornecido pela Google Cloud Platform (GCP). Ele também abstrai a complexidade de configurar e operar um cluster Kubernetes, oferecendo muitos dos mesmos benefícios do EKS, como provisionamento e operação do plano de controle, integração com outros serviços da nuvem e alta disponibilidade.

Azure Kubernetes Service (AKS)

O Azure Kubernetes Service (AKS) é o serviço gerenciado de Kubernetes fornecido pela Microsoft Azure. Ele também simplifica a configuração e a operação de um cluster Kubernetes, com integração profunda com outros serviços da Azure, como o Azure Active Directory para controle de acesso.

DigitalOcean Kubernetes

O DigitalOcean Kubernetes é uma oferta de serviço gerenciado de Kubernetes da DigitalOcean, uma popular plataforma de nuvem. Ele fornece um modo fácil de provisionar e operar clusters Kubernetes, com integração com outros serviços da DigitalOcean.

Além desses serviços gerenciados de Kubernetes na nuvem, existem também ferramentas para implantar e operar clusters Kubernetes em sua própria infraestrutura, como o Minikube (para desenvolvimento local) e o kubeadm (para implantar clusters Kubernetes em hosts Linux).

No geral, essas soluções de Kubernetes na nuvem simplificam significativamente a configuração e a operação de um ambiente Kubernetes, permitindo que as equipes se concentrem mais em implantar e operar seus aplicativos do que em gerenciar a infraestrutura subjacente.

Conclusão

Em resumo, o Docker revolucionou o desenvolvimento e implantação de aplicações ao introduzir uma forma padronizada e portátil de empacotar ambiente. Recursos como Dockerfile, Docker Compose e Docker Hub aceleram os workflows e promovem reutilização, colaboração e consistência.


Mais posts

Cover Image for A psicologia do Dinheiro

A psicologia do Dinheiro

Morgan Housel oferece insights valiosos sobre a gestão financeira e tomada de decisões. O autor enfatiza que o sucesso financeiro depende mais do comportamento do que da inteligência ou conhecimento técnico. Housel destaca a importância da visão de longo prazo e da resiliência diante da volatilidade do mercado, encorajando a forcamos na sustentabilidade em vez de ganhos de curto prazo.

Cover Image for Bellsant

Bellsant

Estou na vanguarda do desenvolvimento de um aplicativo de saúde e bem-estar de ponta. Nossa pilha de tecnologia combina React Native para desenvolvimento móvel multiplataforma com um backend NodeJS sem servidor, aproveitando o AWS Lambda para escalabilidade e eficiência de custos.

Abílio Azevedo
Abílio Azevedo

NewsLetter

Eu enviarei o conteúdo postado aqui no blog. Sem Spam =)

Engenheiro de software experiente, formado em Engenharia Elétrica, com mais de 10 anos de experiência prática na construção de aplicativos móveis, web e back-end robustos e escaláveis em vários projetos, principalmente no setor de fintech. Mobile (React Native), Web (React e Next.JS) e Backend (Node.JS, PHP e DJANGO). Meu objetivo é criar produtos que agreguem valor às pessoas. - © 2024, Abílio Azevedo