I have now upgraded a second (physically remote) cluster from Debian 10 to 11 as well, without instance downtime. It's a two-node cluster with DRBD. The upgrade procedure looked roughly like this:
1. Evacuate all instances from node2: `# gnt-node evacuate --primary-only
node2.example.com`
2. Add bullseye-backports APT sources to node2. Configure APT to prefer the backported Ganeti packages by putting this in /etc/apt/preferences.d/pin_ganeti.pref:
Explanation: Live migration bugfix in 3.0.2
Package: ganeti ganeti-*
Pin: release a=bullseye-backports
Pin-Priority: 500
3. Temporarily hold the 'ganeti' package on node2, it must be upgraded *after* running 'gnt-cluster upgrade': `# echo ganeti hold | dpkg --set-selections`
4. Upgrade node2 to Debian 11 [1] and reboot. The Ganeti cluster version is now still 2.16, but the 3.0.2 packages are installed.
5. Add the Bullseye APT sources, including bullseye-backports, to node1. Add pin_ganeti.pref from step 2 to /etc/apt/preferences.d/. Install Ganeti 3.0.2 packages from bullseye-backports: `# apt install ganeti-3.0 ganeti-haskell-3.0 ganeti-htools-3.0`. This will upgrade some packages, namely glibc and openssh, and will also install Python 3.9.
6. Upgrade the Ganeti cluster: `# gnt-cluster upgrade --to=3.0`
7. Remove the 'ganeti' package hold from node2: `# echo ganeti install | dpkg --set-selections`
8. Upgrade the 'ganeti' package on both node1 and node2: `# apt install ganeti=3.0.2-1~bpo11+1`
9. Restart the 'ganeti' service on both node1 and node2.
10. Try live-migrating an unimportant VM.
11. Evacuate all remaining instances from node1 and upgrade node1 to Debian 11 as well.
Note: I performed a master-failover before each Debian version upgrade. This would have allowed me to still manage my instances if the upgrade went south.
Hope this is useful to someone. Feel free to ask me any questions about my upgrade.