זה הפוסט הראשון בקטגוריה חדשה בבלוג. אשתף תקלות שנתקלתי בהם תוך כדי התמקדות במתודולוגיות עבודה ובתהליך המלא של תחקור התקלה. היום נדבר על GitLab Crash שהיה לנו. מי שלא מכיר את GitLab זו מערכת לניהול קוד עם מגוון פיצ’רים כמו ניהול משימות, CI ועוד הרבה.
מה קרה?
ה-GitLab שלנו פתאום קרס. זה קרה בשעות הצהריים ולא היה שום גורם מקדים לזה. בנוסף, יש לנו ניטורים סיסטמיים ואפליקטיביים על המערכת (dashboard-ים, ניטור על storage וכו’).
כיוון שיש הרבה מאוד משתמשים שצריכים שהמערכת תהיה זמינה עבורם זו הייתה תקלה גדולה והרגשנו הרבה לחץ על הכתפיים.
כשמשתמשים ניסו לגלוש הם לא קיבלו error כלשהו. הדפדפן נתקע ולא הצליח לטעון את התוכן של האתר.
מה ניסינו?
- התחברנו לשרת והסתכלנו על הסטטוס של כל ה-service-ים הפנימיים של gitlab (nginx, db, registry וכו’). כולם היו למעלה והם לא התרסטו לאחרונה. זמן מוערך של הפעולה – 2 דקות.
- הדבר הבא שעשינו היה להסתכל על הלוגים. הלוגים היו מחולקים לתיקיות לפי כל service.
- ישר חשדנו ב-timeout error שנגרם על ידי nginx או על ידי Puma (שרת web ש-nginx משתמש בו). הסתכלנו בלוגים בשני התיקיות תוך כדי פילטור על מילים ספציפיות כמו 500, error, timeout. היו התאמות אבל לא משהו אינדיקטיבי שיכל להצביע על הבעיה.
- לאחר מכן התקדמנו להסתכל על לוגים של עוד דברים. לדוגמא ה-service שאחראי על פעולות git, ה-db ועוד. שוב לא מצאנו משהו אינדיקטיבי.
- הסתכלנו על dashboard-ים שמנטרים על מגוון רחב של דברים שעיקרם אפליקטיביים:
- כמות בקשות.
- כמות error-ים של פניות לקוחות
- סטטוס של ה-db (האם הוא נעול וכולי).
- שימוש במשאבים (ram, cpu)
- בשלב הזה לא היה לנו כיוון והחלטנו שריסוט כללי של GitLab כנראה ייתן שקט זמני למפתחים כדי שיוכלו לדחוף את הקוד שלהם ולהריץ ci. זה ברור שהאידיאל הוא לפתור את התקלה אבל בעיניי צריך לשים את רצון הלקוח בעדיפות הראשונה. ואם עצירה זמנית של התחקור תתן ערך רב ללקוחות, עדיף לזרום איתם.
סיכום הפרק הראשון של התחקור: השקענו בין 15 – 20 דקות כדי לבדוק דברים כלליים ובעיות נפוצות ולא הצלחנו לקבל כיוון כלשהו. החלטנו לרסט את המערכת כי חלק גדול מהלקוחות היו צריכים להשתמש במערכת (גם אם לזמן קצר) כדי למבצע דברים. הריסוט פתר את הבעיה אבל כצפוי – זה היה פיתרון זמני.
המשך תחקור GitLab crash
- בשלב זה הבנו שהבעיה כנראה יותר גדולה ולא שגרתית. חשבנו ביחד כצוות אילו כיוונים חדשים אפשר לבדוק. עלו מספר רעיונות:
- בדיקה מתי התחברו לשרת בפעם האחרונה (גם מטעמי אבטחה וגם כדי להבין אם מישהו מאיתנו עשה שינויים לאחרונה).
- בדיקת היסטורית הפקודות שבוצעו על השרת (להבין אם הורצה פקודה שיכלה לגרום לזה).
- האם קבצי קונפיגורציה (כמו gitlab.rb) השתנו לאחרונה?
- הוצע רעיון של תשאול משתמשים בצ’אט של משתמשי המערכת לגבי שימוש חריג לאחרונה (כלומר אם משתמשים חוו unexpected behavior מכל סוג שהיא).
- חיפוש באינטרנט על התקלה שלנו.
זה כל הרעיונות שאני זוכר ובעיניי כולם טובים.
- התחלנו לבדוק את הכיוונים האלו במקביל (חילקנו משימות). אחרי בערך 20 דקות דיברנו על המסקנות של כל אחד.
- לא התחברו לשרת לאחרונה.
- לא היו פקודות חריגות שיכלו לגרום לתקלה.
- קבצי קונפיגורציות לא השתנו.
- משתמשים לא אמרו שהם חוו משהו חריג עם המערכת לאחרונה.
- באינטרנט היו כמה כיוונים :
- הסתכלות נוספת על קונפיגורציות של nginx
- בדיקת הקונפיגורציות של puma
- בדיקת workhorse service (אחראי על התמודדות עם בקשות איטיות)
- התחלנו לחקור לעומק את הכיוונים של האינטרנט (למרות שכולנו היינו סקפטיים לגבי זה כי הקונפיגורציות לא שונו כבר כמה שבועות). היה לנו מוזר שפתאום זה ייפול אבל עדיין עדיף לשמור על ראש פתוח ולבדוק כמה שיותר כיוונים.
- סרקנו עוד מידע מהאינטרנט, ניסינו לדבג בעזרת פקודות built in של GitLab שעוזרות לבדוק יותר לעומק status של service-ים.
הניסיונות העלו חרס ולא מצאנו משהו קונקרטי שיכל לעזור בתחקור התקלה.
בשלב הזה, כבר הייתה בערך השעה 16:00, 17:00 ולקראת סוף התחקור GitLab קרס שוב. זה חיזק אצלנו את ההבנה שצריך להמשיך להעמיק בדברים.
ריסטנו (כדי שהלקוחות יוכלו להמשיך לעבוד) והמשכנו לתחקר
המשך תחקור GitLab crash
- התחלנו לנסות דברים יותר באזורי ה-IT:
- ping מהשרת החוצה ומשרת אחר לשרת GitLab.
- בדקנו שהשרת וה-service-ים שלו מאזינים בפורטים שהם צריכים ושהפורטים עצמם פתוחים.
- בדקנו את מספר ה-file descriptors (fd) הפתוחים על השרת.
כל הניסיונות העלה לא חידשנו לנו יותר מדי אבל כן החלטנו לכתוב bash scripts שירוצו בלולאה כדי ש-GitLab יקרוס – נראה אם משהו השתנה על השרת.
כתבנו שני bash scripts:
- סקריפט ששולח בקשת get ל-GitLab כל שנייה באופן מחזורי. כאשר מקבלים error הוא מעתיק את כל תיקיית הלוגים הצידה כדי שיהיה לנו קל לפלטר על הלוגים הרלוונטיים.
- סקריפט שמדפיס כל שנייה לקובץ את מספר ה-fd הפתוחים על השרת.
אחרי שכתבנו אותם והרצנו אותם המשכנו לתחקר ולחפש עוד באינטרנט. כמו כן גם התייעצנו עם אנשי IT ואנשים שמכירים GitLab ועוד. לא חידשו לנו יותר מדי בשלב הזה.
הזמן של כתיבת ה-scripts והתייעצות עם אנשים היה בסביבות השעה.
עוד אנשים ניסו לעזור לנו עם התקלה והם גם דיברנו איתנו על gitlab workhorse (מה שאחראי על בקשות איטיות). כן ראינו דברים מוזרים בלוגים שלו אבל לא משהו קונקרטי.
שמנו לב שמשהו מוזר קורה עם התיקייה של gitlab workhorse. הלוגים שם לא עברו log rotate כמו שהם צריכים. המבנה של הקבצים לא היה כמו בתיקיות אחרות.
זה הדליק נורה אדומה שאולי שני service-ים מנסים לכתוב/למחוק log-ים בו זמנית.
כיוון חדש לתקלה
בשלב זה, זה היה הכיוון הכי חזק שלנו. במידה והכיוון נכון, לפני הקריסה הבאה של gitlab אנחנו אמורים לראות הרבה מאוד fd שלא נסגרים.
בשלב הזה היינו חסרי אונים. היינו בשלב שכדי לאשש את הטענות שלנו היינו צריכים לחכות לנפילה נוספת של GitLab.
המשכנו לתחקר ולחשוב בעוד כיוונים (אני לא זוכר כל כך אז אני מניח שלא היה כיוון חדש מעניין) .
לאחר שעה/שעתיים GitLab נפל שוב.
הסתכלנו ב-log-ים שהסקריפטים שלנו כתבו. ראינו עלייה חדה בכמות ה-fd הפתוחים בשניות לפני נפילת GitLab!!!!
הבנו שיש עוד משהו שכותב או מוחק לנתיב של gitlab workhorse logs.
באינטרנט כבר ניסינו לחפש על התנגשויות בין service-ים שכותבים לאותו נתיב אבל לא מצאנו משהו שיכול להיות רלוונטי ל-GitLab.
פתאום חשבנו אולי יש cron על השרת שעושה את זה?
בדקנו את זה וראינו שיש cron על השרת שרץ כמה פעמים ביום שמוחק log-ים מעל גודל מסוים! ישר באותו רגע הבנו…
אחד מחברי הצוות רשם cron שמנקה Log-ים ישנים יום לפני התקלה. ה-cron פשוט מחק לוגים מעל גודל מסוים בכל תיקיות ה–log-ים של המערכת (זה נרשם באופן זמני עד שצוות אחר יגדיל לנו את הנתיב הזה).
זה התנגש עם workhorse שרשם לוגים לנתיב הזה באותו הזמן ולכן GitLab לא ידע איך להתמודד עם זה, נוצרו מלא fd פתוחים וזה הוביל בסוף לקריסה של המערכת.
מחקנו במהירות את ה-cron, ריסטנו את המערכת וזה לא קרה יותר 🙂
מה אפשר ללמוד מהתקלה?
- לתעד הכול!!!! גם אם יש משהו זמני שעשינו על שרת (במיוחד אם הוא מבצעי) צריך להיות חדים על זה, לתעד ולבדוק שכולם מכירים את זה.
- לא להתייאש. התקלה לקחה לנו בסביבות 7 – 10 שעות במצטבר וזה מתסכל כשאתה מרגיש שאין כיוונים. דווקא בגלל זה צריך להמשיך לחשוב ביצירתיות ולא לפחד מכיוונים חדשים.
- לקחת הפסקות. זה אולי נשמע מיותר כשיש תקלה כזאת גדולה אבל בעיניי, זה חיוני. באותה תקלה עבדנו רצוף הרבה מאוד שעות חוץ מהפסקת אוכל של רבע שעה וזה השפיע על העירנות, הריכוז ועל התחושה הכללית.
- לרשום דברים שניסינו על לוח/מקור זמין אחר. כשמתחקרים תקלה, מאוד חשוב לדעת מה ניסינו, מה לא ניסינו, מה שינינו, מה הרצנו. זה דברים ששוכחים די מהר וגם אם בלהט הרגע האינסטינקט הוא לתחקר ולתעד אחר כך – אני ממליץ לשלב ביניהם.
אני מקווה שלמדתם, החכמתם ולקחתם מזה משהו לעצמכם!
1. לעדכן לפני ביצוע את כל חברי הצוות
2. לקבוע יום ל CAB – Change Advisory Board (CAB) בו מציגים את כל השינויים שהולכים להיות בשבוע הבא.
4. RFC פנימי/חיצוני בו ראש הצוות/מחלקה יהיה מעודכן על זה.
5. ראיתם שאין סעיף 3?
??
What I miss the most in this process is that you don’t have enough metrics about the server. Collecting metrics like number of open files of important processes or on the system in general should have shortened your time to resolution.
You absolutely write, that was fixed.
There are many things to monitor, and all of us should keep adding things and trying to challenge our systems.
אם cron גרם לתקלה האם זה קרה כל יום בשעות קבועות/עגולות? זה מרמז על כך שcron אחראי לבעייה.
בגדול אתה צודק. לפעמים ה-log rotate קרה ממש לפני ה-cron ואז התדירות קצת השתנתה, זה למה היה קצת קשה לעקוב אחרי זה.