1
0
Files
pve-lab/06-form-cluster.sh

73 lines
3.0 KiB
Bash
Raw Normal View History

2026-08-02 10:40:47 -05:00
#!/usr/bin/env bash
# Form the 2-node cluster: create on pve1, join pve2. Sets up /etc/hosts and
# root SSH trust between the nodes first so pvecm can run non-interactively.
set -euo pipefail
source "$(dirname "$0")/lab.env"
HOSTS="10.10.10.11 pve1.${DOMAIN} pve1
10.10.10.12 pve2.${DOMAIN} pve2
10.10.10.13 pvestore.${DOMAIN} pvestore"
echo "==> Ensuring /etc/hosts entries on both nodes"
for ip in "$PVE1_IP" "$PVE2_IP"; do
lab_ssh "$ip" "grep -q 'pve1.${DOMAIN}' /etc/hosts || printf '%s\n' \"$HOSTS\" >> /etc/hosts"
done
echo "==> Establishing root SSH trust pve2 -> pve1 (needed by pvecm add)"
# Ensure pve2 has a root key, then trust it on pve1; pre-seed known_hosts.
lab_ssh "$PVE2_IP" "test -f /root/.ssh/id_rsa || ssh-keygen -t rsa -N '' -f /root/.ssh/id_rsa -q"
PVE2_ROOT_PUB=$(lab_ssh "$PVE2_IP" "cat /root/.ssh/id_rsa.pub")
lab_ssh "$PVE1_IP" "mkdir -p /root/.ssh && chmod 700 /root/.ssh; \
grep -qF '$PVE2_ROOT_PUB' /root/.ssh/authorized_keys 2>/dev/null || echo '$PVE2_ROOT_PUB' >> /root/.ssh/authorized_keys"
# Pre-seed host keys so pvecm's ssh doesn't choke on prompts.
lab_ssh "$PVE2_IP" "ssh-keyscan -H ${PVE1_IP} pve1 >> /root/.ssh/known_hosts 2>/dev/null"
lab_ssh "$PVE1_IP" "ssh-keyscan -H ${PVE2_IP} pve2 >> /root/.ssh/known_hosts 2>/dev/null"
echo "==> Creating cluster '${CLUSTER_NAME}' on pve1"
if lab_ssh "$PVE1_IP" "pvecm status >/dev/null 2>&1"; then
echo " pve1 already in a cluster; skipping create"
else
lab_ssh "$PVE1_IP" "pvecm create ${CLUSTER_NAME}"
fi
# corosync reports quorate almost instantly for a single node, but pmxcfs
# (/etc/pve) takes longer to become WRITABLE after 'create'. 'pvecm addnode' on
# pve1 needs a writable /etc/pve or it dies "cluster not ready - no quorum?".
# So wait on an actual write to /etc/pve, not on the corosync quorum flag.
echo "==> Waiting for pve1 /etc/pve (pmxcfs) to become writable"
for i in $(seq 1 36); do
lab_ssh "$PVE1_IP" "echo ok >/etc/pve/.joincheck 2>/dev/null && rm -f /etc/pve/.joincheck" && break
sleep 5
done
# 'pvecm add' can print an error yet still exit 0, so success must be judged by
# the actual node count on pve1, and the join retried until it takes.
pve_nodes() { lab_ssh "$PVE1_IP" "pvecm nodes 2>/dev/null" | grep -cE 'pve[12]' || true; }
echo "==> Joining pve2 to the cluster"
if [[ "$(pve_nodes)" -ge 2 ]]; then
echo " pve2 already joined"
else
for attempt in 1 2 3 4 5; do
lab_ssh "$PVE2_IP" "pvecm add ${PVE1_IP} --use_ssh" || true
sleep 5
cnt="$(pve_nodes)"
if [[ "$cnt" -ge 2 ]]; then echo " joined: cluster now has $cnt node(s)"; break; fi
echo " join attempt ${attempt}: still $cnt node(s); waiting before retry..."
sleep 10
done
fi
cnt="$(pve_nodes)"
[[ "$cnt" -ge 2 ]] || { echo "ERROR: pve2 did not join (nodes=$cnt)"; exit 1; }
echo "==> Waiting for quorum"
for i in $(seq 1 30); do
if lab_ssh "$PVE1_IP" "pvecm status 2>/dev/null | grep -q 'Quorate: *Yes'"; then break; fi
sleep 5
done
echo "==> Cluster status"
lab_ssh "$PVE1_IP" "pvecm status; echo; pvecm nodes"
echo
echo "Cluster formed. Next: ./07-add-shared-storage.sh"