From d3a9739f2f94f1316b62fbee6dffc4096a1c39c5 Mon Sep 17 00:00:00 2001 From: Luca Date: Fri, 5 Jun 2026 12:18:14 +0200 Subject: [PATCH] Fix race su rs.initiate: attendi i 3 pod Mongo + directConnection in mongosh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 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) --- README.md | 4 ++-- deploy.sh | 36 +++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 1048f9a..ee7eece 100644 --- a/README.md +++ b/README.md @@ -119,8 +119,8 @@ kubectl -n logs deploy/tenant-api --tail=100 -f ```bash ROOT_PASS=$(kubectl -n get secret mongodb-tenant-auth -o jsonpath='{.data.root-password}' | base64 -d) -kubectl -n exec mongodb-tenant-0 -c mongodb -- mongosh \ - --tls --tlsCAFile /etc/mongo-tls/ca.crt --tlsAllowInvalidHostnames --host 127.0.0.1 \ +kubectl -n exec mongodb-tenant-0 -c mongodb -- mongosh --quiet \ + 'mongodb://127.0.0.1:27017/?directConnection=true&tls=true&tlsCAFile=/etc/mongo-tls/ca.crt&tlsAllowInvalidHostnames=true' \ -u admin -p "$ROOT_PASS" --authenticationDatabase admin \ --eval 'rs.status()' ``` diff --git a/deploy.sh b/deploy.sh index 7576251..994cf7b 100755 --- a/deploy.sh +++ b/deploy.sh @@ -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.): la +# connessione di monitoring si chiude e ogni comando fallisce con +# "connection 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.) 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