
מעקב אחר חיבורים ("conntrack") הוא מאפיין ליבה של מחסנית הרשת של ליבת לינוקס. זה מאפשר לקרנל לעקוב אחר כל חיבורי הרשת הלוגיים או הזרימות ובכך לזהות את כל החבילות המרכיבות כל זרימה כך שניתן יהיה לעבד אותן יחד ברצף.
Conntrack היא תכונת ליבה חשובה המשמשת בכמה מקרים בסיסיים:
- NAT מסתמך על מידע מ-conntrack כך שהוא יכול להתייחס לכל החבילות מאותו זרם באופן שווה. לדוגמה, כאשר פוד ניגש לשירות Kubernetes, מאזן העומס של kube-proxy משתמש ב-NAT כדי להפנות תעבורה לפוד ספציפי בתוך האשכול. Conntrack רושם כי עבור חיבור נתון, כל החבילות לשירות ה-IP חייבות להישלח לאותו פוד, וכי מנות המוחזרות על ידי הפוד האחורי חייבות להיות משוחזרות ל-Pod שממנו הגיעה הבקשה.
- חומות אש מתקדמות כגון Calico מסתמכות על מידע מ-connecttrack ועד לתעבורת "תגובה" ברשימת ההיתרים. זה מאפשר לך לכתוב מדיניות רשת שאומרת "אפשר לפוד שלי להתחבר לכל כתובת IP מרוחקת" מבלי שתצטרך לכתוב מדיניות שתאפשר במפורש תעבורת תגובה. (בלי זה, תצטרך להוסיף את הכלל הרבה פחות מאובטח "אפשר מנות לתרמיל שלי מכל IP").
בנוסף, conntrack משפר בדרך כלל את ביצועי המערכת (על ידי הפחתת צריכת המעבד והשהיית מנות) מכיוון שרק החבילה הראשונה בזרם
חייב לעבור על כל ערימת הרשת כדי לקבוע מה לעשות איתה. ראה את הפוסט""כדי לראות דוגמה איך זה עובד.
עם זאת, ל-conntrack יש מגבלות...
אז איפה הכל השתבש?
לטבלת ה-conntrack יש גודל מקסימלי שניתן להגדרה, ואם הוא מתמלא, חיבורים בדרך כלל מתחילים להידחות או להישמט. יש מספיק מקום פנוי בטבלה כדי להתמודד עם התעבורה של רוב היישומים, וזה לעולם לא יהפוך לבעיה. עם זאת, ישנם כמה תרחישים שבהם כדאי לשקול להשתמש בטבלת החיבורים:
- המקרה הברור ביותר הוא אם השרת שלך מטפל במספר גדול מאוד של חיבורים פעילים בו-זמנית. לדוגמה, אם טבלת ה-conntrack שלך מוגדרת עבור 128 כניסות, אבל יש לך יותר מ-128 חיבורים במקביל, אתה בוודאי תיתקל בבעיה!
- מקרה קצת פחות ברור: אם השרת שלך מעבד מספר גדול מאוד של חיבורים בשנייה. גם אם החיבורים קצרי מועד, הם ממשיכים להיות במעקב על ידי לינוקס למשך תקופה מסוימת (120 שניות כברירת מחדל). לדוגמה, אם טבלת ה-conntrack שלך מוגדרת ל-128k כניסות ואתה מנסה לטפל ב-1100 חיבורים בשנייה, הם יחרגו מהגודל של טבלת ה-conntrack, גם אם החיבורים קצרים מאוד (128k/120s = 1092 connections/ ס).
ישנם מספר סוגי נישה של אפליקציות הנכללות בקטגוריות אלו. בנוסף, אם יש לך הרבה שחקנים גרועים, מילוי טבלת החיבורים של השרת שלך בהרבה חיבורים פתוחים למחצה יכול לשמש כחלק מהתקפת מניעת שירות (DOS). בשני המקרים, conntrack יכול להפוך לצוואר בקבוק מגביל במערכת שלך. במקרים מסוימים, התאמת פרמטרי טבלת ה-conntrack עשויה להספיק כדי לענות על הצרכים שלך - על ידי הגדלת הגודל או הקטנת פסקי הזמן של ה-conntrack (אבל אם תעשה זאת לא נכון, תתקל בצרות רבות). במקרים אחרים יהיה צורך לעקוף את הכביש לתנועה אגרסיבית.
דוגמא אמיתית
בואו ניתן דוגמה ספציפית: לספק SaaS אחד גדול שעבדנו איתו היו מספר שרתים מאוחסנים ב-memcached במארחים (לא במכונות וירטואליות), שכל אחד מהם עיבד 50K+ חיבורים קצרי טווח בשנייה.
הם ערכו ניסויים בתצורת ה-conntrack, הגדלת גדלי הטבלה והקטנת זמן המעקב, אבל התצורה לא הייתה אמינה, צריכת ה-RAM גדלה משמעותית, מה שהיווה בעיה (בסדר ג'יגה בייט!), והחיבורים היו כל כך קצרים עד שה-conntrack לא היה אמין. ליצור את יתרון הביצועים הרגיל שלו (צריכת מעבד מופחתת או חביון מנות).
הם פנו לקאליקו כחלופה. מדיניות רשת Calico מאפשרת לך לא להשתמש ב-conntrack עבור סוגים מסוימים של תעבורה (באמצעות אפשרות המדיניות doNotTrack). זה נתן להם את רמת הביצועים הדרושים להם, בתוספת רמת האבטחה הנוספת שסיפקה Calico.
לאיזה אורך תצטרך ללכת כדי לעקוף את הקשר?
- מדיניות רשת לא לעקוב צריכה בדרך כלל להיות סימטרית. במקרה של ספק ה-SaaS: האפליקציות שלהם רצו בתוך האזור המוגן ולכן, באמצעות מדיניות רשת, הם יכלו לרשום תעבורה מיישומים ספציפיים אחרים שקיבלו גישה ל-memcached.
- מדיניות "אל תעקבו" אינה לוקחת בחשבון את כיוון החיבור. לפיכך, אם שרת ה-memcached נפרץ, אתה יכול תיאורטית לנסות להתחבר לכל אחד מלקוחות memcached, כל עוד הוא משתמש ביציאת המקור הנכונה. עם זאת, אם הגדרת נכון את מדיניות הרשת עבור לקוחות ה-memcached שלך, ניסיונות החיבור הללו עדיין יידחו בצד הלקוח.
- מדיניות ה-do not-track מוחלת על כל חבילה, בניגוד למדיניות רגילה, המוחלת רק על החבילה הראשונה בזרימה. זה יכול להגדיל את צריכת ה-CPU לכל מנה מכיוון שיש להחיל את המדיניות עבור כל מנה. אבל עבור חיבורים קצרי מועד, הוצאה זו מאוזנת על ידי הפחתת צריכת המשאבים לעיבוד חיבורים. לדוגמה, במקרה של ספק SaaS, מספר החבילות לכל חיבור היה קטן מאוד, כך שצריכת ה-CPU הנוספת בעת החלת מדיניות על כל מנה הייתה מוצדקת.
בואו נתחיל בבדיקה
הרצנו את הבדיקה על פוד בודד עם שרת memcached ומספר רב של memcached client pods הפועלים על צמתים מרוחקים כך שנוכל להריץ מספר גדול מאוד של חיבורים בשנייה. לשרת עם ה-memcached server pod היו 8 ליבות ו-512k כניסות בטבלת conntrack (גודל הטבלה המוגדר הסטנדרטי עבור המארח).
מדדנו את ההבדל בביצועים בין: אין מדיניות רשת; עם מדיניות Calico רגילה; ומדיניות אי-מעקב של Calico.
בבדיקה הראשונה, הגדרנו את מספר החיבורים ל-4.000 בשנייה, כדי שנוכל להתמקד בהבדל בצריכת המעבד. לא היו הבדלים משמעותיים בין היעדר מדיניות לבין מדיניות רגילה, אך אל תעקוב אחר הגדילה את צריכת המעבד בכ-20%:

בבדיקה השנייה, השקנו כמה חיבורים שהלקוחות שלנו יכולים ליצור ומדדנו את המספר המרבי של חיבורים בשנייה שהשרת ה-memcached שלנו יכול להתמודד איתו. כצפוי, המקרים של "אין מדיניות" ו"מדיניות רגילה" הגיעו שניהם למגבלת החיבור של למעלה מ-4,000 חיבורים לשנייה (512k / 120s = 4,369 חיבורים/s). עם מדיניות אל-לעקוב, הלקוחות שלנו שלחו 60,000 חיבורים בשנייה ללא כל בעיה. אנחנו בטוחים שנוכל להגדיל את המספר הזה על ידי הוספת לקוחות נוספים, אבל אנחנו מרגישים שהמספרים האלה כבר מספיקים כדי להמחיש את הפואנטה של מאמר זה!

מסקנה
Conntrack הוא תכונת ליבה חשובה. הוא עושה את העבודה שלו בצורה מושלמת. הוא משמש לעתים קרובות על ידי רכיבי מערכת מרכזיים. עם זאת, בכמה תרחישים ספציפיים, העומס הנובע מהקשר עולה על היתרונות הרגילים שהוא מספק. בתרחיש זה, ניתן להשתמש במדיניות הרשת של Calico כדי להשבית באופן סלקטיבי את השימוש ב-conntrack תוך הגברת אבטחת הרשת. עבור כל תנועה אחרת, conntrack ממשיך להיות חבר שלך!
קרא גם מאמרים אחרים בבלוג שלנו:
מקור: www.habr.com
