מה שאנחנו (ולא רק אנחנו) חיכינו לו הרבה זמן קרה: , כלי הקוד הפתוח שלנו לבניית יישומים ומסירתם ל-Kubernetes, תומך כעת בהחלת שינויים באמצעות תיקוני מיזוג תלת-כיווני! בנוסף לכך, ניתן לאמץ משאבי K3s קיימים לתוך מהדורות Helm מבלי לבנות מחדש משאבים אלו.

אם זה קצר מאוד, אז אנחנו שמים WERF_THREE_WAY_MERGE=enabled - אנו מקבלים פריסה "כמו ב kubectl apply", תואם להתקנות הקיימות של Helm 2 ואפילו קצת יותר.
אבל בואו נתחיל עם התיאוריה: מהם בעצם תיקוני מיזוג תלת כיווני, איך אנשים הגיעו לגישה ליצירתם, ולמה הם חשובים בתהליכי CI/CD עם תשתית מבוססת Kubernetes? ואחרי זה, בואו נראה מה זה מיזוג תלת כיווני ב-werf, באילו מצבים משתמשים כברירת מחדל וכיצד לנהל אותו.
מהו תיקון מיזוג תלת כיווני?
אז בואו נתחיל במשימה של הפעלת המשאבים המתוארים במניפסטים של YAML לתוך Kubernetes.
כדי לעבוד עם משאבים, ה-API של Kubernetes מציע את הפעולות הבסיסיות הבאות: יצירה, תיקון, החלפה ומחיקה. ההנחה היא שבעזרתם יש צורך לבנות פריסה רציפה נוחה של משאבים לאשכול. אֵיך?
פקודות ציווי של kubectl
הגישה הראשונה לניהול אובייקטים ב- Kubernetes היא להשתמש בפקודות ציווי של kubectl כדי ליצור, לשנות ולמחוק אובייקטים אלה. פשוט שים:
- על ידי צוות
kubectl runאתה יכול להפעיל Deployment או Job:kubectl run --generator=deployment/apps.v1 DEPLOYMENT_NAME --image=IMAGE - על ידי צוות
kubectl scale- שנה את מספר ההעתקים:kubectl scale --replicas=3 deployment/mysql - וכו '
גישה זו עשויה להיראות נוחה במבט ראשון. עם זאת יש בעיות:
- זה קשה להפוך.
- כמו משקף תצורה ב-Git? כיצד לסקור שינויים המתרחשים באשכול?
- איך לספק יכולת שחזור תצורות בהפעלה מחדש?
- ...
ברור שגישה זו אינה מתאימה לאחסון יישומים ותשתיות כקוד (IaC; או אפילו כאופציה מודרנית יותר, צוברת פופולריות במערכת האקולוגית של Kubernetes). לכן, פקודות אלו לא זכו להתפתחות נוספת ב-kubectl.
צור, קבל, החלף ומחק פעולות
עם ראשוני יצירה זה פשוט: שלח את המניפסט למבצע create kube api והמשאב נוצר. ניתן לאחסן את ייצוג ה-YAML של המניפסט ב-Git וליצור באמצעות הפקודה kubectl create -f manifest.yaml.
С הסרה גם פשוט: להחליף אותו דבר manifest.yaml מ-Git לצוות kubectl delete -f manifest.yaml.
מבצע replace מאפשר לך להחליף לחלוטין את תצורת המשאב בחדשה, מבלי ליצור מחדש את המשאב. המשמעות היא שלפני ביצוע שינוי במשאב, הגיוני לבצע שאילתה בגרסה הנוכחית עם הפעולה get, שנה אותו ועדכן אותו עם הפעולה replace. kube apiserver מובנה וכן, אם לאחר הניתוח get האובייקט השתנה, ואז הפעולה replace זה לא יעבוד.
כדי לאחסן את התצורה ב-Git ולעדכן אותה באמצעות replace, עליך לבצע את הפעולה get, למזג את התצורה מ-Git עם מה שקיבלנו, ולבצע replace. כברירת מחדל, kubectl מאפשר לך להשתמש בפקודה בלבד kubectl replace -f manifest.yamlאיפה manifest.yaml - מניפסט מוכן כבר במלואו (במקרה שלנו, ממוזג) שצריך להתקין. מסתבר שהמשתמש צריך ליישם מניפסטים של מיזוג, וזה לא עניין של מה בכך...
ראוי גם לציין כי למרות manifest.yaml ומאוחסן ב-Git, אנחנו לא יכולים לדעת מראש אם יש צורך ליצור אובייקט או לעדכן אותו - זה חייב להיעשות על ידי תוכנת משתמש.
סך הכל: האם נוכל לבנות השקה מתמשכת רק באמצעות יצירה, החלפה ומחק, כדי להבטיח שתצורת התשתית מאוחסנת ב-Git יחד עם הקוד וה-CI/CD הנוח?
באופן עקרוני, אנחנו יכולים... בשביל זה תצטרך ליישם את פעולת המיזוג מניפסטים וסוג של כריכה ש:
- בודק נוכחות של אובייקט באשכול,
- מבצע יצירת משאבים ראשונית,
- מעדכן או מוחק אותו.
בעת עדכון, שים לב לכך ייתכן שהמשאב השתנה מאז האחרון get ולטפל אוטומטית במקרה של נעילה אופטימית - בצע ניסיונות עדכון חוזרים ונשנים.
עם זאת, למה להמציא מחדש את הגלגל כאשר kube-apiserver מציע דרך נוספת לעדכן משאבים: הפעולה patch, מה שמשחרר את המשתמש מכמה מהבעיות המתוארות?
תיקון
עכשיו אנחנו מגיעים לטלאים.
תיקונים הם הדרך העיקרית להחיל שינויים על אובייקטים קיימים ב-Kubernetes. מבצע patch זה עובד ככה:
- משתמש kube-apiserver צריך לשלוח תיקון בצורת JSON ולציין את האובייקט,
- ו-apiserver בעצמו יתמודד עם המצב הנוכחי של האובייקט ויביא אותו לצורה הנדרשת.
נעילה אופטימית אינה נדרשת במקרה זה. הפעולה הזו היא יותר הצהרתית מאשר החלפה, אם כי בהתחלה זה עשוי להיראות הפוך.
כך:
- באמצעות פעולה
createאנו יוצרים אובייקט לפי המניפסט מ-Git, - באמצעות
delete- מחק אם האובייקט אינו נחוץ עוד, - באמצעות
patch- אנו משנים את האובייקט, מביאים אותו לצורה המתוארת ב-Git.
עם זאת, כדי לעשות זאת, אתה צריך ליצור תיקון נכון!
כיצד פועלים תיקונים בהלמה 2: מיזוג דו-כיווני
כאשר אתה מתקין גרסה ראשונה, Helm מבצע את הפעולה create עבור משאבי תרשים.
בעת עדכון מהדורת Helm עבור כל משאב:
- שוקל את התיקון בין גרסת המשאב מהתרשים הקודם לגרסת התרשים הנוכחית,
- מחיל את התיקון הזה.
נקרא לתיקון הזה תיקון מיזוג דו-כיווני, כי 2 מניפסטונים מעורבים ביצירתו:
- מניפסט משאבים מהגרסה הקודמת,
- מניפסט משאב מהמשאב הנוכחי.
בעת הסרת הפעולה delete in kube apiserver נקרא למשאבים שהוכרזו במהדורה הקודמת, אך לא הוכרזו במהדורה הנוכחית.
לגישת המיזוג הדו-כיוונית יש בעיה: היא מובילה ל לא מסונכרן עם המצב האמיתי של המשאב באשכול והמניפסט ב-Git.
המחשה של הבעיה עם דוגמה
- ב-Git, תרשים מאחסן מניפסט שבו השדה
imageיש חשיבות לפריסהubuntu:18.04. - משתמש דרך
kubectl editשינה את הערך של שדה זה לubuntu:19.04. - בעת פריסה מחדש של תרשים ההגה לא מייצר תיקון, כי השדה
imageבגרסה הקודמת של המהדורה ובתרשים הנוכחי זהים. - לאחר פריסה מחדש
imageשרידיםubuntu:19.04, למרות שהתרשים אומרubuntu:18.04.
קיבלנו דה-סינכרון ואיבדנו את ההצהרה.
מהו משאב מסונכרן?
באופן כללי מלא אי אפשר להשיג התאמה בין מניפסט המשאב באשכול רץ למניפסט מ-Git. מכיוון שבמניפסט אמיתי עשויים להיות הערות/תוויות שירות, קונטיינרים נוספים ונתונים אחרים שמתווספים ומוסרים מהמשאב באופן דינמי על ידי חלק מהבקרים. אנחנו לא יכולים ולא רוצים לשמור את הנתונים האלה ב-Git. עם זאת, אנו רוצים שהשדות שציינו במפורש ב-Git יקבלו את הערכים המתאימים עם ההשקה.
מסתבר שזה כל כך כללי כלל משאבים מסונכרנים: בעת הפעלת משאב, אתה יכול לשנות או למחוק רק את השדות שצוינו במפורש במניפסט מ-Git (או שצוינו בגרסה קודמת ונמחקים כעת).
תיקון מיזוג דו-כיווני
הרעיון המרכזי : אנו יוצרים תיקון בין הגרסה המוחלת האחרונה של המניפסט מ-Git לבין גרסת היעד של המניפסט מ-Git, תוך התחשבות בגרסה הנוכחית של המניפסט מהאשכול הפועל. התיקון המתקבל חייב להתאים לכלל המשאבים המסונכרנים:
- שדות חדשים שנוספו לגרסת היעד מתווספים באמצעות תיקון;
- שדות קיימים בעבר בגרסה שהוחלה האחרונה ולא קיימים בגרסת היעד מאופסים באמצעות תיקון;
- שדות בגרסה הנוכחית של האובייקט השונים מגרסת היעד של המניפסט מתעדכנים באמצעות התיקון.
על עיקרון זה הוא מייצר טלאים kubectl apply:
- הגרסה המוחלת האחרונה של המניפסט מאוחסנת בהערה של האובייקט עצמו,
- target - נלקח מקובץ YAML שצוין,
- הנוכחי הוא מאשכול רץ.
כעת, לאחר שסיימנו את התיאוריה, הגיע הזמן לספר לכם מה עשינו ב-werf.
החלת שינויים על werf
בעבר, werf, כמו Helm 2, השתמש בתיקוני מיזוג דו-כיווני.
תיקון תיקון
על מנת לעבור לסוג חדש של טלאים - מיזוג תלת כיווני - השלב הראשון שהצגנו הוא מה שנקרא תיקון תיקונים.
בעת הפריסה, נעשה שימוש בתיקון דו-כיווני סטנדרטי, אך werf מייצר בנוסף תיקון שיסנכרן את המצב האמיתי של המשאב עם מה שכתוב ב-Git (תיקון כזה נוצר באמצעות אותו כלל משאבים מסונכרן שתואר לעיל) .
אם מתרחש ביטול סנכרון, בסוף הפריסה המשתמש מקבל אזהרה עם הודעה מתאימה ותיקון שיש להחיל על מנת להביא את המשאב לצורה מסונכרנת. תיקון זה מוקלט גם בביאור מיוחד werf.io/repair-patch. ההנחה היא כי הידיים של המשתמש עצמו יחיל את התיקון הזה: werf לא יחיל אותו בכלל.
יצירת תיקוני תיקון היא אמצעי זמני המאפשר לך למעשה לבדוק את יצירת התיקונים על בסיס עקרון המיזוג התלת-כיווני, אך לא להחיל את התיקונים הללו באופן אוטומטי. כרגע, מצב הפעלה זה מופעל כברירת מחדל.
תיקון מיזוג תלת כיווני רק עבור מהדורות חדשות
החל מ-1 בדצמבר 2019, גרסאות בטא ואלפא של werf מתחילות כברירת מחדל השתמש בתיקוני מיזוג תלת כיווני מלא כדי להחיל שינויים רק על מהדורות חדשות של Helm שהושקו דרך werf. מהדורות קיימות ימשיכו להשתמש בגישת המיזוג הדו-כיווני + תיקוני תיקון.
ניתן להפעיל את מצב ההפעלה הזה במפורש על ידי הגדרה WERF_THREE_WAY_MERGE_MODE=onlyNewReleases עַכשָׁיו.
שים לב: התכונה הופיעה ב-werf במהלך מספר מהדורות: בערוץ האלפא הוא הפך להיות מוכן עם גרסה , ובערוץ בטא - עם .
תיקון מיזוג תלת כיווני עבור כל המהדורות
החל מ-15 בדצמבר 2019, גרסאות בטא ואלפא של werf מתחילות להשתמש בתיקוני מיזוג מלאים תלת כיווני כברירת מחדל כדי להחיל שינויים על כל המהדורות.
ניתן להפעיל את מצב ההפעלה הזה במפורש על ידי הגדרה WERF_THREE_WAY_MERGE_MODE=enabled עַכשָׁיו.
מה לעשות עם קנה מידה אוטומטי של משאבים?
ישנם 2 סוגים של קנה מידה אוטומטי ב-Kubernetes: HPA (אופקי) ו-VPA (אנכי).
אופקי בוחר אוטומטית את מספר העתקים, אנכי - מספר המשאבים. הן מספר ההעתקים והן דרישות המשאבים מצוינים במניפסט המשאבים (ראה מניפסט משאבים). spec.replicas או spec.containers[].resources.limits.cpu, spec.containers[].resources.limits.memory и ).
בעיה: אם משתמש מגדיר משאב בתרשים כך שהוא מציין ערכים מסוימים עבור משאבים או העתקים ו-autoscalers מופעלים עבור משאב זה, אז עם כל פריסה werf יאפס את הערכים האלה למה שכתוב במניפסט התרשים .
יש שני פתרונות לבעיה. מלכתחילה, עדיף להימנע מציון מפורש של ערכים בקנה מידה אוטומטי במניפסט התרשים. אם אפשרות זו אינה מתאימה מסיבה כלשהי (לדוגמה, מכיוון שנוח להגדיר מגבלות משאבים ראשוניות ומספר העתקים בתרשים), werf מציעה את ההערות הבאות:
-
werf.io/set-replicas-only-on-creation=true -
werf.io/set-resources-only-on-creation=true
אם קיים הערה כזו, werf לא יאפס את הערכים המתאימים בכל פריסה, אלא יגדיר אותם רק כאשר המשאב נוצר לראשונה.
לפרטים נוספים, עיין בתיעוד הפרויקט עבור и .
אסור להשתמש בתיקון מיזוג תלת כיווני
המשתמש יכול כרגע לאסור את השימוש בתיקונים חדשים ב-werf באמצעות משתנה סביבה WERF_THREE_WAY_MERGE_MODE=disabled. עם זאת, מתחיל החל מ-1 במרץ 2020, האיסור הזה לא יחול עוד. וזה יהיה אפשרי רק להשתמש בתיקוני מיזוג תלת כיווני.
אימוץ משאבים בוורף
שליטה בשיטה של החלת שינויים עם טלאי מיזוג תלת-כיווני אפשרה לנו ליישם מיד תכונה כזו כמו אימוץ משאבים הקיימים באשכול לתוך מהדורת Helm.
ל-Helm 2 יש בעיה: לא ניתן להוסיף משאב למניפסטים בתרשים שכבר קיים באשכול מבלי ליצור מחדש את המשאב הזה מאפס (ראה. , ). לימדנו את werf לקבל משאבים קיימים לשחרור. לשם כך, עליך להתקין הערה על הגרסה הנוכחית של המשאב מהאשכול הפועל (לדוגמה, באמצעות kubectl edit):
"werf.io/allow-adoption-by-release": RELEASE_NAMEכעת יש לתאר את המשאב בתרשים ובפעם הבאה ש-werf תפרוס מהדורה עם השם המתאים, המשאב הקיים יתקבל לגרסה זו ויישאר בשליטתה. יתרה מכך, בתהליך קבלת משאב לשחרור, werf תביא את המצב הנוכחי של המשאב מהאשכול הפועל למצב המתואר בתרשים, תוך שימוש באותם תיקוני מיזוג תלת כיווני ובכלל המשאב המסונכרן.
שים לב: הגדרה WERF_THREE_WAY_MERGE_MODE אינו משפיע על אימוץ משאבים - במקרה של אימוץ, תמיד נעשה שימוש בתיקון תלת כיווני.
פרטים - ב .
מסקנות ותוכניות עתידיות
אני מקווה שאחרי המאמר הזה התברר יותר מה הם תיקוני מיזוג תלת כיווני ומדוע הם הגיעו אליהם. מנקודת מבט מעשית של הפיתוח של פרויקט werf, יישומם היה צעד נוסף לקראת שיפור הפריסה דמוית הלם. עכשיו אתה יכול לשכוח את הבעיות עם סנכרון תצורה, אשר התעוררו לעתים קרובות בעת שימוש ב- Helm 3. במקביל, נוספה תכונה שימושית חדשה של אימוץ משאבי Kubernetes שכבר הורדו לגרסת Helm.
יש עדיין כמה בעיות ואתגרים עם פריסות דמויות Helm, כמו השימוש בתבניות Go, שנמשיך לטפל בהן.
מידע על שיטות עדכון משאבים ואימוץ ניתן למצוא גם בכתובת .
הגה 3
ראוי לציון מיוחד רק לפני כמה ימים גרסה מרכזית חדשה של Helm - v3 - שמשתמשת גם בתיקוני מיזוג תלת כיווני ונפטרת מטילר. הגרסה החדשה של Helm דורשת התקנות קיימות כדי להמיר אותן לפורמט אחסון המהדורה החדשה.
Werf, מצדה, נפטרה כרגע מהשימוש בטילר, עברה למיזוג תלת כיווני והוסיפה , תוך שהוא נשאר תואם להתקנות Helm 2 קיימות (אין צורך להפעיל סקריפטים להעברה). לכן, עד ש-werf תעבור להלם 3, משתמשי werf לא מאבדים את היתרונות העיקריים של Helm 3 על פני Helm 2 (גם ל-werf יש אותם).
עם זאת, המעבר של werf לבסיס הקוד של Helm 3 הוא בלתי נמנע ויתרחש בעתיד הקרוב. ככל הנראה זה יהיה werf 1.1 או werf 1.2 (כרגע, הגרסה הראשית של werf היא 1.0; למידע נוסף על התקן גרסאות werf, ראה ). במהלך הזמן הזה, להלם 3 יהיה זמן להתייצב.
נ.ב.
קרא גם בבלוג שלנו:
- סדרת הערות על חידושים ב-werf:
- «";
- «";
- «".
- «";
- «";
- «".
מקור: www.habr.com
