Skip to main content
RunBook Academy

← All assessments

Final assessment · expert · ~180 min · pass ≥ 75%

Proxmox final assessment - production readiness of an inherited estate

Objectives

  • Audit an unfamiliar Proxmox estate from its own output alone, without being told where the defects are
  • Rate findings by the harm they can actually do, and defend the rating rather than the label
  • Identify the defects that are only dangerous in combination, and say why the combination is worse than the sum
  • Produce a remediation plan sequenced by risk and by dependency, with validation that is evidence rather than assertion
  • Make and defend a production recommendation with a named blocking set

24 questions · last verified 2026-08-12

Auto-scored questions

The questions below are scored automatically. Combine them with the scenario rubric in the body of this page to assess your readiness.

Knowledge check · 18 questions

  1. Q1. Read the pool definition and the CRUSH rule together: pool 2 'ceph-vm' replicated size 2 min_size 1 crush_rule 1 rule by-osd: step chooseleaf firstn 0 type osd pve-02 loses power. What happens to the ceph-vm pool?

  2. Q2. The handover note states the estate is N+1 on memory: 506 GiB of guest memory is allocated across three nodes with 256 GiB each, so 506 fits inside the 512 GiB that two surviving nodes provide. Is that arithmetic sound?

  3. Q3. A register that lists this estate item by item understates it. Which findings combine into the mechanism that turns one node failure into a simultaneous reboot of all three nodes? Select all that apply.

  4. Q4. Because pve-01 holds two votes in a three-node cluster, the loss of pve-01 leaves 2 votes of an expected 4, which is not a majority. The two surviving nodes therefore become inquorate and their HA watchdogs reset them, so a single node failure takes the whole cluster down.

  5. Q5. The PBS backup job has completed with status OK every night for the last ninety-one nights. What does that green status actually establish about this estate?

  6. Q6. HA recovery starts a guest on a surviving node - it is a cold start, not a live migration. Which of these configurations will prevent an HA-managed guest from being recovered onto another node in this estate? Select all that apply.

  7. Q7. vm 105, the ERP database, is configured with cpu host. pve-01 and pve-02 are Xeon Gold 6338; pve-03 is a Xeon Gold 6542Y. What is the finding, and what is it not?

  8. Q8. The noout flag has been set on this Ceph cluster since March. Given that the pool is at 71% raw usage, leaving it set is a defensible operational choice, because it prevents an expensive and possibly unsurvivable rebuild after a transient node failure.

  9. Q9. cluster.fw carries policy_in DROP, enable 0, an IPSET named management holding 192.0.2.0/24, a rule permitting 8006 from that IPSET, and a rule permitting SSH from 0.0.0.0/0. The administrators moved to 198.51.100.0/24 during the March renumbering. Somebody sets enable 1. What happens?

  10. Q10. The API token monitoring@pve!checkmk exists so a monitoring system can read node status. It has privsep 0, expire 0, and monitoring@pve holds Administrator on /. Which statements about it are accurate? Select all that apply.

  11. Q11. vm 105, the ERP database, is excluded from the PBS job. In its place, a cron entry on pve-01 runs a qm snapshot nightly and discards its output. The guest has 41 snapshots, the newest dated 2026-03-19, and it has been running on pve-02 since the pve-01 kernel reboot that month. State what you would establish, what you would change, and in what order.

  12. Q12. A qm snapshot of a guest whose disk is an RBD image is stored in the same Ceph pool as the disk it protects, so it cannot survive the loss of that pool; and rolling back to one discards every write made since it was taken. Neither property is what the word backup means.

  13. Q13. vm 101 and vm 102 are backed up nightly by PBS in snapshot mode. Both have agent 0. What consistency does the resulting backup have?

  14. Q14. An audit that rates everything Critical has not audited anything. Which of these would you record with a severity of Low or None - real observations that change nothing about whether this estate survives a node failure? Select all that apply.

  15. Q15. You have one four-hour change window before month-end freeze. Which sequence of work reduces the most risk, and why is the ordering the answer rather than the list?

  16. Q16. Which single change most reduces the probability that one compromised credential destroys both production and every copy of it?

  17. Q17. PBS verification reads every chunk of a snapshot and checks it against its recorded checksum. A datastore in which all snapshots are verified is therefore proof that a restore will succeed.

  18. Q18. Every node has an unused pair of 25 GbE ports. Describe the traffic separation you would build with them, state which finding each part of it closes, and name what it does not close.

Passing score: 75%. Answers are checked in this browser.

You have joined Northwind Logistics as the engineer responsible for virtualisation. The person who built the platform left in June. You have been handed three nodes, a Ceph cluster, a backup server, a handover note, and a production workload that has been running on all of it for two years.

Nobody has told you anything is wrong with it. As far as the business is concerned this estate works: guests are up, backups are green, and the last incident anyone connects to it was months ago.

Your job is to find out whether that is true, and to say so in a form somebody can act on.

Format

  • Part A — 18 auto-scored questions, in the set above this text. Machine-marked, 25% of the total. Most of them cannot be answered without having read the estate output properly.
  • Part B — the risk register you write yourself. 45% of the total. The marking key is in this page, under a heading that says not to read it yet.
  • Part C — 6 scenarios with rubrics, in the frontmatter of this assessment and summarised near the end. 30% of the total.
  • Open-book, 3 hours. You may look up anything. You have no shell on the estate; the captures below are what you have.
  • Pass: 75% overall, plus all four mandatory findings. The pass bar is justified where the pass criteria are set out.

The handover note

The previous engineer left this in the datacenter notes field. It is reproduced exactly.

Northwind virtualisation - handover

Cluster:  nwl-prod, pve-01/02/03, Proxmox VE 9.2.4
Storage:  Ceph (pool ceph-vm), plus local-lvm on each node
Backup:   PBS 4.2.5, vm 150 on pve-02, job runs 22:00 nightly
HA:       5 guests, see ha-manager

Notes for whoever picks this up:

- Sizing is N+1. 506 GiB allocated across 3 x 256 GiB nodes, so two
  nodes can carry everything.
- I gave pve-01 two corosync votes so the cluster stays quorate when
  we take a node out for patching. Works well.
- noout is set. Left it on after the March maintenance because the
  rebuild was going to be painful. Take it off when we have more
  disk.
- vm 105 (ERP db) is not in the PBS job - it is too big and the
  window was too tight. There is a snapshot cron on pve-01 instead.
- Restore has not been tested. It is on the list.
- Firewall rules are written but not enabled. Someone should check
  them before turning it on.
- pve-03 is on pvetest, I was chasing a NIC issue in April.
- Do not reboot pve-01 during month-end.

The estate as you received it

Cluster and quorum

Read-only / Safepvecm status
$ pvecm status
Cluster information
-------------------
Name:             nwl-prod
Config Version:   7
Transport:        knet
Secure auth:      on

Quorum information
------------------
Date:             Wed Aug 12 09:41:03 2026
Quorum provider:  corosync_votequorum
Nodes:            3
Node ID:          0x00000001
Ring ID:          1.3f2
Quorate:          Yes

Votequorum information
----------------------
Expected votes:   4
Highest expected: 4
Total votes:      4
Quorum:           3
Flags:            Quorate

Membership information
----------------------
  Nodeid      Votes Name
0x00000001          2 192.0.2.11 (local)
0x00000002          1 192.0.2.12
0x00000003          1 192.0.2.13

Illustrative output

/etc/pve/corosync.conf:

logging {
  debug: off
  to_syslog: yes
}

nodelist {
  node {
    name: pve-01
    nodeid: 1
    quorum_votes: 2
    ring0_addr: 192.0.2.11
  }
  node {
    name: pve-02
    nodeid: 2
    quorum_votes: 1
    ring0_addr: 192.0.2.12
  }
  node {
    name: pve-03
    nodeid: 3
    quorum_votes: 1
    ring0_addr: 192.0.2.13
  }
}

quorum {
  provider: corosync_votequorum
}

totem {
  cluster_name: nwl-prod
  config_version: 7
  interface {
    linknumber: 0
  }
  ip_version: ipv4-6
  link_mode: passive
  secauth: on
  version: 2
}

Networking

/etc/network/interfaces on pve-01, identical in structure on the other two nodes:

auto lo
iface lo inet loopback

iface enp1s0f0 inet manual
iface enp1s0f1 inet manual

# 25 GbE, cabled to the leaf switches, never configured
iface ens2f0 inet manual
iface ens2f1 inet manual

auto bond0
iface bond0 inet manual
    bond-slaves enp1s0f0 enp1s0f1
    bond-mode 802.3ad
    bond-xmit-hash-policy layer3+4
    mtu 9000

auto vmbr0
iface vmbr0 inet static
    address 192.0.2.11/24
    gateway 192.0.2.1
    bridge-ports bond0
    bridge-vlan-aware yes
    bridge-vids 2-4094
    mtu 9000

Relevant lines from /etc/pve/ceph.conf:

[global]
	auth_client_required = cephx
	auth_cluster_required = cephx
	auth_service_required = cephx
	cluster_network = 192.0.2.0/24
	fsid = 4b1f8d2a-9c60-4f13-8a77-2ee5cbb01f4d
	mon_allow_pool_delete = true
	ms_bind_ipv4 = true
	osd_pool_default_min_size = 1
	osd_pool_default_size = 2
	public_network = 192.0.2.0/24

Ceph

Read-only / Safeceph -s
$ ceph -s
  cluster:
  id:     4b1f8d2a-9c60-4f13-8a77-2ee5cbb01f4d
  health: HEALTH_WARN
          noout flag(s) set
          1 daemons have recently crashed

services:
  mon: 3 daemons, quorum pve-01,pve-02,pve-03 (age 5w)
  mgr: pve-01(active, since 5w)
  osd: 12 osds: 12 up (since 5w), 12 in (since 14M)
       flags noout

data:
  pools:   2 pools, 129 pgs
  objects: 4.31M objects, 16 TiB
  usage:   33 TiB used, 13 TiB / 46 TiB avail
  pgs:     129 active+clean

io:
  client:   18 MiB/s rd, 42 MiB/s wr, 1.90k op/s rd, 2.11k op/s wr

Illustrative output

Read-only / Safeceph osd pool ls detail
$ ceph osd pool ls detail
pool 1 '.mgr' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins
pg_num 1 pgp_num 1 autoscale_mode on last_change 41 flags hashpspool
stripe_width 0 pg_num_max 32 pg_num_min 1 application mgr

pool 2 'ceph-vm' replicated size 2 min_size 1 crush_rule 1 object_hash rjenkins
pg_num 128 pgp_num 128 autoscale_mode warn last_change 1832 lfor 0/0/318
flags hashpspool,selfmanaged_snaps stripe_width 0 application rbd

Illustrative output

Read-only / Safeceph osd crush rule dump by-osd
$ ceph osd crush rule dump by-osd
{
  "rule_id": 1,
  "rule_name": "by-osd",
  "type": 1,
  "steps": [
      { "op": "take", "item": -1, "item_name": "default" },
      { "op": "chooseleaf_firstn", "num": 0, "type": "osd" },
      { "op": "emit" }
  ]
}

Illustrative output

Read-only / Safeceph df
$ ceph df
--- RAW STORAGE ---
CLASS     SIZE    AVAIL     USED  RAW USED  %RAW USED
ssd     46 TiB   13 TiB   33 TiB    33 TiB      71.74
TOTAL   46 TiB   13 TiB   33 TiB    33 TiB      71.74

--- POOLS ---
POOL       ID  PGS   STORED  OBJECTS     USED  %USED  MAX AVAIL
.mgr        1    1  449 KiB        2  1.3 MiB   0.00    6.1 TiB
ceph-vm     2  128   16 TiB    4.31M   33 TiB  73.09    6.1 TiB

Illustrative output

Read-only / Safeceph osd tree, trimmed
$ ceph osd tree
ID  CLASS  WEIGHT    TYPE NAME        STATUS  REWEIGHT  PRI-AFF
-1         45.94434  root default
-3         15.31478      host pve-01
0    ssd   3.82870          osd.0        up   1.00000  1.00000
1    ssd   3.82870          osd.1        up   1.00000  1.00000
2    ssd   3.82870          osd.2        up   1.00000  1.00000
3    ssd   3.82870          osd.3        up   1.00000  1.00000
-5         15.31478      host pve-02
4    ssd   3.82870          osd.4        up   1.00000  1.00000
5    ssd   3.82870          osd.5        up   1.00000  1.00000
6    ssd   3.82870          osd.6        up   1.00000  1.00000
7    ssd   3.82870          osd.7        up   1.00000  1.00000
-7         15.31478      host pve-03
8    ssd   3.82870          osd.8        up   1.00000  1.00000
9    ssd   3.82870          osd.9        up   1.00000  1.00000
10    ssd   3.82870          osd.10       up   1.00000  1.00000
11    ssd   3.82870          osd.11       up   1.00000  1.00000

Illustrative output

Storage as Proxmox sees it

Read-only / Safepvesm status
$ pvesm status
Name             Type     Status           Total            Used       Available        %
ceph-vm           rbd     active     24065771520     17557821440      6507950080   72.96%
local             dir     active       100597760        18874368        81723392   18.76%
local-lvm     lvmthin     active      1782579200       929038336       853540864   52.12%
nas-iso           nfs     active      2147483648      1932735283       214748365   90.00%
pbs-nwl           pbs     active     41943040000     38210371584      3732668416   91.10%
zbackup           dir     active     46137344000     31138512896     14998831104   67.49%

Illustrative output

Relevant stanzas from /etc/pve/storage.cfg:

rbd: ceph-vm
	content images,rootdir
	krbd 0
	pool ceph-vm

lvmthin: local-lvm
	thinpool data
	vgname pve
	content rootdir,images

pbs: pbs-nwl
	datastore nwl-store
	server 192.0.2.150
	content backup
	encryption-key a1:b2:c3:REDACTED
	fingerprint 3f:REDACTED
	username backup@pbs!pve

dir: zbackup
	path /zbackup/dump
	content backup,iso
	nodes pve-02
	prune-backups keep-last=2

Guests

Read-only / Safeqm config 105
$ qm config 105
agent: 0
boot: order=scsi0
cores: 16
cpu: host
memory: 131072
name: nwl-erp-db
net0: virtio=BC:24:11:3A:0E:71,bridge=vmbr0,tag=40
numa: 1
onboot: 1
ostype: l26
parent: auto-2026-03-19
scsi0: ceph-vm:vm-105-disk-0,discard=on,iothread=1,size=1200G
scsihw: virtio-scsi-single
sockets: 2

Illustrative output

Read-only / Safeqm listsnapshot 105, trimmed
$ qm listsnapshot 105
`-> auto-2025-06-02             2025-06-02 02:00:11     no-description
`-> auto-2025-06-03           2025-06-03 02:00:09     no-description
  [ ... 37 further snapshots ... ]
      `-> auto-2026-03-18     2026-03-18 02:00:14     no-description
        `-> auto-2026-03-19   2026-03-19 02:00:12     no-description
          `-> current         You are here!

Illustrative output

/etc/cron.d/nwl-erp-snapshot on pve-01:

0 2 * * * root /usr/sbin/qm snapshot 105 auto-$(date +\%F) >/dev/null 2>&1
Read-only / Safeqm config 110 and qm config 120
$ qm config 110 ; echo '---' ; qm config 120
boot: order=scsi0
cores: 4
cpu: x86-64-v2-AES
memory: 16384
name: nwl-fileserver
net0: virtio=BC:24:11:7D:12:9A,bridge=vmbr0,tag=20
onboot: 1
ostype: l26
scsi0: local-lvm:vm-110-disk-0,discard=on,size=800G
scsihw: virtio-scsi-single
---
boot: order=scsi0;ide2
cores: 8
cpu: x86-64-v2-AES
hostpci0: 0000:65:00.0,pcie=1
ide2: local:iso/win2022-eval.iso,media=cdrom
machine: q35
memory: 32768
name: nwl-terminal
net0: virtio=BC:24:11:44:C1:03,bridge=vmbr0,tag=30
onboot: 1
ostype: win11
scsi0: ceph-vm:vm-120-disk-0,discard=on,size=400G
scsihw: virtio-scsi-single

Illustrative output

The capacity sheet from the handover note, reproduced as written:

NodeMemoryGuest memory allocatedGuests
pve-01256 GiB198 GiBvm 101, vm 110, three others
pve-02256 GiB187 GiBvm 102, vm 105, vm 150
pve-03256 GiB121 GiBvm 120, two others
Total768 GiB506 GiB

High availability

Read-only / Safeha-manager status
$ ha-manager status
quorum OK
master pve-01 (active, Wed Aug 12 09:41:00 2026)
lrm pve-01 (active, Wed Aug 12 09:41:02 2026)
lrm pve-02 (active, Wed Aug 12 09:41:04 2026)
lrm pve-03 (active, Wed Aug 12 09:41:01 2026)
service vm:101 (pve-01, started)
service vm:102 (pve-02, started)
service vm:105 (pve-02, started)
service vm:110 (pve-01, started)
service vm:120 (pve-03, started)

Illustrative output

Read-only / Safethe watchdog in use
$ lsmod | grep -E 'softdog|wdt' ; systemctl is-active watchdog-mux
softdog                16384  1
active

Illustrative output

The journal shows no watchdog reset on any node since the cluster was built. Fencing has never been exercised, planned or unplanned.

Backup

Read-only / Safethe backup job, as the dashboard reports it
$ pvesh get /cluster/backup
job-id:    backup-8a41e0c2-9f31
schedule:  22:00
storage:   pbs-nwl
mode:      snapshot
notes:     nightly
exclude:   105
enabled:   1
last-run:  2026-08-11 22:00:03  status OK  duration 41m18s

Illustrative output

Read-only / SafePBS datastore and jobs
$ proxmox-backup-manager datastore list ; proxmox-backup-manager verify-job list ; proxmox-backup-manager garbage-collection status nwl-store
Name        Path                            Comment
nwl-store   /mnt/datastore/nwl-store        primary datastore

(no verify jobs configured)

Datastore:          nwl-store
Last GC run:        2025-11-14 03:00:02
Schedule:           (none)
Removed bytes:      0
Pending bytes:      2.71 TiB

Illustrative output

Read-only / Safea snapshot as PBS records it
$ proxmox-backup-client snapshot list --repository backup@pbs!pve@192.0.2.150:nwl-store
snapshot                             size    verify state
vm/101/2026-08-11T22:00:07Z       412.8 GiB   none
vm/101/2026-08-10T22:00:05Z       412.5 GiB   none
vm/101/2026-08-09T22:00:11Z       412.1 GiB   none

prune options for this datastore: keep-last=3

Illustrative output

vm 150 is the PBS instance. It runs on pve-02, and qm config 150 shows its datastore disk as scsi1: ceph-vm:vm-150-disk-1,size=4000G. The PBS encryption key is the one referenced in storage.cfg and exists in /etc/pve/priv/storage/pbs-nwl.enc. There is no sync job, no second PBS instance, and no tape.

Local storage and ZFS

Read-only / Safezpool status, pve-02
$ zpool status
  pool: rpool
state: ONLINE
status: One or more devices has experienced an unrecoverable error.
action: Determine if the device needs to be replaced.
scan: none requested
config:

NAME                                   STATE     READ WRITE CKSUM
rpool                                  ONLINE       0     0     0
  mirror-0                             ONLINE       0     0     0
    ata-INTEL_SSDSC2KB480G8_PHYF1234   ONLINE       3     0     0
    ata-INTEL_SSDSC2KB480G8_PHYF5678   ONLINE       0     0     0

errors: No known data errors

pool: zbackup
state: ONLINE
scan: scrub repaired 0B in 09:12:44 with 0 errors on Sun Feb  9 2025
config:

NAME                                   STATE     READ WRITE CKSUM
zbackup                                ONLINE       0     0     0
  raidz2-0                             ONLINE       0     0     0
    [ 8 x 8 TB SATA, trimmed ]
logs
  nvme-Consumer_NVMe_2TB_S4X9           ONLINE       0     0     0

errors: No known data errors

Illustrative output

/etc/cron.d/zfsutils-linux on all three nodes:

# Scrub the second Sunday of every month.
# 24 0 8-14 * * root [ $(date +\%w) -eq 0 ] && [ -x /usr/lib/zfs-linux/scrub ] && /usr/lib/zfs-linux/scrub
# Commented 2025-04-11, scrub latency during business hours. Reschedule to weekend nights.

/etc/zfs/zed.d/zed.rc has ZED_EMAIL_ADDR commented out, as shipped.

Identity, firewall and notifications

Read-only / Safepveum acl list and pveum user token list
$ pveum acl list ; pveum user token list monitoring@pve
path   type   ugid              roleid          propagate
/      user   ansible@pve       Administrator   1
/      user   monitoring@pve    Administrator   1
/      user   ebrandi@pam       Administrator   1

tokenid   expire   privsep   comment
checkmk        0         0   checkmk agent, added 2025-04-08

Illustrative output

/etc/pve/firewall/cluster.fw:

[OPTIONS]
enable: 0
policy_in: DROP
policy_out: ACCEPT

[IPSET management]
192.0.2.0/24

[RULES]
IN SSH(ACCEPT) -source 0.0.0.0/0 -log nolog
IN ACCEPT -source +management -p tcp -dport 8006 -log nolog
IN ACCEPT -source +management -p tcp -dport 5900:5999 -log nolog

/etc/pve/nodes/pve-03/host.fw contains enable: 1. The equivalent file on pve-01 and pve-02 contains enable: 0.

Administrator workstations were renumbered from 192.0.2.0/24 to 198.51.100.0/24 during the March migration. The node, storage and corosync addresses stayed where they were.

/etc/pve/notifications.cfg:

matcher: default-matcher
	comment Route all notifications to mail-to-root
	mode all
	target mail-to-root

root@pam has no email address configured. /var/spool/mail/root on pve-01 is 1.4 GiB and has never been read.

SDN and package versions

/etc/pve/sdn/zones.cfg:

evpn: prod
	controller evpnctl
	vrf-vxlan 10040
	exitnodes pve-01
	ipam pve
	mtu 8950

pvesh get /cluster/sdn reports the configuration as pending; the running configuration on the nodes was last generated in February.

Package versions differ across the cluster:

NodeKernelRepository
pve-016.14.11-4-pvepve-no-subscription
pve-026.14.11-4-pvepve-no-subscription
pve-036.17.2-1-pvepve-no-subscription, pvetest

pve-01 and pve-02 are Xeon Gold 6338. pve-03 is a Xeon Gold 6542Y, bought a year later as a capacity addition.

What you must produce

Six deliverables. They are marked together, and an answer that produces findings without severities, or remediation without validation, is incomplete rather than partially correct.

  1. Findings. A risk register. One row per finding: where it is, what it is, and what it can do. Findings that only exist in combination get their own row, and name the components they need.
  2. Evidence. For each finding, the specific artefact or the read-only command that establishes it. “The pool looks wrong” is not evidence. ceph osd pool ls detail next to ceph osd crush rule dump is.
  3. Severity. A rating per finding, from the scale below, with one sentence of reasoning. The reasoning is what is marked; the label on its own is not.
  4. Remediation. What you change, and in what order. The order is marked, and it is marked hardest. A plan that starts with the most interesting defect has chosen wrong.
  5. Validation. For each remediation, the command whose output demonstrates it worked. Not “the pool was updated” — the pool detail line, the resolved vote count, the restored guest booting.
  6. Production recommendation. May this estate keep carrying the workload? Under what conditions? What is the blocking set, and what is merely backlog?

The severity scale

Use this scale, and use all of it.

SeverityMeaning
CriticalCan cause data loss, credential disclosure, or an estate-wide outage. Blocks the next production change.
HighCan cause an outage of a subset of workload, a silent loss of protection, or a serious loss of assurance. Fix before the next maintenance window closes.
MediumDegrades reliability, capacity or diagnosis. Scheduled work with an owner.
LowHygiene and maintainability. Backlog.
NoneLooks like a finding and is not. Record it as examined so nobody re-raises it.

Marking key: the risk register

Thirty-two entries, in two tables. The thirty below are the substantive findings; the two after them are judgement calls a complete register still has to make.

Score two points for each finding you produced independently, and one further point where your severity is within one band of the key and your reasoning holds.

#WhereFindingSeverity
F1corosync.confquorum_votes: 2 on pve-01 gives 4 expected votes and a quorum of 3, so the loss of pve-01 leaves the survivors inquorate and their HA watchdogs reset themCritical
F2ceph osd pool ls detailceph-vm at size 2 min_size 1: one failure removes all redundancy, and writes continue onto a single replica with nothing to reconcile againstCritical
F3ceph osd crush rule dumpThe by-osd rule chooses leaves by OSD, so both replicas of a PG can land on one host and a host failure can make PGs inactiveCritical
F4ceph df + topology16 TiB stored needs 32 TiB raw for two copies; eight surviving OSDs supply 30.6 TiB and full_ratio permits 29.1 TiB, so a node loss cannot be repaired inside the clusterCritical
F5ceph.conf + interfaces + corosync.confCorosync ring0, the Ceph public network, the Ceph cluster network and all guest traffic share one 2x10 GbE bond, with no second corosync linkCritical
F6qm config 150 + storage.cfgThe PBS datastore is a disk of a guest of this cluster, in the pool it is protecting: the backup shares the failure it exists to surviveCritical
F7PBSNo verify job exists and no restore has ever been performed, so nothing has established that any snapshot is readable or usableCritical
F8backup job + cronvm 105, the ERP database, is excluded from the backup job; its only protection is a snapshot cron on pve-01 that has failed silently since the guest relocated on 2026-03-19Critical
F9storage.cfg + /etc/pve/privThe PBS encryption key exists only on the cluster the backups exist to replace, with no escrowCritical
F10pveummonitoring@pve!checkmk: Administrator on /, privsep 0, no expiry, secret stored on a guest of this clusterCritical
F11capacity sheetReserved memory for ARC, OSDs and the host is not modelled, so no single node failure can be absorbed - the smallest node alone exceeds the combined headroom of the other twoCritical
F12HA + F1 + F5The estate-outage machine: weighted votes, a shared corosync wire and an untested software watchdog turn any single node failure into three nodes rebootingCritical (composite: F1, F5, F16)
F13ceph -snoout set since March, converting a capacity crisis into an unbounded window at one replica, with no alarm attached to itHigh
F14qm config 110 + ha-managervm 110 is HA-managed with its disk on local-lvm, so HA recovery onto another node cannot start itHigh
F15qm config 120 + ha-managervm 120 is HA-managed with a bare hostpci0 address and a cdrom from node-local local, so HA recovery cannot start it eitherHigh
F16/etc/default/pve-ha-managerFencing is the software watchdog and has never been exercised on this estate, planned or unplannedHigh
F17qm config 105 + node inventorycpu: host against a differently generationed pve-03 means the ERP database cannot be live-migrated, so the estate has no evacuation path for its most important guestHigh
F18pve-03 packagespvetest enabled on one node of three, running a kernel and toolstack ahead of its peersHigh
F19cluster.fwThe management IPSET holds the pre-March node network while administrators are on 198.51.100.0/24, so the first enable: 1 removes web access from every workstation at onceHigh
F20cluster.fwIN SSH(ACCEPT) -source 0.0.0.0/0 - the one rule that survives the lockout is the one that should not existHigh
F21PBSRetention is keep-last=3 against a stated 30-day requirementHigh
F22PBSGarbage collection last ran 2025-11-14, no schedule, 2.71 TiB pending and the datastore at 91%High
F23notifications.cfgEvery notification targets mail-to-root, root@pam has no address, and 1.4 GiB of unread mail sits in a local spool - so no alert has reached a human since the estate was builtHigh
F24qm listsnapshot 10541 snapshots on the ERP disk, held in the same pool, consuming capacity in a cluster at 71% and lengthening the chain on the live imageHigh
F25zpool statusscan: none requested on rpool, the monthly scrub commented out in April 2025 and never rescheduledHigh
F26zpool status + zed.rcThree read errors on an rpool mirror member with ZED notification unconfigured, so a degrading boot disk is invisibleHigh
F27backup jobvm 101 and vm 102 are backed up with agent: 0, so the images are crash-consistent onlyMedium
F28zpool statusThe zbackup SLOG is a consumer NVMe with no power-loss protection, and the pool has not been scrubbed since February 2025Medium
F29sdn/zones.cfgThe EVPN zone has a single exit node, and the configuration has been pending since February so the next apply pushes changes nobody has reviewedMedium
F30ceph -sOne ceph-mgr with no standby; and 128 PGs with the autoscaler in warn, giving roughly 21 PGs per OSDMedium

And two items that must appear in the register with the right verdict:

#WhereItemSeverity
F31ceph -s1 daemons have recently crashed, from March, investigated and closed but never archivedLow — harmless in itself, and it is holding the cluster at HEALTH_WARN so the next crash arrives into a warning nobody reads
F32pvesm status, repositorieslocal dir storage on every node holding ISOs and templates; pve-no-subscription on pve-01 and pve-02None — the first is the standard layout and no running guest depends on it for a disk; the second is a procurement decision already made. pvetest on pve-03 is the actual defect and it is F18

The interactions

Findings in isolation understate this estate. Six combinations matter more than their parts, and the register is expected to name them.

The estate-outage machine (F1 + F5 + F16). Take pve-01 away and the survivors hold 2 votes of 4, become inquorate, and are reset by their own watchdogs sixty seconds later. Take either other node away and the survivors stay quorate, Ceph marks the dead OSDs out after ten minutes, and the resulting backfill saturates the bond corosync is sharing until the token times out - at which point the watchdogs fire anyway. Two different first steps, one outcome. Any single one of these three findings is a design comment; together they mean this cluster has no survivable single-node failure at all.

The pool that cannot survive what it claims (F2 + F3 + F4 + F13). size 2 means one failure removes redundancy. The by-osd rule means size 2 does not even guarantee two hosts. min_size 1 means production keeps writing onto whatever single copy remains. The capacity arithmetic means the repair cannot complete. And noout means it will not be attempted, so the estate sits at one replica indefinitely with a warning that has been on the screen since March. Fixing any one of these alone leaves the pool unsafe; the register has to say which one goes first and why, and the answer is min_size 2 because it is the only one that costs nothing.

High availability that cannot recover (F14 + F15 + F17 + F16). Five guests are HA-managed. One cannot start elsewhere because its disk is node-local; one cannot start elsewhere because of a raw PCI address and a node-local cdrom; one cannot be evacuated because of cpu: host against a mismatched node. The watchdog that would fence a failed node has never been tested. What the estate has is not high availability, it is a mechanism that will attempt recovery, fail, mark services in error, and leave the operator debugging the HA stack during the incident instead of restoring service.

The unrestorable estate (F6 + F7 + F8 + F9 + F21 + F22). The backup server is a guest of the cluster. Its datastore is a disk in the pool it protects. Nothing verifies the chunks, nothing has ever restored one, retention holds three days against a thirty-day requirement, garbage collection has not run since November so the datastore fills, the key that decrypts it lives on the cluster, and the one guest the business cannot lose is not in the job at all. Six independent mechanisms, each of which alone would be a finding, and in series they mean the loss of the Ceph pool is the loss of the company’s data. This is the interaction that decides the production recommendation.

Failure without a signal (F23 + F13 + F25 + F26 + F31). Alerts go to a mailbox nobody has ever opened. noout and a stale crash keep the Ceph health line at HEALTH_WARN permanently, so a new warning arrives into a state that already looks wrong. The ZFS scrub that would find latent corruption was commented out sixteen months ago, and ZED cannot tell anyone about the read errors it is already seeing. Every one of these is a signal converted into silence, and they are arranged so that the first genuine notification anybody receives about this estate will be a person telephoning.

One credential, everything (F10 + F6 + F9 + F19 + F20). An Administrator token with no expiry and no privilege separation, whose secret sits in a file on a guest of the cluster. That token can delete every guest, the backup job, the backup server guest, and the datastore disk. The encryption key is on the same cluster. The firewall that might have limited where the token can be used from has never been enabled, and when it is, the rule that survives is unrestricted SSH. There is no second copy anywhere and no pull-mode remote. One credential, one step, nothing left.

Working the arithmetic

Two findings in this estate are arithmetic rather than judgement, and the register is expected to show the working rather than assert the conclusion.

Read-only / Safeestablish the post-failure capacity, before believing anything about it
ceph df
ceph osd df tree
ceph osd pool ls detail

Ceph, after losing one node. 16 TiB stored, size 2, so 32 TiB of raw capacity is required to hold two copies. Twelve OSDs supply 46 TiB; eight survivors supply 30.6 TiB. The requirement exceeds the survivors before full_ratio is even considered, and full_ratio at 0.95 caps usable raw at 29.1 TiB. The rebuild therefore cannot complete: it fills the cluster and blocks client I/O across every guest, which is a worse outcome than the node failure that started it.

Raising size to 3 needs 48 TiB of raw capacity against the 46 TiB that exists, and that is before headroom for a failure. The honest figure for the budget request is not “more disk” - it is roughly 24 TiB of additional raw capacity to run size 3 with a node’s worth of headroom, which on these OSDs is six more drives.

Memory, after losing one node. Each node has 256 GiB. Subtract the ARC cap of 16 GiB, four OSDs at the default 4 GiB osd_memory_target for roughly 16 GiB more, and the host, monitor, manager and PVE services for several more - call it 40 GiB. That leaves about 216 GiB per node for guests, against allocations of 198, 187 and 121 GiB.

Every node fits today. No node failure fits. pve-01 has 18 GiB of headroom and pve-02 has 29 GiB; between them they cannot take the 121 GiB that pve-03 is carrying, let alone the 198 GiB that pve-01 is. The handover note’s “506 fits in 512” is arithmetic performed on memory the guests were never going to get.

Scenarios

Six scenarios, with full rubrics in this assessment’s frontmatter. Items marked REQUIRED are pass or fail on their own.

#ScenarioThe element most often missed
1The cluster and quorum layerWorking the loss of each node separately instead of assuming a three-node cluster is symmetric
2The Ceph layerReading the pool line and the CRUSH rule together, and doing the post-failure capacity arithmetic explicitly
3The 02:14 incidentNot leaving a temporary quorum override in place afterwards - which is how the estate acquired its current defect
4Proving the backupsCopy before prune, verify before trusting, restore before claiming
5Identity, access and network policyEvaluating the firewall rule set against the addresses administrators actually use, before applying it
6The production recommendationA blocking set small enough to be credible, plus interim controls that survive month-end without a large change

Pass criteria

  • 75% overall: Part A auto-scored at 25%, the risk register at 45%, the scenarios at 30%.
  • All four mandatory findings present in Part B, each with a defensible severity:
    • F1, the weighted corosync vote that makes pve-01 a single point of failure for the whole cluster.
    • F2 with F3, the replication and placement pairing, which must be identified as one finding about the pool rather than two unrelated settings.
    • F8, the ERP database excluded from backup with a snapshot cron that has failed silently since March.
    • F6, the backup datastore living inside the failure domain it exists to survive.
  • At least three of the six interactions named, because a register of isolated items misrepresents this estate even when every item in it is correct.
  • At least two findings rated Low or None with reasoning. An audit that cannot say what is not urgent has not made a judgement.
  • Four of six scenarios passed against their rubrics, with no REQUIRED element missed in any scenario answer.

Why the bar is 75 and not 70

The rest of this course passes coursework at 70. This assessment is set higher deliberately, for three reasons.

The first is the marking scheme. Part B awards marks for findings a careless reader still stumbles into. size 2 on a production pool is not hard to see. Neither is a backup job that excludes the database, or an Administrator token for a monitoring system. A candidate who skims the captures, reports the eight most visible items and writes nothing about severity, sequencing or interaction can assemble something close to 70% out of the obvious half of the register. The bar has to sit above that, or the result certifies the wrong thing.

The second is that the interactions carry the estate. Every one of the six is composed of findings that are individually survivable and jointly are not. An engineer who lists thirty items and never connects three of them has produced a document that will be triaged into a backlog and worked in the wrong order - which is materially worse than a shorter register that names the outage machine first.

The third is what the credential claims. This estate holds a company’s operational data on two replicas that can share a host, backed up to itself, alerting to a mailbox nobody opens. The question this assessment answers is not “does this person know Proxmox” - it is “would I let this person sign off the platform”. That is a higher bar in real life and it should be a higher bar here.

The mandatory findings exist for the same reason. A candidate could reach 75% on breadth while missing that the database has had no recoverable copy since March, and breadth does not compensate for that, so the scoring does not let it.