Descrição
Como um projeto paralelo, estou tentando usar o Hashicorp Packer junto com o Docker para criar imagens de disco inicializáveis a partir de contêineres do Docker.
Hashicorp Packer geralmente assume a responsabilidade de trazer os containers docker para cima e executar tarefas dentro deles e então criar tarballs do sistema de arquivos ou usar containers para criar arquivos de imagem etc.
Como funciona
Eu uso um
ubuntu:focal
contêiner dockeruse este contêiner docker e instale um Kernel / Systemd nele:
apt-get update && apt-get install -y --no-install-recommends linux-image-virtual systemd-sysv
Crie um tarball do contêiner que agora contém o kernel, initrd e sistema da etapa 2
descompacte o tarball na máquina host para poder usá-lo ao criar um arquivo de imagem
Ative outro
ubuntu
contêiner com privilégios e monte o diretório de trabalho nele para criar o arquivo de imagem inicializável.
Neste ponto, estou contando com um script bash abaixo para criar uma imagem para mim:
set -e
echo "[Install APT dependencies]"
DEBIAN_FRONTEND=noninteractive apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y extlinux fdisk qemu-utils
echo "[Create disk image of 1GB]"
dd if=/dev/zero of=/os/${DISTR}.img bs=$(expr 1024 \* 1024 \* 1024) count=1
blue "[Make partition]"
sfdisk /os/${DISTR}.img < /os/config/partition.txt
echo "\n[Format partition with ext4]"
losetup -D
LOOPDEVICE=$(losetup -f)
echo -e "\n[Using ${LOOPDEVICE} loop device]"
losetup -o $(expr 512 \* 2048) ${LOOPDEVICE} /os/${DISTR}.img
mkfs.ext4 ${LOOPDEVICE}
echo "[Copy ${DISTR} directory structure to partition]"
mkdir -p /os/mnt
mount -t auto ${LOOPDEVICE} /os/mnt/
cp -R /os/${DISTR}.dir/. /os/mnt/
echo "[Setup extlinux]"
extlinux --install /os/mnt/boot/
cp /os/config/syslinux.cfg /os/mnt/boot/syslinux.cfg
echo "[Unmount]"
umount /os/mnt
losetup -D
echo_blue "[Write syslinux MBR]"
dd if=/usr/lib/syslinux/mbr/mbr.bin of=/os/${DISTR}.img bs=440 count=1 conv=notrunc
O DISTR
no script acima é ubuntu
e o ubuntu.dir
é o tarball descompactado que é montado no contêiner para poder copiá-lo para a partição montada.
Progresso
Atualmente tenho tido sucesso na criação de tais imagens para ubuntu
. O repositório criado pode ser encontrado aqui
No entanto, ao tentar inicializar a imagem usando qemu-system-x86_64
:
sudo qemu-system-x86_64 -drive file=ubuntu.img,index=0,media=disk,format=raw
O respectivo syslinux.cfg
para o bootloader é:
DEFAULT linux
SAY Now booting the kernel from SYSLINUX...
LABEL linux
KERNEL /boot/vmlinuz
INITRD /boot/initrd.img-5.4.0-125-generic
APPEND ro root=/dev/sda1
Alterações adicionais
Eu tentei atualizar o syslinux.cfg
para
DEFAULT linux
SAY Now booting the kernel from SYSLINUX...
LABEL linux
KERNEL /boot/vmlinuz
APPEND ro root=/dev/sda1 initrd=/boot/initrd.img
no entanto recebo o mesmo erro, embora /boot/initrd.img
não seja encontrado é a mensagem de erro.
O que estou faltando no momento para tornar o initrd.img
detectável para o bootloader.
Eu tentei usar cp -dR /os/ubuntu.dir/. /os/mnt
o script bash para garantir que os links simbólicos sejam preservados durante a cópia.
Eu também me certifiquei de ver se o initrd.img
arquivo de link simbólico existe na partição montada /os/mnt/boot
que existe e também a fonte do arquivo de link simbólico, por exemploreadlink -f /os/mnt/boot/initrd.img
Fontes
iximiuz blogpost em dispositivos docker-to-bootable PockerISO
Descobri a solução para o problema. Foi o fato de que embora eu estivesse instalando o kernel linux via
Não foi possível gerar o
initrd
que geralmente acontece quando deixo os pacotes completos recomendados serem instalados.Consegui resolver esse problema simplesmente
e sou capaz de criar imagens inicializáveis para Ubuntu e Debian