כאשר ארגונים מבצעים הגירת סביבות מחשוב קיימות לענן, או כאשר הם בונים ומטמיעים סביבות חדשות בענן, קיימות מספר חלופות לביצוע המשימה – אין כאן תשובה נכונה או שגויה.
במאמר זה, נסקור כיצד היינו משתמשים בתשתיות מחשוב בעבר (בדרך המסורתית והמוכרת) ומהן החלופות המודרניות להטמעת סביבות מחשוב כיום בסביבת ענן ציבורי.
פריסת סביבות בשיטה המסורתית והמוכרת
בעבר, כאשר נדרשנו להטמיע סביבת פיתוח/בדיקות או אפילו סביבת production עבור שירות חדש או אפליקציה, נהגנו להסתכל על ארכיטקטורת 3 שכבות, המורכבת משכבת תצוגה (לרוב מדובר בשרת Web או התקנת אפליקציה בצד הלקוח), שכבת הלוגיקה העסקית (כגון שרת אפליקציה) ושכבת אחסון נתונים (דוגמת בסיס נתונים).
מכיוון שכל שכבה מקושרת בצורה הדוקה לייתר השכבות, בכל פעם שנדרשנו לבצע שדרוג תוכנה או הוספת שרת (לצורכי שרידות או התמודדות עם עומסים), נדרשנו לבצע השבתה מלאה של השירות (או האפליקציה) ולמעשה מימשנו כאן monolith.
מדובר בתהליך מסורבל, אשר לוקח מספר שבועות הכוללים התקנת מערכת ההפעלה, הוספת שכבות האפליקציה, הגדרות האפליקציה, תהליך בדיקות, אישור מהגורם העסקי ("בעל האפליקציה") ועוד זמן כמעט זהה לביצוע עבור פריסת סביבת ה-production.
התהליך ישים עבור פריסת סביבות קטנות או עבור יישומים קטנים ופשוטים, המשרתים מספר נמוך יחסית של לקוחות.
לרוב נתמקד בהיבטי התשתית, ייתכן שנבחר להטמיע את כלל מרכיבי התשתית והאפליקציה על גבי שרת בודד, עד השלב בו נגיע למגבלות החומרה (מבחינת צריכת מעבד, זיכרון, נפחי אחסון, תעבורת תקשורת ועוד), לפני שנבחר לבצע scale-up ולהגר לחומרה חזקה יותר (מבחינת כמויות מעבדים, זיכרון, נפחי אחסון וכרטיס תקשורת מהיר יותר), עד השלב בו נגלה כי גם להחלפת החומרה יש מגבלות סופיות והיא אינה מספיקה על-מנת לשרת לקוחות רבים לאורך זמן.
כאשר החלפת סוג השרת אינו פותרת את צווארי הבקבוק, נתחיל בתהליך של scale-out, ע"י הוספת שרתים נוספים (כגון הוספת שרתי Web, בניית cluster של שרתי database וכו') ואז אנו מוצאים את עצמנו מתמודדים עם עולם חדש של אתגרים, כאשר אנו נדרשים להשבית את כלל ה-monolith שלנו, בכל פעם שנרצה לבצע הפצת עדכוני אבטחה, שדרוגי תוכנה ועוד.
הגירת יישומים תוך שמירה על הארכיטקטורה הנוכחית של האפליקציה (מסביבת ה-On premise) בתהליך הידוע גם כ-lift & shift, הינה חלופה ישימה, אך חשוב שנכיר את היתרונות והחסרונות של חלופה זו:
יתרונות:
- שמירה על הארכיטקטורה הקיימת
- פחות ידע נדרש מגופי התשתיות
- קיצור הזמן שלוקח להגר סביבה קיימת לענן
- ככל הנראה נוכל לשמור על ההשקעה שביצענו ברכישת רישיונות ("Bring your own license")
- ככל הנראה נוכל להמשיך להשתמש בתשתיות הקיימות מסביבת ה-on premise (דוגמת מערכות גיבויים, ניטור וכלי הפצת תוכנה)
חסרונות:
- שימוש במודל תשלום עבור שימוש בפועל ( “Pay as you go” או "On demand") מתאים לדפוסי שימוש אשר אין לנו אפשרות לצפות אותם מראש (דוגמת סביבת פיתוח או בדיקות), אך מהר מאוד העלות הקבועה תיהפך לרכיב יקר במשוואה, כאשר נעבור לסביבות production, הפועלות 24×7 (גם כאשר מחשבים עלות שעתית), בהשוואה לרכש חומרה פיזית לסביבות ה-on premise, אשר רכש חומרה פיזית מאפשר לנו לנצל את משאבי החומרה ללא מגבלת שעות (עד אשר מסתיימת אחריות היצרן על חומרה…)
- כאשר אנו מטמיעים שרתים וירטואליים בענן, בדומה לסביבת ה-On premise, אנו נשארים אחראיים על תחזוקת מערכת ההפעלה (עדכונים, גיבויים, ניטור, הפצת agents למיניהם וכו') – ככל שחוות השרתים שלנו גדולה יותר, כך גדלה התקורה על תחזוקת חוות השרתים, עד השלב בו הדבר אינו scale מספיק ואנו נדרשים לצוותי תשתיות גדולים יותר ובכך אנו מקטינים את הערך המוסף לארגון וללקוחות שלנו.
פריסת סביבות בצורה מודרנית
הדגש על פיתוח והפצת סביבות בצורה מודרנית, אשר ידוע לעיתים בכינוי "Cloud Native applications", מבוסס על שירותים (במקום על שרתים ועליהם שכבת אפליקציה) והוא מאפשר לנצל את היתרונות המובנים בענן:
יכולת גידול (Scale) – אנו בונים את השירותים שלנו על-מנת שיכולו לשרת מיליוני לקוחות בו-זמנית (במקום מאות בודדות של לקוחות)
גמישות (Elasticity) – היכולות להגדיל ולהקטין את משאבי התשתית בהתאם לעומסים על האפליקציה שלנו
זמינות (High Availability) – במקום לחשוף לגישת לקוחות שירות המבוסס על שרת בודד ב-data center בודד, אנו מתקינים מספר רב של שרתים (מאחורי רכיב מנוהל של Load Balancer) ואנו פורסים את השרתים על פני מספר availability zones (לרוב availability zone פירושו data center), דבר המאפשר לנו לנטר את העומס והזמינות של חוות השרתים ובצורה אוטומטית להחליף שרת שאינו מתפקד או להוסיף שרת בהתאם לעומס הנדרש.
בשל העובדה שהענן מאפשר לנו לצרוך שירותים מנוהלים (מרכיבי Load-balancer, רכיבי NAT Gateway, שירותי VPN, שירותי אחסון מסוג object storage, בסיסי נתונים מנוהלים ועוד), אנו נהנים מ-SLA מובטח מספקי הענן, דבר מאוד מאתגר ליישום בסביבות ה-data center המסורתיות.
Observability – בעבר נהגנו לנטר מדדים בסיסיים דוגמת עומס על המעבד או הזיכרון, מקום פנוי בדיסק (או כמות קריאות/כתיבות לדיסק), אך כעת, אנו מסוגלים להוסיף יותר ויותר מדדי ניטור אודות האפליקציה עצמה (כגון מספר משתמשים בו-זמנית, משך הזמן לביצוע שאילתה מול בסיס הנתונים, כמות הודעות שגיאה משרת ה-Web, תקשורת בין רכיבי המערכת ועוד), דבר המאפשר לנו לצפות מראש תקלות ברמת השירות עצמו, לפני שהלקוחות שלנו יחוו זאת בעצמם.
אבטחת מידע – ניהול ותחזוקת חוות שרתים גדולה בשיטות המסורתיות מה-data center המקומי, חייבה עבודה רבה (הפצת עדכוני אבטחה, חוקי תקשורת, הגנה מפני מתקפות DDoS, ניהול תצורה, הצפנת נתונים בעת אחסון ובעת תעבורה ברשת, ניטור אירועי אבטחה ועוד), כאשר בסביבת הענן, נוכל להנות מיכולות אבטחת מידע מובנות, הזמינות לתחזוקה ידנית (עבור סביבות מחשוב קטנות) או בצורה אוטומטית (כחלק מהמטעה סביבות בשיטת Infrastructure as a Code או בגישה באמצעות שפות פיתוח נפוצות).
שימוש ב-Containers וב-Kubernetes
השימוש בארכיטקטורת micro-services אפשר מהפיכה באופן בו אנו מפתחים ומטמיעים יישומים מודרניים, ע"י פיצול ארכיטקטורה מורכבת לרכיבים קטנים, עפ"י המשימה אותה הם משרתים כחלק מהשירות או האפליקציה שלנו.
במקום לפרוס שרתים וירטואליים, עם מערכת הפעלה מלאה ושכבת אפליקציה שלמה, אנו עוברים להשתמש ב-Containers, המאפשרים לנו לארוז את הכמות המינימלית של binaries, ספריות הרצה וקוד, הנדרשים לביצוע משימה (דוגמת הזדהות לאפליקציה, הרצת לוגיקה עסקית, שמירת מידע ב-object storage או ישירות לתוך בסיס נתונים, הרצת מודל דוחות ועוד)
שימוש ב-Containers מאפשר לנו לנצל בצורה מיטבית את ה"חומרה", ע"י הרצת מספר רב של Containers (כל אחד עשוי לשמש עבור שירות אחר) על גבי אותה חומרה וירטואלית (או חומרה פיזית בתצורת bare metal) ולהגיע לקרוב ל-100% ניצול של משאבי החומרה.
זה בדיוק המקום בו containers נכנסים לתמונה. הם מאפשרים לצוות פיתוח קטן להתמקד במשימה ספציפית או רכיב ספציפי כחלק מהשירות שלנו, בצורה נפרדת (כמעט לחלוטין) מיתר צוותי הפיתוח (רכיבי המערכת עדיין נדרשים לתקשר אחד עם השני…), להיות מסוגלים לעדכן שורות קוד, להגדיל ולהקטין את משאבי המחשוב הנדרשים עבור כל רכיב במערכת הארוז בתוך container, בהתאם לעומס על השירות, ובתקווה יום אחד, גם לאפשר לנו להגר בין ספקי ענן ("Cloud agnostic").
Kubernetes, הפך להיות הסטנדרט בארגונים הזקוקים לרכיב Orchestrator עבור הרצת containers. הוא מסוגל לפרוס כמות של containers בהתאם לצורך (כגון עומס על המערכת), לנטר את הסטאטוס של כל container שרץ במערכת (ולהתקין container חדש במקום container שאינו מתפקד), לעדכן גרסאות תוכנה (ע"י פריסת container המכיל גרסה עדכנית של הקוד שלנו), לוודא שה-containers נפרסים בצורה שווה בין שכבת השרתים הווירטואלית אשר מריצה את ה-containers (לצורך שרידות וזמינות) ועוד.
יתרונות:
- הקטנת כמות ה-binaries וספריות ההרצה הנדרשות לצורך הרצת השירות, למינימום האפשרי
- ניתן לבצע פיתוח על גבי המחשב המקומי (אפילו על המחשב הנייד) ולאחר מכן להריץ ב-scale גדול בסביבת הענן (פותר את הסוגייה של "זה רץ על המחשב שלי…")
- נחשב cloud vendor agnostic (אלא אם אנו מסתמכים על שירותים מה-eco system של ספק הענן)
חסרונות:
- לוקח זמן ללמוד כיצד לארוז ולתחזק סביבת containers
- מאתגר לאתר תקלות (debugging)
- אחוז גבוה מה-containers הזמינים כחלק מקהילת הקוד הפתוח אינם מעודכנים או מכילים חולשות אבטחה
שימוש ב-Serverless או Function as a Service
מדובר בשיטות מודרניות להפצת אפליקציות, בצורה המאפשרת עלות/תועלת גבוהה יותר משיטות קודמות, בהנחה שאנו מסוגלים לקחת חלק מהקוד שלנו ("פונקציה") על-מנת לבצע משימה מסוימת ולייבא אותו לתוך סביבת מחשוב מנוהלת ("Serverless") ולשלם עבור כמות המשאבים בפועל (כמות מעבדים/זיכרון) ועבור זמן הריצה של הפונקציה (בשניות).
Serverless יכול להיות חלק מארכיטקטורת micro-service, ע"י החלפת חלק מהמשימות שנהגנו להריץ עד כה בתוך containers.
השימוש ב-Serverless מתאים לפונקציות אשר אינן נדרשות לשמור state (מצב נוכחי) דוגמת היעדר הצורך לשמור caching של מידע או עבור תרחישים בהם יש דרישה להרצת פונקציונליות ספציפית (דוגמת הרצת קטע קוד כתגובה לאירוע במערכת – חסימת חוק תקשורת המהווה חריגה מהגדרות אבטחת מידע כתוצאה מאירוע שהתגלה בעקבות ניטור compliance במערכת).
יתרונות:
- אין צורך לתחזק את שכבת התשתית (משאבי מחשוב, מערכת הפעלה, עדכוני אבטחה וכו')
- משאבי המחשוב גדלים בהתאם לעומס על השירות
- עלות מזערית ב-scale נמוך (בהשוואה לעלות הרצת container)
חסרונות:
- זמן הריצה של הפונקציה מוגבל ל-15 דקות
- נפח אחסון מוגבל (לאחסון קוד ו-libraries)
- מאתגר לאתר תקלות (debugging) מכיוון שמדובר בסביבת מחשוב סגורה (אין גישה למערכת ההפעלה)
- הפתרון עשוי להיות יקר ב-scale גדול (בהשוואה לעלות הרצת container)
- תמיכה במספר נמוך של שפות פיתוח
- זמני אתחול פונקציה ("Warm up") ארוכים
סיכום
עולם המחשוב משתנה וזו בשורה טובה.
במקום חוות שרתים, ומיקוד על עולם התשתית, אשר עשוי שלא להתאים (מבחינת יחס עלות/תועלת) עבור היישומים שלנו, פיתוח ופריסת שרתים בצורה מודרנית ממוקדים על ערך מוסף ללקוחות שלנו, ע"י קיצור זמני פיתוח ("Time to market") והיכולת להתנסות, לעשות טעויות ולתקן אותן במהירות ("Fail safe"), ולעשות שימוש מיטבי למשאבים שלנו (תשלום עבור שימוש בפועל), היכולת לצפות תקלות וזמני השבתה מראש ולהפיק את המיטב משימוש בענן ציבורי.