Docker implementado em cerca de 100 linhas de Bash, Bocker (2015)
(github.com/p8952)- Bocker é um projeto que implementa o Docker em cerca de 100 linhas de Bash, oferecendo um fluxo semelhante ao Docker para pull de imagens, run de contêineres, visualização de logs, commit e remoção
- Para executar, são necessários btrfs-progs, curl, iproute2, iptables, libcgroup-tools, util-linux 2.25.2 ou superior, e coreutils 7.5 ou superior, além de uma configuração com sistema de arquivos btrfs sob
/var/bockere redebridge0 - O exemplo no README mostra o fluxo de fazer pull da imagem
centos:7, executar comandos em um contêiner e fazer commit do resultado deyum install -y wgetpara depois verificar/usr/bin/wgetem execuções posteriores - O Bocker é executado como root e altera interfaces de rede, tabela de roteamento e regras de firewall, por isso é recomendado executá-lo em uma máquina virtual, sem garantia contra possíveis danos ao sistema
- Atualmente implementa
docker pull,images,ps,run,exec,logs,commit,rm/rmi, rede e cotas baseadas em CGroups, mas ainda não implementa volumes de dados, contêineres de volume de dados e encaminhamento de portas
Objetivo e escopo do Bocker
- Bocker é um projeto que implementa o Docker em cerca de 100 linhas de Bash
- O README mostra um fluxo de comandos semelhante ao Docker com base em Bash, incluindo recursos como gerenciamento de imagens, execução de contêineres, consulta de logs, commit de alterações e limitação de recursos
Requisitos de execução
- Os pacotes necessários para execução são os seguintes
-
btrfs-progs
- curl
- iproute2
- iptables
- libcgroup-tools
- util-linux 2.25.2 ou superior
- coreutils 7.5 ou superior
- Como a maioria das distribuições não inclui uma versão suficientemente nova do util-linux, pode ser necessário baixar o código-fonte do util-linux 2.25 e compilá-lo manualmente
- O sistema precisa da seguinte configuração
- sistema de arquivos btrfs montado em
/var/bocker - ponte de rede chamada
bridge0com IP10.0.0.1/24 - encaminhamento de IP ativado em
/proc/sys/net/ipv4/ip_forward - configuração de firewall que roteie o tráfego de
bridge0para a interface física - Um Vagrantfile está incluído para facilitar a criação do ambiente necessário
-
Cuidados ao executar
- Mesmo que os requisitos sejam atendidos, recomenda-se executar o Bocker em uma máquina virtual
- O Bocker é executado como root e precisa alterar os seguintes itens
- interfaces de rede
- tabela de roteamento
- regras de firewall
- O README declara explicitamente que não pode garantir que o Bocker não danificará o sistema
Fluxo de uso de exemplo
- Com
bocker pull centos 7, a imagemcentos:7é baixada e um ID de imagem comoimg_42150é gerado bocker imagesmostra o ID da imagem e a origem- Exemplo de saída:
img_42150,centos:7
- Exemplo de saída:
bocker run img_42150 cat /etc/centos-releaseimprime as informações de release do CentOS dentro do contêiner- Exemplo de saída:
CentOS Linux release 7.1.1503 (Core)
- Exemplo de saída:
bocker psmostra os IDs dos contêineres em execução e os comandosbocker logs ps_42045mostra os logs de saída desse contêinerbocker rm ps_42045remove o contêiner- Ao executar
bocker run img_42150 which wget, no início o resultado indica quewgetnão existe - Após instalar
wgetcombocker run img_42150 yum install -y wget, usa-sebocker commit ps_42018 img_42150para refletir as alterações na imagem - Depois disso,
bocker run img_42150 which wgetimprime/usr/bin/wget
Limitação de recursos e CGroups
- O exemplo de execução do Bocker mostra que os contêineres são colocados sob CGroups
- Em
/proc/1/cgroupaparecem entradas comomemory:/ps_42152ecpuacct,cpu:/ps_42152
- Em
- Os exemplos padrão de CPU share e limite de memória são os seguintes
/sys/fs/cgroup/cpu/ps_42152/cpu.shares:512/sys/fs/cgroup/memory/ps_42152/memory.limit_in_bytes:512000000
- É possível alterar os limites de recursos com variáveis de ambiente
BOCKER_CPU_SHARE=1024BOCKER_MEM_LIMIT=1024
- Após a alteração, o exemplo mostra os seguintes valores
- CPU shares:
1024 - memory limit:
1024000000
- CPU shares:
Recursos implementados e não implementados
- Os recursos atualmente implementados são os seguintes
docker build†docker pulldocker imagesdocker psdocker rundocker execdocker logsdocker commitdocker rm/docker rmi-
Rede
- Suporte a cotas / CGroups
- †
bocker initfornece uma implementação muito limitada dedocker build - Os recursos ainda não implementados são os seguintes
- Contêineres de volume de dados
- Volumes de dados
- Encaminhamento de portas
Licença
- O Bocker é software livre que pode ser redistribuído e modificado sob os termos da GNU General Public License
- A versão da licença pode ser a GPL v3 publicada pela Free Software Foundation ou qualquer versão posterior
- O programa é distribuído na expectativa de ser útil, mas sem qualquer garantia implícita, inclusive de comercialização ou adequação a um propósito específico
1 comentários
Opiniões no Hacker News
Já fiz algo parecido com proot, chamado Bag [1], e provavelmente eu não o teria descrito como uma alternativa ao Docker.
Não tinha relação com cgroups, e a interface de linha de comando também era diferente da do Docker. O contexto era que eu tinha criado uma cadeia de proxies que parecia tráfego HTML comum para contornar censura na internet e inspeção profunda de pacotes, e precisava mantê-la rodando em qualquer lugar, mas não queria portá-la para um app nativo de Android.
Eu queria rodar isso no Termux, mas na época o Termux não tinha JDK/JRE; ao subir um ambiente Arch Linux com proot, dava para usar o JDK. O ambiente Arch dentro do Termux era, no geral, mais útil, e também era fácil automatizar por script a criação e remoção de ambientes descartáveis com configurações diferentes, entrando neles via proot só para executar um único comando. Por isso dei o nome bag.sh, no sentido de ser uma forma muito menor que um contêiner de transporte.
Curiosamente, o bag.sh ainda tem um roadmap/TODO que não é mexido há 5 anos. Como foi escrito em uma tela de celular, a maior parte está alinhada em 40 colunas para dar para ver sem rolar.
[1]: https://github.com/hkoosha/bag
Criei um pequeno Debian dentro de /opt, com o software necessário e dependências como MySQL, e funcionava muito bem; foi usado até a empresa para a qual fiz isso ser adquirida, por volta de 2016. De modo mais geral, acho que implementar por conta própria uma versão tosca de uma aplicação grande é uma das melhores formas de aprender como ela funciona por dentro.
mkdir -p $(dirname "$2")Combinado com um teclado Bluetooth de cerca de 10 polegadas que cabe confortavelmente no bolso interno de uma jaqueta de couro, dá para sair de casa sem bolsa e ainda sentar num canto de um biergarten por perto para escrever código. É até surpreendentemente produtivo; talvez porque haja um pouco mais de atrito para alternar para as distrações habituais do que em um notebook, você acaba tomando um gole de cerveja e continuando a encarar o código.
Gosto desse tipo de coisa. Sempre gostei de coisas feitas com o mínimo de Bash.
Há também uma prova de conceito de balanceador de carga interno de cluster em 40 linhas de Bash, feita em um hackathon que organizei há cerca de 10 anos para divulgar infra distribuída como Docker e Mesos: https://github.com/cell-os/metal-cell/blob/master/discovery/...
Provavelmente perdi, mas também havia uma ferramenta de transferência colo-to-cloud baseada em túneis SSH reversos, com redundância e distribuição. O Shell Fu e afins organizam bem esse tipo de coleção: https://www.shell-fu.org/
O fato de ser possível reimplementar de forma tão simples uma grande parte do Docker é o maior problema que a Docker, como empresa, enfrentou e ainda enfrenta. Fundamentalmente, ele está mais para código de cola costurando recursos do kernel.
Onde a Docker realmente agrega valor não é só no Docker Hub, mas no Docker for Windows e Mac. O grande ponto é que a experiência integrada é muito melhor do que mexer diretamente com VirtualBox e Vagrant para rodar Docker na máquina de desenvolvimento.
Pessoalmente, acho que a verdadeira mágica do Docker foi o formato de imagem Docker/OCI. É uma forma excelente de lidar com cache e distribuição de imagens de contêiner, e ainda é o ponto central que diferencia o workflow de uma VM “completa”.
No Windows, dá para usar Docker no WSL, e funciona muito bem. É difícil entender por que alguém usaria Docker Desktop.
Em vez disso, criou o Docker Swarm, que era meia-boca e não funcionava de forma realmente confiável, e foi rapidamente superado pelo Kubernetes.
A forma como eu usei foi só para pegar o ambiente de build virtual de alguém para compilar software, alguns anos atrás.
Há frases no repositório como “ainda não implementado”, “TODO”, “em andamento”, e é bom ver que o último commit foi há vários anos
Fico um pouco mais tranquilo por não voltar para rever os TODOs que espalhei pelo meu código. Não quero desmerecer o autor; é só reconfortante
Se em código não remunerado, voluntário ou de hobby você sente o peso de ter que fazer só porque está público, programar fica menos divertido, e você pode acabar não publicando código que originalmente publicaria
Se sempre existe uma próxima ideia, por definição sempre vão sobrar TODOs não concluídos. Na verdade, esse deveria ser o estado normal de todo projeto
É totalmente aceitável, e muitas vezes útil, definir claramente os limites do escopo. Assim você não fica perseguindo desvios e com a sensação de que o projeto nunca está “pronto”
Surpreende que o lazydocker ainda não tenha sido mencionado como uma ótima alternativa ao Docker Desktop. Dá para usar em Linux/macOS/Windows [1]
É uma UI de terminal bem rica em recursos, e ainda tem a vantagem de poder ser executada via SSH
[1] https://github.com/jesseduffield/lazydocker
Pelo menos eu nunca tinha visto isso. Também fico curioso se esse tipo de anúncio é permitido pelos termos de serviço ou pela política de uso aceitável do GitHub
Fico me perguntando por que o Bocker aparece com tanta frequência na primeira página. Em 2024, Docker ainda é tão controverso assim?
Não entendo por que não reconhecem que o Docker trouxe algo realmente útil, principalmente distribuição de software e “rodar facilmente em qualquer lugar”
Docker é uma combinação de tecnologias de kernel que já existiam. Namespaces, cgroups, sistemas de arquivos union e provavelmente mais algumas coisas
Por isso é interessante e, na prática, uma história perfeita no estilo HN
Só depois de demonstrar para algumas pessoas percebi que eles poderiam simplesmente usar
/, ou que eu poderia ter lhes dado DockerComo uma espécie de irmão de outra mãe, existe https://bastillebsd.org/
O Bastille usa muitas estruturas que você esperaria ver no Docker, em shell, para gerenciar jails do FreeBSD. Ele tem pouquíssimas dependências, por isso gosto mais dele do que de outros softwares de gerenciamento de jail no BSD
Ainda assim, mesmo sendo uma ferramenta baseada em CLI/TUI, é uma solução próxima do “excesso máximo”. Ultimamente estou passando pelas etapas de criar e gerenciar jails só com a configuração padrão do FreeBSD, mas isso é apenas uma fase temporária
Vou fazer isso só até ter gravado o suficiente na cabeça como tudo se encaixa para me sentir confiante ao depurar; depois, como uma pessoa sensata, pretendo parar de bater pedras umas nas outras e voltar para ferramentas de nível mais alto
Mas levei um tempo para entender por que o nome é Bastille. La Bastille era uma fortaleza construída para defender Paris de ataques ingleses durante a Guerra dos Cem Anos e depois foi transformada em prisão
É preciso ter cuidado com a parte que diz “a maioria das distribuições não fornece uma versão suficientemente recente do util-linux, então você terá que pegar o código-fonte daqui e compilar por conta própria”
Como o prefixo de instalação padrão é
/usr/bin, o processo de instalação pode sobrescrever o comando mount existente por uma versão que exige bibliotecas inexistentes. Então, na próxima inicialização, o kernel montará o sistema de arquivos como somente leitura/usr/local/binNão é bom para uso cotidiano, mas dá uma noção do que é o Docker e de como ele funciona
No Linux, o Docker é basicamente um chroot sofisticado
Curiosidade: o Docker começou em Bash, depois migrou para Python e, por fim, se estabeleceu em Go
Além disso, em um meetup do Docker em 2013, alguém escreveu um clone do Docker em Bash. As pessoas querem aprender, e espero que coisas como esta ajudem