Saudações. Instruções de como instalar o Docker (CE – Community Edition) no Linux.
Artigo vivo, sofrerá adições constantes.
Procedimentos prévios recomendados:
- Instalação de programas básicos;
- Data/hora via NTP;
- Ajuste fino no kernel Linux;
- DNS Cache local de alta velocidade;
1 – Instalando Docker (CE – Community Edition)
# Baixar script instalador oficial:
curl -fsSL get.docker.com -o /tmp/get-docker.sh
# Executar script instalador:
sh /tmp/get-docker.sh
# Ferramentas recomendadas:
apt-get -y install iproute2
apt-get -y install bridge-utils
apt-get -y install tcpdump
apt-get -y install strace
2 – Criar comandinhos rápidos
# Comando para parar e destruir um container:
(
echo '#!/bin/sh';
echo;
echo 'for x in $@; do'
echo ' docker stop $x;'
echo 'docker stop $x;'
echo 'docker rm $x;'
echo 'done';
echo;
) > /usr/bin/undocker
chmod +x /usr/bin/undocker
# Comando para entrar no shell (/bin/sh) de um container:
(
echo '#!/bin/sh';
echo;
echo 'docker exec -it $1 /bin/bash';
echo;
) > /usr/bin/dsh
chmod +x /usr/bin/dsh
# Comando para listar containers em execucao (inclusive parados):
(
echo '#!/bin/sh';
echo;
echo 'docker ps -a';
echo;
) > /usr/bin/dps
chmod +x /usr/bin/dps
3 – Conferindo processos principais
# Conferindo docker em execução:
# 1 - verificar se o containerd está rodando:
ps aux | grep '[c]ontainerd'
# root 1895 0.4 0.2 3575228 74044 ? Ssl Nov17 14:49 /usr/bin/containerd
# 2 - verificar se o dockerd está rodando:
ps aux | grep '[d]ockerd'
# root 1986 0.8 0.4 5011344 151252 ? Ssl Nov17 25:01 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
4 – Comandos mais utilizados
# Listar containers:
docker ps -a
docker container ls
docker container ls -a
# Listar imagens presentes (inicialmente não há nada mesmo!)
docker image ls
docker images
# Listar redes:
docker network ls
# Procurar por imagens publicas:
docker search alpine
docker search debian
docker search redis
docker search n8n
# Procurar por imagens públicas e OFICIAIS (seguras):
docker search --filter is-official=true php
docker search --filter is-official=true debian
# Baixando imagens:
docker pull ubuntu
docker pull alpine
docker pull debian
# Baixar versoes (tags) específicas de uma imagem:
docker pull debian:bookworm
docker pull debian:bullseye
docker pull debian:buster
docker pull alpine:3.9
# Removendo imagem do repositório local:
docker rmi alpine:3.9
docker rmi debian:buster
# Listar volumes:
docker volume ls
# Removendo todas as imagens sem uso:
docker image prune -f
# Removendo todas as redes sem uso:
docker network prune -f
# Removendo todos os volumes abandonados (perigoso, faz backup primeiro):
docker volume prune -f
# Removendo todos os objetos (redes, imagens, ...) sem uso:
docker system prune -f
5 – Exemplos de manipulação de redes em docker
# Listar redes:
docker network ls
# REDES BRIDGE (tipo padrão/normal):
#------------------------------------------------------------------------
# - Criar uma rede bridge adicional simples (nome: sites1):
docker network create sites1
# - Criar uma rede bridge adicional simples (nome: sites2):
docker network create -d bridge sites2
# - Cuidado:
# ** o docker cria a rede inicial na faixa 172.17.0.0/16
# ** ao criar redes novas sem informar a faixa, ele usa um /16 seguinte
# ou seja, a proxima rede 172.18.0.0/16, e 172.19.0.0/16, ...
# mas a faixa privada termina em 172.31.0.0/16,
# ** a rede 172.32.0.0/16 NÃO É PRIVADA, SE VOCÊ INVADIR ESSA FAIXAR
# ou faixas acima dela sites vão deixar de abrir no seu servidor.
#
# - Criar uma rede bridge adicional simples com faixa ipv4 específica:
docker network create -d bridge --subnet 192.168.3.0/24 sites3
docker network create -d bridge --subnet 192.168.4.0/24 sites4
# - Nota: o primeiro IP é usado como gateway, mas vc pode especificar:
docker network create -d bridge \
--subnet 192.168.5.0/24 --gateway 192.168.5.254 \
sites5
# - Nota: por padrão todas as redes são criadas ipv4-only
# - Criar uma rede bridge adicional com IPv6:
docker network create -d bridge \
--subnet 10.6.0.0/16 --gateway 10.6.255.254 \
--ipv6 \
--subnet=2001:db8:10:6::/64 \
--gateway=2001:db8:10:6::1 \
sites6
# - Criar uma rede bridge adicional com nome especifico
# de interface de rede (ip link show; brctl show):
docker network create -d bridge \
-o "com.docker.network.bridge.name"="brsites7" \
--subnet 10.7.0.0/16 --gateway 10.7.255.254 \
--ipv6 \
--subnet=2001:db8:10:7::/64 \
--gateway=2001:db8:10:7::1 \
sites7
# - Criar uma rede bridge adicional com nome especifico
# de interface de rede (ip link show; brctl show) e
# permitir comunicação livre entre containers:
docker network create -d bridge \
-o "com.docker.network.bridge.name"="brsites8" \
-o "com.docker.network.bridge.enable_icc"="true" \
--subnet 10.8.0.0/16 --gateway 10.8.255.254 \
--ipv6 \
--subnet=2001:db8:10:8::/64 \
--gateway=2001:db8:10:8::1 \
brsites8
# - Criar uma rede bridge adicional com nome especifico
# de interface de rede (ip link show; brctl show),
# configurar MTU em 9000 (jumbo-frame), desativar NAT,
# permitir comunicação livre entre containers e
# nao fazer NAT (rotear ou usar ip publico mesmo!):
docker network create -d bridge \
-o "com.docker.network.bridge.name"="brsites9" \
-o "com.docker.network.bridge.enable_icc"="true" \
-o "com.docker.network.driver.mtu"="9000" \
-o "com.docker.network.bridge.enable_ip_masquerade"="false" \
--subnet 45.255.128.128/25 --gateway 45.255.128.254 \
--ipv6 \
--subnet=2804:cafe:ffff:a009::/64 \
--gateway=2804:cafe:ffff:a009::1 \
brsites9
# REDES MACVLAN (tipo transparente, joga o container na rede externa):
#------------------------------------------------------------------------
# - Nota: o container receberá um MAC novo, a bridge do Linux vai
# deixar passar, mas o Port-Group e vSwitch do VMware
# por padrão não permitirá, vc precisa ativar o recurso
# allow-mac-change na Port-Group no no vSwitch
# - Nota: a rede MACVLAN precisa ser anexada uma interface
# ethernet (eth0, eno0, ens192, ...) que esteja UP
#
# - Nota: você só pode usar 1 rede MACVLAN por interface ethernet
#
# - Alerta: a gerencia de IP é selvagem, cuidado ao
# informar a faixa pois criar containers e alocar
# IPs em uso na LAN externa pode resultar em conflito
# de ARP (o famoso conflito de IP)
#
# - No VMware ESXi (terminal):
# esxcli network vswitch standard policy security set \
# --vswitch-name=vSwitch0 --allow-mac-change yes
#
# Criar rede MACVLAN simples para contato externo na eth0:
docker network create -d macvlan -o parent=eth0 \
--subnet=10.160.0.0/16 --gateway 10.160.255.254 \
mth0
# Criar rede MACVLAN com IPv6 para contato externo na eth1:
docker network create -d macvlan -o parent=eth1 \
--subnet=45.255.130.0/27 --gateway 45.255.130.1 \
--ipv6 \
--subnet=2804:cafe:ffff:b000::/64 --gateway=2804:cafe:ffff:b000::1
mth1
# Removendo todas as redes sem uso (todas acima se vc não as usou):
docker network prune -f
6 – Exemplos: criação e manipulação de containers
# Nota: todo container precisa rodar alguma coisa pra justificar
# sua existencia na lista de processos do Linux, assim,
# imagens puras como Debian, Alpine, não possuem programas
# de ENTRYPOINT ou CMD. Você precisará imperativamente
# informar um comando após o nome da imagem.
# As imagens de aplicativos (MariaDB, Redis, ...)
# já possuem ENTRYPOINT/CMD e por isso não exigem
# um comando após o nome da imagem.
# Nos exemplos abaixo, vou executar o comando 'sleep'
# como uma forma de manter um processo rodando dentro
# do container.
#
# Exemplo 1
#------------------------------------------------------------------
# Criar e rodar em 2 etapas (pouco usual, apenas exemplo):
# - Criar container (não roda)
docker create --name debian01 debian:bookworm sleep 999999999
# - Executar/iniciar o container:
docker start debian01
# Listar (comando puramente informativo):
docker ps -a
# Extrair todas as informações do container:
docker inspect debian01
# Extrair todas as informações do container (puramente informativo):
docker exec -it debian01 /bin/bash
exit #< para sair do container
# Parar o container:
docker stop debian01
# Destruir o container:
docker rm -f debian01
# Exemplo 2 (versão rápida dos comandos acima)
#------------------------------------------------------------------
# Criar e rodar:
docker run -d --name debian02 debian:bookworm sleep 999999999
# Listar (comando puramente informativo):
docker ps -a
# Extrair todas as informações do container (puramente informativo):
docker inspect debian02
# Entrar no container (executar um shell interativo no ambiente):
docker exec -it debian02 /bin/bash
exit #< para sair do container
# Parar e destruir o container:
docker rm -f debian02
# Exemplo 3 (adicionando elegancia e mais opções)
#------------------------------------------------------------------
# Criar pasta de dados:
mkdir -p /storage/debian03
# Criar container cheio de opções elegantes:
docker run -d \
--name debian03 \
-h debian03.intranet.br \
--restart=unless-stopped \
\
-e TZ=America/Sao_Paulo \
-e MAINTAINER="Patrick Brandao" \
\
--mount \
type=bind,source=/storage/debian03,destination=/data,readonly=false \
\
debian:bookworm \
sleep 999999999
# Argumentos:
# -h especifica o hostname interno
# --restart pode ser always ou unless-stopped
# -e define variável de ambiente (comando: env)
# --mount mapeia uma pasta do HOST (Linux) dentro do container
# no exemplo acima, tudo que dentro do container
# que gravar em /data/ estará de fato gravando
# no HOST principal em /storage/debian03/
#
# Parar e destruir o container:
docker rm -f debian03
# Exemplo 4 (argumentos de rede e multi-rede)
#------------------------------------------------------------------
# Criando duas redes:
# - Rede para acesso à Internet
docker network create -d bridge \
-o "com.docker.network.bridge.name"="brsites" \
--subnet 10.99.0.0/24 --gateway 10.99.0.254 \
--ipv6 \
--subnet=2001:db8:ffff:1099::/64 --gateway=2001:db8:ffff:1099::1 \
brsites
# - Rede para acesso entre containers e container banco de dados
docker network create -d bridge \
-o "com.docker.network.bridge.name"="brdatabase" \
-o "com.docker.network.driver.mtu"="9000" \
-o "com.docker.network.bridge.enable_icc"="true" \
-o "com.docker.network.bridge.enable_ip_masquerade"="false" \
\
--subnet 10.255.0.0/24 --gateway 10.255.0.254 \
brdatabase
# - Criar container de banco de dados MariaDB:
mkdir -p /storage/mariadb-main
docker run \
-d --restart=unless-stopped \
--name mariadb-main \
-h mariadb-main.intranet.br \
\
--network brdatabase \
--ip=10.255.0.100 \
\
-e MYSQL_ROOT_PASSWORD=tulipasql \
-e MYSQL_DATABASE=admin \
-e MYSQL_USER=suporte \
-e MYSQL_PASSWORD=tulipasql \
\
--mount \
type=bind,source=/storage/mariadb-main,destination=/var/lib/mysql,readonly=false \
\
mariadb:latest
# - Criar container Debian que se conectará na Internet
# e possuirá uma segunda conexão de rede conectada à rede
# de banco de dados
docker run -d \
--name debian04 \
-h debian04.intranet.br \
--restart=always \
\
--network brsites --mac-address "00:ca:fe:f1:f2:f0" \
--ip=10.99.0.14 \
--ip6=2001:db8:ffff:1099::14 \
\
debian:bookworm \
sleep 999999999
# - Conectar container debian04 na rede de banco de dados:
docker network connect brdatabase debian04 --ip=10.255.0.14
# - Destruir tudo!
undocker debian04
undocker mariadb-main
docker system prune -f
# - Observe os arquivos em /storage/mariadb-main/
# se você recriar o container mariadb-main novamente
# ele continuará de onde parou pois os dados objetivos
# foram salvos, somente software (parte descartavel) foi
# destruida.
7 – Configuração principal do Docker
O Docker faz a leitura do arquivo (JSON) no caminho /etc/docker/daemon.json (precisa criar o arquivo), segue algumas configurações comuns, junte as que precisa num único objeto JSON.
Acelerar downloads
# Paralelismo de downloads e uploads de imagens
{
"max-concurrent-uploads": 16,
"max-concurrent-downloads": 16
}
Suporte a GPU
# Suporte a GPU NVIDIA (requer instalacao previa dos drivers):
{
"runtimes": {
"nvidia": {
"args": [],
"path": "nvidia-container-runtime"
}
}
}
Desativar firewall e redirecionamento de portas
Referência: https://docs.docker.com/reference/cli/dockerd/
# Desativar suporte a regras de firewall e redirecionamento
{
"iptables": false,
"ip6tables": false,
"ip-masq": false
}
Rede IPv4 da rede padrão (docker default network)
# Rede IP padrao: 172.17.0.0/16
# Escolha uma das opcoes abaixo:
# Alterar rede padrão:
{
"bip": "10.251.0.0/16"
}
# Versao mais nova do docker requer a config assim:
{
"default-address-pools": [ { "base":"10.251.0.0/16", "size": 16 } ]
}
Reinicie para aplicar
Para aplicar as alterações realizadas no /etc/docker/daemon.json, reinicie o docker:
systemctl restart docker
Em caso de problemas, retire o daemon.json e reinicie o servidor.
8 – Ferramentas de gestão de containers
Algumas ferramentas podem te ajudar a monitorar e manipular containers usando interface WEB e templates prontos, vou deixar 2 exemplos:
- WeaveScope: permite visualização de ambiente e manipulação básica;
- Portainer CE: permite gestão completa, desde o básico ao avançado de todos os recursos do Docker, fornece templates de ambientes prontos e pre-configurados, considerado um dos melhores sistemas para gestão de containers;
WeaveScope
Referência: https://github.com/weaveworks/scope
# Nota: se ele bugar, apenas destrua-o e execute novamente!
# Baixar script de provisionamento:
curl -L git.io/scope -o /usr/sbin/scope
# Tornar executavel:
chmod a+x /usr/sbin/scope
# Subir container do WeaveScope com usuário e senha (senão ele fica aberto):
arg1="ENABLE_BASIC_AUTH=true"
arg2="BASIC_AUTH_USERNAME=admin"
arg3="BASIC_AUTH_PASSWORD=tulipa"
export WEAVESCOPE_DOCKER_ARGS="-e $arg1 -e $arg2 -e $arg3"
scope launch
# Acesso: http:// + IP + :4040/
# Para destruir o WeaveScope:
undocker weavescope
Portainer CE (Community Edition)
Referência: https://docs.portainer.io/start/install-ce/server/docker/linux
# Nota: se ele bugar, apenas destrua-o e execute novamente, os dados
# que importa estarão no diretorio de armazenamento persistente
# Diretorio de dados persistentes:
mkdir -p /storage/portainer-data
# Criar e rodar:
docker run \
-d --restart=always \
--name portainer \
-h portainer.intranet.br \
\
-p 8000:8000 \
-p 9443:9443 \
\
-v /var/run/docker.sock:/var/run/docker.sock \
--mount \
type=bind,source=/storage/portainer-data,destination=/data,readonly=false \
\
portainer/portainer-ce:2.21.4
# Acesso: https:// + IP + :9443/
# Defina a primeira senha e salve-a
Terminamos por hoje, isso deve ter te economizado alguns livros de Docker!
Patrick Brandão, patrickbrandao@gmail.com