Cómo instalé Ubuntu Server 20.04 sin ISOs y con muy poca RAM

Ayer, jueves 23 de abril de 2020 se ha lanzado la nueva versión de Ubuntu 20.04 LTS. Yo estaba esperando esta versión por varias cosas:

  • Soporte de 5 años (el soporte de versiones anteriores es de 3)
  • Módulo Wireguard integrado en el kernel 5.4 y también con soporte oficial
  • Livepatch para todo lo anterior

Se ve muy bien para instalar en una máquina virtual donde el uptime sea importante, y había agendado instalar esa versión en un VPS importante. Como su tarea básicamente es enrutar paquetes, lo compré con un buen ancho de banda asignado y con poca RAM (512 MB) para ahorrar dinero. Luego de hacer una copia de seguridad a las cosas importantes y montar la ISO de Ubuntu Server, llegué a este kernel panic:

Analizando el mensaje de error, podemos ver que el init no pudo ejecutarse (error code 2 = ENOENT = no existe el archivo). Los mensajes arriba muestran que el initramfs (mini sistema de archivos comprimido que se descomprime en la RAM para luego ser ejecutado) no pudo descomprimirse. El error más común es grabar mal un disco (devolvería algo como I/O error), pero como estoy usando un ISO con sha256sum verificado, me hace estar más atento al error final: «Write error».

La instalación de Ubuntu Server ahora es más «live»: se ha dejado de utilizar por completo debian-installer para dar paso a Subiquiti, su nuevo instalador. Quizás el problema sea en la memoria RAM, y resultó que sí.

Asi que nos toca instalar el sistema operativo de otra manera.

Revisando el entorno

Usé btrfs como el sistema de archivos de la raíz para aprovechar la compresión transparente con compress=zstd. Esto nos ayudará: btrfs soporta subvolúmenes y con eso podemos trabajar sin necesidad de particionar.

El entorno original es Ubuntu 18.04: ya que no necesitaremos particionar, podemos usar el mismo entorno Linux para levantar otro.

Instalando

Necesitamos una «partición»

Sin preveer nada, yo instalé el viejo Ubuntu en la raíz de la partición btrfs. Necesitaré un nuevo subvolumen:

sudo btrfs sub create /ubuntu2004

Esta operación crea el subvolumen ubuntu2004 al inicio del montaje actual (/) y podré usarlo como si fuera una partición independiente, ahorrándome muchas horas en particionar o hacer copias. Cabe aclarar que yo usé el instalador oficial antiguo, y eso me da certeza que mi / no está ya en un subvolumen (si eso sucede no es malo de por sí, solo que no quedaría bien organizado).

Ahora montaré mi subvolumen en una carpeta cualquiera:

sudo mount -o compress=zstd,subvol=ubuntu2004 /dev/vda3 /mnt2

Instalamos Ubuntu

La utilidad debootstrap nos permite desplegar una distribución GNU/Linux basada en Debian usando solo los paquetes de los repositorios: una solución segura y elegante.

sudo debootstrap --arch amd64 focal /mnt2 http://us.archive.ubuntu.com/ubuntu

Luego de que haya terminado, ingresaré a esa nueva instalación.

sudo mount --bind /dev /mnt2/dev
sudo mount --bind /proc /mnt2/proc
sudo mount --bind /sys /mnt2/sys
sudo chroot /mnt2

Tenemos ya acceso a una instalación funcional, pero a un estilo contenedor. Necesitamos más paquetes para que esta instalación pueda funcionar por sí sola:

apt install linux-image-generic grub-pc ssh nano

Ahora configuramos la red:

nano /etc/netplan/10-internet.yaml

network:
  version: 2
  renderer: networkd
  ethernets:
    ens3:
      dhcp4: no
      addresses:
        - x.x.x.x/24
        - "y:y:y:y::y/60"
      gateway4: x.x.x.x
      gateway6: "x:x:x::x"
      nameservers:
        addresses: [x.x.x.x, y.y.y.y]

El nombre del host ya debería estar en /etc/hostname. Puedes cambiarlo si quieres.

Luego, agregué el hostname en /etc/hosts para mantener al comando sudo al tanto:

echo "127.0.1.1 $(hostname)" > /etc/hosts

Adapto la configuración regional para activar es_BO.UTF-8 y mi zona horaria:

dpkg-reconfigure locales
timedatectl set-timezone America/La_Paz

Necesito que la instalación se acuerde de su partición raíz:

nano /etc/fstab

UUID=6b02ed42-d91f-48a5-85af-d3d5cba35be7       /       btrfs   rw,compress=zstd,subvol=ubuntu2004      0     2

Y, finalmente, necesito agregar un usuario y adicionarlo a grupos relevantes. El grupo sudo me da poderes de superusuario y systemd-journal me da acceso al registro completo de sucesos del sistema.

adduser elusuario
adduser elusuario sudo
adduser elusuario systemd-journal

Antes de reiniciar, me aseguro de que el sistema es arrancable:

update-grub
grub-install --recheck /dev/vda

Y eso es todo. Ya tengo una instalación rápida y limpia de Ubuntu 20.04 sin utilizar la ISO, ni reparticionar, ni nada.

Algunos comentarios

Yo había utilizado dos particiones: una ext4 para /boot y otra btrfs para el /: la versión de grub que venía en Ubuntu 18.04 no soportaba compresión zstd, y el sistema quedaba sin poder arrancar, a menos que ponga el kernel y otras cosas importantes en ext4. Ahora Ubuntu 20.04 viene con grub 2.04, que sí tiene soporte y me permite tener todo en un solo subvolumen.

Ah, sí, ahora update-grub (o bueno, grub-mkconfig y os-prober) ya reconoce instalaciones distintas de GNU/Linux separadas en subvolúmenes, lo cual nos ahorra mucho trabajo en configurarlo.