Por baixo dos panos, o Docker é construído sobre várias tecnologias do kernel do Linux, incluindo namespaces, cgroups, UnionFS e outras ferramentas para permitir o isolamento e gerenciamento eficiente de containers.
Namespaces:
Os namespaces permitem isolar recursos do sistema, como processos, rede, sistema de arquivos, entre outros. Cada container Docker é criado em um conjunto de namespaces, o que garante que os processos em um container não possam ver nem interagir com processos fora dele.
Os principais namespaces usados pelo Docker são: PID (para isolar processos), NET (para isolar a rede), MNT (para isolar o sistema de arquivos), UTS (para isolar o hostname), IPC (para isolar a comunicação interprocesso) e USER (para isolar os IDs de usuário).
Cgroups (Control Groups):
Os cgroups permitem limitar, contabilizar e isolar o uso de recursos, como CPU, memória, E/S de disco e rede, para grupos de processos. O Docker usa cgroups para garantir que os containers tenham uma cota de recursos definida, evitando que um container consuma todos os recursos do sistema.
Com cgroups, o Docker pode controlar e distribuir recursos entre diferentes containers de forma justa e previsível.
UnionFS:
O UnionFS é usado para criar um sistema de arquivos em camadas dentro de um container Docker. Ele permite que diferentes camadas (imagens) sejam empilhadas para formar o sistema de arquivos completo do container.
Cada camada representa alterações ou adições ao sistema de arquivos. Isso permite que múltiplos containers compartilhem camadas de imagem idênticas, economizando espaço em disco e facilitando o gerenciamento de imagens.
Docker Daemon e Cliente:
O Docker funciona em um modelo cliente-servidor, onde o Docker Daemon é o servidor e o Docker Cliente é a interface pela qual os usuários interagem com o Docker.
O Docker Daemon é responsável por gerenciar os containers, imagens, volumes e redes. Ele é responsável por criar, iniciar, parar e destruir containers, bem como gerenciar o ciclo de vida das imagens.
O Docker Cliente é uma CLI (Interface de Linha de Comando) que permite aos usuários enviar comandos para o Docker Daemon. O Cliente envia as solicitações para o Daemon, que as processa e executa as ações necessárias.
Docker Image e Container:
Uma Docker Image é uma estrutura de arquivos somente leitura usada para criar containers. Uma imagem contém o sistema de arquivos raiz e as configurações necessárias para executar um aplicativo. Ela é composta por uma ou mais camadas de UnionFS, onde cada camada é uma modificação ou adição em relação à camada anterior.
Um Docker Container é uma instância em execução de uma imagem. É um ambiente isolado que contém um sistema de arquivos que deriva da imagem, juntamente com um conjunto de processos que estão sendo executados.
Quando você executa um container Docker, o Docker Daemon utiliza as tecnologias do kernel mencionadas (namespaces, cgroups e UnionFS) para criar o ambiente isolado para o container. A partir da imagem base, ele cria uma camada de sistema de arquivos (layer) somente leitura e, em seguida, adiciona uma camada somente leitura para os arquivos do sistema de arquivos do container. A partir daí, ele cria uma camada de escrita para quaisquer alterações feitas no sistema de arquivos durante a execução do container.
Esse modelo de camadas permite que os containers sejam leves e eficientes, compartilhando recursos sempre que possível e tornando o processo de criação e distribuição de containers mais rápido e fácil.
Criando um container sem o Docker, utilizando apenas os recursos de namespaces, cgroups e o utilitário chroot.
Após entendermos a teoria do funcionamento do Docker, agora vamos criar um container sem Docker, utilizando os recursos de namespaces, cgroups e o chroot.
No GNU/Linux Debian ou Ubuntu, segue:
sudo apt update
sudo apt install debootstrap -y
mkdir /mnt/debian
sudo debootstrap stable /mnt/debian http://deb.debian.org/debian
Para visualizar os arquivos da imagem Debian que foi criado pelo pacote debootstrap.
ls -la /mnt/debian
chroot /mnt/debian /bin/bash
A partir desse momento está no outro SO que foi instalado com a imagem do Debian com debootstrap
cat /etc/debian_version
cat /etc/issue
Agora vamos fazer o isolamento de processos da imagem minialista do Debian criada com debootstrap com o comando seguinte:
unshare --mount --uts --ipc --net --pid --user --map-root-user --fork --uts --ipc chroot /mnt/debian /bin/bash
mount -t proc proc /proc
ps -ef
Outra aba do terminal
ps aux | grep bash
Identificar o PID do bash
sudo chroot debian bash
apt update
apt install stress
exit
unshare --mount --uts --ipc --net --pid --user --map-root-user --fork --uts --ipc chroot /mnt/debian /bin/bash
mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t tmpfs tmp /tmp
ps -ef
Na máquina física
sudo apt install cgroup-tools
sudo cgcreate -g memory,cpu,blkio,freezer,devices:/nome-grupo
cat /sys/fs/cgroup/memory/nome-grupo
cgclassify -g memory,cpu,blkio,freezer,devices:nome-grupo PID(bash-criado-pelo-unshare)
cat /sys/fs/cgroup/cpu/nome-grupo/tasks
sudo cgset -r memory.limit_in_bytes=128M nome-grupo
sudo cgget -r memory.stat nome-grupo
cat /sys/fs/cgroup/memory/nome-grupo/memory.limit_in_bytes
sudo cgset -r cpu.cfs_periodo_us=100000 -r cpu.cfs_quota_us=$[ 10000 * 32] nome-grupo
stress --cpu 1 --vm-bytes 120M --VM 1
Com esses procedimentos executados você pode observar o funcionamento por debaixos dos panos do Docker, a criação de um container sem Docker, por meio da imagem minialista do Debian e o isolamento de processos com namespaces, cgroups, chroot, unshare e teste de stress do container puro criado.
Feito!
Nenhum comentário:
Postar um comentário