Eu já passei do tempo de comentar sobre esse assunto aqui, então hoje vou aproveitar que perguntaram sobre esse tema e escrever o que tenho feito.
Primeiro eu preciso explicar mais sobre meu dia à dia no trabalho. O que faço é compilar código em Go, criar e configurar helm charts e gerar containers. Pra isso temos um containers base de desenvolvimento que criamos baseado em Ubuntu 20.04 (e que precisamos atualizar pro 22.04 algum dia). Com o brew eu instalei todas as ferramentas que preciso e uso como o próprio compilador Go, fish shell, Python, git, kubectl, helm, etc. A única coisa foi que precisei alterar o meu PATH pra ler do brew ao invés do PATH normal. Então eu tenho algo como:
if [ "$OperatingSystem" = "Darwin" ]
set -gx PATH /opt/homebrew/bin /opt/homebrew/sbin $PATH $HOME/bin $HOME/.local/bin $HOME/go/bin
end
nas minhas configurações do fish.
Um dos motivos de forçar isso é que o bash que vem no Apple é uma versão muito velha. Então é melhor rodar a versão mais recente através do brew. E descobri que alguns scripts dava problemas com... getopts. Sim, o programa que usamos pra ler opções de scripts. Até isso precisei usar o que vem do brew. Aparentemente o Apple tem um getopt que é BSD e não funciona com as configurações da GNU. Mas seu script não sabe disso. Então tive de forçar a precedência dos binários do brew.
$ which -a bash
/opt/homebrew/bin/bash
/opt/homebrew/bin/bash
/bin/bash
$ /opt/homebrew/bin/bash --version
GNU bash, version 5.2.2(1)-release (aarch64-apple-darwin21.6.0)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin21)
Copyright (C) 2007 Free Software Foundation, Inc.
$ which -a getopt
/opt/homebrew/bin/getopt
/opt/homebrew/bin/getopt
/usr/bin/getopt
$ /opt/homebrew/bin/getopt --version
getopt from util-linux 2.38.1
$ /usr/bin/getopt --version
--
Além disso precisei mudar quase todos os shebangs dos shell scripts pra #! /usr/bin/env bash pra evitar rodar com o bash do sistema.
E como bom usuário de Linux eu não uso nada que tenha de pagar. Nem na loja da Apple eu registrei. Aliás criei um login e entrei pra baixar o skitch pra usar de screenshot saver como usava o flameshot, já que o que vem com o sistema é miserável o uso. Mas o restante eu instalo tudo via brew. E assim instalei o UTM, que na loja da Apple é pago mas via brew é só instalar e usar.
Por baixo do UTM roda tudo em qemu. Mas ele tem uma interface bacana de gerenciamento.
Eu instalei um Ubuntu 20.04 x86_64, chamado de amd64 (e guarde esse nome), e armv8, chamado de aarch64 ou arm64. Eu uso mais a versão pra ARM porque essa roda via VM usando a CPU nativa e é bem rápida, enquanto o x86_64 é via emulação e é bastante lento, além de ter problemas na emulação de tempos em tempos.
Nesse Linux eu instalei um pacote recente do qemu estático pra poder rodar o Docker multiplataforma.
# Latest qemu for docker/bob
RUN curl -OL http://ports.ubuntu.com/ubuntu-ports/pool/universe/q/qemu/qemu-user-static_6.2+dfsg-2ubuntu6.4_arm64.deb \
&& dpkg -i qemu-user-static_6.2+dfsg-2ubuntu6.4_arm64.deb \
&& rm qemu-user-static_6.2+dfsg-2ubuntu6.4_arm64.deb
Como são binários estáticos, você pode pegar qualquer pacote, inclusive do Debian mesmo, e instalar. A versão que vem com o Ubuntu dá um crash no kernel do Apple e reboot o laptop, então pegue essa última versão e tenha certeza de ter aplicado os últimos patches de seguranças do Macos.
Agora começa o balaio de gato de plataformas. O pacote, como pode ser visto acima, é chamado "arm64". Mas se eu entro no meu terminal no Apple, o que tenho é isso:
$ uname -m
x86_64
$ uname -a
Darwin EMB-QG9ND6H2 21.6.0 Darwin Kernel Version 21.6.0: Mon Aug 22 20:19:52 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T6000 x86_64
e dentro da VM rodando Linux/arm64:
$ uname -m
aarch64
$ uname -a
Linux ubuntu-2004 5.4.0-128-generic #144-Ubuntu SMP Tue Sep 20 11:03:09 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
então já começa o balaio de gato aí. O Apple acha que ele é um x86_64, o que não é verdade. Linux diz que é aarch64, mas os pacotes referem-se à arm64.
E pra fazer containers x86_64?
Pra fazer isso você entra na configuração do Docker e adiciona a seguinte linha:
"experimental": "enabled"
isso habilite o build em múltiplas plataformas. Ou chamar o container de outras plataformas.
Então pra fazer um build x86_64 você usa algo como:
$ docker build --platform=linux/amd64 .
e um exemplo baixando um container baseado em alpine e usando:
$ docker pull --platform=linux/amd64 quay.io/aptible/alpine
Using default tag: latest
latest: Pulling from aptible/alpine
207e252fc310: Pull complete
8a9527e58fed: Pull complete
cdb7f38bc74b: Pull complete
3eb2d0c301f8: Pull complete
Digest: sha256:9790231800450f0e5fb93c03aecd22de0d5d43ae9898aa713350bdbeb9bd1e70
Status: Downloaded newer image for quay.io/aptible/alpine:latest
quay.io/aptible/alpine:latest
$ docker run --rm --platform=linux/amd64 quay.io/aptible/alpine uname -a
Linux 249590268d5c 5.4.0-128-generic #144-Ubuntu SMP Tue Sep 20 11:03:09 UTC 2022 x86_64 Linux
E pronto. Lembram que escrevi acima sobre a bagunça de nomenclaturas e que o amd64 era usado em algum momento? Pois olha ele aí.
Mas nem tudo são flores. Descobri alguns problemas quando parte do nosso build usa ferramentas feitas em... Java! Ou o container trava (e por sua vez a instância do qemu rodando) ou gera um core dump.
O erro é o mesmo descrito aqui:
https://github.com/adoptium/temurin-build/issues/893
mas eu acho que o bug não do openjdk ou do jdk, porque testei também com o jdk da própria Oracle, mas da emulação do qemu.
One container to rule them all
Isso foi no começo da minha aventura. Depois de um tempo eu vi um vídeo sobre o Rancher Desktop e resolvi testar. Primeiro que tive de configurar pra usar Docker nativo.
Pra rodar o rancher corretamente eu precisei solicitar acesso root à máquina via sudo, que não é dado por padrão e é preciso solicitar. Mas após isso, roda a partir do próprio macos sem precisar da VM.
$ docker pull --platform=linux/amd64 quay.io/aptible/alpine
Using default tag: latest
latest: Pulling from aptible/alpine
207e252fc310: Pull complete
8a9527e58fed: Pull complete
cdb7f38bc74b: Pull complete
3eb2d0c301f8: Pull complete
Digest: sha256:9790231800450f0e5fb93c03aecd22de0d5d43ae9898aa713350bdbeb9bd1e70
Status: Downloaded newer image for quay.io/aptible/alpine:latest
quay.io/aptible/alpine:latest
$ docker run --rm --platform=linux/amd64 quay.io/aptible/alpine uname -a
Linux 1a7f8e55ce09 5.15.57-0-virt #1-Alpine SMP Fri, 29 Jul 2022 07:15:20 +0000 x86_64 Linux
mas sofre do mesmo problema que o UTM em relação ao Java. No momento eu tenho usado mais a VM no UTM por ser um pouco mais rápida que o container no Rancher Desktop/Docker. E o que faço é trabalhar no Macos, geralmente usando VSCode da Microsoft mesmo, e mandando um git push pro meu repo na VM. E lá rodando testes.
Não é um workflow muito prático, mas pra mim tem funcionado bem.