ממסר ה-VPN מפסיק לקבל SSH: מגבלות מתארי קבצים
תעבורת המנהרה ממשיכה לזרום בעוד ממסר ה-socat שמאחוריה מסרב לחיבורים חדשים. עקבו אחרי הנתיב, ואז קראו את המגבלה בירושה על ה-PID החי.
לחיצת יד של WireGuard עדיין מסתיימת, ה-peer עדיין מציג נקודת קצה עדכנית, ובכל זאת הפעלת SSH חדשה דרך הממסר שמאחוריו נתקעת בלי באנר. הצירוף הזה מפנה הרחק מהמנהרה ואל התהליך שמקבל את ה-socket. ממסר כמו socat יושב בנתיב היישום עם תקציב מתארים משלו, ילדים משלו ומגבלות בירושה משלו. המסלול שלמטה מתחיל אצל הלקוח ונעצר ברכיב הראשון שאינו יכול לפתוח socket נוסף.
עקבו אחרי הנתיב לפני שמשנים מספר
עקבו אחרי בקשה אחת שנכשלה במקום לנמק על המנהרה כולה. הלקוח כותב אל המנהרה, דמון ה-VPN מפענח ומנתב, והממסר מקבל בצד השני. כל שלב צורך מתארים, וזה שבדרך כלל נגמר הוא האחרון.
התחילו מבקשה שאתם יכולים לשחזר ומדדו את זמנה. אם לחיצת היד של TCP מסתיימת אבל באנר של היישום לא מגיע, הממסר לקח את ה-socket ואז נתקע בילד או ברגל ה-upstream שלו. אם לחיצת היד עצמה לעולם לא מסתיימת, הסיבה היא ניתוב, חומת אש או מצב מאזין, לא תקרת מתארים. רשמו איזו משתי הצורות ראיתם, כי הן מפנות לתהליכים שונים.
ספרו גם את הקפיצות שמכפילות עבודה. מאזין שמתפצל מוסר כל socket שהתקבל לילד ששומר עותק משלו, ולכן הסכום האמיתי הוא תכונה של כל העץ, לא של האב בלבד.
קראו את המגבלה שהממסר ירש
המגבלה היחידה שחשובה שייכת לתהליך שרץ, והיא נקבעה על ידי מה שהשיק את התהליך. הקלדת ulimit -n ב-shell מתארת את ה-shell. שאלו את מנהל השירותים מה הוא יישם, ואז אשרו על ה-PID.
systemctl show -p MainPID -p LimitNOFILE vpn-relay.service
cat /proc/$(systemctl show -p MainPID --value vpn-relay.service)/limits
הקובץ limits מדפיס את התקרה הרכה והקשיחה כפי שהתהליך רואה אותן. ערך רך נמוך מתחת לערך קשיח נדיב פירושו שהדמון רשאי להעלות את התקרה שלו, ויש כאלה שעושים זאת באתחול; ערכים רכים נמוכים ושווים פירושם שקובץ ה-unit הוא המקור.
קובצי drop-in נטענים בסדר לקסיקוגרפי וקבצים מאוחרים יותר מנצחים, ולכן systemctl cat vpn-relay.service הוא התצוגה הסמכותית של מה שחל. עריכת קובץ שהמנהל אף פעם לא קורא היא הסיבה הנפוצה ביותר לכך שמספר מוגבה אינו משפיע.
הפרידו בין מקביליות יציבה לבין מצב נשמר
שני תהליכים יכולים לפגוע באותה תקרה מסיבות לא קשורות, והתרופות שונות. ביקוש שעוקב אחרי הפעלות מקבילות שימושיות הוא שאלת קיבולת. גדילה שנמשכת אחרי שהעבודה נגמרה היא דליפה או קבוצה של הפעלות שאיש לא סגר.
מדדו במנוחה, בשיא הרגיל שלכם, ושוב כמה דקות אחרי שהעומס נפסק. ספירת רשומות פתוחות עם ls /proc/PID/fd | wc -l מול המגבלה הרכה מספרת לכם את הפער, וספירה אחת או שתיים מתחת לתקרה היא עצירה קשה ולא מסלול איטי.
כשהספירה מסרבת לרדת, הסתכלו על מצבי socket ולא על סכומים. מתארים שיושבים ב-CLOSE_WAIT פירושם שה-peer סגר והצד שלכם מעולם לא עשה זאת, וזה פגם במחזור החיים של היישום שמגבלה גדולה יותר רק דוחה. הגבילו גם את מודל הילדים: ממסר מתפצל בלי תקרה על ילדים מקבילים מכלה מתארים, מקומות תהליך וזיכרון יחד.
בדקו את הערך החדש על התהליך החי
אחרי עריכת ה-unit, טענו מחדש את המנהל והפעילו מחדש את השירות, שכן טעינה מחדש לבדה לעולם אינה מחליפה מגבלות שכבר ירש תהליך רץ. אמתו על התהליך שבאמת משרת תעבורה.
systemctl daemon-reload
systemctl restart vpn-relay.service
awk '/Max open files/ {print}' /proc/$(systemctl show -p MainPID --value vpn-relay.service)/limits
ss -tnp state established '( sport = :2222 )' | wc -l
השורה awk מחזירה את הזוג החדש; אם היא עדיין מציגה את הישן, ה-drop-in שערכתם אינו זה שנטען. ספירת ss היא בדיקת העומס שלכם, אז פתחו את מספר ההפעלות שאתם מצפים לו וצפו בו עולה. ספירה שממשיכה לעלות אחרי סגירת ההפעלות האלה פירושה שהמגבלה מעולם לא הייתה כל הבעיה.
אזהרה אחת מלווה כל הגדלה גדולה. יישומים שמתשאלים עם select() אינם יכולים לצפות במתארים מעל FD_SETSIZE, שהוא 1024 בבניות טיפוסיות, ולכן תקרה שהועלתה מעל לכך עלולה לייצר כשלים שנראים לא קשורים. מדריך ההרצה של systemd נושא את אותה אזהרה לשירותים שהוא מפעיל.
הרחיקו את ההפעלה מחדש מזמינות המנהרה
הפעלה מחדש של הממסר מפילה את ההפעלות הפעילות שלו, וזה אירוע נפרד מהירידה של ה-VPN. סדרו את השינוי כך שהמנהרה תישאר למעלה בזמן שהממסר עובר מחזור, והזהירו כל מי שהפעלתו הארוכה חוצה אותו.
חזרה לאחור היא קובץ ה-unit הקודם ועוד הפעלה מחדש, והקובץ הזה נשאר במקומו עד שהערך החדש ישרוד יום עבודה. אחר כך סגרו את הלולאה עם הבקשה שנכשלה במקור: הפעלת SSH חדשה אחת דרך הממסר, העברה אחת ארוכה מספיק כדי למנות, וספירת מתארים שחוזרת לרמת המנוחה שלה.