לאחרונה, בעוד עובד על סדנה בשםTesting Your Pull Request on Kubernetes with GKE and GitHub Actions, I faced the same issue twice: service A needs service B, but service A starts faster than service B, and the system fails. In this post, I want to describe the context of these issues and how I solved them both with the same tool.
צפייה בKubernetes
ייתכן שזה נשמע מוזר לחכות ב-Kubernetes. האופי העצמי של פלטפורמת Kubernetes הוא אחד היתרונות הגדולים ביותר שלה.
האפליקציה מתחילה במהירות רבה ומנסה בהתלהבות ליצור חיבור למסד הנתונים. בינתיים, המסד הנתונים מתחיל את עצמו עם הנתונים המסופקים; החיבור נכשל.Failed
מדינה
לאחר זמן מה, Kubernetes מבקש את מצב האפליקציה pod. כי זה נכשל, הוא מסתיים אותו ומתחיל pod חדש. בשלב זה, שני דברים יכולים לקרות: האפליקציה Pod עדיין לא מוכנה, והוא חוזר לרבע אחד, או שהוא מוכן, והאפליקציה סוף סוף מתחבר.
כדי להאיץ את התהליך, Kubernetes מציעסטארט-אפ ניסויים:
startupProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 30
periodSeconds: 10
עם הסונדה לעיל, Kubernetes ממתין עשר שניות ראשונות לפני שתבקש את מצב ה-pod. אם הוא נכשל, הוא ממתין עוד עשר שניות.
You may have noticed the HTTP /health
endpoint above. Kubernetes offers two exclusive Probeתצוגת Configuration:httpGet
אוexec
. The former is suitable for web applications, while the latter is for other applications. It implies we need to know which kind of container the pod contains and how to check its status, provided it can. I'm no PostgreSQL expert, so I searched for a status check command. The Bitnami Helm Chartזה נראה ככה כשאתה משתמש:
startupProbe:
exec:
command:
- /bin/sh
- -c
- -e
- exec pg_isready -U $PG_USER -h $PG_HOST -p $PG_PORT
שים לב כי הדבר הנ"ל הוא הפשטות, שכן הוא מתעלם בשמחה מהשם של מסד הנתונים ומסמך SSL.
החללית מהירה יותר מהמצב ברירת המחדל אם תגדיר אותו כראוי.ניתן להגדיר עיכוב ראשוני ארוך ולאחר מכן קיצורים קצרים יותר.עם זאת, ככל שהחבילות מגוונות יותר, כך קשה יותר להגדיר אותן, מכיוון שאתה צריך להיות מומחה בכל אחד מהחבילות הבסיסיות.
זה יהיה מועיל לחפש חלופות.
Wait4x
חלופות הן כלים שמטרתם היא להמתין.לפני זמן רב, מצאתי אתמחכה script for this. The idea is straightforward:
→./wait-for הוא סקריפט שנועד לסנכרן שירותים כגון מכולות docker.It is sh and alpine compatible.
→
./wait-for
הוא תסריט שנועד לסנכרן שירותים כגון מכולות docker.sh
וalpine
זה תואם
הנה איך לחכות ל-HTTP API:
sh -c './wait-for http://my.api/health -- echo "The api is up! Let's use it"'
זה עשה את העבודה, אבל באותו זמן, היה עליך להעתיק את התסריט ולבדוק באופן ידני על עדכונים.
ארבעהxמשחק את אותה התפקיד, אבל זמין כמתקן גרסה ומספק יותר שירותים להמתין: HTTP, DNS, מסדי נתונים, וצידי הודעות.
Whatever tool you use, you can use it inside an init container:
לפוד יכול להיות מספר חבילות הפעלה של אפליקציות בתוכו, אך יכול להיות גם אחד או יותר חבילות init, אשר פועלות לפני הפעלת חבילות האפליקציות.
→מכולות Init הן מכולות רגילות, למעט:
→
כל תיבת init חייבת להסתיים בהצלחה לפני שהאחת הבאה תתחיל.
→
לפוד יכול להיות מספר חבילות הפעלה של אפליקציות בתוכו, אך יכול להיות גם אחד או יותר חבילות init, אשר פועלות לפני הפעלת חבילות האפליקציות.
Init containers are regular containers, except:
- כל תיבת init חייבת להסתיים בהצלחה לפני שהאחת הבאה תתחיל.
דמיינו את הדברים הבאיםPod
זה תלוי PostgreSQLDeployment
• :
apiVersion: v1
kind: Pod
metadata:
labels:
type: app
app: recommandations
spec:
containers:
- name: recommandations
image: recommandations:latest
envFrom:
- configMapRef:
name: postgres-config
היישום הוא Python ומתחיל די מהר. הוא מנסה להתחבר למסד הנתונים של PostgreSQL. למרבה הצער, המסד הנתונים לא סיים את ההתחלה, ולכן החיבור נכשל, ו- Kubernetes מפעיל מחדש את הפוד.
אפשר לתקן את זה עםinitContainer
חבילת חשמל ממתינה:
apiVersion: v1
kind: Pod
metadata:
labels:
type: app
app: recommandations
spec:
initContainers:
- name: wait-for-postgres
image: atkrad/wait4x:3.1
command:
- wait4x
- postgresql
- postgres://$(DATABASE_URL)?sslmode=disable
envFrom:
- configMapRef:
name: postgres-config
containers:
- name: recommandations
image: recommandations:latest
envFrom:
- configMapRef:
name: postgres-config
על פי ההסבר לעיל, הinitContainer
לא מפסיק עד שהבסיס מקבל חיבורים.recommandations
הקובץ יכול להתחיל. Kubernetes לא צריך לסיים אתPod
כמו בהגדרה הקודמת!היא כוללת פחות יומנים ופוטנציאל פחות אזהרות.
כאשר ההמתנה הופכת לחובה
הדבר לעיל הוא שיפור קטן, אבל אתה יכול לעשות בלי זה.במקרים אחרים, ההמתנה הופכת לחובה.חוויתי את זה לאחרונה כאשר מתכוננים לסדנה שהוזכרה לעיל.
- →
- הצינור מפרסם מודעה בצד של Kubernetes →
- בשלב הבא, הוא מבצע את המבחן →
- כאשר הבדיקה מתחילה לפני קריאת היישום, היא נכשלה. →
We must wait until the backend is ready before we test. Let's use wait4x
כדי לחכות ל- ThePod
כדי לקבל בקשות לפני שאנחנו פותחים את הבדיקות:
- name: Wait until the application has started
uses: addnab/docker-run-action@v3 #1
with:
image: atkrad/wait4x:latest
run: wait4x http ${{ env.BASE_URL }}/health --expect-status-code 200 #2
- הפעולה של GitHub מאפשרת להפעיל מיכל.הייתי יכול להוריד את בינארי Go במקום. →
- חכו עד שנקודת הסיום /Health תחזיר קוד תגובה 200.
מסקנה
תחנות התחלה של Kubernetes הן דרך מצוינת למנוע התחלות מחדש מיותרות בעת הפעלת שירותים תלויים אחד בשני.initContainer
→wait4x
זהו כלי שניתן להשתמש בו בהקשרים אחרים, והוא כעת חלק מחגורת הכלים שלי.
To go further:
- →
- ארבעהx →
- אז אתה צריך לחכות כמה משאבים Kubernetes? →
פורסם במקור ב A Java Geek ב 20 באפריל, 2025
ג'ייק Java