בדף הזה מפורטות אסטרטגיות לפתרון בעיות וגם פתרונות לכמה שגיאות נפוצות.
כשמנסים לפתור בעיות ב-Knative serving, קודם צריך לוודא שאפשר להריץ את קובץ האימג' של הקונטיינר באופן מקומי.
אם האפליקציה לא פועלת באופן מקומי, תצטרכו לאבחן ולתקן אותה. כדאי להשתמש ב-Cloud Logging כדי לנפות באגים בפרויקט שנפרס.
כשמנסים לפתור בעיות ב-Knative Serving, כדאי לעיין בקטעים הבאים כדי למצוא פתרונות אפשריים לבעיה.
בדיקת פלט של שורת פקודה
אם משתמשים ב-Google Cloud CLI, בודקים את פלט הפקודה כדי לראות אם היא הצליחה או לא. לדוגמה, אם הפריסה הסתיימה ללא הצלחה, אמורה להיות הודעת שגיאה שמתארת את הסיבה לכישלון.
הסיבה הסבירה ביותר לכשלים בהטמעה היא מניפסט שהוגדר בצורה שגויה או פקודה שגויה. לדוגמה, בפלט הבא מצוין שצריך להגדיר את אחוז התעבורה של המסלול כך שהסכום יהיה 100.
Error from server (InternalError): error when applying patch:</p><pre>{"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"serving.knative.dev/v11\",\"kind\":\"Route\",\"metadata\":{\"annotations\":{},\"name\":\"route-example\",\"namespace\":\"default\"},\"spec\":{\"traffic\":[{\"configurationName\":\"configuration-example\",\"percent\":50}]}}\n"}},"spec":{"traffic":[{"configurationName":"configuration-example","percent":50}]}}
to:
&{0xc421d98240 0xc421e77490 default route-example STDIN 0xc421db0488 264682 false}
for: "STDIN": Internal error occurred: admission webhook "webhook.knative.dev" denied the request: mutation failed: The route must have traffic percent sum equal to 100.
ERROR: Non-zero return code '1' from command: Process exited with status 1
בדיקת היומנים של השירות
אתם יכולים להשתמש ב-Cloud Logging או בדף Knative serving בGoogle Cloud מסוף כדי לבדוק את יומני הבקשות ואת יומני הקונטיינרים. לפרטים מלאים, קראו רישום ביומן וצפייה ביומנים.
אם אתם משתמשים ב-Cloud Logging, המשאב שצריך לסנן הוא Kubernetes Container.
בדיקת סטטוס השירות
מריצים את הפקודה הבאה כדי לקבל את הסטטוס של שירות Knative serving שנפרס:
gcloud run services describe SERVICE
אפשר להוסיף --format yaml(status) או --format json(status) כדי לקבל את הסטטוס המלא, לדוגמה:
gcloud run services describe SERVICE --format 'yaml(status)'
התנאים בstatus יכולים לעזור לכם לאתר את הסיבה לכישלון.
התנאים יכולים לכלול True, False או Unknown:
- מוכן:
Trueמציין שהשירות מוגדר ומוכן לקבל תנועה. - ConfigurationReady:
Trueמציין שההגדרה הבסיסית Configuration מוכנה. במקרה שלFalseאוUnknown, כדאי לבדוק את הסטטוס של הגרסה האחרונה. - RoutesReady:
Trueמציין שרכיב Route הבסיסי מוכן. במקרה שלFalseאוUnknown, כדאי לבדוק את סטטוס המסלול.
פרטים נוספים על תנאי הסטטוס מופיעים במאמר בנושא Knative Error Signaling.
בדיקת הסטטוס של המסלול
כל שירות Knative serving מנהל נתיב שמייצג את מצב הניתוב הנוכחי ביחס לגרסאות של השירות.
כדי לבדוק את הסטטוס הכולל של המסלול, אפשר לעיין בסטטוס של השירות:
gcloud run services describe SERVICE --format 'yaml(status)'
התנאי RoutesReady ב-status מספק את הסטטוס של המסלול.
כדי לבדוק את סטטוס הנתיב לעומק, מריצים את הפקודה הבאה:
kubectl get route SERVICE -o yaml
התנאים בstatus מספקים את הסיבה לכשל. למשל:
מוכן מציין אם השירות מוגדר ויש לו קצוות עורפיים זמינים. אם זה
true, המסלול מוגדר כראוי.הערך AllTrafficAssigned מציין אם השירות מוגדר כראוי ויש לו קצוות עורפיים זמינים. אם התנאי הזה
statusהוא לאTrue:כדאי לבדוק אם חלוקת התנועה בין הגרסאות של השירות מסתכמת ב-100%:
gcloud run services describe SERVICE
אם לא, משנים את חלוקת התנועה באמצעות הפקודה
gcloud run services update-traffic.אפשר לבדוק את סטטוס הגרסה של גרסאות שמקבלות תנועה.
IngressReady מציין אם ה-Ingress מוכן. אם התנאי הזה
statusהוא לאTrue, כדאי לבדוק את סטטוס ה-Ingress.CertificateProvisioned מציין אם הוקצו אישורים של Knative. אם התנאי
statusהוא לאTrue, כדאי לנסות לפתור בעיות ב-TLS מנוהל.
פרטים נוספים על תנאי סטטוס מופיעים במאמר Knative Error Conditions and Reporting.
בדיקת סטטוס ה-Ingress
Knative serving משתמש בשירות מאזן עומסים שנקרא istio-ingressgateway, שאחראי לטיפול בתעבורה נכנסת מחוץ לאשכול.
כדי לקבל את כתובת ה-IP החיצונית של מאזן העומסים, מריצים את הפקודה הבאה:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
מחליפים את ASM-INGRESS-NAMESPACE במרחב השמות שבו נמצאת הכניסה של Cloud Service Mesh. מציינים istio-system אם התקנתם את Cloud Service Mesh באמצעות הגדרת ברירת המחדל שלו.
הפלט שיתקבל ייראה כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) istio-ingressgateway LoadBalancer XX.XX.XXX.XX pending 80:32380/TCP,443:32390/TCP,32400:32400/TCP
כאשר הערך EXTERNAL-IP הוא כתובת ה-IP החיצונית של מאזן העומסים.
אם EXTERNAL-IP הוא pending, אפשר לעיין בקטע EXTERNAL-IP הוא pending במשך זמן רב בהמשך.
בדיקת סטטוס גרסה
כדי לקבל את הגרסה האחרונה של שירות Knative serving, מריצים את הפקודה הבאה:
gcloud run services describe SERVICE --format='value(status.latestCreatedRevisionName)'
מריצים את הפקודה הבאה כדי לקבל את הסטטוס של גרסה ספציפית של Knative Serving:
gcloud run revisions describe REVISION
אפשר להוסיף --format yaml(status) או --format json(status) כדי לראות את הסטטוס המלא:
gcloud run revisions describe REVISION --format yaml(status)
התנאים ב-status מספקים את הסיבות לכשל. למשל:
- מוכן מציין אם משאבי זמן הריצה מוכנים. אם זה
true, הגרסה הוגדרה בצורה תקינה. - ResourcesAvailable מציין אם משאבי Kubernetes הבסיסיים הוקצו.
אם הערך של
statusבתנאי הזה הוא לאTrue, כדאי לבדוק את הסטטוס של ה-Pod. - ContainerHealthy מציין אם בדיקת המוכנות של הגרסה הושלמה.
אם הערך של
statusבתנאי הזה הוא לאTrue, כדאי לבדוק את הסטטוס של ה-Pod. - Active מציין אם הגרסה מקבלת תנועה.
אם אחד מהתנאים האלה status לא מתקיים True, כדאי לבדוק את הסטטוס של ה-Pod.
בדיקת הסטטוס של ה-Pod
כדי לקבל את ה-Pods של כל הפריסות:
kubectl get pods
אמורה להופיע רשימה של כל ה-Pods עם סטטוס קצר. לדוגמה:
NAME READY STATUS RESTARTS AGE
configuration-example-00001-deployment-659747ff99-9bvr4 2/2 Running 0 3h
configuration-example-00002-deployment-5f475b7849-gxcht 1/2 CrashLoopBackOff 2 36s
בוחרים אחת מהאפשרויות ומשתמשים בפקודה הבאה כדי לראות מידע מפורט על status. אלה כמה מהשדות השימושיים ברשומה: conditions ו-containerStatuses:
kubectl get pod POD-NAME -o yaml
כתובת ה-IP החיצונית היא <pending> במשך זמן רב
יכול להיות שלא תקבלו כתובת IP חיצונית מיד אחרי שתיצרו אשכול, אלא תראו את כתובת ה-IP החיצונית כ-pending. לדוגמה, אפשר לראות את זה על ידי הפעלת הפקודה:
כדי לקבל את כתובת ה-IP החיצונית של מאזן העומסים, מריצים את הפקודה הבאה:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
מחליפים את ASM-INGRESS-NAMESPACE במרחב השמות שבו נמצאת הכניסה של Cloud Service Mesh. מציינים istio-system אם התקנתם את Cloud Service Mesh באמצעות הגדרת ברירת המחדל שלו.
הפלט שיתקבל ייראה כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) istio-ingressgateway LoadBalancer XX.XX.XXX.XX pending 80:32380/TCP,443:32390/TCP,32400:32400/TCP
כאשר הערך EXTERNAL-IP הוא כתובת ה-IP החיצונית של מאזן העומסים.
יכול להיות שמיציתם את מכסת כתובות ה-IP החיצוניות ב- Google Cloud. כדי לבדוק את הסיבה האפשרית, מפעילים את הפקודה:
kubectl describe svc istio-ingressgateway -n INGRESS_NAMESPACE
Name: istio-ingressgateway Namespace: INGRESS_NAMESPACE Labels: app=istio-ingressgateway istio=ingressgateway istio.io/rev=asm-1102-3 operator.istio.io/component=IngressGateways operator.istio.io/managed=Reconcile operator.istio.io/version=1.10.2-asm.3 release=istio Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"addonmanager.kubernetes.io/mode":"Reconcile","app":"istio-ingressgateway","... Selector: app=istio-ingressgateway,istio=ingressgateway Type: LoadBalancer IP: 10.XX.XXX.XXX LoadBalancer Ingress: 35.XXX.XXX.188 Port: http2 80/TCP TargetPort: 80/TCP NodePort: http2 31380/TCP Endpoints: XX.XX.1.6:80 Port: https 443/TCP TargetPort: 443/TCP NodePort: https 3XXX0/TCP Endpoints: XX.XX.1.6:XXX Port: tcp 31400/TCP TargetPort: 3XX00/TCP NodePort: tcp 3XX00/TCP Endpoints: XX.XX.1.6:XXXXX Port: tcp-pilot-grpc-tls 15011/TCP TargetPort: 15011/TCP NodePort: tcp-pilot-grpc-tls 32201/TCP Endpoints: XX.XX.1.6:XXXXX Port: tcp-citadel-grpc-tls 8060/TCP TargetPort: 8060/TCP NodePort: tcp-citadel-grpc-tls 31187/TCP Endpoints: XX.XX.1.6:XXXX Port: tcp-dns-tls 853/TCP TargetPort: XXX/TCP NodePort: tcp-dns-tls 31219/TCP Endpoints: 10.52.1.6:853 Port: http2-prometheus 15030/TCP TargetPort: XXXXX/TCP NodePort: http2-prometheus 30944/TCP Endpoints: 10.52.1.6:15030 Port: http2-grafana 15031/TCP TargetPort: XXXXX/TCP NodePort: http2-grafana 31497/TCP Endpoints: XX.XX.1.6:XXXXX Session Affinity: None External Traffic Policy: Cluster Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal EnsuringLoadBalancer 7s (x4318 over 15d) service-controller Ensuring load balancer
אם הפלט מכיל אינדיקציה לכך שIN_USE_ADDRESSESחלה חריגה מהמכסה, אפשר לבקש מכסה נוספת. לשם כך, עוברים אל הדף IAM & Admin במסוף Google Cloud ומגישים בקשה להגדלת המכסה.
השער ימשיך לנסות עד שתוקצה לו כתובת IP חיצונית. זה יכול לקחת כמה דקות.
פתרון בעיות בדומיינים מותאמים אישית וב-TLS מנוהל
כדי לפתור בעיות כלליות שקשורות לדומיינים בהתאמה אישית ולתכונה אישורי TLS מנוהלים, אפשר להיעזר בשלבי פתרון הבעיות שמפורטים בהמשך.
דומיינים מותאמים אישית לרשתות פרטיות ופנימיות
אם מיפיתם דומיין מותאם אישית לאשכול או לשירותים של Knative Serving ברשת פרטית פנימית, אתם צריכים להשבית את אישורי ה-TLS המנוהלים. אחרת, הגדרת הדומיין לא תגיע למצב ready. כברירת מחדל, למאזן העומסים הפנימי אין אפשרות לתקשר עם רשות האישורים באופן חיצוני.
בדיקת הסטטוס של מיפוי דומיין ספציפי
כדי לבדוק את הסטטוס של מיפוי דומיין ספציפי:
מריצים את הפקודה:
gcloud run domain-mappings describe --domain DOMAIN --namespace NAMESPACE
החלפה
- DOMAIN עם שם הדומיין שבו אתם משתמשים.
- NAMESPACE עם מרחב השמות שבו אתם משתמשים למיפוי הדומיין.
בתוצאות
yamlשל הפקודה הזו, בודקים את התנאי של השדהCertificateProvisionedכדי להבין את מהות השגיאה.אם מוצגת שגיאה, היא צריכה להיות אחת מהשגיאות שבטבלאות שלמטה. כדי לפתור את הבעיה, פועלים לפי ההצעות שבטבלאות.
שגיאות בהגדרת המשתמש
| קוד שגיאה | פרטים |
|---|---|
| DNSErrored | הודעה:
רשומת ה-DNS לא מוגדרת בצורה נכונה. צריך למפות את הדומיין [XXX] לכתובת ה-IP XX.XX.XX.XX
פועלים לפי ההוראות שמופיעות כדי להגדיר את רשומת ה-DNS בצורה נכונה. |
| RateLimitExceeded | הודעה:
acme: urn:ietf:params:acme:error:rateLimited: Error creating new order
:: too many certificates already issued for exact set of domains: test.your-domain.com: see https://letsencrypt.org/docs/rate-limits/ הייתה חריגה מהמכסה של Let's Encrypt. צריך להגדיל את מכסת האישורים של Let's Encrypt עבור המארח הזה. |
| InvalidDomainMappingName | הודעה:
השם של DomainMapping %s לא יכול להיות זהה למארח של כתובת ה-URL של Route %s.
השם של DomainMapping לא יכול להיות זהה בדיוק למארח של המסלול שהוא ממופה אליו. להשתמש בדומיין אחר לשם DomainMapping. |
| ChallengeServingErrored | הודעה: המערכת לא הצליחה לטפל בבקשת HTTP01.
השגיאה הזו יכולה להתרחש אם שירות
|
שגיאות מערכת
| קוד שגיאה | פרטים |
|---|---|
| OrderErrored
AuthzErrored ChallengeErrored |
שלושת סוגי השגיאות האלה מתרחשים אם האימות של הבעלות על הדומיין על ידי Let's Encrypt נכשל.
בדרך כלל השגיאות האלה הן זמניות, ומערכת Knative Serving תנסה לבצע שוב את הפעולה. העיכוב בין ניסיונות השליחה הוא אקספוננציאלי, עם מינימום של 8 שניות ומקסימום של 8 שעות. אם רוצים לנסות שוב באופן ידני לתקן את השגיאה, אפשר למחוק ידנית את ההזמנה שנכשלה.
|
| ACMEAPIFailed | השגיאה הזו מתרחשת כש-Knative Serving לא מצליח להתקשר אל Let's Encrypt. בדרך כלל מדובר בשגיאה זמנית, ומערכת Knative Serving תנסה שוב.
אם רוצים לנסות שוב באופן ידני לתקן את השגיאה, צריך למחוק ידנית את ההזמנה שנכשלה.
|
| UnknownErrored | השגיאה הזו מציינת שגיאת מערכת לא ידועה, שאמורה לקרות לעיתים רחוקות מאוד באשכול GKE. אם אתם רואים את ההודעה הזו, פנו לתמיכה ב-Cloud לקבלת עזרה בניפוי באגים. |
בדיקת סטטוס ההזמנה
סטטוס ההזמנה מתעד את תהליך האינטראקציה עם Let's Encrypt, ולכן אפשר להשתמש בו כדי לנפות באגים בבעיות שקשורות ל-Let's Encrypt. אם צריך, מריצים את הפקודה הבאה כדי לבדוק את סטטוס ההזמנה:
kubectl get order DOMAIN -n NAMESPACE -oyaml
החלפה
- DOMAIN עם שם הדומיין שבו אתם משתמשים.
- NAMESPACE עם מרחב השמות שבו אתם משתמשים למיפוי הדומיין.
אם ההזמנה בוצעה בהצלחה, התוצאות יכללו את האישורים שהונפקו ומידע נוסף.
הזמן הקצוב לתפוגת ההזמנה
אובייקט Order יגיע לזמן קצוב לתפוגה אחרי 20 דקות אם עדיין לא ניתן לקבל אישורים.
בודקים את סטטוס מיפוי הדומיין. אם חלף הזמן הקצוב לתפוגה, מחפשים הודעת שגיאה כמו זו בפלט הסטטוס:
order (test.your-domain.com) timed out (20.0 minutes)
סיבה נפוצה לבעיית זמן קצוב לתפוגה היא שרשומת ה-DNS לא מוגדרת בצורה נכונה למיפוי הדומיין שבו אתם משתמשים לכתובת ה-IP של שירות הכניסה. מריצים את הפקודה הבאה כדי לבדוק את רשומת ה-DNS:
host DOMAINבודקים את כתובת ה-IP החיצונית של מאזן העומסים של תעבורת הנתונים הנכנסת:
כדי לקבל את כתובת ה-IP החיצונית של מאזן העומסים, מריצים את הפקודה הבאה:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
מחליפים את ASM-INGRESS-NAMESPACE במרחב השמות שבו נמצאת הכניסה של Cloud Service Mesh. מציינים
istio-systemאם התקנתם את Cloud Service Mesh באמצעות הגדרת ברירת המחדל שלו.הפלט שיתקבל ייראה כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) istio-ingressgateway LoadBalancer XX.XX.XXX.XX pending 80:32380/TCP,443:32390/TCP,32400:32400/TCP
כאשר הערך EXTERNAL-IP הוא כתובת ה-IP החיצונית של מאזן העומסים.
אם כתובת ה-IP החיצונית של הדומיין לא תואמת לכתובת ה-IP של הכניסה, צריך להגדיר מחדש את רשומת ה-DNS כך שתמופה לכתובת ה-IP הנכונה.
אחרי שרשומת ה-DNS (המעודכנת) תיכנס לתוקף, מריצים את הפקודה הבאה כדי למחוק את אובייקט ההזמנה, וכך להפעיל מחדש את התהליך של בקשת אישור TLS:
kubectl delete order DOMAIN -n NAMESPACE
החלפה
- DOMAIN עם שם הדומיין שבו אתם משתמשים.
- NAMESPACE מחליפים במרחב השמות שבו אתם משתמשים.
כשלים בהרשאה
כשלים בהרשאה יכולים להתרחש כשלא מתבצעת הפצה גלובלית של רשומת DNS בזמן. כתוצאה מכך, אי אפשר לאמת את הבעלות על הדומיין באמצעות Let's Encrypt.
בודקים את סטטוס ההזמנה. הקישור לאישור הגישה מופיע בשדה
acmeAuthorizationsשל הסטטוס. כתובת ה-URL צריכה להיראות כך:https://acme-v02.api.letsencrypt.org/acme/authz-v3/1717011827
פותחים את הקישור. אם מופיעה הודעה דומה לזו:
urn:ietf:params:acme:error:dns
אז הבעיה היא בגלל הפצה לא מלאה של ה-DNS.
כדי לפתור את שגיאת ההפצה של ה-DNS:
בודקים את כתובת ה-IP החיצונית של מאזן העומסים של תעבורת הנתונים הנכנסת:
כדי לקבל את כתובת ה-IP החיצונית של מאזן העומסים, מריצים את הפקודה הבאה:
kubectl get svc istio-ingressgateway -n ASM-INGRESS-NAMESPACE
מחליפים את ASM-INGRESS-NAMESPACE במרחב השמות שבו נמצאת הכניסה של Cloud Service Mesh. מציינים
istio-systemאם התקנתם את Cloud Service Mesh באמצעות הגדרת ברירת המחדל שלו.הפלט שיתקבל ייראה כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) istio-ingressgateway LoadBalancer XX.XX.XXX.XX pending 80:32380/TCP,443:32390/TCP,32400:32400/TCP
כאשר הערך EXTERNAL-IP הוא כתובת ה-IP החיצונית של מאזן העומסים.
כדי לבדוק את רשומת ה-DNS של הדומיין, מריצים את הפקודה הבאה:
host DOMAINאם כתובת ה-IP של רשומת ה-DNS לא תואמת לכתובת ה-IP החיצונית של איזון העומסים של תעבורת הנתונים הנכנסת (ingress), צריך להגדיר את רשומת ה-DNS כך שתמפה את הדומיין של המשתמש לכתובת ה-IP החיצונית.
אחרי שרשומת ה-DNS (המעודכנת) תיכנס לתוקף, מריצים את הפקודה הבאה כדי למחוק את אובייקט ההזמנה ולהפעיל מחדש את התהליך של בקשת אישור TLS:
kubectl delete order DOMAIN -n NAMESPACE
החלפה
- DOMAIN עם שם הדומיין שבו אתם משתמשים.
- NAMESPACE עם מרחב השמות שבו אתם משתמשים למיפוי הדומיין.
כשל בפריסה לאשכול פרטי: שגיאה בקריאה ל-webhook
יכול להיות שחומת האש לא מוגדרת כמו שצריך אם הפריסה שלכם לאשכול פרטי נכשלת עם ההודעה:
Error: failed calling webhook "webhook.serving.knative.dev": Post
https://webhook.knative-serving.svc:443/?timeout=30s: context deadline exceeded (Client.Timeout
exceeded while awaiting headers)
מידע על שינויים בחומת האש שנדרשים כדי לתמוך בפריסה לאשכול פרטי זמין במאמר הפעלת פריסות באשכול פרטי.
סטטוס הדוח של שירותים הוא IngressNotConfigured
אם הסמל IngressNotConfigured מופיע בסטטוס השירות, יכול להיות שתצטרכו להפעיל מחדש את הפריסה של istiod במרחב השמות istio-system אם אתם משתמשים ב-Cloud Service Mesh במישור הבקרה בתוך האשכול. השגיאה הזו, שזוהתה בתדירות גבוהה יותר ב-Kubernetes 1.14, יכולה להתרחש אם השירותים נוצרים לפני ש-istiod מוכן להתחיל את העבודה שלו בתיאום VirtualServices ובדחיפת הגדרות Envoy לשערי ה-Ingress.
כדי לפתור את הבעיה, צריך להגדיל את הפריסה ואז להקטין אותה שוב באמצעות פקודות דומות לאלה:
kubectl scale deployment istiod -n istio-system --replicas=0
kubectl scale deployment istiod -n istio-system --replicas=1
חסרים מדדים של מספר הבקשות וזמן האחזור של הבקשות
יכול להיות שהשירות שלכם לא ידווח על מדדים של מספר בקשות לגרסה ושל זמן האחזור של הבקשות אם הפעלתם את איחוד זהויות של עומסי עבודה ל-GKE ולא הענקתם הרשאות מסוימות לחשבון השירות שבו השירות שלכם משתמש.
כדי לפתור את הבעיה, פועלים לפי השלבים שמפורטים בקטע הפעלת מדדים באשכול עם איחוד זהויות של עומסי עבודה ל-GKE.