קוברנטיס: Deployments ו ReplicaSets


בפוסט הקודם על קוברנטיס, הגדרנו Pod – יחידת ההרצה הקטנה ביותר בקוברנטיס.
סיימנו בכך ש Pod שנוצר בגפו, מה שקרוי ״Naked Pod״ – ואיננו בעל שרידות גבוהה: אם הוא קרס, או ה node שבו הוא רץ קרס / נסגר – קוברנטיס לא יחדש אותו.

בפוסט הזה נציג סמנטיקה מרכזית נוספת בעבודה עם קוברנטיס: ה Deployment – המכמיסה בתוכה סמנטיקה בשם ReplicaSet אותה נסביר גם כן. הסמנטיקות הללו הן מה שמאפשרות להגדיר/לעדכן pods כך שיהיו resilient. זוהי תכונה קריטית שאנו מקבלים מקוברנטיס, ולא היינו מקבלים מ Dokcer לבדו.

בואו נתחיל.

Resilient Pods

בכדי ליהנות מיכולת מתקדמות של קוברנטיס כגון Self-Healing ו Auto-Scaling – עלינו להימנע מהגדרה של naked pods, ולהשתמש בסמנטיקה בשם ReplicaSet.

ReplicaSet הוא המקבילה של AWS Auto-Scaling-Group, מנגנון המוודא שמספר ה Pods שרצים:

  • לא יורד ממספר מסוים (Auto-Healing)
  • עולה בצורה דינאמית כאשר יש עומס על ה Pods (למשל: CPU utilization מעל 60%) – עד גבול מסוים שהגדרנו, ויורד בחזרה – כאשר העומס חולף.
למי שעבד עם שירותי-ענן, הצורך הזה אמור להיות ברור כשמש.
בעבודה עם קוברנטיס, אנחנו לא נעבוד בד"כ עם ReplicaSet, אלא עם סמנטיקה גבוהה יותר בשם Deployment
Deployment היא בעצם הסמנטיקה לעבוד איתה.

תרשים קונספטואלי ולא מדויק. נדייק אותו בהמשך.

מה Deployment מוסיף על ReplicaSet? במחשבה ראשונה נשמע שאנו זקוקים רק ל ReplicaSet.

ובכן, בואו ניקח תסריט מאוד נפוץ ויומיומי: עדכון Pod לגרסה חדשה יותר. ביצענו שינוי במיקרו-שירות הרץ כ Pod, ואנו רוצים לעדכן את הקוד שלו.
כפי שאנחנו זוכרים, צורת העבודה (המומלצת) עם קוברנטיס היא הגדרה דקלרטיבית:
  • אנו מגדירים מצב רצוי
  • קוברנטיס דוגם כל הזמן את המצב המערכת, ואם יש פעם בין המצב הנוכחי למצב הרצוי – היא פועלת לסגירת הפער. 
נניח שיש לנו 3 Pod replicas של מיקרו-שירות, הרצים כולם בגרסה 11 (למשל: build number). אנו רוצים לעדכן אותם לגרסה 12.

אם פשוט נעדכן את קוברניס שאנו רוצים את ה Pod replicas בגרסה 12, עלול לקרות המקרה המאוד-לא-רצוי הבא:
  1. קוברנטיס רואה שלא רוצים יותר את גרסה 11 – הוא מכבה את כל ה Pod replicas בגרסה הזו.
  2. לא טוב! מרגע זה אנחנו ב downtime.
  3. קוברנטיס רואה שרוצים את גרסה 12 – הוא מתחיל להריץ Pod replicas של הגרסה הזו.
  4. אבוי! בגרסה 12 יש באג בקוד, והמיקרו-שירות לא מצליח לרוץ.
  5. קוברנטיס יוצר Log מפורט וברור של הבעיה – אבל עד שלא נטפל בה בעצמנו – אנחנו ב Full Downtime.
זה בהחלט לא תסריט שאנו רוצים שיהיה אפשרי בסביבת Production!

Deployment, לשמחתנו, מוסיף את היכולות / האחריות הבאה:

  • ביצוע סדר הפעולות בצורה נכונה – כך שתמיד יהיו מספיק Pods שרצים.
  • בחינת (probing) ה Pod replicas החדשים – ו rollback במקרה של בעיה.
    • למשל: בדוק שה pod replica החדש שעלה הוא תקין (ע״פ תנאים מסוימים, מה שנקרא Readiness check) – לפני שאתה מעלה עוד pod replicas מהגרסה החדשה או מוריד עוד ישנים.
    • ישנן מגוון הגדרות בכדי לשלוט בהתנהגות המדויקת.

בתרשים למעלה ערבבתי, לצורך הפשטות, בין entities שהם קונפיגורציה (באפור: deployment, replica set) לבין entities של זמן-ריצה (בכתום: Pod replica). אני רוצה כעת לדייק את הדברים בעזרת התרשים הבא:

קונספט ארכיטקטוני מרכזי בקוברנטיס הוא ה Controllers, שהם בעצם מעין Modules או Plug-Ins של סביבת הניהול של קוברנטיס (ה Control Plane). ה Controllers מאזינים ל API Server הפנימי של קוברנטיס אחר שינויים על ה Resource הרלוונטי להם (Deployment, Service, וכו') או שינויים בדרישות – ואז מחילים את שינויים נדרשים.

בעיקרון ה Controllers רצים ב Reconciliation loop (כמו event loop) שנקרא כך בגלל שכל פעם שיש אירוע (שינוי שנדרש) הם מבצעים פעולה על מנת "ליישר קו" (reconcile) וכך, לעתים בצעדים, ה loop דואג שכל הזמן המצב בשטח יגיע במהרה למצב שהוגדר. מדי כמה זמן הם בודקים את סה"כ ההגדרות ומגיבים לפער – אם קיים. כלומר: גם אם event מסוים פוספס / לא טופל – תוך זמן קצר ה controller יגלה את הפער וישלים אותו.


בניגוד להפשטה המוצגת בתרשים למעלה, Controllers לעולם לא יתקשרו ישירות אחד עם השני (אחרת: הם לא יהיו Pluggable). כל קריאה היא ל API Server, למשל "צור משאב מסוג Replication", שבתורו יפעיל אירוע מתאים שייקלט ע"י ה Replication Controller ויוביל לפעולה.

אנחנו נראה בהמשך את ההגדרות של ה Deployment ואת ה template המדובר.


הנה תיאור דינאמי של תהליך ה deployment:

ה Deployment ישמור את ה replica set הקודם (ועליו כל ההגדרות), על מנת לאפשר תהליך של Rollback.
כמובן שההתנהגות המדויקת של שלב ה Mid (ליתר דיוק: סדרת שלבי ה mid) תלויה מאוד באסטרטגיית ה Deployment שנבחרת.

אני מניח שאתם מכירים את 2 האסטרטגיות המרכזיות, המקובלות בכלל בתעשייה: Rolling deployment ו Blue/Green deployment.
קוברנטיס לא תומך היום (בעת כתיבת הפוסט) ב Blue/Green deployments כיכולת-ליבה (אם כי יש מדריכים שמראים כיצד ניתן להשיג זאת, על בסיס יכולות קיימות של קוברנטיס – הנה דוגמה לאחד).

בכלל, כל נושא ה deployments הוא GA רק מגרסה 1.9 (תחילת 2018). כיום קוברנטיס תומך רק באסטרטגיות: "Recreate" (אסטרטגיה סופר פשוטה, בה יש downtime בהגדרה) ו "RollingUpdate" (ברירת המחדל).

הנה שני מקורות, המציגים כ"א כמה תסריטי deployment אפשריים, בהתבסס על יכולות הליבה של קוברנטיס:

  • מצגת של Cloud Native Computing Foundation (בקיצור: CNCF) – הארגון שהוקם על מנת לקחת אחריות על פרויקט קוברנטיס, ולנהל אותו כ Open Source בלתי-תלוי. יש גם סיכום one-pager של האסטרטגיות שהוא מציג. 
  • פוסט של ארגון בשם Container Solutions – שגם הוא מציג בצורה ויזואלית יפה, את משמעות האסטרטגיות השונות (סט דומה, אך לא זהה לקודם).

הגדרת Deployment בפועל


בלי לקשקש הרבה, נגדיר manifest של deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deploy
  labels:
    app: hello-world-deployment
spec:
  replicas: 4
  selector:
    matchLabels:
      app: hello-world
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      maxSurge: 1
  minReadySeconds: 5
  template:
    metadata:
      labels:
        app: hello-world
        env: dev
        version: v1
    spec:
      containers:
      - name: hello-pod
        image: hello-world:latest
        ports:
        - containerPort: 8080
          protocol: TCP
אתם כבר אמורים להכיר את 3 המפתחות הראשונים, ולכן נתמקד ב spec:
  • את הגדרת ה pod ניתן למצוא תחת ה template והן זהות ל Pod שהגדרנו בפוסט הקודם (מלבד label אחד שהוספנו). שימו לב שה metadata של ה Pod מופיע תחת template, ולא במפתח ה metadata של ה manifest.
  • replicas הוא מספר העותקים של ה pod שאנו רוצים להריץ.
  • ה selector משמש לזיהוי חד משמעי של סוג ה pod שאנו מתארים. חשוב שניתן label "יציב" שבעזרתו קוברנטיס יידע לקשר ולהשוות אם היו שינויים בין pod templates. אם היה שינוי – עליו לבצע deploy.
    • למשל: אם שינינו גם את label הגרסה וגם את ה image – איך אפשר לקשר בוודאות שמדובר באותו האפליקציה, ולא בחדשה?
    • מקובל להשתמש ב label בשם app או app.kubernetes.io/name.
  • על אסטרטגיית ה deployment כבר דיברנו. הנה 2 פרמטרים חשובים של אסטרטגית rolling deployment:
    • maxUnavailable – הכמות המרבית המותרת של pods שאינם זמינים תוך כדי פעולת deploy. הדבר משפיע כמה pods קוברנטיס יכול "להוריד במכה" כאשר הוא מתקין גרסה חדשה. המספר מתייחס למספר ה pods התקינים בגרסה הישנה + החדשה ביחד, וברירת המחדל היא 25%. ניתן גם לקבוע 0.
    • maxSurge – הוא פחות או יותר הפרמטר ההופכי: כמה pods חדשים ניתן להרים "במכה". ככל שהמספר גדול יותר – כך ה rolling deployment עשוי להיות מהיר יותר. גם כאן ברירת המחדל היא 25%.
      בקיצור גמור: אם יש לנו 4 pod replicas, הערכים שקבענו ב manifest יבטיחו שה cluster תמיד יכיל בין 3 ל 5 pod replicas בזמן deployment.
  • minReadySeconds – שדה רשות (ערך ברירת מחדל = 0) שמציין כמה שניות לחכות לאחר שה pod מוכן ("ready") לפני שמעבירים לו תעבורה. ההמתנה הזו היא פרקטיקה מקובלת, מכיוון שהנזק מ pod בעייתי שמחובר ל production traffic – עשוי להיות משמעותי. אפשר להיתקל גם בערכים של 20 ו 30 שניות. חשוב להזכיר שערך גבוה יאט את תהליך ה rolling deployment מכיוון שאנו ממתינים ל minReadySeconds – לפני שאנו ממשיכים להחליף עוד pods.
    • כאן שווה להזכיר את ה Readiness & Liveliness Probes של קוברנטיס. קוברנטיס מריץ ב nodes רכיב טכני הרץ כ container ומבצע בדיקות Health-check על ה pods השונים ב node ומדווח את התוצאות הלאה. כל pod צריך לענות ל2 קריאות: well-known/live./ ו well-known/ready./
      • מצב ה live הוא אות חיים בסיסי. המימוש המומלץ הוא פשוט להחזיר HTTP 200 OK מבלי לבצע פעולות נוספות. אם התשובה המתקבלת היא לא 2xx – קוברנטיס יאתחל את ה pod הזה מיד.
      • מצב ה ready אמור להיות עשיר יותר, בד"כ בודקים גישה לבסיס הנתונים ("SELECT 1") או גישה למשאבים קריטיים אחרים ל Pod (למשל: גישה לרדיס, או שירותים אחרים הקריטיים לפעילות ה pod). אם האפליקציה עוברת עדכון (למשל: הטמעת קונפיגורציה חדשה / עדכון caches ארוך) – הדרך הנכונה היא להגדיר אותה כ "לא ready" בזמן הזה.
        אם התשובה ל ready היא שלילית, קוברנטיס עשויה לנתק אותו מתעבורה נכנסת עד שיסתדר. אם המצב מתמשך (ברירת המחדל = 3 כישלונות רצופים) – ה pod יעבור restart.

        • שגיאה נפוצה היא להגדיר את live ו ready אותו הדבר – אבל אז מערבבים פעולות live יקרות מדי, ו restarts מיותרים של pods (כי עשינו restart בעקבות live אחד שכשל, נניח – מתקלת רשת נקודתית ואקראית).
את המניפסט, כמובן, מחילים כרגיל:
$ kubectl apply -f my-deployment.yaml
נוכל לעקוב אחר מצב ה deployment בעזרת הפקודה:
$ kubectl get deployment hello-deploy

אם אנו מגלים שהגרסה לא טובה (נניח: עלה באג חדש ומשמעותי לפרודקשיין), אנו יכולים לבצע rollback. הפקודה:

$ kubectl rollout history deployment hello-deploy
תציג לנו רשימה של revisions של ה deployment. נניח שאנו רוצים לחזור לגרסה 1, עלינו לפקוד:
$ kubectl rollout undo deployment hello-deploy --to-revision=1
כאשר מדובר ב RollingDeployment, ה rollback כמובן הוא deploy בפני עצמו שייקח זמן, ויעבוד לפי אותם הכללים של deploy חדש. תאורטית אנו יכולים פשוט לשנות את ה deployment.yaml בחזרה  למצב הקודם ולבצע deploy חדש – אי כי זה פחות מומלץ, אפילו רק מטעמי תיעוד.

סיכום

סקרנו את משאבי ה ReplicaSet וה Deployment בקוברנטיס – הדרך העיקרית לעדכן את המערכת ב pods חדשים / מעודכנים, בצורה Resilient.
על הדרך, הרחבנו מעט את ההבנה כיצד קוברנטיס עובד.

עדיין, לאחר שביצענו deployment לא נוכל לגשת ל pods שלנו (בקלות הרצויה). לשם כך עלינו להגדיר עוד משאב-ליבה בקוברנטיס בשם Service, המתייחס ל"קבוצה של Pod replicas בעלי אותו הממשק".

סמנטיקת ה Service מתוכננת להיות הנושא לפוסט הבא בסדרה.

שיהיה בהצלחה!

לקבל מושג ירוק על קוברנטיס (Kubernetes)

הפוסט הזה נכתב לאנשי-תוכנה מנוסים, המעוניינים להבין את Kubernetes – בהשקעת זמן קצרה.
הבאזז מסביב ל Docker ו Docker Orchestration הוא כרגע רב מאוד. דברי שבח רבים מסופרים על הטכנולוגיות הללו, מבלתי להתייחס לפרטים ועם מעט מאוד ראיה עניינית וביקורתית. כאנשי-תוכנה ותיקים אתם בוודאי מבינים שהעולם הטכנולוגיה מלא Trade-offs, וכדאי לגשת לטכנולוגיות חדשות עם מעט פחות התלהבות עיוורת – וקצת יותר הבנה.

 

אני הולך לספק את הידע בפוסט לא בפורמט ה "From A to Z" כפי שדיי מקובל – אבל ע"פ סדר שנראה לי יותר נכון והגיוני. אני רוצה לדלג על דיון ארוך על ההתקנה, ועוד דיון ארוך על הארכיטקטורה – עוד לפני שאנחנו מבינים מהי קוברנטיס. אני הולך לדלג על כמה פרטים – היכן שנראה לי שהדבר יתרום יותר להבנה הכללית.

בואו נתחיל.

 

אז מהי בעצם קוברנטיס?

 

פורמלית קוברנטיס היא Container Orchestration Framework (הנה פוסט שלי על הנושא) שהפכה בשנתיים האחרונות לסטנדרט דה-פאקטו (הנה פוסט אחר שלי שמנתח את העניין).

 

בכדי לפשט את הדברים, ניתן פשוט לומר שקוברנטיס היא סוג של סביבת ענן: 

  • אנו אומרים לה מה להריץ – והיא מריצה. אנו ״מזינים״ אותה ב Containers (מסוג Docker או rkt) והגדרות – והיא ״דואגת לשאר״.
  • אנו מקצים לקוברנטיס כמה שרתים (להלן ״worker nodes״ או פשוט "nodes") שהם השרתים שעליהם ירוצו הקונטיינרים שלנו. בנוסף יש להקצות עוד כמה שרתים (בד״כ – קטנים יותר) בכדי להריץ את ה master nodes – ה״מוח״ מאחורי ה cluster.
  • קוברנטיס תדאג ל containers שלנו:
    • היא תדאג להרים כמה containers בכדי לאפשר high availability – ולהציב אותם על worker nodes שונים.
    • אם יש עומס עבודה, היא תדאג להריץ עוד עותקים של ה containers, וכשהעומס יחלוף – לצמצם את המספר. מה שנקרא auto-scaling.
    • אם container קורס, קוברנטיס תדאג להחליף אותו ב container תקין, מה שנקרא גם auto-healing.
    • קוברנטיס מספקת כלים נוחים לעדכון ה containers לגרסה חדשה יותר, בצורה שתצמצם למינימום את הפגיעה בעבודה השוטפת – מה שנקרא deployment
      • כפי שראינו בפוסט על Docker – פעולת restart של Container תהיה מהירה משמעותית מ VM, שזה גם אומר לרוב deployments מהירים יותר.
    • לשימוש בקוברנטיס יש יתרון בצמצום משמעותי של ה Lock-In ל Cloud Vendor [א], והיכולת להריץ את אותה תצורת ״הענן״ גם On-Premises.
      • הסתמכות על קוד פתוח, ולא קוד של ספק ספציפי – הוא גם יתרון, לאורך זמן, וכאשר הספק עשוי להיקלע לקשיים או לשנות מדיניות כלפי הלקוחות.
  • קוברנטיס גם מספקת לנו יכולות ליבה של ניהול Infrastructure as Code, היכולת להגדיר תצורה רצויה לתשתיות רשת, אבטחה בצורה הצהרתית ופשוטה – מה שמייתר כלי ניהול תצורה (Provisioning) כגון Chef, Puppet או Ansible – ויכול לחסוך עבודה משמעותית.

יעילות

 
עם כל היעילות המוגברת שהתרגלנו אליה מריצה בענן בעזרת שירותים כמו AWS EC2 או Azure Virtual Machines (להלן ״ענן של מכונות וירטואליות״) – קוברנטיס מאפשרת רמה חדשה וגבוהה יותר של יעילות בניצול משאבי-חומרה.

 

בתצורה קלאסית של מיקרו-שירותים, הפופולרית כיום – ייתכן ומדובר בניצולת חומרה טובה בכמה מונים. הכל תלוי בתצורה, אבל דיי טיפוסי להריץ את אותו ה workload של מיקרו-שירותים בעזרת קוברנטיס על גבי 20-50% בלבד מהחומרה שהייתה נדרשת על גבי ״ענן ציבורי של מכונות וירטואליות״.

 
איך זה קורה? למכונה וירטואלית יש overhead גבוה של זיכרון (הרצת מערכת ההפעלה + hypervisor) על כל VM שאנו מריצים. זה לא כ״כ משמעותי כשמריצים שרת גדול (כיום נקרא בבוז: Monolith) – אך זה מאוד משמעותי כאשר מריצים שרתים קטנים (להלן: מיקרו-שירותים).

 

מעבר לתקורה הישירה שעתה ציינו, יש תקורה עקיפה וגדולה יותר: כאשר אני מריץ על שרת 4 מיקרו-שירותים בעזרת VMs ומקצה לכל אחד מהמיקרו-שירותים 25% מהזיכרון וה CPU ההגבלה היא קשיחה. אם בזמן נתון שלושה מיקרו-שירותים משתמשים ב 10% ממשאבי המכונה כ״א, אבל המיקרו-שירות הרביעי זקוק ל 50% ממשאבי המכונה – הוא לא יכול לקבל אותם. ההקצאה של 25% היא קשיחה ואינה ניתנת להתגמשות, אפילו זמנית [ב].
 
בסביבת קוברנטיס ההגבלה היא לא קשיחה: ניתן לקבוע גבולות מינימום / מקסימום ולאפשר מצב בו 3 מיקרו-שירותים משתמשים ב 10% CPU ו/או זיכרון כ״א, והרביעי משתמש ב 50%. אפשר שגם 10 דקות אח״כ המיקרו-שירות הרביעי יהיה idle – ומיקרו-שירות אחר ישתמש ב 50% מהמשאבים.

 

 

 
 

הכרה חברתית

 
יהיה לא נכון להתעלם מהתשואה החברתית של השימוש בקוברנטיס. מי שמשתמש היום בקוברנטיס, ובמיוחד בפרודקשן – נתפס כמתקדם טכנולוגית, וכחדשן. ההכרה החברתית הזו – איננה מבוטלת.
 
כמובן שזו הכרה זמנית, שרלוונטית רק שנים בודדות קדימה. ביום לא רחוק, שימוש בקוברנטיס ייחשב מפגר ומיושן, ועל מנת להיתפס כמתקדמים / חדשנים – יהיה עלינו לאמץ טכנולוגיה אחרת.
 
יש לי תחושה שפעמים רבות, ההכרה החברתית היא שיקול חזק לא פחות משיקולי היעילות – בבחירה בקוברנטיס. טבע האדם.
 
 

מחירים

 
כמובן שיש לכל הטוב הזה גם מחירים:
  • קוברנטיס היא טכנולוגיה חדשה שיש ללמוד – וכמות / מאמץ הלמידה הנדרש הוא לרוב גבוה ממה שאנשים מצפים לו.
    • התסריטים הפשוטים על גבי קוברנטיס נראים דיי פשוטים ואוטומטים. כאשר נכנסת לתמונה גם אבטחה, הגדרות רשת, ותעדוף בין מיקרו-שירות אחד על האחר – הדברים הופכים למורכבים יותר!
      Troubleshooting – עשוי להיות גם דבר לא פשוט, מכיוון ש"מתחת למכסה המנוע" של קוברנטיס – יש מנגנונים רבים.
    • ברוב המקרים נרצה להריץ את קוברנטיס על שירות ענן, ולכן נידרש עדיין לשמר מידה של מומחיות כפולה בשני השירותים: לשירות הענן ולקוברנטיס יש שירותים חופפים כמו Auto-Scaling, הרשאות ו Service Discovery (בד"כ: DNS). 
  • הטכנולוגיה אמנם לא ממש ״צעירה״, והיא בהחלט מוכחת ב Production – אך עדיין בסיסי הידע והקהילה התומכת עדיין לא גדולה כמו פתרונות ענן מסחריים אחרים. יש הרבה מאוד אינטגרציות, אך מעט פחות תיעוד איכותי וקל להבנה.
  • כמו פעמים רבות בשימוש ב Open Source – אין תמיכה מוסדרת. יש קהילה משמעותית ופעילה – אבל עדיין הדרך לפתרון בעיות עשויה להיות קשה יותר מהתבססות על פתרון מסחרי. 
    • גם בשימוש ב״קוברנטיס מנוהל״ (EKS, AKS, ו GKE), החלק המנוהל הוא החלק הקטן, והשאר – באחריותנו.
    • האם החיסכון הצפוי מניהול משאבים יעיל יותר, יצדיק במקרה שלכם שימוש בסביבה שדורשת מכם יותר תפעול והבנה?
      • במקרה של ניהול מאות או אלפי שרתים – קרוב לוודאי שזה ישתלם.
      • שימוש בקוברנטיס עשוי לפשט את סביבת התפעול, וה Deployment Pipeline. ההשקעה הנדרשת היא מיידית – בעוד התשואה עשויה להגיע רק לאחר זמן ניכר, כאשר היישום הספציפי באמת הגיע לבגרות.
      • במקרים לא מעטים, ארגונים נקלעים לשרשרת של החלטות שנגזרות מצו האופנה ובניגוד לאינטרס הישיר שלהם: עוברים למיקרו-שירותים כי ״כך כולם עושים״ / ״סיפורי הצלחה״ שנשמעים, משם נגררים לקוברנטיס – כי יש להם הרבה מאוד שרתים לנהל, שכבר נהיה דיי יקר.
        לו היינו עושים שיקולי עלות/תועלת מול המצב הסופי – כנראה שהרבה פעמים היה נכון לחלק את המערכת למודולים פשוטים, או להשתמש במיקרו-שירותים גדולים ("midi-services") – וכך לשלוט טוב יותר בעלויות והמורכבויות האחרות.
 

 

 
 

קוברנטיס בפועל

 
דיברנו עד עכשיו על עקרונות ברמה הפשטה גבוה. בואו ניגש לרמה טכנית קצת יותר מוחשית.

לצורך הדיון, נניח שהעברנו כבר את כל השירותים שלנו לעבוד על-גבי Docker וגם התקנו כבר Cluster של קוברנטיס. זה תהליך לא פשוט, שכולל מעבר על כמה משוכות טכניות לא קלות – אך נניח שהוא נגמר. בכדי להבין קוברנטיס חשוב יותר להבין מה יקרה אחרי ההתקנה, מאשר להבין את ההתקנה עצמה.

 
לצורך הדיון, נניח שאנו עובדים על AWS ו EKS ואמזון מנהלים עבורנו את ה Masters nodes. ה Worker nodes שלנו נמצאים ב Auto-Scaling Group – מה שאומר שאמזון תנהל עבורנו את ה nodes מבחינת עומס (תוסיף ותוריד מכונות ע״פ הצורך) והחלפת שרתים שכשלו. זה חשוב!
 
אנחנו גם משתמשים ב ECR (קרי Container Registry מנוהל) , ואנו משתמשים בכל האינטגרציות האפשריות של קוברנטיס לענן של אמזון (VPC, IAM, ELB, וכו׳). התצורה מקונפגת ועובדת היטב – ונותר רק להשתמש בה.
 
אנחנו רק רוצים ״לזרוק״ קונטיינרים של השירותים שלנו – ולתת ל״קסם״ לפעול מעצמו. רק לומר בפשטות מה אנחנו רוצים – ולתת לקוברנטיס לדאוג לכל השאר!
 

 

יצירת Pod

הפעולה הבסיסית ביותר היא הרצה של Container. בקוברנטיס היחידה האטומית הקטנה ביותר שניתן להריץ נקראת Pod והיא מכילה Container אחד או יותר. כרגע – נתמקד ב Pod עם Container יחיד, זה יהיה המצב ברבים מהמקרים.

אני מניח שאנחנו מבינים מהו Container (אם לא – שווה לחזור צעד אחורה, ולהבין. למשל: הפוסט שלי בנושא), ויש לנו כבר Image שאנו רוצים להריץ ב ECR.

בכדי להריץ Container, עלינו לעדכן את קוברנטיס ב manifest file המתאר Pod חדש מצביע ל container image. קוברנטיס ירשום את ה Pod ויתזמן אותו לרוץ על אחד מה nodes שזמינים לו.

כאשר ה node מקבל הוראה להריץ Pod עליו להוריד את ה container image – אם אין לו אותו כבר. כל node מחזיק עותקים עצמאיים של ה container images משיקולים של high availability.

הנה קובץ ה manifest שהרכבנו:

apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
env: dev
version: v1
spec:
containers:
- name: hello-world-ctr
image: hello-world:latest
ports:
- containerPort: 8080
protocol: TCP

קובץ ה manifest בקוברנטיס מורכב מ 4 חלקים סטנדרטיים:

  1. גרסת ה API
    1. הפורמט הוא לרוב / אבל כמה הפקודות הבסיסיות ביותר בקוברנטיס נמצאות תחת API Group שנקרא core – ולא צריך לציין אותו.
    2. ה API של קוברנטיס נמצא (בעת כתיבת הפוסט) בגרסה 1.13 – אז למה גרסה 1?
      ניהול הגרסאות בקוברנטיס הוא ברזולוציה של משאב. הקריאה לייצור pod היא עדיין בגרסה 1 (כמו כמעט כל ה APIs. בעת כתיבת הפוסט אין עדיין גרסת v2 לשום API, מלבד v2alpha או v2beta – כלומר גרסאות v2 שעדיין אינן GA).
  2. סוג (kind) – הצהרה על סוג האובייקט המדובר. במקרה שלנו: Pod.
  3. metadata – הכולל שם ו labels שיעזרו לנו לזהות את ה pod שיצרנו.
    1. ה labels הם פשוט זוגות key/value שאנחנו בוחרים. הם חשובים מאוד לצורך ניהול Cattle של אובייקטים, והם בלב העבודה בקוברנטיס.
  4. spec – החלק המכיל הגדרות ספציפיות של המשאב שהוגדר כ "Type". 
    1. name – השם שניתן ל container בתוך ה Pod, וצריך להיות ייחודי. במקרה של container יחיד בתוך ה pod – אין בעיה כזו. 
    2. image – כמו בפקודת docker run…
    3. ports – ה port שיהיה published.
      TCP הוא ערך ברירת-המחדל, אך הוספתי אותו בכדי לעשות את ה Yaml לקריא יותר.

תזכורת קצרה על Yaml:

פה ייתכן וצריך לעצור שנייה ולחדד כמה מחוקי-הפורמט של Yaml.
ייתכן ונדמה לכם ש Yaml הוא פורמט פשוט יותר מ JSON – אבל זה ממש לא נכון. זה פורמט "נקי לעין" – אבל מעט מורכב.

רשימה ב Yaml נראית כך:

mylist:
- 100
- 200

"mylist" הוא ה key, והערך שלו הוא רשימה של הערכים 100 ו 200.
כל האיברים שלפניהם הסימן " – " ובעלי עימוד זהה – הם חברים ברשימה.
סימן ה Tab ברוב ה Editors מתתרגם ל 2 או 4 רווחים. ב Yaml הוא שקול לרווח אחד, ולכן שימוש בו הוא מקור לבעיות ובלבולים. הימנעו משימוש ב Tab בתוך קבצי Yaml!

המבנה הבא, שגם מופיע ב manifest (ועשוי לבלבל) הוא בעצם רשימה של Maps:

channels:
- name: '#mychannel'
password: ''
- name: '#myprivatechannel'
password: 'mypassword'

"channel" הוא המפתח הראשי, הכולל רשימה.
כאשר יש "מפתח: ערך" מתחת ל"מפתח: ערך" באותו העימוד – משמע שמדובר ב Map.
כלומר, המפתח "channel" מחזיק ברשימה של שני איברים, כל אחד מהם הוא מפה הכוללת שני מפתחות "name" ו "password".

אם נחזור לדוגמה של הגדרת ה container ב manifest למעלה, בעצם מדובר במפתח "containers" המכיל רשימה של איבר אחד.
בתוך הרשימה יש מפה עם 3 מפתחות ("image", "name", ו "ports") כאשר המפתח האחרון "ports" מכיל רשימה עם ערך יחיד, ובה מפה בעלת 2 entries.

הנה מדריך המתאר את ה artifacts הבסיסיים ב Yaml ממנו לקחתי את הדוגמאות.
חשוב להזכיר שיש עוד כמה וכמה artifacts ב Yaml – אם כי כנראה שלא נזדקק להם בזמן הקרוב.

 

עכשיו כשיש לנו manifest, אנחנו יכולים להריץ את ה Pod:

$ kubectl apply -f my-manifest-file.yml
 

kubectl הוא כלי ה command line של קוברנטיס. פקודות מסוימות בו יזכירו לכם את ה command line של docker.
במקרה הזה אנו במקרה הזה אנו מורים לקוברנטיס להחיל קונפיגורציה. הפרמטר f- מציין שאנו מספקים שם של קובץ.

תוך כמה עשרות שניות, לכל היות, ה pod שהגדרנו אמור כבר לרוץ על אחד ה nodes של ה cluster של קוברנטיס.

אנו יכולים לבדוק אלו Pods רצים בעזרת הפקודה הבאה:

$ kubectl get pods

עמודה חשובה שמוצגת כתוצאה, היא עמודת הסטטוס – המציגה את הסטטוס הנוכחי של ה pod. אמנם יש רשימה סגורה של מצבים בו עשוי להיות pod, אולי עדיין הסטטוס המדווח יכול להיות שונה.
למשל: הסטטוס ContainerCreating יופיע בזמן שה docker image יורד ל node. זה מצב נפוץ – אך לא מתועד היטב. את הסטטוס ניתן למצוא בעיקר… בקוד המקור של קוברנטיס.

הפקודה הבאה (וריאציות), בדומה לפקודת ה Docker המקבילה – תציג את הלוגים של ה Container ב Pod :

$ kubectl logs my-pod 
אם ב Pod יש יותר מ-2 containers (מצב שלא אכסה בפוסט), הפקודה תציג לוגים של ה container הראשון שהוגדר ב manifest. אפשר לציין את שם ה container כפי שצוין ב manifest – וכך להגיע ל container נתון בתוך Pod-מרובה containers.
 
עבור תקלות יותר בסיסיות (למשל: ה pod תקוע על מצב ContainerCreating וכנראה שה node לא מצליח להוריד את container image) – כדאי להשתמש בפקודה:
$ kubectl describe pods my-pod
התוצאה תהיה ססטוס מפורט שיכיל את הפרטים העיקריים מתוך ה manifest, רשימה של conditions של ה pod, ורשימת כל אירועי-המערכת שעברו על ה pod מרגע שהורנו על יצירתו. הנה דוגמה להפעלה הפקודה (מקור):
 
 
Name:  nginx-deployment-1006230814-6winp
Node: kubernetes-node-wul5/10.240.0.9
Start Time: Thu, 24 Mar 2016 01:39:49 +0000
...
Status: Running
IP: 10.244.0.6
Controllers: ReplicaSet/nginx-deployment-1006230814
Containers:
nginx:
Container ID: docker://90315cc9f513c750f244a355eb1149
Image: nginx
Image ID: docker://6f623fa05180298c351cce53963707
Port: 80/TCP
Limits:
cpu: 500m
memory: 128Mi
State: Running
Started: Thu, 24 Mar 2016 01:39:51 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-5kdvl (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-4bcbi:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-4bcbi
Optional: false
...
Events:
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
54s 54s 1 {default-scheduler } Normal Scheduled Successfully assigned nginx-deployment-1006230814-6winp to kubernetes-node-wul5
54s 54s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Pulling pulling image "nginx"
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Pulled Successfully pulled image "nginx"
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Created Created container with docker id 90315cc9f513
53s 53s 1 {kubelet kubernetes-node-wul5} spec.containers{nginx} Normal Started Started container with docker id 90315cc9f513
 
ניתן גם, בדומה ל Docker, לגשת ישירות ל console של ה container שרץ ב pod שלנו בעזרת הפקודה:
$ kubectl exec my-pod -c hello-world-ctr -it -- bash
במקרה הזה ציינתי את שם ה container, אם כי לא הייתי חייב.

נראה לי שזה מספיק, לבינתיים. בואו נסגור את העניינים:

$ kubectl delete -f my-manifest-file.yml

הפעולה הזו עלולה להיראות מוזרה ברגע ראשון. הסרנו את הקונפיגורציה – ולכן גם ה Pod ייסגר?

לשימוש בקוברנטיס יש שתי גישות עיקריות:

  • גישה אימפרטיבית – בה מורים לקוברנטיס איזה שינוי לבצע: להוסיף משאב, לשנות משאב, או להוריד משאב.
    • פקודות כגון kube ctl create או kubectl replace הן בבסיס הגישה האימפרטיבית.
  • גישה דקלרטיבית – בה מורים לקוברנטיס מה המצב הרצוי – והוא יגיע עליו בעצמו.
    • פקודת kubectl apply – היא בבסיס הגישה הדקלרטיבית. אפשר להגדיר כמעט הכל, רק באמצעותה.
    • החלת patch על גבי קונפיגורציה קיימת הוא משהו באמצע: זו פקודה דקלרטיבית, אך מעט חורגת מה lifecycle המסודר של הגישה הדקלרטיבית הקלאסית. סוג של תרגיל נינג'ה.
כמובן שהגישה הדקלרטיבית נחשבת קלה יותר לשימוש ולתחזוקה לאורך זמן – והיא הגישה הנפוצה והשלטת.

מכיוון שאין לנו הגדרה אלו Pods קיימים סה"כ במערכת – לא יכולנו לעדכן את המערכת בהגדרה הכוללת – ולכן הסרנו את המניפסט.

סיכום

ניסינו להגדיר בקצרה, ובצורה עניינית מהם היתרונות הצפויים לנו משימוש בקוברנטיס – מול הצפה של החסרונות והעלויות.

לא פעם קראתי מאמרים שמתארים את קוברנטיס כמעבר מהובלת מסע על גבי פרד – לנסיעה ברכב שטח יעיל!
אני חושב שההנחה הסמויה ברוב התיאורים הללו היא שהקוראים עדיין עובדים על גבי מערכות On-Premises ללא טכנולוגיות ענן. מעבר משם לקוברנטיס – היא באמת התקדמות אדירה.

המעבר משימוש ב"ענן של מכונות וירטואליות" לקוברנטיס – הוא פחות דרמטי. קוברנטיס תספק בעיקר יעילות גבוהה יותר בהרצת מיקרו-שירותים, וסביבה אחידה וקוהרנטית יותר למגוון פעולות ה deployment pipeline.
עדיין, נראה שקוברנטיס היא סביבה מתקדמת יותר – ואין סיבה שלא תהפוך לאופציה הנפוצה והמקובלת, בתוך מספר שנים.

אחרי ההקדמה, עברנו לתהליך יצירה של Pod בסיסי, ובדרך עצרנו בכמה נקודות בכדי להדגים כיצד התהליך "מרגיש" בפועל.

חשוב לציין שה Pod שהגדרנו הוא עצמאי ו"חסר גיבוי" – מה שנקרא "naked pod".
אם naked pod כשל מסיבה כלשהי (הקוד שהוא מריץ קרס, או ה node שעליו הוא רץ קרס/נסגר) – הוא לא יתוזמן לרוץ מחדש. מנגנון ה auto-healing של קוברנטיס שייך לאובייקט / אבסטרקציה גבוהה יותר בשם ReplicaSet. אבסטרקציה מעט יותר גבוהה, שבה בדרך כלל משתמשים – נקראת Deployment.

כיסינו דיי הרבה לפוסט אחד. הנושאים הללו מצדיקים פוסט משלהם.

שיהיה בהצלחה!

—-

לינקים רלוונטיים

רפרנס של פקודות ה kubectl

 

—-
 
[א] אל דאגה! לספקי הענן יש אינטרס עליון לגרום לנו ל Lock-In גם על סביבת קוברנטיס. לאחר שהניסיונות להציע חלופות ״מקומיות״ לקוברנטיס כשלו – רק טבעי שהם יתמקדו בלהציע יכולות שיפשטו את השימוש בקוברנטיס, אך גם יוסיפו סוגים חדשים של Lock-In. בכל מקרה, ברוב הפעמים אנו כבר תלויים בתשתיות כמו RDS, Athena, S3 ועוד – ולכן כבר יש Lock-In מסוים גם בלי קשר לקוברנטיס.
"Cloud Agnostic Architecture״ הוא בסה״כ מיתוס, השאלה היא רק מידת התלות.
 
[ב] שווה לציין שזה המצב בענן ציבורי. כששכן שלנו למכונה ב AWS רוצה יותר CPU – למה שנסכים לתת לו? אנחנו משלמים על ה ״slice״ שלנו במכונה – שהוגדר בתנאי השירות.
בפתרונות של ענן פרטי (כמו VMWare) ישנן יכולות ״ללמוד״ על brusts של שימוש בקרב VM ולהתאים את המשאבים בצורה יעילה יותר. כלומר: המערכת רואה ש VM מספר 4 דורש יותר CPU אז היא משנה, בצורה מנוהלת, את ההגדרות הקשיחות כך שלזמן מסוים – הוא יקבל יותר CPU מה VMs האחרים הרצים על אותה המכונה. טכנולוגית ה VM עדיין מקצה משאבים בצורה קשיחה – אך תכנון דינמי יכול להגביר יעילות השימוש בהם. זה יכול לעבוד רק כאשר כל ה VMs על המכונה שייכים לאותו הארגון / יש ביניהם הסכמה.
T3/T2 instances ב EC2 הם VMs שעובדים על עיקרון דומה: ב״חוזה״ שלנו רשום שה instance יכול לעבוד ב burst ולקבל יותר משאבים – אך עדיין יש פה עבודה לפי חוזה, ולא אופטימיזציה גלובלית של המשאבים על המכונה (מכיוון שה VMs שייכים לארגונים שונים).  

קוברנטיס (Kubernetes) עומד להיות הענן-בתוך-הענן של רובנו

אני לא כותב כ״כ בבלוג על נושאים "חדשותיים", זו לא ההתמחות של הבלוג – אבל בפוסט הבא אני הולך להיות טיפה ספקולטיבי, על מגמה שנראית שהולכת להיות השלטת בשנים הקרובות, גם אם כרגע היא רק החלה.

מדוע אני כותב את הפוסט דווקא עכשיו? שום דבר לא קרה בשבוע האחרון. רק יצא יום כיפור (אין קשר), אמנם הכריזו על ליין חדש של אייפונס, ויש גם את ארכיטקטורת Turing החדשה של nvidia – אבל לא באמת היה השבוע משהו גדול ורועש בגזרת ה Containers ו/או Container Orchestration Framework (בקיצור עבור הפוסט: COF).
בכל זאת, לפני כשנה כתבתי פוסט שעסק ב COFs והשווה קצת בין מזוס, ECS, קוברנטיס, Swarm ו Nomad – ובאותה עת נראה היה שהתחרות בין כמה מה COFs שהוזכרו עדיין פתוחה.
כשאני מסתכל על ההתרחשויות של השנה האחרונה – נראה שהעניין נסגר. אם "קולות החיילים" לא יבצעו מהפך של הרגע האחרון – Kubernetes הוכרזה בחודשים האחרונים כ COF שתכתיב את הטון בעתיד הנראה לעין.
תזכורת קצרה:
  • קוברנטיס (לעתים נכתב בקיצור K8s) היא פריימוורק ששוחרר כפרויקט קוד פתוח ע״י גוגל באמצע שנת 2014 לניהול Orchestrations של Containers. בסה"כ בת ארבע שנים.
    • לגוגל היה ניסיון קודם בפרויקטים פנימיים דומים: הראשון בשם Borg והמחליף שלו – Omegaֿ, להרצת קונטיינרים. הם לא הריצו Docker או Rkt – אלא קונטיינרים פרי פיתוח מוקדם של גוגל. הניסיון הזה הוכיח את עצמו.
  • קוברנטיס (בדומה ל COFs אחרים) מספקת יכולות Load Balancing, Discovery ו Auto-Scaling ובעצם מהווה סוג של ״מיני-ענן״ בו יחידת ה compute היא Container. האיום הזה לא נחבא מעיניהם של ספקי-הענן הגדולים, והם ניסו לפתח COFs מקבילים שישמרו את ה Lock-In לענן שלהם.
  • אמזון יצאה עם ECS, ומייקרוסופט עם ACS (שתי החברות שאולי היה להן הכי הרבה להפסיד) – פתרון הרצת ו Orchestrations של Containers שתפור לענן שלהן. והן הטילו את כובד משקלן בכדי לשכנע שזו אלטרנטיבה ראויה (וטובה יותר) לקוברנטיס – אלטרנטיבה שרק צריכה עוד זמן להבשיל.
  • השוק לא הגיב יפה להצעות הללו – ופנה ל manual installation של קוברנטיס על גבי EC2.
  • מייקורוסופט הוציאה את AKS (קרי Azure Kubernetes Service) ואמזון את EKS (קרי Elastic Kubernetes Service) כ Kubernetes מנוהל. בהתחלה נראה היה ש EKS ו AKS הולכים להיות offering משני על מנת לשמר לקוחות ולא להישאר יותר מדי מאחור, אבל מהר מאוד התברר שהשירותים הללו תופסים את תשומת-לב הלקוחות, ומשם השתנו הדברים והם התחילו לקבל גם את מירב ההשקעה מצד ספקי הענן. ECS/ACS הופכים להיות פתרונות נישה, בעיקר עבור לקוחות שכבר נרתמו לחזון שהוצג ב 2015, והשקיעו בו, או אולי יצליחו לשלב אותם גם בעולם של קוברנטיס (עבור ה worker nodes – על זה בהמשך).
  • גם פתרונות ענן כגון Pivotal Container Service ו Cloud Foundary – הגיעו למסקנה דומה, ופנו לכיוון קוברנטיס.
  • אפילו החברה מאחורי Docker שניסתה להציג חזון משלה בדמות Swarm (לאחר שהבינה שב COFs יש פוטנציאל עסקי גדול יותר מתמיכה ב Docker בלבד) הכריזה לפני כשנה על תמיכה ״גם״ בקוברנטיס – מה שבפועל ״הוציא את העוקץ״ מ Swarm שמותג כ"פתרון הרשמי של דוקר".
  • Mesosphere DC/OS – הגרסה המסחרית של Mesos, מציעה גם היא תמיכה בקוברנטיס.
בקיצור: מלחמת ה COFs הסתיימה. Long live Kubernetes!
חשוב לציין שלמרות שקוברנטיס הוא ה COF שהפך לברירת-המחדל, יש עדיין תהליכים שלא ברור כיצד יסתיימו:
  • מייקרוסופט שחררה את ACI (קרי Azure Container Instances) ואמזון את AWS Fargate כשירותים בהם ניתן להריץ container on-demand ולשלם ע״פ השימוש הנקודתי. השירותים מזכירים מאוד את AWS Lambda או Azure functions כאשר הרזולוציה היא Container ולא פונקציה, על אף שמנסים לשווק אותם כ"תחליף ל EC2".
    • השימוש העיקרי הוא בהפעלה של containers המבצעים batch של עבודה – ולא בהרכבה של containers מסוגים שונים המתקשרים זה עם זה. האלמנט של Orchestration לא ממש קיים בשירותים הללו.
    • גם קוברנטיס תומכת בהפעלת containers באופן on-demand, מה שעשוי לרמז שהלקוחות העיקריים של ACI ו Fargate הם לקוחות שלא מריצים קובנרטיס או כאלו שיש להם Workload מאסיבי שאינם רוצים להפעיל על ה Kubernetes cluster הרגיל שלהם (למשל: משימות AI כבדות).
  • קוברנטיס עצמה נפתחה לספקי הענן, למשל: החל מגרסה 1.9 קוברנטיס תומכת באופן טבעי ב AWS NLB (קרי Network Load Balancer). מיותר לציין שיש הרבה Kubernetes-plugins שמסייעים לבצע את החיבורים לעננים ספציפיים בצורה טבעית יותר.
  • ישנה השקעה בהרצה של Kubernetes בכדי להפעיל VMs ולא רק Containers. המוטיבציה היא לשלב גם שרתים שאינם לינוקס (למשל Windows או אפליקציות Unikernel) ו/או בידוד גבוה יותר – בעיקר משיקולי אבטחה.
  • קוברנטיס מאפשרת יכולות ניהול משאבים טובות ברמת התשתית, אבל ניהול של מאות מיקרו-שירותים הוא עדיין דבר קשה מאוד בקוברנטיס. יש פרויקטים (למשל: lstio הנתמך ע״י Lyft, IBM וגוגל) המנסים לספק שכבת ניהול ברמה יותר ״אפליקטיבית״ שתקל על ניהול שכזה. פרויקטים כאלו יכולים להשתלב עם קוברנטיס כ plug-in ו/או להחליף כמה מיכולות הליבה שלה (למשל: Service Discovery או Load Balancing).
Amazon EKS

Managed Kubernetes

כמה שאנו אוהבים לשמוע כמה אוטומטית ו״חכמה״ היא קוברנטיס בניהול ה Containers Cluster, הפעלה של קוברנטיס היא עדיין משימה מורכבת:

  • יש שורה של בחירות שיש לבצע בהתקנה של קוברנטיס. האם אתם מעדיפים א או ב, ג או ד? דוגמה טובה היא תקשורת בין Containers: האם Kubenet (ברירת-המחדל) מספיק לכם? אולי אתם צריכים scale, ביצועים, ו/או יכולות שליטה מתקדמות יותר ברמת הרשת וכדאי להשתמש ב Weave? אולי בעצם ב Calico? ואם אתם בוחרים ב Calico – אתם מעדיפים אותו עם Flannel (כלומר: Canal) או בלעדיו?
  • קוברנטיס מטפל בשורה של מקרי-קצה מורכבים להבנה, שללא ניסיון ניכר – קשה להבין אותם ולוודא שהם עובדים בצורה תקינה.
    • High Availability – איך להבטיח ש pods ימשיכו לתפקד ככל האפשר. לדוגמה: האם ה masters הם באמת highly available? האם אתם יכולים ליצור master חדש עם קונפיגורציה שלמה בצורה אוטומטית?
    • אבטחה – האם אתם מודעים כיצד להקשיח התקנה של קוברנטיס, ויש לכם את המנגנון להתקין עדכונים בכל השכבות?
  • חיבור של קוברנטיס לספק הענן הספציפי היא עוד משוכה שיש לעבור. למשל: על EC2 לא תוכלו ליצור cluster גדול מ 50 nodes ללא החלפה של ה CNI Network plugin. כנראה שתרצו כמה מה nodes שירוצו על spots. כדאי מאוד להתחבר ל IAM בצורה נכונה, לקנפג את Route53 כך שה master ימצא את כל הרכיבים שלו ואם יש כמה clusters – הם יהיו זקוקים ל subdomains, וכו׳.
הפתרון הטבעי, בדומה מאוד לבחירה בספק ענן (ולא הפעלה של Data Center של החברה) – הוא שימוש ב Managed Kubernetes. זו הבחירה הטבעית עבור הרוב הגדול של משתמשי Kubernetes, במיוחד אלו שלא הולכים להריץ אלפי שרתים ב Cluster של קוברנטיס (ולכן סביר יותר שיהיה לכם את האינטרנס והמשאבים לעבוד עם קונפיגורציה מאוד ספציפית ("לא מקובלת") לצרכים שלכם).

יש כמה פתרונות מקובלים של Managed Kubernetes בימים אלו, חלקם בשלים יותר מהאחרים. מכיוון שקוברנטיס הוא טרנד חזק כרגע – אין ספק שספקי הענן עושים מאמצים אדירים על מנת לשפר את ה offering שלהם במהירות האפשרית:

  • גוגל – בתור היוצרים של Kubernetes והמאמצים הראשונים שלו כשירות Managed בענן, אין הפתעה בכך ש GKE (להלן Google Kubernetes Engine) הוא המוצר הבשל ביותר.
    • האינטגרציה הטובה ביותר, UI מלוטש לניהול, והפעלה מהירה של Cluster מאשר של המתחרות.
    • הבעיה היחידה: רוב החברות (בכלל, אך בישראל בפרט) לא פועלות על הענן של גוגל, והם לא יעבירו אותן לשם בשביל "Managed Kubernetes טוב יותר". זה עשוי להשתנות בעתיד – אבל כרגע לא נראה שזה המצב.
    • בניגוד ל BigQuery שהוא שירות שלקוח של AWS עשוי להשתמש בו על אף שהוא שוכן בענן אחר – קוברנטיס מריצה את לב המערכת שלנו. להשתמש בקוברנטיס בענן אחר, משמע להתחיל לעבור לענן אחר.
  • אמזון מציעה את EKS, שהיה עד לא מזמן plan B – שהתממש.
    • EKS תנהל עבורכם את ה Control plane מבחינת scalability ו high-availability על גבי AZs שונים. לא תהיה לכם גישה ברמת Admin אליו (בדומה ל RDS), אבל אתם ממשיכים לעבוד עם kubectl כרגיל.
    • לEKS יש אינטגרציה עם שירותי אמזון בראשם IAM, אבל גם ELB, VPC ו CloudTrail.
    • את ה Worker nodes עדיין עליכם לנהל לבד – ויש עוד קונפיגורציה ועבודה שעליכם לעשות על גבי EKS. יש תוכניות לבצע אינטגרציה בין EKS ל ECS כך ש ECS ינהל את ה worker nodes. מכיוון שהוא לא נבנה מלכתחילה לצורת העבודה הזו – צריך לראות כמה טוב זה יעבוד. רעיון דומה מתוכנן לאינטגרציה בין EKS ל Fargate להרצה של Containers שהם task-oriented.
    • לאחרונה שוחררה גרסאת eks.2 של EKS – ויהיו עוד רבות. כרגע ל EKS יש סיכוי טוב להיות פתרון ה Managed Kubernetes הפופולארי ביותר (גם אם לא בהכרח יהיה המתקדם ביותר).
  • מייקורוספט מציעה על גבי Azure את שירות AKS המנוהל, שדומה ביכולות ל EKS.
    • אולי בגלל קהילה קטנה יותר ופעילה פחות, AKS נראה כשירות קצת פחות פופולארי. אפשר לנחש שהלקוחות הקלאסיים של מייקרוסופט הם ברובם לא early adapters של טכנולוגיות חדשות.
  • גם OpenShift ויבמ BlueMix – מציעות פתרונות Kubernetes שנחשבים מפותחים, אך הם מתאימים בפועל בעיקר למי שכבר פעיל על תשתיות הענן הללו.
  • Stackpoint מציעה פתרון של managed control plane על ידה, כאשר את ה worker nodes תתקינו על ענן לבחירתכם. הפתרון אטרקטיבי בעיקר למי שמריץ את ה workload בענן שבו אין offering סביר של managed kubernetes.
השוואה שנעשתה בין שלושת פתרונות ה Managed Kubernetes הנפוצים. מקור

גם מי שמתקין קוברנטיס לבד (על הענן או On-Premises) לרוב לא עושה זה בדרך הארוכה והקשה.
kubernetes-the-hard-way הוא שם של מדריך פופולארי ונחשב להתקנת קוברנטיס מ scratch, שבעיקר משמש בכדי ללמוד את הפרטים השונים שקיימים בהתקנת קוברנטיס, ואת השיקולים שנלקחים בכזו התקנה.

בפועל, מי שמתקין קוברנטיס, יעשה זאת כמעט תמיד עם "installer" המיועד לכך:

  • Kops הוא המקובל ביותר. הוא חלק מפרויקט קוברנטיס והיה במשך תקופה כלי להתקנת קוברנטיס על גבי AWS בלבד. הוא יודע לייצר קבצי Terraform, יודע לבנות תצורות high-availability (כמובן), ותומך ב-7 אפשרויות שונות ל CNI (כלומר: plugin לתקשורת פנימית. אחת הבחירות עם הווריאציות המגוונות יותר בהתקנת קוברנטיס).
  • Kubespray (לשעבר Kargo), תת-פרויקט של קוברנטיס הוא כלי להתקנת קוברנטיס בהתבסס על Ansible, כלי ה configuration management שנחשב לפופולארי ולמתקדם – עד להופעת ה COFs שהולכים ומייתרים אותו. Kubespray נחשב יותר גמיש מ Kops ומציע מגוון רחב יותר של אפשרויות התקנה. יש לו גם תמיכה ספציפית ב AWS, Azure, Google Cloud, Digital Ocean ו Open Stack.
  • TK8 הוא עוד כלי פופולרי, שהדגש שלו הוא עבודה צמודה עם Terraform והוא זוכה לכמה נקודות פופולריות בזכות זה שהוא כתוב ב Go (אזהרת באזז). TK8 כולל גם אפשרות התקנה של כמה אפליקציות פופולריות בהמשך ל Kubernetes Cluster כמו Zipkin+Jagger, Prometheus ועוד.
  • עוד שמות שאפשר לציין הם RKE (להתקנה של ה Cluster בלבד, לאחר שהכנתם את המכונות באופן מסוים), מודול שקיים ומתוחזק ב Puppet להתקנה של Kubernetes, או Kubeinformation שהוא כלי online שעוזר לייצר templates של קונפיגורציות ע"פ סט בחירות שתתנו לו. Kubeinformation עשוי להיות מקור מעניין להתרשם בזריזות מתהליך ההתקנה, אבל בעת כתיבת פוסט זה הוא עדיין לא תומך ב EKS (זו הפריט הבא ב roadmap שלו).

מכיוון שהתקנת קוברנטיס הפכה לעניין שדרש הרבה השלמות, פרויקט Kubernetes החל לחשוף את ה Kubernetes Cluster API שאמור להיות בעתיד הדרך הקלה והנפוצה ליצור ולקנפג Kubernetes Cluster. התוכנית היא שה Installers השונים יעברו דרכו, ותוך כדי כך יהפכו לפשוטים, אמינים, ו"סטנדרטיים" יותר (מנקודת המבט של קוברנטיס).

כלים להתקנת קוברנטיס יכלו בקלות להפוך לסוג של Distros כמו Linux Distros אך מכיוון שנראה היום שרוב העולם ילך לכיוון של managed Kubernetes – להם תישאר נישה קטנה יחסית, של משתמשים מתקדמים שרוצים לשלוט בהתקנת ה Kubernetes שלהם בעצם.

סיכום

העולם הטכנולוגי מתקדם בחזית רחבה לכיוון קוברנטיס (גם בצורה עיוורת לפעמים – סממן חזק להפיכתו ל"באזז"). קוברנטיס היא תשתית מרשימה, אבל גם לא-פשוטה לניהול. התסריט הסביר ביותר הוא שפתרונות של Managed Kubernetes ישמשו את רוב השחקנים בשוק, בעיקר הקטנים והבינוניים (תמיד יכולה להיות שחקנית שתדמה ל Netflix ע"ג AWS, כלומר: שתחליט להריץ גם מאות-אלפי worker nodes על גבי פתרון Managed).

Enterprises שרצים On-Premises, או מריצים ענן משלהם, או סתם חברות שמריצות Workload גדול במיוחד – כנראה ימשיכו לנהל את ה Kubernetes Cluster מא' עד ת' – אבל זו התמחות שהן יכולות להרשות לעצמן לפתח ולתחזק.

בעת כתיבת הפוסט, קוברנטיס הוא עדיין "דבר ממש מגניב", אבל עוד כמה שנים הוא עשוי להפוך לדבר מובן מאליו עבור רוב החברות, כמו "ריצה בענן". אתם מדמיינים את עצמכם מתרשמים ממקום עבודה רק מכיוון שהוא עובד בענן?

EKS נראה כרגע כאופציה בעלת נקודת הפתיחה הטובה ביותר להיות הפופולרית ביותר (פופולריות שנגזרת באופן ישיר מ AWS ומגוון השירותים הטובים שהיא מציעה) – אבל הכל עוד יכול לקרות. למשל: אם הקוברנטיס יהפוך לחשוב יותר משאר שירותי הענן – אזי ל GKE (קרי Google Kubernetes Engine) יש את היתרון הברור.

בגדול, עובדות בפניכם כרגע האפשרויות הבאות:

  • להתקין קוברנטיס לבד – על בסיס Installers כמובן, ולא בדרך הקשה והארוכה. יש לפניכם השקעה משמעותית בלמידה והתמחות של Infrastructure חדש ונוסף.
  • להשתמש בפתרון Managed Kubernetes, תוך שאתם משלמים "מחיר התבגרות" בשנה-שנתיים הבאות עד שהפתרון שבחרתם יתבגר.
  • לדחות בשנה-שנתיים את אימוץ קוברנטיס עד שהוא יהיה קל מאוד לצריכה בצורה Managed.
    • אם אתם לא יודעים לומר מה Kubernetes יתרום לכם ברגע זה – זו הבחירה הנבונה (אם כי לא הכי-מגניבה)
  • להחליט שאתם בוחרים לא להשתמש בקוברנטיס כעיקרון, מה שיכול לזרוק אתכם לאחת משתי נקודות קיצון חברתיות בעולם התוכנה: "סופר מיושנים" או "סופר מגניבים וחתרניים".
  • להחליט שאתם מתחילים עם קוברנטיס היום, לדבר על זה הרבה, להשקיע ב POCs ולמידה – אבל בעצם להתברבר עם זה עוד שנה-שנתיים עד שנקודה שבה אימוץ Kubernetes יהיה דבר קל – מה שבעצם שם אתכם עם ה Majority של התעשייה.

שיהיה בהצלחה!

לינקים רלוונטיים: 

השוואה בין GKE, EKS וAKS (מקור: Kubdex)