Fix race su rs.initiate: attendi i 3 pod Mongo + directConnection in mongosh
Due bug che bloccavano deploy.sh su tenant con provisioning PVC lento: 1. Race DNS: lo step 8 aspettava solo mongodb-tenant-0 prima di rs.initiate. Se i pod 1/2 erano ancora in provisioning, i loro record DNS nel service headless non esistevano e rs.initiate falliva il quorum check con "Could not find address for mongodb-tenant-1...". Ora si attende che tutti e 3 i pod siano Ready. 2. mongosh "connection <monitor> closed": con --host 127.0.0.1, appena il replica set è inizializzato mongosh passa in modalità topology e prova a monitorare il PRIMARY via hostname annunciato, chiudendo la connessione. Sostituito con URI directConnection=true, compatibile con la localhost exception per la creazione del primo utente. Allineati gli hint diagnostici in deploy.sh e l'esempio rs.status() nel README al nuovo form directConnection. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -113,11 +113,17 @@ kc_cluster() { kubectl --context "$CONTEXT" "$@"; }
|
||||
# mongosh dentro pod-0 — JS letto da stdin per non esporre credenziali in argv
|
||||
# (kubectl exec mette argv nei log audit dell'API server e nel command line del kubelet).
|
||||
# Connessione mongosh dentro pod-0 con TLS verso 127.0.0.1.
|
||||
# - --tls + --tlsCAFile: valida il cert via la CA interna.
|
||||
# - --tlsAllowInvalidHostnames: il cert non include 'localhost' nei SAN; la CA però
|
||||
# - tls=true + tlsCAFile: valida il cert via la CA interna.
|
||||
# - tlsAllowInvalidHostnames: il cert non include 'localhost' nei SAN; la CA però
|
||||
# è validata, quindi MITM resta impossibile (siamo già dentro al pod).
|
||||
# - 127.0.0.1: necessario per la "localhost exception" di mongo (creazione primo utente).
|
||||
MONGO_TLS_ARGS=(--tls --tlsCAFile /etc/mongo-tls/ca.crt --tlsAllowInvalidHostnames --host 127.0.0.1)
|
||||
# - directConnection=true: OBBLIGATORIO. Appena il replica set è inizializzato,
|
||||
# senza directConnection mongosh passa in modalità topology e prova a monitorare
|
||||
# il PRIMARY tramite l'hostname annunciato (mongodb-tenant-0.<headless>): la
|
||||
# connessione di monitoring si chiude e ogni comando fallisce con
|
||||
# "connection <monitor> closed". directConnection forza la sessione sul solo
|
||||
# 127.0.0.1, restando compatibile con la localhost exception.
|
||||
MONGO_TLS_ARGS=('mongodb://127.0.0.1:27017/?directConnection=true&tls=true&tlsCAFile=/etc/mongo-tls/ca.crt&tlsAllowInvalidHostnames=true')
|
||||
|
||||
mongo_eval() {
|
||||
# Localhost exception: usabile solo prima della creazione del primo utente.
|
||||
@@ -358,16 +364,22 @@ done
|
||||
|
||||
render "$TEMPLATES_DIR/04-mongodb.yaml" | kc_cluster apply -f -
|
||||
|
||||
log " Attendo che $POD0 sia Ready (timeout 10 min — il provisioning PVC+attach può essere lento)"
|
||||
# kubectl wait sfrutta direttamente la readiness probe del pod. Dieci minuti
|
||||
log " Attendo che i 3 membri ($POD0, $POD1, $POD2) siano Ready (timeout 10 min — il provisioning PVC+attach può essere lento)"
|
||||
# kubectl wait sfrutta direttamente la readiness probe dei pod. Dieci minuti
|
||||
# coprono provisioning PVC + attach + boot Mongo anche su CSI lenti (vSphere,
|
||||
# Scaleway block storage in cold start, ecc.).
|
||||
if ! kc wait "pod/$POD0" --for=condition=Ready --timeout=600s 2>&1; then
|
||||
err "$POD0 non è Ready dopo 10 minuti. Diagnostica:
|
||||
# IMPORTANTE: aspettiamo TUTTI e 3 i pod, non solo pod-0. Il record DNS per-pod
|
||||
# del service headless (es. mongodb-tenant-1.<headless>) viene pubblicato solo
|
||||
# quando il pod è Ready: lanciare rs.initiate con il solo pod-0 pronto fa fallire
|
||||
# il quorum check con "Could not find address for mongodb-tenant-1...". Questo
|
||||
# accade quando pod-0 parte veloce e 1/2 sono ancora in provisioning PVC.
|
||||
if ! kc wait "pod/$POD0" "pod/$POD1" "pod/$POD2" --for=condition=Ready --timeout=600s 2>&1; then
|
||||
err "Uno dei pod mongodb-tenant-{0,1,2} non è Ready dopo 10 minuti. Diagnostica:
|
||||
kubectl --context '$CONTEXT' -n '$NAMESPACE' get pods
|
||||
kubectl --context '$CONTEXT' -n '$NAMESPACE' describe pod $POD0
|
||||
kubectl --context '$CONTEXT' -n '$NAMESPACE' logs $POD0 -c mongodb"
|
||||
fi
|
||||
ok "$POD0 pronto"
|
||||
ok "I 3 membri del replica set sono Ready"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Init replica set + utenti
|
||||
@@ -398,8 +410,9 @@ EOF
|
||||
STATE=$(echo "try { print('@@RES@@' + rs.status().members.find(m=>m.self).stateStr) } catch(e) { print('@@RES@@') }" | mongo_get)
|
||||
[[ "$STATE" == *"PRIMARY"* ]] && { ok "$POD0 è PRIMARY"; break; }
|
||||
[[ $i -eq 150 ]] && err "Nessun PRIMARY eletto entro 5 minuti.
|
||||
Diagnostica: kc exec $POD0 -c mongodb -- mongosh --tls --tlsCAFile /etc/mongo-tls/ca.crt \\
|
||||
--tlsAllowInvalidHostnames --host 127.0.0.1 --eval 'rs.status()'"
|
||||
Diagnostica: kc exec $POD0 -c mongodb -- mongosh --quiet \\
|
||||
'mongodb://127.0.0.1:27017/?directConnection=true&tls=true&tlsCAFile=/etc/mongo-tls/ca.crt&tlsAllowInvalidHostnames=true' \\
|
||||
--eval 'rs.status()'"
|
||||
sleep 2
|
||||
done
|
||||
else
|
||||
@@ -516,7 +529,8 @@ echo "Verifiche:"
|
||||
echo " kc get all"
|
||||
echo " kc logs deploy/tenant-api --tail=100 -f"
|
||||
echo " # Per rs.status() recupera la root password da $CREDS_FILE:"
|
||||
echo " kc exec $POD0 -c mongodb -- mongosh \\"
|
||||
echo " kc exec $POD0 -c mongodb -- mongosh --quiet \\"
|
||||
echo " 'mongodb://127.0.0.1:27017/?directConnection=true&tls=true&tlsCAFile=/etc/mongo-tls/ca.crt&tlsAllowInvalidHostnames=true' \\"
|
||||
echo " -u '$ROOT_USER' -p \"\$MONGO_ROOT_PASSWORD\" --authenticationDatabase admin \\"
|
||||
echo " --eval 'rs.status()'"
|
||||
echo
|
||||
|
||||
Reference in New Issue
Block a user