↓ דילוג לתוכן
  1. כתבות/

המקרה המוזר של ה-DNS שנעלם בשעת לילה

·939 מילים·5 דקות
רועי בנדל
מחבר
רועי בנדל
תוכן עניינים

אני מריץ את ה-Homelab as Code מבוסס ה-Kubernetes שלי כבר שישה חודשים. זו חוויה מאתגרת אך מתגמלת. הפעלת הומלאב מהונדס-יתר (over-engineered) עלולה לא פעם להביא יותר צרות מתועלת, אך יחד עם זאת אני מוצא את עצמי לומד שיעורים יקרי ערך.

התקרית

מוקדם יותר השבוע, קראתי על סרט שרציתי לראות והחלטתי להוסיף אותו לרשימת הצפייה שלי ב-Floppy, אחד השירותים שפרסתי לאחרונה כדי לעקוב אחר מדיה.

כשניסיתי לגשת לדומיין שלי מהטלפון, קיבלתי את שגיאת ה-ERR_CONNECTION_REFUSED המאיימת. מה קרה כאן? זה יכול היה לנבוע ממגוון רחב של סיבות. ניהול הומלאב מבוסס Kubernetes מלמד אותך מהר מאוד את כל דפוסי הכשל המרתקים של פריסת עומסי עבודה ברמת enterprise על גבי מחשבי מיני-PC חלשים: nodes בעומס יתר, בעיות קישוריות, לולאות קריסה (crash loops), ועוד המון. בשלב זה, כבר ראיתי יותר ממה שהייתי רוצה להודות. עם זאת, התברר שהבעיה לא נבעה מאף אחד מאלה.

כשניגשתי למחשב הנייד שלי, הופתעתי לראות שכל השירותים פועלים ללא דופי: הקלאסטר היה בריא ב-100%, וכל הפודים (pods) רצו. בשלב זה, אם הניחוש הראשון שלכם לגבי הגורם לבעיה היה DNS, צדקתם לחלוטין. הכל עבד במחשב הנייד שלי, אך לא בטלפון, הודות ל-split-horizon DNS, מה שאומר שהמחשב הנייד התחבר ישירות לרשת ההומלאב, בעוד שהטלפון שלי התחבר לדומיין הציבורי דרך ה-DNS הציבורי.

אני מנהל את כל הדומיינים ורשומות ה-DNS שלי דרך Cloudflare. כשנכנסתי ללוח הבקרה (dashboard) של Cloudflare, נחרדתי לגלות שכל רשומות ה-DNS נעלמו. זה הסביר את הבעיה, אך לא את הסיבה. מה גרם למחיקת רשומות ה-DNS? בדקתי את פריסת ה-GitOps שלי עבור external-dns. לא ביצעתי שום שינוי ברשומות ה-DNS הדקלרטיביות שלי לאחרונה, כך שזה לא יכול היה להיות הגורם, נכון? בדיוק אז נזכרתי שמיזגתי עדכון chart של external-dns בלילה שלפני כן (באמצעות Renovate).

רשומות DNS חסרות עבור הדומיין בלוח הבקרה של Cloudflare

האשם

בחודש שעבר, פרויקט external-dns שחרר את v0.22.0 עם השינוי השובר (breaking change) הבא:

Quote
  • ⚠️ The default annotation prefix is now external-dns.kubernetes.io/ with no fallback (#6424)

    • 🚨 This change can delete all your DNS records.

המקור של השינוי הזה היה pull request ממאי, ששינה את קידומת ברירת המחדל של annotations עבור external-dns. הבעיה היא שכאשר external-dns מוגדר עם מדיניות sync, הוא מאפשר מחיקה של רשומות DNS שאינן מנוהלות. ברגע שקידומת ברירת המחדל השתנתה, כל משאבי הקלאסטר שהחזיקו ב-annotations הישנות נחשבו כעת כבלתי מנוהלים, מה שגרם ל-external-dns למחוק את כל רשומות ה-DNS של המשאבים הללו.

הפתרון

ה-pull request של external-dns הציע את הפתרון הבא:

This change can be harmless for users that needs or want to stay with previous prefix. ExternalDNS can be configured to use it:

--annotation-prefix=external-dns.alpha.kubernetes.io/

אמנם השינוי היה רחוק מלהיות נטול נזק, ולדעתי היה מקום לתקשר אותו בצורה טובה בהרבה, אך הפתרון הזה אכן עובד.

חלופה נוספת היא לעדכן את כל ה-annotations כך שישתמשו בקידומת החדשה, באמצעות החלפת external-dns.alpha.kubernetes.io/ ב-external-dns.kubernetes.io/. בקלאסטר המנוהל ב-GitOps כמו ה-homelab-as-code שלי, מדובר בפתרון פשוט ברגע שיודעים מה לחפש. ואכן, זה הפתרון שבחרתי בו: fix(dns): migrate ExternalDNS annotation prefix by roib20 · Pull Request #1341 · roib20/homelab-as-code.

ברגע שה-pull request מוזג, הבעיה נפתרה לחלוטין עבורי: רשומות ה-DNS הוגדרו מחדש במהירות על ידי external-dns שהתחבר ל-Cloudflare DNS, והגישה לדומיין שלי שוחזרה (לאחר השלמת ה-DNS propagation).

תגובת הקהילה

ב-pull request של external-dns, תגובת הקהילה הייתה קשה (אך הוגנת). הנה כמה מהתגובות:

Quote

In hindsight, I think the release that included this change should have been v1.0.0 by this logic and more importantly to draw more attention to the massive breaking change included in this that can wipe/misconfigure DNS, or leak sensitive info and IP addresses via misconfigured DNS entries. If the project wasn’t ready for v1.0.0 then the alpha annotation is (was) still very much necessary and this should not have been merged. Not much we can do now though, except incorporate the lessons learned for the future since the act of retracting the release would probably also cause harm as well.


how is this a minor? Not cool. ⚠️ The default annotation prefix is now external-dns.kubernetes.io/ with no fallback (#6424)

🚨 This change can delete all your DNS records.

What a disaster.


It seems extremely irresponsible to release this without a safe and easy-to-understand migration path. I’m glad I always read the release notes!

התגובה הרשמית הייתה:

Quote

We hear you. Please do not upgrade if you do not have done it already we discuss the best solution to move out of this. Sorry that it happened, we are all human and can do errors (oh AI can also do errors). Thanks for your understanding.

עדכון ה-Helm Chart

שלושה שבועות לאחר מכן, שוחרר external-dns-helm-chart-1.22.0. זה היה העדכון שמחק את רשומות ה-DNS שלי. עדכון ה-chart צירף בתוכו את עדכון האפליקציה v0.22.0. בנוסף, ל-chart היה שינוי שובר משל עצמו, שדרש הגדרת ערך policy שלא היה חובה בגרסאות קודמות של ה-chart.

דעתי

לדעתי, מתחזקי external-dns היו צריכים לקדם את הגרסה הראשית (major version) הן של האפליקציה והן של ה-Helm chart. למרות שתמיד חשוב לקרוא release notes, מפתחים ומנהלי מערכות מסתמכים על פרויקטים שיפעלו לפי גרסאות סמנטיות ויקדמו את הגרסה הראשית כאשר ישנם שינויים שוברים. סייג לכך הוא שעד היום, תשע שנים לאחר שחרורו הראשוני, פרויקט external-dns עדיין נמצא בגרסה ראשית 0, שאינה נחשבת ליציבה ואינה מספקת ערבויות כלשהן. מאידך, ה-Helm chart נמצא בגרסה ראשית 1, והיה צריך לקדם בו את הגרסה הראשית עקב השינויים השוברים.

פרויקט external-dns הוא חלק מארגון Kubernetes SIGs. קוברנטיס עצמה ספגה ביקורת בעבר על האופן שבו היא מיישמת גרסאות סמנטיות.

הסבר על גרסאות ‘סמנטיות’ ב-Kubernetes

בסופו של דבר, אני רואה בכך הזדמנות למידה חשובה. אני שמח שזה קרה לי בהומלאב ולא בסביבת אמת (production). במקום להרתיע אותי מלהשתמש ב-external-dns ב-production, הניסיון הזה עודד אותי להיות ערני במיוחד לקריאת release notes (בכל הפרויקטים). אני משתמש ב-external-dns כבר שנים. לדוגמה, הנה דמו שיצרתי לפני ארבע שנים המציג external-dns דקלרטיבי.

בסופו של דבר, החלק הכי מתסכל היה שעד שסיימתי לטפל בתקרית הזו, כבר שכחתי איזה סרט בכלל רציתי להוסיף ל-Floppy. אני מאשים את ה-DNS.


תמונה מוצגת מאת Conny Schneider ב-Unsplash.

Related

חברות טכנולוגיה רוכשות את הכלים האהובים עליי

··975 מילים·5 דקות
במאמר ‘Next Generation Tooling for Developers’ תהיתי כיצד החברות הללו, הממומנות בהון סיכון, ירוויחו כסף. מאז רובן נרכשו: Anthropic רכשה את Oven, החברה שמאחורי Bun; Cloudflare רכשה את Astro ואת VoidZero; ו-OpenAI רכשה את Astral.