קונטיינרים ללא שרת: ארכיטקטורת Serverless Containers כמו Cloud Run ו-Fargate

מאת צוות מדיה דיל · 09.08.2026 · DevOps · 7 דק'

מדריך מעמיק ל-Serverless Containers: איך Cloud Run, Fargate ו-Azure Container Apps מבטלים את הצורך בניהול נודים, ומה המחיר האמיתי של הנוחות הזו.

צוות תשתיות בחברת סטארטאפ ישראלי הריץ Kubernetes cluster עם שני נודים בלבד כדי לארח שירות אחד שמקבל כמה עשרות בקשות בשעה. עלות ה-cluster - כולל control plane מנוהל, נודים שרצים 24/7, ותקורת התחזוקה - עלתה על עלות הרצת השירות עצמו בפי כמה. זו בדיוק הבעיה ש-Serverless Containers נועדו לפתור: לקחת את מודל האריזה הנוח של קונטיינרים (Dockerfile, image רשום ב-registry) ולהריץ אותם בלי לנהל אף נוד, אף control plane, ואף שרת - התשלום הוא רק על זמן ריצה בפועל, ולפעמים אפילו אפס כשאין תעבורה.

מה זה בעצם Serverless Containers ואיך זה שונה מ-Kubernetes

ההבדל המהותי מ-Kubernetes הוא לא בפורמט הקונטיינר עצמו - זה עדיין אותו OCI image שנבנה מ-Dockerfile - אלא באחריות התפעולית. ב-Kubernetes, הצוות אחראי על הנודים: קיבולת, תיקוני אבטחה למערכת ההפעלה, autoscaling של הנודים עצמם, ותזמון. ב-Serverless Containers כמו Google Cloud Run, AWS Fargate או Azure Container Apps, כל השכבה הזו מנוהלת לגמרי על ידי הספק. המפתח מגדיר image, כמות CPU וזיכרון, ומדיניות scaling - והפלטפורמה דואגת לכל השאר, כולל להעלות instances חדשים כשיש עומס ולהוריד אותם לגמרי (scale to zero) כשאין.

זה שונה גם מ-FaaS קלאסי (AWS Lambda) - שם המודל מוגבל לפונקציה בודדת עם runtime מוגדר מראש ומגבלות זמן ריצה קשיחות. Serverless Containers מרחיבים את הגמישות: כל שפה, כל תלות מערכתית, וכל תהליך ריצה ארוך יחסית (עד שעה או יותר, תלוי בספק) יכולים לרוץ, כל עוד הם ארוזים כקונטיינר תקני.

Cloud Run לעומק: מודל הריצה וה-scale-to-zero

Google Cloud Run היה מהראשונים להביא את המודל הזה לבשלות. כל revision של שירות ב-Cloud Run הוא קונטיינר שמאזין לפורט HTTP; הפלטפורמה מנתבת אליו בקשות, ומגדילה את מספר ה-instances לפי concurrency מוגדר (כמה בקשות instance בודד יכול לטפל בו-זמנית). כשאין תעבורה כלל, Cloud Run יכול להוריד את מספר ה-instances לאפס לגמרי - אין עלות כשאין שימוש. זה בדיוק המודל שהופך אותו לכלכלי לworkloads עם תעבורה לא-אחידה: אתר תדמית שמקבל רוב הביקורים בשעות מסוימות, API פנימי שמופעל רק לפי דרישה.

הפרמטר הכי חשוב לכוונן ב-Cloud Run הוא concurrency - כמה בקשות מקבילות instance בודד מטפל בו זמנית. עבור workload עתיר CPU (עיבוד תמונות, חישובים), concurrency נמוך (1-10) מונע מבקשות "לחכות" זו לזו על אותו ליבה. עבור workload עתיר I/O (רוב הזמן ממתין לתשובה ממסד נתונים או API חיצוני), concurrency גבוה (עד 1000) מנצל טוב יותר את המשאבים כי ה-CPU לא באמת עסוק ברוב הזמן.

AWS Fargate: קונטיינרים בלי לנהל EC2

Fargate פותר בעיה דומה בתוך אקוסיסטם AWS: הוא נותן launch type לקונטיינרים בתוך ECS או EKS שבו אין צורך לנהל ולתחזק שרתי EC2 בכלל. במקום להגדיר Auto Scaling Group של מכונות ולדאוג לתיקוני אבטחה, גדלים מערכת ההפעלה ותפוסה - כל task ב-Fargate מקבל את המשאבים המדויקים שהוגדרו לו (CPU, זיכרון) ורץ בבידוד מלא (ברמת MicroVM, דרך Firecracker) בלי שיתוף עם workloads של לקוחות אחרים.

ההבדל המרכזי בין Fargate ל-Cloud Run הוא מודל התמחור והגמישות: Fargate מחייב הגדרה מדויקת יותר מראש של CPU וזיכרון (בשילובים קבועים), ואינו תומך ב-scale-to-zero אמיתי באותה קלות - task שרץ, ממשיך לרוץ ולחייב עד שהוא מופסק במפורש, גם אם אין לו תעבורה. זה הופך את Fargate למתאים יותר לworkloads שרצים באופן רציף עם עומס יציב יחסית, בעוד Cloud Run מתאים יותר לworkloads עם תעבורה פרצית או לא צפויה.

Azure Container Apps ו-KEDA

Azure Container Apps מביא גישה שלישית שמשלבת רעיונות מ-Kubernetes בלי לחשוף את המורכבות שלו: מתחתיו רץ בפועל KEDA (Kubernetes Event-Driven Autoscaling), מה שמאפשר scaling לא רק לפי CPU/זיכרון אלא לפי מדדים חיצוניים אמיתיים - אורך תור הודעות, קצב הודעות ב-Kafka, או מדדים מותאמים אישית. זה הופך את Container Apps לאופציה חזקה במיוחד לworkloads שמעבדים תורים (event-driven processing) ולא רק שירותי HTTP סינכרוניים - יכולת שגם Cloud Run וגם Fargate תומכים בה רק בצורה מוגבלת יותר.

Cold Start: הבעיה שלא נעלמת

למרות כל ההתקדמות בטכנולוגיית בידוד (ראו את הדיון על MicroVMs ו-Firecracker), cold start נשאר האתגר המרכזי של המודל הזה. כשinstance חדש עולה אחרי תקופת חוסר פעילות, יש עלות: הורדת ה-image (אם לא cached), אתחול ה-runtime (JVM איטי משמעותית מ-Node.js או Go בהקשר הזה), וטעינת האפליקציה עצמה. אצל שירותים שכתובים ב-Go או Rust, cold start יכול להיות מתחת ל-100 מילישניות; אצל שירותי Java/Spring כבדים, זה יכול להגיע לשניות ארוכות - פער שמשפיע ישירות על חוויית המשתמש בבקשה הראשונה אחרי תקופת שקט.

הטכניקות המקובלות להתמודדות: minimum instances (לשמור instance חם אחד לפחות, במחיר תשלום קבוע גם בלי תעבורה - זה בעצם ביטול חלקי של ה-scale-to-zero לטובת latency עקבי), אופטימיזציית זמן אתחול של האפליקציה עצמה (lazy loading של תלויות כבדות), ובחירת runtime קליל יותר כשהדבר אפשרי.

מגבלות: state, networking וזמני ריצה

Serverless Containers הם, כמעט תמיד, stateless מטבעם - אין הבטחה שאותה בקשה תגיע לאותו instance פעמיים, ואין דיסק מקומי שנשמר בין הרצות. כל state חייב לגור במקום חיצוני (מסד נתונים, cache מנוהל, אחסון אובייקטים). מגבלה נוספת שמפתיעה צוותים היא timeouts - לרוב הפלטפורמות יש הגבלת זמן ריצה מקסימלית לבקשה בודדת (בדרך כלל דקות ולא שעות), מה שהופך אותן ללא מתאימות ל-batch jobs ארוכי טווח או תהליכים שרצים ברקע לאורך זמן ממושך בלי אינטראקציה.

גם networking מוגבל יחסית ל-VM מלא או Kubernetes - חיבור ל-VPC פנימי, IP סטטי יוצא, או פרוטוקולים שאינם HTTP/gRPC דורשים קונפיגורציה נוספת ולא תמיד נתמכים באותה קלות בכל הספקים.

עלות: מודל תמחור ומתי זה יקר יותר מ-Kubernetes

המודל הכלכלי של Serverless Containers - תשלום לפי זמן ריצה בפועל - משתלם מאוד לworkloads עם תעבורה נמוכה או לא-אחידה, אבל הופך יקר יותר מ-Kubernetes סטנדרטי כשהעומס גבוה ויציב. שירות שרץ 24/7 בעומס גבוה עם Cloud Run ישלם, לרוב, פרמיה משמעותית ביחס לאותו workload על נודים שמורים (reserved instances) ב-Kubernetes או אפילו VM רגיל. הכלל האצבע: ככל שהתעבורה יציבה יותר וגבוהה יותר, כך היתרון הכלכלי של serverless קטן, וההשקעה בתשתית מנוהלת עצמאית (או שמורה) משתלמת יותר.

כדי לקבל תמונה מדויקת שווה לחשב שני תרחישים בפועל ולא רק להעריך: נניח שירות שצורך בממוצע 0.5 vCPU ו-512MB זיכרון, עם 60% ניצול לאורך היממה. בתמחור Cloud Run הבלתי-קלוד לפי מילישניות שימוש, זה יכול להצטבר לעלות חודשית שגבוהה משמעותית ממחיר נוד EC2 קבוע בגודל דומה עם ניצול דומה. לעומת זאת, אותו שירות עם 5% ניצול בלבד (תעבורה פרצית, רוב הזמן אין בקשות כלל) יעלה בקירוב אפס ב-Cloud Run מול עלות קבועה מלאה בנוד ייעודי שרץ סתם כל הלילה. המסקנה המעשית: יש לחשב עלות בפועל לפי פרופיל השימוש הספציפי לפני שמחליטים, לא להסתמך על הנחות כלליות על "serverless זול" או "serverless יקר".

Observability ו-Health Checks במודל Serverless

ניטור Serverless Containers שונה מניטור Kubernetes רגיל בגלל מחזור החיים הקצר של כל instance - אי אפשר "להיכנס" ל-instance ולדבג אותו בזמן אמת כי הוא עלול להיעלם תוך שניות. לכן כל הפלטפורמות דורשות logging מובנה שנשלח החוצה (stdout/stderr נאסף אוטומטית ומועבר למערכת לוגים מרכזית) ולא הסתמכות על קבצי לוג מקומיים. חשוב גם להגדיר readiness ו-liveness checks נכונים - Cloud Run ו-Fargate כברירת מחדל בודקים שהקונטיינר מאזין על הפורט המוגדר, אבל בלי health check ייעודי שבודק תלותיות פנימיות (חיבור למסד נתונים, cache), הפלטפורמה עלולה לנתב תעבורה ל-instance שטכנית "רץ" אבל לא מסוגל לשרת בקשות בפועל.

FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
ENV PORT=8080
EXPOSE 8080
CMD ["node", "server.js"]

דוגמה כזו ל-Dockerfile מינימלי היא כל מה שצריך כדי להריץ שירות ב-Cloud Run או Fargate - אין שום קונפיגורציה ייעודית לפלטפורמה בתוך ה-image עצמו, מה שגם הופך את המעבר בין ספקי serverless שונים לפשוט יחסית באם יש צורך.

טעויות נפוצות

הטעות הראשונה היא לצפות לביצועים עקביים ללא כל תשומת לב ל-cold start, ואז להתפלא כשמשתמש ראשון אחרי תקופת שקט חווה latency גבוה. השנייה היא לנסות לאחסן state מקומי (session, קבצים זמניים) בהנחה שהinstance יישאר קבוע - הנחה שגויה שמובילה לבאגים לא עקביים שקשה לשחזר. השלישית היא להריץ workloads עתירי-חישוב וארוכי-טווח על פלטפורמה serverless בגלל הנוחות הראשונית, ואז לגלות שהעלות בפועל גבוהה משמעותית מ-VM ייעודי.

מתי כן ומתי לא

Serverless Containers מתאימים במיוחד לAPI-ים עם תעבורה לא-אחידה, workloads אירוע-מונחים (webhook handlers, עיבוד תור), וצוותים קטנים שרוצים להימנע לחלוטין מתחזוקת תשתית. הם פחות מתאימים לworkloads עם עומס גבוה ויציב לאורך היום (שם Kubernetes מנוהל או VMs שמורים זולים יותר), תהליכים ארוכי-טווח שחורגים ממגבלות timeout, ומקרים שדורשים networking מורכב או שליטה מדויקת בתשתית התחתית. במדיה דיל אנחנו ממליצים להתחיל תמיד ב-serverless עבור שירותים חדשים - זה הזול והמהיר ביותר להקמה - ולעבור לתשתית מנוהלת עצמאית רק כשהמדדים בפועל (עומס, latency, עלות) מוכיחים שזה משתלם.

סיכום

Serverless Containers סוגרים פער אמיתי בין הנוחות של FaaS לגמישות של קונטיינרים מלאים - הם מאפשרים לצוותים להריץ כמעט כל workload ארוז כקונטיינר בלי לגעת בתשתית תחתית כלל. אבל הם לא פתרון קסם: cold start, מגבלות state, וטיימאאוטים הם מחיר אמיתי שצריך לתכנן סביבו, וככל שהעומס גדל, שווה לבדוק מחדש אם המודל הכלכלי עדיין הגיוני. ההחלטה הנכונה תלויה תמיד בפרופיל התעבורה בפועל, לא בטרנד הטכנולוגי הנוכחי.

במדיה דיל אנחנו רואים לעיתים קרובות ארגונים שמתחילים ב-Kubernetes "כי זה מה שכולם עושים" בזמן שכל הצורך שלהם היה שירות HTTP בודד עם תעבורה נמוכה - מקרה קלאסי שבו Serverless Containers היו חוסכים שבועות של עבודת תשתית וחודשים של תחזוקה שוטפת. וההפך גם נכון: ארגונים שממשיכים לשלם פרמיית serverless על workload שכבר גדל לעומס יציב וגבוה, בזמן שמעבר לתשתית מנוהלת עצמאית היה חוסך להם משמעותית מדי חודש. הבדיקה התקופתית של פרופיל העומס בפועל, לא רק בזמן ההחלטה הראשונית, היא מה שמבדיל תשתית שמתפתחת נכון מתשתית שנשארת תקועה בהחלטה ישנה.

תגיות: Serverless Containers · Cloud Run · AWS Fargate · Azure Container Apps · Cold Start · Autoscaling · Kubernetes Alternative

← חזרה לבלוג · צור קשר