/srv/tramontana/backups lleva semanas creciendo. Cada madrugada, a las 4:20, respaldo_tramontana.sh deja allí una copia nueva sin que nadie haya calculado cuánto cabe, y el disco raíz de 23 GB va por el 30 %. La pregunta no es si se llenará, sino cuándo — y qué pasará con la aplicación cuando ocurra, porque un / lleno no es «va lento»: es una máquina que no puede ni escribir un log ni completar una transacción. En esta lección bajas por fin al hardware: verás la pila completa desde el disco físico hasta el punto de montaje, particionarás, formatearás, entenderás /etc/fstab campo a campo (y por qué una línea mal escrita impide arrancar), y montarás LVM, que es lo que un servidor de verdad usa. Al final, /srv/tramontana/backups vivirá en su propio volumen lógico ampliable en caliente.
Contenido
- La pila de almacenamiento, de arriba abajo
- Identificar el hardware:
lsblk,blkid,fdisk -l - Tablas de particiones: MBR frente a GPT
- Particionar con
fdiskyparted - Sistemas de ficheros comparados, e inodos revisitados
- Montar:
mount, opciones, bind yfindmnt /etc/fstabcampo a campo y la red de seguridad- Espacio:
df,du, y el fichero borrado que no lo libera - Swap: partición, fichero y cuánta hace falta
- LVM: PV, VG, LV, ampliar en caliente y snapshots
- RAID por software con
mdadm - Cuotas de disco
- Caso Tramontana: un disco nuevo para las copias
- La pila de almacenamiento, de arriba abajo
Entre el plato (o la celda NAND) y el cat fichero.txt que escribes hay cinco o seis capas. Confundirlas es la causa del 90 % de los errores de almacenamiento.
flowchart TD
D["Disco físico<br/>/dev/sdb — 20 GiB"] --> T["Tabla de particiones GPT"]
T --> P1["Partición /dev/sdb1"]
P1 --> PV["PV — pvcreate"]
PV --> VG["VG vg-datos<br/>agrupa PVs, 5G libres"]
VG --> LV1["LV lv-backups 15G"]
LV1 --> FS["Sistema de ficheros<br/>mkfs.ext4 — UUID"]
FS --> M["Punto de montaje<br/>/srv/tramontana/backups"]
Las capas de LVM son opcionales —sin ellas la partición se formatea directamente—, pero resuelven el peor problema de todos: una partición no se puede ampliar si el espacio libre no está justo detrás; un volumen lógico sí, aunque el espacio esté en otro disco.
- Identificar el hardware:
lsblk, blkid, fdisk -l
lsblk, blkid, fdisk -l$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 25G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 2G 0 part /boot
└─sda3 8:3 0 23G 0 part /
sdb 8:16 0 20G 0 disk # el disco nuevo, aún sin tabla de particiones
$ lsblk -f
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
sda3 ext4 raiz 3f0a91c4-8d2e-4b17-9c55-0a7ce31f77b2 14,8G 30% /
sdblsblk -f es el comando que más veces usarás: dice el tipo de sistema de ficheros, la etiqueta, el UUID y el uso real.
$ sudo blkid /dev/sda3
/dev/sda3: LABEL="raiz" UUID="3f0a91c4-8d2e-..." TYPE="ext4" PARTUUID="a1b2c3d4-03"
$ sudo fdisk -l /dev/sda | sed -n '1,2p;5p'
Disco /dev/sda: 25 GiB, 26843545600 bytes, 52428800 sectores
Tipo de etiqueta de disco: gpt| Prefijo | Qué es | Dónde aparece |
|---|---|---|
/dev/sda, sdb… |
SATA, SAS, USB y la mayoría de los virtuales | VirtualBox, físicos |
/dev/nvme0n1 (particiones p1) |
SSD NVMe | Servidores y portátiles modernos |
/dev/vda |
Disco paravirtualizado virtio | KVM, cloud (AWS, OpenStack) |
Y el detalle crítico: estos nombres pueden cambiar entre arranques. Basta con añadir un disco, cambiar el orden de los controladores o que el kernel detecte los dispositivos en otro orden para que el sdb de hoy sea el sdc de mañana. Por eso jamás se monta por nombre de dispositivo en fstab: se monta por UUID o por LABEL, que viajan dentro del propio sistema de ficheros.
- Tablas de particiones: MBR frente a GPT
| Aspecto | MBR (msdos) | GPT |
|---|---|---|
| Antigüedad | 1983 | 2000, parte de UEFI |
| Tamaño máximo de disco | 2 TiB | 8 ZiB (sin límite práctico) |
| Número de particiones | 4 primarias (o 3 + extendida) | 128 por defecto |
| Redundancia e integridad | Ninguna: un sector dañado y adiós | Copia al final del disco y CRC32 |
| Arranque | BIOS heredada | UEFI (y BIOS con partición bios_grub) |
Para cualquier disco nuevo hoy: GPT, sin excepciones que merezcan discusión. La partición de 1 MiB que ves en sda1 es precisamente la bios_grub que GRUB necesita en un GPT arrancado por BIOS heredada; su papel se explica en 07-01.
- Particionar con
fdisk y parted
fdisk y partedfdisk es interactivo y cómodo; parted admite órdenes en una línea, lo que lo hace apto para scripts. Preparamos /dev/sdb con una única partición que ocupe el disco entero:
$ sudo parted -s /dev/sdb mklabel gpt
$ sudo parted -s /dev/sdb mkpart datos 1MiB 100%
$ sudo parted -s /dev/sdb set 1 lvm on
$ sudo parted -s /dev/sdb print | tail -3
Tabla de particiones: gpt
Numero Inicio Fin Tamaño Nombre Banderas
1 1049kB 21,5GB 21,5GB datos lvmEl 1MiB de inicio no es capricho: alinea la partición con los bloques físicos y evita una penalización de rendimiento notable en SSD y en cabinas.
En fdisk la sesión equivalente sería g (crear GPT), n (nueva partición), Intro tres veces, t y 31 (tipo Linux LVM) y w para escribir. Nada se escribe hasta la w: q te saca sin tocar nada, y esa es la red de seguridad de fdisk.
Si el kernel no se entera de la nueva tabla —típico cuando el disco tiene alguna partición montada—, sudo partprobe /dev/sdb la relee, y lsblk /dev/sdb confirma que aparece sdb1.
- Sistemas de ficheros comparados, e inodos revisitados
| FS | Madurez | Ampliar / Reducir | Snapshots | Cuándo elegirlo |
|---|---|---|---|---|
| ext4 | Máxima; por defecto en Ubuntu | Sí / sí, desmontado | No (los da LVM) | La opción segura para casi todo |
| XFS | Muy alta; por defecto en RHEL | En caliente / no | No | Ficheros grandes, escritura paralela |
| Btrfs | Estable en usos comunes | Sí / sí | Sí, nativos | Instantáneas frecuentes, checksums |
| ZFS | Muy alta, integrado en Ubuntu | Sí / según diseño | Sí, y envío/recepción | RAID + FS unificados; exige RAM |
Regla práctica para un servidor Ubuntu convencional: ext4 sobre LVM. Tienes redimensionado, snapshots (los del LVM) y el sistema de ficheros más probado que existe.
$ sudo mkfs.ext4 -L backups /dev/vg-datos/lv-backups
Creando sistema de ficheros con 3932160 bloques de 4k y 983040 nodos-i
UUID del sistema de ficheros: 9d4f2b70-6c1a-4e8b-b3f7-52a0c9e14d68
$ sudo tune2fs -l /dev/vg-datos/lv-backups | grep -E 'Volume name|Inode count'
Volume name: backups
Inode count: 983040tune2fs permite cambiar la etiqueta (-L), el intervalo de comprobación (-i) y, muy útil en un volumen de datos, el 5 % reservado para root: sudo tune2fs -m 1 /dev/vg-datos/lv-backups recupera unos 600 MiB en 15 GiB. Ese 5 % tiene sentido en / —evita que un disco lleno impida a root arreglar la situación—, pero en un volumen dedicado a copias es espacio tirado.
Inodos: el otro límite
En 02-06 viste que el inodo guarda los metadatos y que el nombre es solo una entrada de directorio. Aquí llega la consecuencia operativa: el número de inodos se fija al formatear y no crece. Un directorio con millones de ficheros diminutos puede agotarlos con el disco medio vacío, y el error es desconcertante:
$ df -h /srv/tramontana/backups | tail -1
/dev/mapper/vg--datos-lv--backups 15G 6,1G 8,2G 43% /srv/tramontana/backups
$ df -i /srv/tramontana/backups | tail -1
/dev/mapper/vg--datos-lv--backups 983040 983021 19 100% /srv/tramontana/backups43 % de espacio libre y No queda espacio en el dispositivo al crear un fichero. Ante ese error, df -i es la segunda comprobación obligatoria. La solución pasa por borrar ficheros pequeños o reformatear con más inodos (mkfs.ext4 -i 8192).
- Montar:
mount, opciones, bind y findmnt
mount, opciones, bind y findmntsudo mkdir -p /mnt/pruebas && sudo mount /dev/vg-datos/lv-backups /mnt/pruebas
sudo mount -o remount,ro /mnt/pruebas # cambiar opciones sin desmontar; umount para soltarSi umount responde «objetivo ocupado», retoma lsof y fuser de 03-06:
Alguien —tú, probablemente— tiene ahí su directorio de trabajo. umount -l (lazy) desmonta cuando se libere, pero es un parche.
| Opción | Qué hace | Cuándo usarla |
|---|---|---|
defaults |
rw,suid,dev,exec,auto,nouser,async |
Punto de partida |
noatime |
No actualiza la marca de último acceso | Siempre en servidores: ahorra escrituras |
nodev / nosuid |
Ignora ficheros de dispositivo / bits SUID | Cualquier volumen de datos: cierra la vía de 05-02 |
noexec / ro |
Prohíbe ejecutar binarios / solo lectura | Copias, /tmp, subidas; forense |
nofail |
El arranque continúa si falta el dispositivo | Todo disco que no sea / |
$ findmnt -no SOURCE,FSTYPE,OPTIONS /srv/tramontana/backups
/dev/mapper/vg--datos-lv--backups ext4 rw,noatime,nodev,nosuidfindmnt es infinitamente más legible que mount sin argumentos, y findmnt --verify valida el fstab sin montar nada. Un montaje bind (sudo mount --bind /srv/tramontana/backups/envios /opt/tramontana/salida) hace aparecer un directorio existente en otro punto del árbol sin copiar nada: es la forma limpia de exponer una carpeta a un servicio confinado, y en 05-05 verás que systemd hace lo mismo con BindPaths.
/etc/fstab campo a campo y la red de seguridad
/etc/fstab campo a campo y la red de seguridad# /etc/fstab
# <dispositivo> <punto> <tipo> <opciones> <dump> <fsck>
UUID=3f0a91c4-8d2e-4b17-9c55-0a7ce31f77b2 / ext4 defaults,noatime 0 1
UUID=b7e12a55-0c4d-4e39-8a61-3f9d2b70c1a8 /boot ext4 defaults,noatime 0 2
/dev/mapper/vg--datos-lv--backups /srv/tramontana/backups ext4 defaults,noatime,nodev,nosuid,nofail 0 2| Campo | Contenido | Notas |
|---|---|---|
| 1 | Dispositivo | UUID= o LABEL=, nunca /dev/sdb1 |
| 2 y 3 | Punto de montaje y tipo | El directorio debe existir; ext4, xfs, swap, auto |
| 4 | Opciones | Separadas por comas, sin espacios |
| 5 y 6 | dump y fsck |
El 5 es una reliquia (siempre 0); el 6 vale 1 para /, 2 para el resto y 0 para no comprobar |
Por qué un fstab mal escrito impide arrancar
En el arranque, systemd convierte cada línea de fstab en una unidad .mount y las hace dependencia de local-fs.target. Si un dispositivo no aparece, el arranque espera 90 segundos y luego cae a modo de emergencia pidiendo la contraseña de root — que en Ubuntu está bloqueada. Un servidor remoto en ese estado es un servidor perdido hasta que alguien abra la consola.
Por eso hay dos reglas innegociables:
sudo cp -a /etc/fstab /etc/fstab.bak-$(date +%F) # copia previa, como siempre
sudo vim /etc/fstab && sudo diff -u /etc/fstab.bak-$(date +%F) /etc/fstab
sudo findmnt --verify --verbose # validación sintáctica
sudo mount -a # montar TODO lo del fstab AHORAmount -a antes de reiniciar no es opcional. Si falla, lo arreglas con el servidor en pie; si no lo ejecutas, lo descubrirás con el servidor caído. Y añade nofail a todo lo que no sea /: convierte un fallo de arranque en un aviso en el log.
- Espacio:
df, du, y el fichero borrado que no lo libera
df, du, y el fichero borrado que no lo libera$ df -h --total | tail -1
total 25G 6,9G 17G 30%
$ sudo du -sh --max-depth=1 /srv/tramontana 2>/dev/null | sort -h
4,8G /srv/tramontana/backups
6,1G /srv/tramontanancdu hace lo mismo de forma interactiva y es lo que usarás cuando busques al culpable con prisa. Recuerda de 02-03 que du mide espacio ocupado en bloques y ls -l el tamaño lógico: no tienen por qué coincidir.
El clásico: df dice lleno, du dice vacío
Faltan gigas que nadie ve. La explicación conecta directamente con los inodos de 02-06: cuando borras un fichero que un proceso tiene abierto, desaparece el nombre del directorio, pero el inodo y sus bloques siguen vivos hasta que el último descriptor se cierre. Alguien hizo rm sobre un log gigante y el proceso sigue escribiendo en un fichero sin nombre.
$ sudo lsof +L1
COMMAND PID USER FD TYPE SIZE/OFF NLINK NODE NAME
tramonta 1284 svc-tramontana 3w REG 16106127360 0 262147 /var/log/tramontana/acceso.log (deleted)NLINK 0 y (deleted) son la firma del problema. Las dos salidas: reiniciar el proceso (systemctl restart, que veremos en 05-05) o, si no puedes, truncar el fichero por su descriptor con sudo truncate -s 0 /proc/1284/fd/3, que libera el espacio sin matarlo.
Y la lección de fondo: un log no se borra, se rota — que es exactamente lo que montaremos en 05-06.
- Swap: partición, fichero y cuánta hace falta
La swap es espacio de disco que el kernel usa para descargar páginas de memoria poco usadas. Hoy se prefiere un fichero de swap a una partición: se redimensiona sin tocar la tabla de particiones.
$ sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile
$ sudo mkswap /swapfile && sudo swapon /swapfile && swapon --show
NAME TYPE SIZE USED PRIO
/swapfile file 2G 0B -2Con su línea en fstab (/swapfile none swap sw 0 0). El chmod 600 es obligatorio: el contenido de la swap incluye trozos de memoria de procesos, y eso incluye secretos.
vm.swappiness (0–200, por defecto 60) decide cuánta prisa se da el kernel en usarla; bajarlo a 10 es lo habitual en un servidor de aplicación. El ajuste fino de este y otros parámetros del kernel es materia de 07-03. ¿Cuánta swap? Con 3,8 GB de RAM, entre 2 y 4 GB es razonable: no como sustituto de memoria —si el servidor swapea constantemente, va a ir muy lento igual—, sino como colchón que evita que el OOM killer mate la aplicación ante un pico puntual.
- LVM: PV, VG, LV, ampliar en caliente y snapshots
LVM introduce tres niveles: los PV (particiones o discos enteros entregados a LVM), el VG (una bolsa de espacio formada por uno o varios PV) y los LV (los «discos virtuales» que se formatean y montan). El VG se divide en extents de 4 MiB, y un LV es simplemente un conjunto de extents, que no tienen por qué ser contiguos ni estar en el mismo disco. De ahí viene todo el poder de LVM.
$ sudo pvcreate /dev/sdb1 && sudo vgcreate vg-datos /dev/sdb1
Physical volume "/dev/sdb1" successfully created.
Volume group "vg-datos" successfully created
$ sudo lvcreate -L 15G -n lv-backups vg-datos
Logical volume "lv-backups" created.
$ sudo vgs && sudo lvs
VG #PV #LV #SN Attr VSize VFree
vg-datos 1 1 0 wz--n- <20,00g <5,00g
LV VG Attr LSize
lv-backups vg-datos -wi-a----- 15,00gFíjate en que hemos dejado 5 GiB libres en el VG a propósito: son el margen para ampliar el volumen y, sobre todo, para poder crear un snapshot. Un VG al 100 % es un VG sin maniobra.
Ampliar en caliente, con el volumen montado y en uso:
$ sudo lvextend -L +3G -r /dev/vg-datos/lv-backups
Size of logical volume vg-datos/lv-backups changed from 15,00 GiB to 18,00 GiB.
El sistema de ficheros tiene ahora 4718592 bloques.La opción -r (--resizefs) es la clave: amplía el LV y el sistema de ficheros de encima en un solo paso. Sin ella tendrías un volumen mayor y un df idéntico, que es el error más frecuente de quien empieza con LVM. lvextend -l +100%FREE -r se come todo el espacio libre del VG.
Reducir es otra historia. Hay que hacerlo al revés (primero el sistema de ficheros, luego el LV), con el volumen desmontado, y XFS directamente no se puede reducir. Un error de orden aquí destruye datos. Regla: crea los LV pequeños y amplía cuando haga falta; nunca al revés.
Snapshots LVM
Un snapshot es un LV que guarda las diferencias respecto al original desde el instante de su creación. Se crea en segundos y permite copiar un volumen en un estado congelado y coherente mientras la aplicación sigue escribiendo:
$ sudo lvcreate -L 2G -s -n snap-pre-despliegue /dev/vg-datos/lv-backups
Logical volume "snap-pre-despliegue" created.
$ sudo mount -o ro /dev/vg-datos/snap-pre-despliegue /mnt/snapshot # copiar de aquí
$ sudo umount /mnt/snapshot && sudo lvremove -y /dev/vg-datos/snap-pre-despliegueDos advertencias imprescindibles: el snapshot se llena si el original cambia más de lo que su tamaño permite, y cuando se llena se invalida y se pierde. Y no es una copia de seguridad: vive en el mismo VG, en el mismo disco. Es una herramienta de consistencia, y así la usaremos en 05-08.
- RAID por software con
mdadm
mdadm| Nivel | Discos mín. | Capacidad útil | Tolera | Escritura |
|---|---|---|---|---|
| 0 (striping) | 2 | 100 % | Nada: un disco cae y se pierde todo | Muy rápida |
| 1 (espejo) | 2 | 50 % | 1 disco | Normal |
| 5 / 6 | 3 / 4 | n−1 / n−2 | 1 / 2 discos | Penalizada por la paridad |
| 10 (1+0) | 4 | 50 % | 1 por espejo | Rápida; la elección para bases de datos |
$ sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdc1 /dev/sdd1
mdadm: array /dev/md0 started.
$ cat /proc/mdstat | tail -1
20955136 blocks super 1.2 [2/2] [UU]
$ sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf && sudo update-initramfs -u[UU] significa los dos discos sanos; un [U_] es un disco caído y hay que actuar hoy, no la semana que viene. Sobre /dev/md0 se pone después un PV de LVM, y así se combinan redundancia y flexibilidad.
RAID no es una copia de seguridad. RAID protege de que un disco se rompa. No protege de un
rm -rf(se replica al instante en el espejo), ni de un cifrado por ransomware, ni de un fallo del controlador que corrompa ambos discos, ni de un incendio en la sala. La copia de seguridad es 05-08, y son cosas distintas y complementarias.
- Cuotas de disco
Cuando varios usuarios comparten un volumen, las cuotas limitan cuánto ocupa cada uno. Se activan con usrquota,grpquota en fstab, se inicializan con quotacheck -cug y se fijan con edquota -u usuario o sin interacción: sudo setquota -u luis 5G 6G 0 0 /srv/tramontana/backups (blando 5G, duro 6G), y sudo repquota -s /srv/tramontana/backups da el informe de uso. El límite blando puede superarse durante un periodo de gracia; el duro no se supera nunca. En un servidor de aplicación con un único usuario de servicio son poco útiles; en uno compartido son la diferencia entre un incidente y una llamada a las tres de la mañana.
- Caso Tramontana: un disco nuevo para las copias
Marta aprueba añadir un disco de 20 GiB a la VM. El objetivo: que /srv/tramontana/backups deje de competir por el espacio de /, sin perder ni un byte de las copias existentes y sin que respaldo_tramontana.sh se entere.
Paso 1 — Añadir el disco. Con la VM apagada, VirtualBox → Almacenamiento → disco de 20 GiB. Al arrancar, lsblk debe mostrar sdb sin particiones.
Paso 2 — Partición, PV, VG y LV: los comandos de los apartados 4 y 10, ya ejecutados. Resultado: vg-datos de 20 GiB con lv-backups de 15 GiB y 5 GiB de margen.
Paso 3 — Formatear y montar en un punto temporal.
sudo mkfs.ext4 -L backups /dev/vg-datos/lv-backups && sudo tune2fs -m 1 /dev/vg-datos/lv-backups
sudo mkdir -p /mnt/nuevo && sudo mount /dev/vg-datos/lv-backups /mnt/nuevoPaso 4 — Copiar preservándolo todo. rsync -aHAX no es lujo: -a conserva permisos y propietarios (el operador:tramontana de 05-01), -H los enlaces duros, -A las ACL de 05-02 y -X los atributos extendidos.
$ sudo rsync -aHAX --info=progress2 /srv/tramontana/backups/ /mnt/nuevo/
$ sudo diff -qr /srv/tramontana/backups /mnt/nuevo && echo "Contenido idéntico"
Contenido idéntico
$ sudo du -sh /srv/tramontana/backups /mnt/nuevo
4,8G /srv/tramontana/backups
4,8G /mnt/nuevo(Antes de copiar, comenta la línea de cron de la copia para que no entre una a media faena.)
Paso 5 — Intercambiar, con red de seguridad. No borramos el original: lo renombramos, y así el rollback es instantáneo. sudo umount /mnt/nuevo && sudo mv /srv/tramontana/backups /srv/tramontana/backups.viejo && sudo mkdir /srv/tramontana/backups.
Paso 6 — fstab, con las tres protecciones.
$ sudo cp -a /etc/fstab /etc/fstab.bak-$(date +%F)
$ echo "UUID=$(sudo blkid -s UUID -o value /dev/vg-datos/lv-backups) /srv/tramontana/backups ext4 defaults,noatime,nodev,nosuid,nofail 0 2" | sudo tee -a /etc/fstab
$ sudo diff -u /etc/fstab.bak-$(date +%F) /etc/fstab | tail -1
+UUID=9d4f2b70-... /srv/tramontana/backups ext4 defaults,noatime,nodev,nosuid,nofail 0 2
$ sudo mount -a && findmnt -no SOURCE,OPTIONS /srv/tramontana/backups
/dev/mapper/vg--datos-lv--backups rw,nosuid,nodev,noatimenosuid y nodev porque en un volumen de copias no debe haber nunca un binario SUID ni un fichero de dispositivo; nofail porque un fallo de este disco no puede impedir que arranque el servidor.
Paso 7 — Restaurar propiedad, verificar y limpiar.
$ sudo chown -R operador:tramontana /srv/tramontana/backups
$ sudo chmod 2770 /srv/tramontana/backups # SGID de 05-02: grupo heredado
$ sudo -u operador /home/operador/scripts/respaldo_tramontana.sh --dry-run
[2026-08-18T11:04:12+02:00] simulacion: destino /srv/tramontana/backups (9,4G libres)
$ df -h /srv/tramontana/backups | tail -1
/dev/mapper/vg--datos-lv--backups 15G 4,9G 9,4G 35% /srv/tramontana/backupsSolo cuando una copia real haya funcionado y se haya verificado su sha256sum se borra /srv/tramontana/backups.viejo, y se anota todo:
sudo tee -a /opt/tramontana/HISTORIAL >/dev/null <<'FIN'
2026-08-18 Disco de copias (operador)
- sdb 20G -> GPT + PV + vg-datos (5G libres para snapshots) + lv-backups 15G ext4
- rsync -aHAX, fstab por UUID con nofail/nodev/nosuid, mount -a OK
- backups.viejo conservado hasta la primera copia verificada
FINErrores Comunes y Consejos
- Montar por
/dev/sdb1enfstab. El día que el orden de detección cambie, arrancará el disco equivocado o ninguno. UUID o LABEL, siempre. - Reiniciar sin
mount -a. Es la causa número uno de servidores que no vuelven. Ynofailen todo lo que no sea/. lvextendsin-r. El volumen crece,dfno cambia y pierdes media hora. Con-r, el sistema de ficheros crece con él. Y no llenes el VG al 100 %: sin espacio libre no hay snapshot ni margen para ampliar.- Confiar en RAID como copia de seguridad. No lo es, y descubrirlo el día del borrado accidental es caro.
rmsobre un log en uso. El espacio no se libera hasta que el proceso cierre el descriptor:lsof +L1lo delata. Los logs se rotan (05-06).- Copiar datos con
cp -ren vez dersync -aHAX: pierdes propietarios, enlaces duros, ACL y atributos, y luego los permisos de 05-01 no cuadran. - Consejo: guarda
lsblk -f,vgs,lvsy una copia delfstabjunto alHISTORIAL. Reconstruir de memoria la disposición de discos, con el servidor caído, no es un plan.
Ejercicios
- Diagnóstico de disco lleno.
df -h /marca 100 %, perodu -sh /suma bastante menos. Enumera las tres causas posibles en orden de probabilidad y el comando que confirma cada una. - Ampliar en caliente.
lv-backups(15 GiB) se ha quedado corto y el VG tiene 5 GiB libres. Amplíalo 3 GiB sin desmontar, verifica que el espacio es visible paradfy explica qué habría pasado sin-r. - Entrada de
fstabsegura. Escribe la línea defstabpara un volumen de subidas de usuarios montado en/opt/tramontana/shared/uploads, con las opciones que un directorio donde escriben terceros debe tener, y describe cómo la validarías antes de reiniciar.
Soluciones
1. Por orden de probabilidad:
sudo lsof +L1 # (a) fichero borrado con un proceso que lo mantiene abierto
df -i / # (b) inodos agotados: hay espacio pero no se puede crear nada
sudo mount --bind / /mnt/raiz && sudo du -sh /mnt/raiz/* # (c) datos bajo un montajeLa tercera es la más traicionera: si alguien escribió en /srv/tramontana/backups antes de montar el volumen encima, esos ficheros siguen ocupando espacio en / pero son invisibles porque el montaje los tapa. El bind mount de / en otro punto los deja a la vista. Es el riesgo del paso 5 del caso Tramontana, y por eso creamos el directorio vacío en lugar de reutilizar el que tenía datos.
2.
$ df -h /srv/tramontana/backups | tail -1
/dev/mapper/vg--datos-lv--backups 15G 4,9G 9,4G 35% /srv/tramontana/backups
$ sudo lvextend -L +3G -r /dev/vg-datos/lv-backups
Size of logical volume vg-datos/lv-backups changed from 15,00 GiB to 18,00 GiB.
$ df -h /srv/tramontana/backups | tail -1
/dev/mapper/vg--datos-lv--backups 18G 4,9G 12G 29% /srv/tramontana/backupsSin -r, lvs mostraría 18 GiB y df seguiría diciendo 15 GiB: el sistema de ficheros ext4 no sabe que el dispositivo por debajo ha crecido hasta que se le dice con resize2fs. La operación es segura en caliente porque ext4 admite crecer montado; reducir exigiría desmontar y hacerlo en el orden inverso.
3.
noexec es el añadido clave respecto al volumen de copias: en un directorio donde escriben terceros, impedir la ejecución de binarios corta en seco que una subida maliciosa se convierta en código en marcha. nodev y nosuid cierran las otras dos vías, y nofail evita que un problema con este volumen impida arrancar. Validación antes de reiniciar:
sudo cp -a /etc/fstab /etc/fstab.bak-$(date +%F) # copia previa
sudo findmnt --verify --verbose # sintaxis y coherencia
sudo mount -a && findmnt /opt/tramontana/shared/uploads # montar y ver opciones efectivasNótese que findmnt al final muestra las opciones efectivas: es la única prueba de que lo que escribiste es lo que el kernel aplicó.
Conclusión
Ya no hay una capa opaca entre tus ficheros y el hardware. Recorres la pila entera —disco, tabla de particiones, partición, PV, VG, LV, sistema de ficheros, punto de montaje— y sabes qué problema resuelve cada peldaño; identificas el hardware con lsblk -f, blkid y fdisk -l, y sabes por qué los nombres /dev/sdX no son de fiar y el UUID sí; eliges GPT sin dudarlo, particionas con parted en una línea y con fdisk sabiendo que nada se escribe hasta la w; comparas ext4, XFS, Btrfs y ZFS con criterio, ajustas con tune2fs y reconoces el desconcierto de un df -h con sitio y un df -i al 100 %.
Montas con las opciones que un servidor necesita —noatime, nodev, nosuid, noexec, nofail—, lees /etc/fstab campo a campo y sabes que mount -a antes de reiniciar es la diferencia entre un ajuste y una noche perdida. Diagnosticas el disco lleno en sus tres variantes, incluido el fichero borrado que lsof +L1 delata. Y dominas LVM: creas PV, VG y LV, amplías en caliente con lvextend -r, sabes por qué reducir es peligroso y usas snapshots para congelar un estado coherente. Conoces mdadm y sus niveles, y tienes grabado que RAID no es una copia de seguridad.
Sobre todo, /srv/tramontana/backups vive ya en su propio volumen lógico de 15 GiB, ampliable en caliente, montado por UUID con nofail, con las copias migradas byte a byte con rsync -aHAX y verificadas, y con 5 GiB de margen en el VG reservados para snapshots.
Y llegamos al núcleo del módulo. Tienes identidades, permisos, paquetes y disco, pero la aplicación de Tramontana sigue arrancándose a mano: si el servidor se reinicia, no vuelve; si el proceso muere, nadie lo levanta; desplegar.sh cambia el enlace simbólico y sigue sin reiniciar nada; y la copia de las 4:20 depende de una línea de cron sin control real de solapamiento ni registro decente. En systemd y la Gestión de Servicios se acaba todo eso: escribirás tramontana.service desde cero y endurecido, entenderás la diferencia real entre orden y dependencia, convertirás respaldo_tramontana.sh en un .service con su .timer y Persistent=true, y desplegar.sh hará por fin el systemctl restart que le faltaba.
Curso de Linux: De Principiante a Administrador de Sistemas
Módulo 1: Introducción a Linux
- ¿Qué es Linux?
- Historia de Linux
- Distribuciones de Linux
- Instalando Linux
- Primer Contacto con el Sistema
- Estructura del Sistema de Archivos de Linux
Módulo 2: Comandos Básicos de Linux
- Introducción a la Línea de Comandos
- Obtener Ayuda y Documentación del Sistema
- Navegando el Sistema de Archivos
- Operaciones con Archivos y Directorios
- Visualización y Edición de Archivos
- Enlaces Duros y Simbólicos
- Permisos y Propiedad de Archivos
Módulo 3: Habilidades Avanzadas en la Línea de Comandos
- El Entorno del Shell: Variables, Alias e Historial
- Uso de Comodines y Expresiones Regulares
- Búsqueda de Archivos y Contenido: find, locate y grep
- Tuberías y Redirección
- Procesamiento de Texto: cut, sort, uniq, sed y awk
- Gestión de Procesos
- Programación de Tareas con Cron
- Comandos de Redes
Módulo 4: Scripting en Shell
- Introducción al Scripting en Shell
- Variables y Tipos de Datos
- Entrada, Salida y Argumentos de un Script
- Estructuras de Control
- Funciones y Librerías
- Depuración y Manejo de Errores
- Scripts de Producción: Buenas Prácticas
Módulo 5: Administración del Sistema
- Gestión de Usuarios y Grupos
- sudo y Permisos Especiales
- Gestión de Paquetes
- Gestión de Discos
- systemd y la Gestión de Servicios
- Registros del Sistema: journald y syslog
- Monitoreo del Sistema y Optimización del Rendimiento
- Respaldo y Restauración
Módulo 6: Redes y Seguridad
- Configuración de Redes
- SSH y Acceso Remoto
- Firewall y Seguridad Perimetral
- Sistemas de Detección de Intrusos
- Gestión de Secretos y Certificados TLS
- Asegurando Sistemas Linux
Módulo 7: Temas Avanzados
- El Proceso de Arranque y la Recuperación del Sistema
- Diagnóstico Avanzado: strace, perf y eBPF
- Optimización del Kernel de Linux
- Virtualización con Linux
- Contenedores de Linux y Docker
- Automatización con Ansible
- Alta Disponibilidad y Balanceo de Carga
