בדף הזה מוסבר איך לתכנן ולבנות תהליכי צינור עיבוד נתונים של CI/CD GitOps ל-Kubernetes. GitOps, יחד עם כלים כמו סנכרון תצורות, מציע יתרונות כמו יציבות משופרת של הקוד, קריאות טובה יותר ואוטומציה.
GitOps היא גישה שמתפתחת במהירות לניהול תצורת Kubernetes בהיקף גדול. בהתאם לדרישות שלכם לגבי צינור ה-CI/CD, יש הרבה אפשרויות לאופן שבו אתם מתכננים ומארגנים את האפליקציה ואת קוד ההגדרה. אם תלמדו כמה שיטות מומלצות ל-GitOps, תוכלו ליצור ארכיטקטורה יציבה, מאורגנת היטב ומאובטחת.
הדף הזה מיועד לאדמינים, לארכיטקטים ולמפעילים שרוצים להטמיע GitOps בסביבה שלהם. מידע נוסף על תפקידים נפוצים ועל משימות לדוגמה שאנחנו מתייחסים אליהן בתוכן זמין במאמר תפקידים נפוצים של משתמשים ב-GKE ומשימות. Google Cloud
ארגון המאגרים
כשמגדירים את ארכיטקטורת GitOps, צריך להפריד בין המאגרים על סמך סוגי קובצי ההגדרות שמאוחסנים בכל מאגר. באופן כללי, כדאי לשקול לפחות ארבעה סוגים של מאגרי מידע:
- מאגר חבילות לקבוצות של הגדרות קשורות.
- מאגר פלטפורמה להגדרת תצורה של צי שלם עבור אשכולות ומרחבי שמות.
- מאגר הגדרות של אפליקציה.
- מאגר קוד אפליקציה.
התרשים הבא מציג את הפריסה של המאגרים האלה:
באיור 2:
- צוותי הפיתוח דוחפים קוד לאפליקציות ולהגדרות של אפליקציות למאגר.
- הקוד של שתי האפליקציות וההגדרות מאוחסן באותו מקום, ולצוותי האפליקציות יש שליטה במאגרים האלה.
- צוותי האפליקציה דוחפים קוד ל-build.
שימוש במאגר חבילות פרטי מרכזי
כדי לעזור לצוותים למצוא חבילות, כדאי להשתמש במאגר מרכזי לחבילות ציבוריות או פנימיות,כמו תרשימי Helm. לדוגמה, אם המאגר בנוי בצורה הגיונית או מכיל readme, שימוש במאגרי חבילות פרטיים ומרוכזים יכול לעזור לצוותים למצוא מידע במהירות. אתם יכולים להשתמש בשירותים כמו Artifact Registry או במאגרי Git כדי לארגן את המאגר המרכזי.
לדוגמה, צוות הפלטפורמה בארגון יכול להטמיע מדיניות שבה צוותי האפליקציות יכולים להשתמש בחבילות רק מהמאגר המרכזי.
אתם יכולים להגביל את הרשאות הכתיבה למאגר כך שרק מספר קטן של מהנדסים יוכלו לכתוב בו. לשאר הארגון יכולה להיות גישת קריאה. מומלץ להטמיע תהליך לקידום חבילות למאגר המרכזי ולפרסום עדכונים.
למרות שניהול מאגר מרכזי יכול להוסיף תקורה מסוימת, כי מישהו צריך לתחזק את המאגר המרכזי, והוא מוסיף תהליך נוסף לצוותי האפליקציות, יש הרבה יתרונות לגישה הזו:
- צוות מרכזי יכול לבחור להוסיף חבילות ציבוריות במרווחי זמן מוגדרים, כדי למנוע בעיות שנובעות מבעיות בקישוריות או משינויים בנתונים.
- שילוב של מערכות אוטומטיות ובודקים אנושיים יכול לבדוק חבילות כדי לזהות בעיות לפני שהן הופכות לזמינות לכולם.
- המאגר המרכזי מאפשר לצוותים לגלות מה נמצא בשימוש ומה נתמך. לדוגמה, צוותים יכולים למצוא את פריסת Redis הרגילה שמאוחסנת במאגר המרכזי.
- אתם יכולים להפוך את השינויים בחבילות במעלה הזרם לאוטומטיים כדי לוודא שהן עומדות בתקנים פנימיים, כמו ערכי ברירת מחדל, הוספת תוויות ומאגרי תמונות של קונטיינרים.
יצירת מאגרי WET
WET מייצג את המונח Write Everything Twice (לכתוב כל דבר פעמיים). הוא שונה מ-DRY, שפירושו Don't Repeat Yourself (אל תחזרו על עצמכם). הגישות האלה מייצגות שני סוגים שונים של קובצי הגדרה:
- הגדרות DRY, שבהן קובץ תצורה יחיד עובר פעולת שינוי כדי לאכלס שדות בערכים שונים עבור סביבות שונות. לדוגמה, יכול להיות שיש לכם הגדרת אשכול משותפת שמאוכלסת באזור אחר או בהגדרות אבטחה שונות עבור סביבות שונות.
- הגדרות WET (או לפעמים 'fully-hydrated'), שבהן כל קובץ הגדרה מייצג את מצב הסיום.
למרות שמאגרי WET יכולים להוביל לכמה קובצי תצורה חוזרים, יש להם את היתרונות הבאים בתהליך עבודה של GitOps:
- קל יותר לחברי הצוות לבדוק את השינויים.
- לא נדרש עיבוד כדי לראות את המצב המיועד של קובץ הגדרה.
בדיקה מוקדמת יותר כשמאמתים הגדרות
המתנה עד שסנכרון תצורות יתחיל לסנכרן כדי לבדוק אם יש בעיות עלולה ליצור קומיטים מיותרים ב-Git ולגרום ללולאת משוב ארוכה. אפשר למצוא הרבה בעיות לפני שמחילים הגדרה על אשכול באמצעות פונקציות אימות של kpt.
למרות שצריך להוסיף כלים ולוגיקה לתהליך השליחה, יש יתרונות לבדיקה לפני החלת ההגדרות:
- הצגת שינויים בהגדרות בבקשת שינוי יכולה לעזור למנוע שגיאות בהעלאה למאגר.
- מפחיתה את ההשפעה של בעיות בהגדרות משותפות.
שימוש בתיקיות במקום בענפים
להשתמש בתיקיות לגרסאות שונות של קובצי תצורה במקום בהסתעפויות. כשמשתמשים בתיקיות, אפשר להשתמש בפקודה tree כדי לראות את הווריאציות. כשמשתמשים בהסתעפויות, אי אפשר לדעת אם הדלתא בין הסתעפות של ייצור לבין הסתעפות של פיתוח היא שינוי בהגדרות שעתיד להתבצע או הבדל קבוע בין מה שסביבות prod ו-dev אמורות להכיל.
החיסרון העיקרי בגישה הזו הוא שאי אפשר להשתמש בתיקיות כדי לקדם שינויים בהגדרות באמצעות בקשת שינוי לאותם קבצים. עם זאת, לשימוש בתיקיות במקום בענפים יש את היתרונות הבאים:
- קל יותר לגלות תיקיות מאשר ענפים.
- אפשר להשוות בין תיקיות באמצעות הרבה כלים של CLI ו-GUI, אבל השוואה בין הסתעפויות פחות נפוצה מחוץ לספקי Git.
- השימוש בתיקיות מקל על ההבחנה בין הבדלים קבועים לבין הבדלים שלא קודמו.
- אפשר לפרוס שינויים לכמה אשכולות ומרחבי שמות בבקשת שינוי אחת, בעוד שבמקרים של ענפים נדרשות כמה בקשות שינוי לענפים שונים.
צמצום השימוש ב-ClusterSelectors
ClusterSelectors מאפשרות להחיל חלקים מסוימים של הגדרה על קבוצת משנה של אשכולות. במקום להגדיר אובייקט RootSync או RepoSync, אפשר לשנות את המשאב שמוחל או להוסיף תוויות לאשכולות. זו דרך פשוטה להוסיף מאפיינים לאשכול, אבל ככל שמספר המאפיינים ClusterSelectors גדל לאורך זמן, יכול להיות שיהיה קשה להבין את המצב הסופי של האשכול.
מאחר שסנכרון תצורות מאפשר לסנכרן כמה אובייקטים של RootSync ושל RepoSync בבת אחת, אפשר להוסיף את ההגדרה הרלוונטית למאגר נפרד ואז לסנכרן אותה עם האשכולות הרצויים. כך קל יותר להבין את המצב הסופי של האשכול, ואפשר לאסוף את ההגדרות של האשכול בתיקייה במקום להחיל את החלטות ההגדרה ישירות על האשכול.
איך נמנעים מניהול משימות באמצעות סנכרון תצורות
ברוב המקרים, משימות מסוג Jobs ומשימות אחרות שקשורות למצבים מסוימים צריכות להיות מנוהלות על ידי שירות שמטפל בניהול מחזור החיים שלהן. אחרי זה תוכלו לנהל את השירות באמצעות סנכרון תצורות, במקום באמצעות המשימות עצמן.
למרות שסנכרון תצורות יכול להחיל משימות בשבילכם, משימות לא מתאימות לפריסות של GitOps מהסיבות הבאות:
שדות שלא ניתן לשינוי: הרבה שדות של משרות הם שדות שלא ניתן לשינוי. כדי לשנות שדה שלא ניתן לשינוי, צריך למחוק את האובייקט וליצור אותו מחדש. עם זאת, סנכרון תצורות לא מוחק את האובייקט אלא אם מסירים אותו מהמקור.
הפעלה לא מכוונת של משימות: אם מסנכרנים משימה עם סנכרון תצורות ואז המשימה נמחקת מהאשכול, סנכרון תצורות מחשיב את זה כסטייה מהמצב שבחרתם ויוצר מחדש את המשימה. אם מציינים אורך חיים (TTL) של משימה, סנכרון תצורות מוחק את המשימה באופן אוטומטי, יוצר אותה מחדש ומפעיל אותה מחדש באופן אוטומטי, עד שמוחקים את המשימה ממקור האמת.
בעיות בהתאמה: בדרך כלל, סנכרון תצורות ממתין להתאמה של אובייקטים אחרי שהם מוחלים. עם זאת, משימות נחשבות כמתואמות כשהן מתחילות לפעול. כלומר, סנכרון תצורות לא ממתין לסיום של Job לפני שהוא ממשיך להחיל אובייקטים אחרים. עם זאת, אם העבודה נכשלת בהמשך, זה נחשב ככישלון בהתאמה. במקרים מסוימים, זה יכול לחסום סנכרון של משאבים אחרים ולגרום לשגיאות עד שתתקנו את הבעיה. במקרים אחרים, הסנכרון עשוי להצליח ורק ההתאמה נכשלת.
לכן, אנחנו לא ממליצים לסנכרן משימות עם סנכרון תצורות.
שימוש במאגרי מידע לא מובנים
סנכרון תצורות תומך בשני מבנים לארגון מאגר: לא מובנה והיררכי.
הגישה המומלצת היא לא מובנית, כי היא מאפשרת לארגן את המאגר בצורה הכי נוחה לכם.
לעומת זאת, במאגרים היררכיים יש מבנה ספציפי, כמו Custom Resource Definitions (CRDs) בספרייה cluster.
זה עלול לגרום לבעיות כשצריך לשתף הגדרות. לדוגמה, אם צוות אחד מפרסם חבילה שמכילה CRD, צוות אחר שצריך להשתמש בחבילה הזו יצטרך להעביר את ה-CRD לספרייה cluster, מה שיוסיף עוד עבודה לתהליך.
שימוש במאגר לא מובנה מאפשר לשתף חבילות הגדרות ולהשתמש בהן מחדש בקלות רבה יותר. עם זאת, בלי תהליך מוגדר או הנחיות לארגון מאגרי מידע, מבני מאגרי המידע יכולים להיות שונים בין צוותים, מה שמקשה על הטמעה של כלים בכלל המאגרים.
מידע נוסף על המרת מאגר היררכי מופיע במאמר המרת מאגר היררכי למאגר לא מובנה.
מאגרי קוד ומאגרי הגדרות נפרדים
כשמגדילים את מאגר הקודים, צריך ליצור build ספציפי לכל תיקייה. ההרשאות והחששות של אנשים שעובדים על הקוד שונים בדרך כלל מאלה של אנשים שעובדים על הגדרת האשכול.
להפרדה בין מאגרי קוד ומאגרי הגדרות יש את היתרונות הבאים:
- מונעים ביצוע של קומיטים חוזרים. לדוגמה, ביצוע פעולת Commit במאגר קוד עשוי להפעיל בקשת CI, שעשויה ליצור תמונה, ואז נדרש ביצוע פעולת Commit של קוד.
- מספר הקומיטים הנדרש יכול להפוך לנטל על חברי הצוות שמשתתפים בפרויקט.
- אתם יכולים להשתמש בהרשאות שונות לאנשים שעובדים על קוד האפליקציה ולאנשים שעובדים על הגדרת האשכול.
להפרדה בין מאגרי קוד ומאגרי הגדרות יש חסרונות:
- הוא מקטין את הסיכוי למצוא את הגדרות האפליקציה כי הן לא נמצאות באותו מאגר כמו קוד האפליקציה.
- ניהול של הרבה מאגרי מידע יכול לגזול זמן רב.
שימוש במאגרים נפרדים כדי לבודד שינויים
כשמגדילים את מאגר הקוד, נדרשות הרשאות שונות בתיקיות שונות. לכן, הפרדה בין המאגרים מאפשרת ליצור גבולות אבטחה בין הגדרות האבטחה, הפלטפורמה והאפליקציה. מומלץ גם להפריד בין מאגרי ייצור לבין מאגרים שאינם ייצור.
ניהול של הרבה מאגרי קוד יכול להיות משימה גדולה בפני עצמה, אבל יש יתרונות לבידוד של סוגים שונים של הגדרות במאגרי קוד שונים:
- בארגון עם צוותי פלטפורמה, אבטחה ואפליקציות, קצב השינויים וההרשאות שונה.
- ההרשאות נשארות ברמת המאגר. קבצים ב-
CODEOWNERSמאפשרים לארגונים להגביל את הרשאת הכתיבה, אבל עדיין לאפשר הרשאת קריאה. - סנכרון תצורות תומך במספר סנכרונים לכל מרחב שמות, וכך אפשר להשיג אפקט דומה לזה של קבצים ממספר מאגרי מידע.
הצמדת גרסאות של חבילות
בין אם משתמשים ב-Helm או ב-Git, צריך להצמיד את גרסת חבילת ההגדרות למשהו שלא יועבר בטעות קדימה בלי פריסה מפורשת.
ההגדרה הזו מוסיפה בדיקות נוספות לפריסות כשמתעדכן קובץ הגדרה משותף, אבל היא מפחיתה את הסיכון לכך שלעדכונים משותפים תהיה השפעה גדולה יותר מהמתוכנן.
שימוש באיחוד שירותי אימות הזהות של עומסי עבודה ב-GKE
אפשר להפעיל איחוד שירותי אימות הזהות של עומסי עבודה ל-GKE באשכולות GKE, כדי שעומסי עבודה של Kubernetes יוכלו לגשת לשירותי Google באופן מאובטח וניתן לניהול.
למרות ששירותים מסוימים שאינם שלGoogle Cloud , כמו GitHub ו-GitLab, לא תומכים באיחוד שירותי אימות הזהות של עומסי עבודה ל-GKE, מומלץ להשתמש באיחוד שירותי אימות הזהות של עומסי עבודה ל-GKE בכל הזדמנות אפשרית, כי הוא משפר את האבטחה ומפשט את ניהול הסודות והסיסמאות.