הטעינת נפח Docker נכשלת לאחר חיבור VPN: בדקו את הדמון
ה-bind mount שלכם תקין. VPN משנה איזה דמון עונה ללקוח, אז הדפיסו את ה-endpoint, הוכיחו את הנתיב שם, והפסיקו לערוך את הנפח.
כמעט כל כתיבה על הבעיה הזו מאשימה את הנפח, וזו בדיוק הסיבה שהתיקון לוקח כל כך הרבה זמן. היה לכם bind mount שעבד, ה-VPN הארגוני התחבר, ו docker compose up נכשל עכשיו בגלל נתיב מקור חסר, תיקייה ריקה או טעינה שהמנוע מסרב ליצור. בסביבות שניקיתי, קובץ ה-Compose לא השתנה והנתיב היה נכון. מה שהשתנה הוא איזה דמון קיבל את הבקשה, ושגיאת הטעינה הייתה רק המקום הראשון שבו ההבדל הזה נעשה גלוי.
הנפח מעולם לא זז; הבקשה זזה
דגל -v /srv/app:/app אינו העתקת תיקייה שהקליפה שלכם מבצעת. הלקוח הופך אותו לבקשת API, והדמון שעונה מפענח את /srv/app מול מערכת הקבצים שלו עצמו. כששני הצדדים רצים על אותו קרנל, זה הנתיב שאתם רואים במנהל הקבצים. כשנקודת הקצה משתנה, אותה מחרוזת נדרשת במכונה שמעולם לא שמעה על תיקיית הפרויקט שלכם, והדמון מדווח שהמקור חסר או יוצר בשקט תיקייה ריקה במקומו.
זו גם הסיבה שנפח בעל שם ממשיך לעבוד בעוד bind mount לא. -v appdata:/app נותן שם לאחסון שהדמון מחזיק בו, ולכן שום נתיב מארח לא צריך להתקיים במקום מסוים. אם החלפת שירות אחד מ-bind mount לנפח בעל שם מעלימה את השגיאה, לא תיקנתם את הבעיה. אישרתם שהלקוח והדמון חלוקים על איזו מערכת קבצים הנתיב שייך לה, והמחלוקת הזו חוזרת ברגע שתזדקקו שוב לתיקיית מארח אמיתית.
הדפיסו את נקודת הקצה לפני שאתם נוגעים בטעינה
כמה הגדרות יכולות לכוון את הלקוח לנקודת קצה, והן לא תמיד מסכימות: דגל --context , DOCKER_CONTEXT, DOCKER_HOST בקליפה הנוכחית, וההקשר השמור בתצורת הלקוח. במקום לנמק על קדימות, הדפיסו את כולם והשוו את התשובות.
docker context show
docker context ls
docker version
docker info --format "{{.Name}} {{.OperatingSystem}} {{.ServerVersion}}"
תצורת הלקוח נמצאת ב- ~/.docker/config.json ב-Linux וב-macOS וב- %USERPROFILE%\.docker\config.json ב-Windows, וערך שמיוצא במסוף הנוכחי דורס את השמור רק לאותה הפעלה. אם נקודת הקצה היא שם מארח ולא socket מקומי, פתרון השמות והמסלולים קובעים היכן היא נוחתת, ואלה בדיוק מה שלקוח VPN כותב מחדש. מנהרה שמוסיפה מסלול או מחליפה את הפותר יכולה לשלוח שם שהתכוון בעבר למחשב הנייד הזה לכתובת בתוך הרשת הארגונית.
השוו מצב ולא תצורה. הריצו docker ps -a ו- docker images כשהמנהרה סגורה, ואז שוב כשהיא פתוחה. רשימת מכולות שונה היא ראיה חזקה יותר מכל קובץ תצורה, כי היא מראה שדמון אחר ענה לבקשה שלכם.
שאלו את הדמון אם הנתיב קיים שם
לאחר שאתם יודעים לאיזה דמון הגעתם, גרמו לו להסתכל בתיקייה. הצורה --mount נכשלת בהודעה ברורה יותר מהדגל הקצר, כי היא מאמתת את המקור לפני שהיא מפעילה את המכולה:
docker run --rm --mount type=bind,source=/srv/app,target=/app alpine ls -la /app
אם הוא מדווח שהמקור חסר, צרו אותו במכונה שענתה, או כוונו את השירות לנפח בעל שם והעתיקו את הנתונים לשם. מה שאסור לכם לעשות הוא ליצור נפחים מחדש ולהתקין את המנוע מחדש לפני הבדיקה הזו. הפעולות האלה משנות את הסביבה מספיק כדי להסתיר את אי-ההתאמה ובכל זאת להשאיר אותה במקומה.
נתיב נוסף רץ במקום אחר לגמרי: משיכת image היא עבודת דמון, לא עבודת לקוח. משיכה מוצלחת מוכיחה רק שהדמון יכול להגיע ל-registry, ו-bind mount עובד מוכיח רק שנתיב נפתר. בדקו כל נתיב במקום שבו הוא באמת מתבצע, אחרת תבזבזו אחר צהריים על הנתיב הלא נכון.
שמות אינטראנט נכשלים מסיבה אחרת
המחצית השנייה של אותו דוח היא בדרך כלל שהמכולה לא מצליחה להגיע אל intranet.corp.example. זה מנגנון נפרד, לא בעיית נפח שנייה. מכולה מקבלת את /etc/resolv.conf שלה בעת ההפעלה, שנוצר מהגדרות הפותר של הדמון, ולכן שרת DNS שה-VPN הוסיף אחרי יצירת המכולה לא יופיע בו עד שהמכולה תיווצר מחדש.
הפותר המובנה של Docker ברשת שמוגדרת על ידי המשתמש מעביר חיפושים חיצוניים לשרתים המוגדרים במארח, מה שעוזר כשה-VPN כותב מחדש את פותר המארח ומזיק כש-DNS מפוצל שולח אזור פנימי לשרת שהדמון כבר לא רואה. מיפוי צר ומפורש עוקף את הוויכוח עבור שמות שלעולם לא משתנים:
services:
web:
extra_hosts:
- "intranet.corp.example:10.20.30.40"
זה כותב רשומה בקובץ ה-hosts של המכולה, כך שהמכולה לא לומדת דבר על המנהרה, והוא גם מקפיא את הכתובת. כשהמארח הפנימי זז, הרשומה נשארת שגויה עד שמישהו עורך את קובץ ה-Compose. השתמשו בזה עבור התקן קבוע או מסד נתונים מוצמד, והשאירו ל-DNS שמות שזזים.
מה התקנה מחדש באמת משנה
התקנה מחדש של Docker Desktop יוצרת מחדש את ה-VM, את ה-socket ואת רשימת ההקשרים, והטעינה מתחילה לעבוד שוב. התוצאה הזו אמיתית והיא לא מלמדת דבר, ולכן אותה תקלה חוזרת אחרי עדכון ה-VPN הבא. ההתקנה מחדש החליפה את נקודת הקצה שהלקוח השתמש בה; היא לא יישבה את הנתיב שהפרויקט שלכם נותן לו שם עם מערכת הקבצים שהדמון באמת קורא.
סדר העבודה שלי קצר. אשרו באיזו נקודת קצה הלקוח ישתמש. אשרו איזה דמון ענה על ידי השוואת רשימות מכולות. בקשו מאותו דמון לפרט את נתיב המקור. רק אז ערכו את הטעינה, הוסיפו רשומת hosts או שנו סוג נפח. אם אתם מתחזקים את קובץ ה-Compose עבור צוות שעובד דרך VPN, העדיפו נפחים בעלי שם עבור נתונים שהדמון אמור להחזיק בהם, כדי שנתיב מארח לעולם לא יהפוך לחלק מהחוזה.