Estudos sobre o funcionamento e gestão de containers utilizando Docker, seguindo a orientação do Getting Started, utilizado no Docker Desktop.
Containers são simplesmente outro processo que foi isolado dos demais processos na máquina host. Potencializando os namespaces e cgroups do kernel, recursos que já existem no Linux há muito tempo e que o Docker tornou acessíveis e fáceis de usar.
Namespaces é uma feature que permite criar e lidar com diversos contextos em um mesmo sistema, vendo propriedades globais diferentes e isoladas em cada contexto. Um exemplo prático é a possibilidade de criar um contexto (ou ambiente) de rede isolado do ambiente físico, onde existirão interfaces de rede física que não são visíveis no contexto do sistema. Estas interfaces terão endereços físicos e lógicos diferentes do sistema e todo tráfego, regras de firewall, existentes nesse novo contexto e não são vistos por nenhum outro contexto, incluindo a máquina host.
Referência completa.
Cgroups é um recurso que limita, contabiliza e isola o uso de recursos de uma coleção de processos.
# Roda um container baseado na imagem passada
# docker run <imagem>
docker run -d -p 80:80 docker/getting-started
-d
- executa o container em modo background (detached mode)-p 80:80
- faz o mapeamento da porta do host para a porta do container host:containerdocker/getting-started
- imagem utilizada
As flags podem ser combinadas para diminuir o comando:
`docker run -dp 80:80 docker/getting-started
O filesystem utilizando na execução de um container é provida pela imagem do Container. Esta imagem precisa conter tudo para rodar uma aplicação - todas as dependências, configurações, scripts, arquivos binários, etc. A imagem também contém outras configurações para o container, como variáveis de ambiente, comandos padrões de execução e demais metadatas.
docker ps
- Visualiza todos os containersdocker stop <container-id>
- Interrompe a execução de um containerdocker rm -f <container-id>
- Remove o containerdocker login -u <username>
- Efetua login local com um usuário do DockerHubdocker tag nome usuario/image
- Adicionar uma tag padrão para a imagem local criada através do Dockerfiledocker push usuario/image
- Envia uma imagem local criada através do Dockerfile para o DockerHubdocker volume inspect <volume>
- Inspeciona os dados do volume (data, labels, caminho, nome, escopo)docker logs -f <container-id>
- Visualiza os logs do containerdocker exec -it <container-id> <comando>
- Executa um comando interno através da máquina host
Volumes são utilizados para compartilhar informações entre o host e o container, além de também ser utilizado caso seja necessário compartilhar informações/pastas/db-files entre containers.
# Cria um novo volume com o nome informado
# docker volume create <nome-do-volume>
docker volume create todo-db
# Adiciona o volume criado ao rodar o container
# Ex.: docker run -v <nome-do-volume>:<caminho-container> <imagem>
docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
Diferentemente dos volumes, que são nomeados e não precisamos nos preocupar onde a informação é armazenada, as pastas vinculadas controlamos exatamente o ponto de vinculação no host local. Podemos utilizar para persistir dados mas é mais utilizado para prover mais informações para os containers.
Um exemplo prático é no caso de uma aplicação, podemos manter o código original em uma máquina e a aplicação rodando dentro de um container, podendo validar as modificações do código imediatamente.
Para comparação entre os Volumes e os Bind Mounts.
Volumes | Bind Mounts | |
---|---|---|
Caminho local | Docker define | Usuário define |
Exemplo usando -v | meu-volume:/usr/local/data | /path/:/usr/local/data |
Preenche o volume com dados do container |
Sim | Não |
Suporta Volume de Drivers | Sim | Não |
$ docker run -dp 3000:3000 \
-w /app -v "$(pwd):/all" \
node:12-alpine \
sh -c "yarn install && yarn run dev"
-dp 3000:3000
- Roda em modo detached e cria um mapeamento de porta-w /app
- Define o diretório de trabalho, ou o diretório onde serão executados comandos-v "$(pwd):/app"
- Vincula a pasta de trabalho atual ao diretório/app
do containernode:12-alpine
- É a imagem a ser utilizadash -c "yarn install && yarn run dev"
- O comando que será utilizado. Iniciando um shell usandosh
(a imagem alpine não tembash
) e rodandoyarn install
para resolver todas as dependências do projeto e finalmenteyarn run dev
, que deve estar definido nopackage.json
do projeto. Levando em consideração que o projeto do exemplo estaria rodando uma aplicação JS/TS/Node...
A utilização das pastas vinculadas (Bind Mounts) é muito usada em setups de desenvolvimento. A grande vantagem é que a máquina local não necessita todas as ferramentas de build e ambientes instaladas. Com um simples comando docker run
o ambiente de desenvolvimento está iniciado e pronto para ser utilizado.
Quando falamos em aplicações distribuídas ou com a inclusão de banco de dados, devemos seguir o conceito de que cada container deve ter apenas uma aplicação, por diversas razões: Escalabilidade, versionamento de aplicação, deploy em produção apenas das aplicações necessárias e quando há mais de uma aplicação dentro de um container, será preciso um gerenciador de processos, o que adiciona complexidade no container e mais configurações para o startup/shutdown.
Por padrão os containers rodam de forma isolada e não tem conhecimento sobre outros processos ou containers na mesma máquina. Para permitir que haja comunicação entre containers, utilizamos networking.
Se um ou mais containers estiverem na mesma network, eles serão capazes de conversar entre eles. Caso não estejam, não terão esta capacidade.
# $ docker network create <nome_da_network>
docker network create todo-app
# Iniciando um container com imagem mysql:5.1 utilizando network
docker run -d \
--network todo-app --network-alias mysql \
-v todo-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=todos \
mysql:5.7
Este contém um volume chamado
todo-mysql-data
que está sendo montado em/var/lib/mysql
, este volume nunca foi criado, porém o comandodocker
reconhece e, caso não exista, cria o volume automaticamente.
Dockerfile são simplesmente scripts descritos com instruções que são usadas para a criação de uma imagem. O Docker file não pode conter extensão.
# Compila as informações do Dockerfile
# docker build -t usuario/imagem:tag .
docker build -t andersonkoester/getting-started:1.0
Este comando é usado para gerar uma nova imagem de container baseada no Dockerfile, todas as dependências são baixadas para que o builder