nvme0 and nvme1 are assigned in the order the firmware hands the
controller IDs to the kernel. When you boot from drive A, the firmware
enumerates A first, so it becomes nvme0 and B becomes nvme1; when
you boot from B the order flips. The names are not meant to be stable.
Use the identifiers that never change:
In /etc/fstab, GRUB, crypttab, etc.
Ubuntu already uses UUIDs or PARTUUIDs by default, so nothing
breaks even though nvme0/nvme1 swap.
When you work by hand, look under /dev/disk/by-id/
ls -l /dev/disk/by-id | grep nvme
You’ll see symlinks like
nvme-KINGSTON_SKC2000_SerialNumber → ../../nvme1n1
nvme-KIOXIA_KBG40ZNV256G_SerialNumber → ../../nvme0n1
Those by-id names stay the same no matter which drive you boot from.
If you really want short, friendly names, add your own udev rule.
sudo nano /etc/udev/rules.d/80-local-nvme.rules
ENV{ID_SERIAL_SHORT}=="S5ZANRB123456", SYMLINK+="nvme_kioxia"
ENV{ID_SERIAL_SHORT}=="50026B76832E3C3D", SYMLINK+="nvme_kingston"
Then reload:
sudo udevadm control --reload && sudo udevadm trigger
You’ll have /dev/nvme_kioxia and /dev/nvme_kingston that always
point at the same hardware.
In short, you can’t force the kernel to keep nvme0/nvme1 fixed, but you
don’t need to use /dev/disk/by-id/… (or your own udev symlinks) and the
confusion goes away.