תיעוד 143
הפניה לסביבות באירוח עצמי
הפניה מלאה ל-runner ול-orchestrator באירוח עצמי: דגלי CLI, משתני סביבה ומדדי Prometheus.
[!NOTE]
סביבות באירוח עצמי נמצאות בבטא ציבורית בתוכניות Team ו-Enterprise. Owner מפעיל אותן על ידי הפעלת Allow self-hosted environments בדף הניהול Cloud environments. הדף הזה הוא ההפניה לדגלים ולמדדים. ראו את ה-quickstart להתקנה ואת Deploy to production למתכוני הצי.
הדף הזה הוא ההפניה לשני התהליכים שאתם מריצים בסביבה באירוח עצמי: ה-runner, שמריץ cloud sessions של Claude Code על המארחים שלכם, וה-orchestrator האופציונלי ל-autoscaling, שמתחיל runners כש-sessions נכנסים לתור. לכל אחד טבלת דגלים משלו. שניהם רצים על מארחי Linux או macOS, שהברירות המחדל כמו /workspace ו-~/.claude מניחות. הריצו claude self-hosted-runner --help לרשימה הסמכותית בגרסה המותקנת אצלכם.
סדרות מדדים וכמה שדות API עדיין משתמשים ב-pool למה שהדפים האלה קוראים environment. שני המונחים מציינים את אותו הדבר. מזהה ה-environment הוא השדה pool_id, בצורה ccpool_...: בכל מקום שהדפים האלה מציגים מזהה pool, הוא מציין את ה-environment. דגלי CLI ומשתני סביבה כותבים אותו environment, למשל --environment-secret-file. איותי pool שיצאו משימוש עדיין עובדים, כפי שמתארת השורה של --environment-secret-file.
#דגלי CLI של ה-runner
לרוב הדגלים יש משתנה סביבה מתאים. כששניהם מוגדרים, הדגל גובר. דגלי משך מקבלים דקות או שניות ב-CLI, אבל משתנה הסביבה המזווג תמיד במילישניות, כפי שמציינת הסיומת _MS, ועמודת ברירת המחדל מציגה את יחידת הדגל: --exit-if-unused-min 10 שקול ל-SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS=600000, וערך Helm כמו SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS: "15" פירושו 15 מילישניות, ולא ברירת המחדל של 15 דקות.
| דגל | משתנה סביבה | ברירת מחדל | תיאור |
|---|---|---|---|
--api-url <url> | אין | https://api.anthropic.com | כתובת בסיס של ה-API. לעקוף רק לצורך בדיקות. |
--base-dir <path> | SELF_HOSTED_RUNNER_BASE_DIR | /workspace. אין ב-Windows | ספרייה ל-checkouts של מאגרים ולספריות עבודה לפי סשן. ה-runner זקוק לגישת כתיבה לנתיב הזה או להורה שלו. ה-runner יוצר את הספרייה בהפעלה ויוצא עם cannot create or write to base directory כשהוא לא יכול ליצור אותה או לכתוב אליה. לפני v2.1.225, ה-runner יצר את הספרייה כשהסשן הראשון התחיל, כך שנתיב בלתי שמיש הכשיל סשנים ולא את ההפעלה. ב-Windows, שאינו מארח runner נתמך, אין ברירת מחדל: ה-runner יוצא בהפעלה אלא אם מעבירים את הדגל או מגדירים את המשתנה. השתמשו באותו ערך בכל runner בסביבה. ראו שמירה על ספריית הבסיס והקיבולת זהות בכל ה-runners. |
--capacity <n> | אין | 1 | מספר הסשנים המקבילים המרבי שה-runner הזה מטפל בהם. כל הסשנים שייכים לאותו בעלים נעול. השתמשו באותו ערך בכל runner בסביבה. ראו שמירה על ספריית הבסיס והקיבולת זהות בכל ה-runners. |
--client-label <label> | SELF_HOSTED_RUNNER_CLIENT_LABEL | שם המארח של המארח | התווית שה-runner שולח כשהוא נרשם. ה-runner גם מדווח אותה כתווית client_label של claude_code_self_hosted_runner_info. דורש Claude Code v2.1.248 או מאוחר יותר. |
--configure-git | SELF_HOSTED_RUNNER_CONFIGURE_GIT=1 | כבוי | בהפעלה, כותב זהות git גלובלית, מפעיל חתימת commit של Anthropic, מדליק משא ומתן על git push, ומתקין commit hooks שמוסיפים trailer של Co-authored-by:. משא ומתן על push דורש Claude Code v2.1.257 או מאוחר יותר. ראו הגדרת git. |
--confine-repo-settings <mode> | SELF_HOSTED_RUNNER_CONFINE_REPO_SETTINGS | warn | קובע את מצב השומר שמסמן סשן כשהגדרות שהמאגר commit-הן מנסות להעניק גישת כתיבה או קריאה מחוץ ל-workspace של אותו סשן, להגדיר משתני סביבה, או לעקוף את עמדת ה-sandbox או ה-hooks של המפעיל, למשל sandbox.enabled: false או disableAllHooks. ברירת המחדל warn רושמת את ההפרה ועדיין מתחילה את הסשן, enforce מסרב לסשן, ו-off משבית את הסריקה. ראו הקשחת הפריסה. |
--debug-token-dir <path> | SELF_HOSTED_RUNNER_DEBUG_TOKEN_DIR | לא מוגדר | כותב טוקנים חיים לדיסק לבדיקה. לדיבוג בלבד. אל תשתמשו בפרודקשן. |
--defer-shutdown-max-min <n> | SELF_HOSTED_RUNNER_DEFER_SHUTDOWN_MAX_MS | 0 | ב-SIGTERM או SIGINT הראשון, ממשיך לשרת את הסשנים שכבר מחוברים במקום לנקז אותם, ואז משחרר את מה שעדיין מחובר N דקות אחר כך ויוצא. העלו את פסק הזמן לעצירה של המארח לפני שאתם מגדירים את זה. ראו דחיית הניקוז מעבר לאות הראשון. 0 משבית. דורש Claude Code v2.1.238 או מאוחר יותר. |
--drain-grace-sec <n> | SELF_HOSTED_RUNNER_DRAIN_GRACE_MS | 0 | עד שה-runner מקבל אות כיבוי או מגיע לזמן הפרישה שלו, שולט מתי ה-runner יוצא אחרי שהסשנים הפעילים שלו מסתיימים: 0 יוצא מיד בלי polling לעוד עבודה, וערך חיובי משאיר את ה-runner חי ומבצע polling מחדש לתור של הבעלים הנעול במשך אותו מספר שניות קודם, במחיר בידוד הקונטיינר לפי סשן שמתואר במקטע ההקשחה. אחרי אות ראשון שדחיתם עם --defer-shutdown-max-min, ה-runner יוצא ברגע שאין לו סשנים, בלי קשר למה שהגדרתם כאן. |
--drain-marker-file <path> | SELF_HOSTED_RUNNER_DRAIN_MARKER_FILE | לא מוגדר | קובץ סמן שהמארח כותב כדי להודיע על ניקוז מסודר לפני שליחת SIGTERM. כשהקובץ קיים כשהניקוז מתחיל, ה-runner מדווח על היציאה שלו ל-Anthropic כניקוז מארח ולא כאות כיבוי רגיל. הניקוז עצמו, כולל ההמתנה של --drain-wait-sec, רץ אותו דבר כמו בלי הדגל. ציינו נתיב במערכת קבצים מקומית שסשנים לא יכולים לכתוב אליה. דורש Claude Code v2.1.271 או מאוחר יותר. |
--drain-wait-sec <n> | SELF_HOSTED_RUNNER_DRAIN_WAIT_MS | 0 | ברגע שהניקוז מתחיל, וזה ב-SIGTERM אלא אם הגדרתם --defer-shutdown-max-min, מחכה עד N שניות שתור בתהליך ומשימות רקע של כל סשן יסתיימו לפני סיום תהליך הילד. במהלך ההמתנה הזו, ה-runner סופר משימת רקע שזה עתה הסתיימה כעדיין רצה עד שהתור ההמשך שקורא את התוצאה שלה מתחיל, לכל היותר בחלון SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. העלו גם את פסק הזמן לעצירה. |
--environment-secret-file <path> | SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET | נדרש | נתיב לקובץ שמכיל את סוד הסביבה, או, עבור runners שה-orchestrator יצר, JWT חד-פעמי של work-order. SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET נושא את ערך הסוד ישירות, לא נתיב קובץ. הדגל הישן --pool-secret-file והמשתנה SELF_HOSTED_RUNNER_POOL_SECRET עדיין עובדים ומדפיסים הודעת deprecation ל-stderr. בניית runner של תוכנית התצוגה המקדימה ישנות מ-2.1.216 מזהות רק את השמות הישנים האלה. |
--exec-path <path> | SELF_HOSTED_RUNNER_EXEC_PATH | הבינארי של עצמו | בינארי או סקריפט wrapper להפעלה עבור כל סשן. ראו סקריפטי wrapper. |
--exit-if-unused-min <n> | SELF_HOSTED_RUNNER_IDLE_SHUTDOWN_MS | 0 | יוצא אחרי N דקות של polling בלי שעבודה הוקצתה אי פעם, לצמצום של autoscaler. 0 משבית. |
--git-host-rewrite <from>=<to> | אין | לא מוגדר | משכתב כתובות מקור https://<from>/... ל-https://<to>/... לפני clone, עבור DNS מסוג split-horizon. ניתן לחזור עליו. דגל בלבד. |
--git-ssh-rewrite <host> | אין | לא מוגדר | משכתב כתובות מקור https://<host>/... ל-git@<host>:... לפני clone, עבור מארחי git של SSH בלבד. ניתן לחזור עליו. דגל בלבד. |
--health-port <port> | SELF_HOSTED_RUNNER_HEALTH_PORT | 8080 | פורט למאזין /healthz ו-/metrics. הגדירו 0 כדי להשבית. |
--hold-idle-file <path> | SELF_HOSTED_RUNNER_HOLD_IDLE_FILE | לא מוגדר | קובץ שהמארח ממשיך לשנות כדי להחזיק סשן סרק על ה-runner. ראו שמירת סשן סרק בזמן שהתהליכים שלו רצים. דורש Claude Code v2.1.311 או מאוחר יותר. |
--hooks-dir <path> | SELF_HOSTED_RUNNER_HOOKS_DIR | לא מוגדר | ספרייה של סקריפטי lifecycle hook. ראו ווי מחזור חיים. |
--host-config-snapshot <mode> | SELF_HOSTED_RUNNER_HOST_CONFIG_SNAPSHOT | disk | איפה ה-runner שומר את צילום ההפעלה של ספריית תצורת המארח שממנה הוא מזריע כל סשן. disk מעתיק את הצילום לספרייה בבעלות ה-runner תחת --base-dir, ובכל התחלת סשן מאמת כל קובץ מול digest בזיכרון. אם קובץ בעותק שונה, הסשן נכשל וה-runner מסרב לסשנים עד שמפעילים אותו מחדש. memory מחזיק את כל הצילום על ה-heap, עם תקרה של 64 MiB. מעל התקרה, סשנים מתחילים בלי תצורת מארח ומציגים הודעה שאומרת זאת. כשה-runner לא יכול לכתוב את צילום הדיסק, הוא רושם את הכשל ומשתמש ב-memory עבור הריצה הזו. דורש Claude Code v2.1.271 או מאוחר יותר. |
--kill-session-after-min <n> | SELF_HOSTED_RUNNER_MAX_LIFETIME_MS | 0 | מגביל סשן ל-N דקות של שעון קיר, כגבול בטיחות לסשנים תקועים. ב-v2.1.260 או מאוחר יותר, ה-runner משחרר סשן שמגיע לגבול כדי שיוכל להתחדש בהודעה הבאה של המשתמש שלו, ומסיים אותו רק אם הוא עדיין על ה-runner כשחלון החסד SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS מסתיים. לפני v2.1.260, ה-runner סיים את הסשן בגבול. ראו יש סשנים שלא נספרים כסרק לפרטים ולאופן בחירת ערך. 0 משבית. |
--lock-to-account <id> | SELF_HOSTED_RUNNER_LOCK_TO_ACCOUNT | לא מוגדר | נועל מראש את ה-runner לחשבון מסוים בהפעלה במקום נעילה בסשן הראשון. מקבל כתובת אימייל או מזהה user_... בארגון של הסביבה. runner שננעל מראש לעולם לא קולט סשני ערוץ Claude Tag, שאין להם חשבון. |
--log-file <path> | SELF_HOSTED_RUNNER_LOG_FILE | לא מוגדר | משקף לוגים של ה-runner לקובץ בנוסף ל-stdout ול-stderr, שנוצר עם הרשאות 0600. נדרש כדי ש-self-hosted-runner doctor יעקוב אחרי לוגים מקומית. |
--log-level <level> | אין | info | info או debug |
--max-hold-min <n> | SELF_HOSTED_RUNNER_MAX_HOLD_MS | 1440 | עם --hold-idle-file, משחרר סשן מוחזק בכל מקרה N דקות אחרי שהוא עבר לסרק. ערך ששווה ל---release-idle-session-min או נמוך ממנו לא מחזיק כלום. 0 מכבה את ההחזקה. דורש Claude Code v2.1.311 או מאוחר יותר. |
--post-session-hook-timeout-sec <n> | SELF_HOSTED_RUNNER_POST_SESSION_HOOK_TIMEOUT_MS | 60 | תקציב ל-hook של post-session בכל סיום סשן, כולל כיבוי ה-runner |
--proxy-authorization-command <command> | SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_COMMAND | לא מוגדר | פקודת shell שה-runner מריץ עבור כל חיבור ל-egress proxy שלכם, ומשתמש ב-stdout הגזום שלה כערך כותרת Proxy-Authorization. דורש HTTPS_PROXY או HTTP_PROXY, ואי אפשר לשלב עם --proxy-authorization-file. ראו אימות מול egress proxy. דורש Claude Code v2.1.238 או מאוחר יותר. |
--proxy-authorization-file <path> | SELF_HOSTED_RUNNER_PROXY_AUTHORIZATION_FILE | לא מוגדר | קובץ שה-runner קורא עבור כל חיבור ל-egress proxy שלכם, ומשתמש בתוכן הגזום שלו כערך כותרת Proxy-Authorization. השתמשו בדגל הזה לטוקן שתהליך אחר מסובב במקום. נושא את אותן דרישות כמו --proxy-authorization-command, ואי אפשר לשלב איתו. ראו אימות מול egress proxy. דורש Claude Code v2.1.238 או מאוחר יותר. |
--push-outcome-on-release | SELF_HOSTED_RUNNER_PUSH_OUTCOME_ON_RELEASE | כבוי | בסיום סשן שיזם ה-runner, כמו ניקוז או שחרור סרק, ה-runner דוחף ענפי סשן ראשיים עם commits חדשים ל-origin לפני מחיקת ה-workspace. במיטב היכולת. מוסיף 30 שניות לתקציב הכיבוי. דורש git 2.29 או מאוחר יותר כדי לחדש מהם. הגבילו גישת push ל-refs של claude/*. ראו סשנים שחודשו מאבדים עבודה שלא נדחפה. מאגרים של hook מסוג checkout לא נדחפים. צלמו אותם מ-hook של post-session. |
--release-idle-session-min <n> | SELF_HOSTED_RUNNER_SESSION_IDLE_MS | 0 | משחרר חריץ סשן אחרי N דקות של חוסר פעילות ברגע שתור מסתיים או שהסשן ממתין לפעולת המשתמש. יש סשנים שלא נספרים כסרק, לכן שלבו עם --kill-session-after-min. משימת רקע שהסתיימה משאירה את הסשן עסוק לכל היותר בחלון SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS. כדי לעכב שחרור, הגדירו --hold-idle-file. 0 משבית. |
--remove-session-state [bool] | SELF_HOSTED_RUNNER_REMOVE_SESSION_STATE | כבוי | מסיר את ספריות לפי-סשן של סשן תחת <base-dir>/_sessions/ כשהסשן מסתיים על ה-runner הזה, בכל תוצאה. שימוש חוזר ב-checkout שחומם מראש מתאר מה הן מחזיקות ומי יכול לקרוא אותן כשהן נשארות. ההסרה היא במיטב היכולת: ספריות לפי-סשן נשארות במקום כשה-runner נהרג או מגיע למועד הניקוז לפני שהניקוי רץ. כשהדגל מופעל, לוג הדיבוג של סשן שנכשל או שנקטע לא נשמר על הדיסק. דורש Claude Code v2.1.268 או מאוחר יותר. |
--retire-at <epoch-seconds> | SELF_HOSTED_RUNNER_RETIRE_AT | לא מוגדר | פורש את ה-runner בחותמת זמן Unix מוחלטת בשניות, עבור תשתית שהורגת את ה-runner בזמן ידוע. מחזור החיים של ה-runner מתאר את רצף השחרור ואת אופן קביעת גודל השוליים. ערכים לפני 2001 או אחרי שנת 5138 נדחים על ידי הדגל ומתעלמים מהם במשתנה הסביבה. |
--server-auto-mode-lists <mode> | SELF_HOSTED_RUNNER_SERVER_AUTO_MODE_LISTS | no-allow | אילו מרשימות כללי המסווג של מצב אוטומטי שמישור הבקרה שולח עם סשן רשאיות להגיע לאותו סשן: all, no-allow, או none. ראו רשימות כללים של מצב אוטומטי למה כל ערך חל. ערך לא תקין עוצר את ה-runner בהפעלה. דורש Claude Code v2.1.295 או מאוחר יותר. |
--session-stop-grace-sec <n> | SELF_HOSTED_RUNNER_SESSION_STOP_GRACE_MS | 5 | כמה זמן להמתין שתהליך Claude ייצא בצורה נקייה אחרי שסשן מסתיים, לפני הריגה בכוח. העלו את הערך אם ה-hooks של SessionEnd של הילד עצמו זקוקים ליותר זמן. |
--startup-timeout-min <n> | SELF_HOSTED_RUNNER_STARTUP_TIMEOUT_MS | 15 | כמה זמן להמתין על תהליך ילד שלא אותחל לפני שחרור החריץ של הסשן. ראו פסק זמן להפעלת סשן לאיפה הספירה מתחילה ואילו סשנים הוא משאיר רצים. 0 משבית את פסק הזמן. |
--trust-workspace [bool] | SELF_HOSTED_RUNNER_TRUST_WORKSPACE | מופעל | מזריע אמון שנשמר לנתיבי המאגר של כל סשן כדי ש-permissions.allow ו-additionalDirectories שהמאגר commit-הן יכובדו. הגדירו false כדי להשמיט הענקות הרשאה שהמאגר commit-הן ולהגדיר כללי allow ב-settings.json של תצורת המארח. הגדרות sandbox.* שהמאגר commit-הן עדיין חלות בכל מקרה, ולכן שומר הגדרות המאגר סורק אותן בלי קשר לדגל הזה. |
--use-anthropic-git-proxy | CLAUDE_RUNNER_USE_GIT_PROXY=1 | כבוי | משכפל מאגרים ב-github.com דרך פרוקסי git של Anthropic במקום אימות git שמנוהל על ידי הלקוח. דורש --capacity 1 ו-git 2.32 או מאוחר יותר. ה-runner מסרב להתחיל אחרת. מחליף את דגלי השכתוב. |
לרוב דגלי המשך יש מקסימום, שנבחר כדי לשמור כל פסק זמן בתוך תקרת הטיימר של 32 סיביות של זמן הריצה, בערך 24.85 ימים. דגלי --*-min מוגבלים ל-10080 דקות, 7 ימים. --drain-grace-sec ל-604800 שניות, גם 7 ימים. ו---drain-wait-sec ל-86400 שניות, 24 שעות. --session-stop-grace-sec ו---post-session-hook-timeout-sec בלי תקרה. חריגה מתקרה מתנהגת אחרת לפי משטח:
- דגל: ההפעלה נכשלת עם שגיאה.
- משתנה סביבה: ה-runner מצמיד את הערך לתקרת הטיימר במקום לדחות אותו.
#פסק זמן להפעלת סשן
אם סשן איבד את המשבצת שלו במהלך תור כמו /code-review, עדכנו את ה-runner ואת הבינארי של הילד ל-v2.1.309 או לגרסה חדשה יותר. מ-v2.1.299 ועד v2.1.308, ה-runner שחרר סשן, גם באמצע תור, ברגע שפסק הזמן להפעלה חלף בלי הודעת user או assistant.
עם --startup-timeout-min <n>, ה-runner משחרר את המשבצת של סשן כשהילד שלו לא אותחל בתוך <n> דקות אחרי השכפול. במהלך תור שמתחיל לפני שהילד מאותחל, הסשן שומר את המשבצת שלו עד שחולפות <n> דקות בלי שורה בערוץ הפעילות של הילד. מרגע שהילד מאותחל, ה-runner מאפס את הספירה הזו ו---release-idle-session-min קובע את השחרור. כדי להגביל סשן שהילד שלו חי אבל תקוע, הגדירו --kill-session-after-min.
#רשימות כללים של מצב אוטומטי
--server-auto-mode-lists מאפשר לכם להחליט אילו כללי מסווג של מצב אוטומטי שמחוץ ל-runner מגיעים אל הסשנים על ה-runners שלכם. מישור הבקרה של Anthropic יכול לשלוח רשימות כללים עם סשן ולבקש מה-runner להחיל אותן. ייתכן שחלק מהרשומות הן כללים שמנהל בארגון שלכם כתב. הרשימות הן environment, soft_deny ו-allow:
environment: רשומה יכולה לגרום למסווג להתיר יותר וגם פחות.soft_deny: רשומה חוסמת פעולה אלא אם המשתמש ביקש אותה במפורש או שחל חריגallow.allow: החריגים לרשומותsoft_deny.
הערך של הדגל קובע אילו רשימות ה-runner מחיל:
no-allow: ברירת המחדל. מחיל אתenvironmentואתsoft_denyואינו מחיל אתallow. רשומתenvironmentעדיין יכולה לגרום למסווג להתיר יותר, ולכן ברירת המחדל אינה שוללת כל הקלה.all: מחיל את שלוש הרשימות.none: אינו מחיל אף אחת מהן. בחרוnoneכדי לשלול כל הקלה מהרשימות האלה. הבחירה הזו גם מסירה את המגבלות שלsoft_deny.
אין הגדרה של ה-runner שגורמת למישור הבקרה לבקש מה-runner להחיל את הרשימות. כשהוא אינו מבקש, הסשנים אינם מקבלים רשימה, בכל ערך שתגדירו. כדי לראות איזה משני המקרים קרה, הפעילו את ה-runner עם --log-level debug. עבור כל סשן ה-runner כותב אז שורה שמכילה the server asked this runner to apply, או שורה שמכילה the server did not ask this runner to apply the auto mode lists it sends.
#דגלי CLI של ה-orchestrator
פקודת המשנה self-hosted-runner orchestrator, שיוצרת runners לפי דרישה, מקבלת את --api-url, --environment-secret-file, --hooks-dir, --health-port ו---log-level עם אותן ברירות מחדל כמו ה-runner, ובמקום שלדגל של ה-runner יש משתנה סביבה, עם אותו משתנה סביבה, חוץ מכך ש---hooks-dir נדרש וחייב להכיל hook בשם spawn-runner. יש לה גם דגלים משלה:
| דגל | ברירת מחדל | תיאור |
|---|---|---|
--hook-concurrency <n> | 4 | מקסימום hooks של spawn-runner שרצים במקביל. גם מגביל כמה בקשות spawn נתפסות בכל poll. ה-orchestrator בודק בקשות spawn חדשות רק אחרי שכל hook שהוא התחיל הסתיים, ולכן hook איטי אחד מעכב את ה-hooks הבאים של אותו orchestrator. |
--hook-timeout <sec> | 60 | מסיים את עץ התהליכים של ה-hook אחרי מספר השניות הזה. פסק הזמן ועוד 5 שניות הארכה להריגה חייבים להישאר מתחת ל---expected-spawn-seconds. ה-orchestrator אוכף זאת בהפעלה. |
--expected-spawn-seconds <sec> | 120 | זמן p99 צפוי מהרגע שבו ה-orchestrator מקבל בקשת spawn עד שה-runner נרשם, כולל כל המתנה לקיבולת בפלטפורמה שלכם. השרת אוכף טווח של 10 עד 3600. נשלח בכל poll כחכירה בצד השרת. אם אף runner לא נרשם לפני שהזמן חולף, הסשן מוצע מחדש עם מזהה הזמנה חדש. כל הרפליקות חייבות לחלוק את הערך הזה. |
--min-idle <n> | 0 | שומר לפחות N משבצות סשן פנויות על ידי יצירה יזומה של runners בהמתנה. 0 משבית חימום מראש. שלבו עם --exit-if-unused-min של ה-runner כדי ש-runners בהמתנה עודפים יפנו את עצמם. |
--shutdown-drain-sec <n> | 0 | בעת SIGTERM, מפסיק poll לבקשות spawn ונותן ל-hooks של spawn-runner שרצים ולכל poll שלא נענה עד מספר השניות הזה כדי לסיים, לפני עצירה של מה שנשאר. בערך 0, עוצר מיד. המקסימום הוא 3600, וה-orchestrator אוכף זאת בהפעלה. כדי לבחור ערך, ראו קביעת גודל ל---shutdown-drain-sec ולפסק הזמן לעצירה של ה-orchestrator. נדרש Claude Code v2.1.299 או חדש יותר. |
--debug-dir <path> | לא מוגדר | כותב לדיסק את הזמנת העבודה של כל בקשת spawn ואת stderr של ה-hook. לניפוי שגיאות בלבד. אל תגדירו בייצור. |
#דגלי מחבר SCM
מחבר ה-SCM אינו זמין, לכן השאירו את הדגלים בסעיף זה לא מוגדרים. אם תגדירו --scm-connector-host, החיבור אינו נפתח, וה-orchestrator ממשיך לנסות אותו. runners עדיין מתחילים כשסשנים נכנסים לתור.
המחבר הוא חיבור WebSocket קבוע מה-orchestrator אל מישור הבקרה של Anthropic. הוא נועד לאפשר לזרימות מתארחות שלפני הסשן, כמו בוחר המאגר והפותר של ענף או ref, להגיע למארח GitHub Enterprise Server שאפשר לנתב אליו רק מתוך הרשת שלכם. ראו דרישות רשת בדף GitHub Enterprise Server לגבי מה שהזרימות האלה צריכות.
| דגל | ברירת מחדל | תיאור |
|---|---|---|
--scm-connector-host <host[:port]> | לא מוגדר | שם מארח של GitHub Enterprise Server שאליו מעבירים בקשות. הפורט ברירת המחדל שלו היא 443. |
--scm-connector-id <n> | נדרש עם --scm-connector-host | המזהה המספרי של חיבור GitHub Enterprise Server של הארגון שלכם. |
--scm-connector-provider <slug> | ghe | מקטע נתיב שמזהה את הספק, שתואם את ^[a-z0-9-]{1,32}$. |
--scm-connector-ca-file <path> | לא מוגדר | חבילת CA נוספת, בפורמט PEM, לחיבורי TLS אל מארח GitHub Enterprise Server. |
--scm-connector-host-rewrite <from>=<to_host:to_port> | לא מוגדר | לבדיקות מקצה לקצה בלבד: מפנה את חיבור ה-TCP, ושומר את כותרת Host ואת ה-SNI של TLS כמו --scm-connector-host. |
בכל ניסיון חיבור ה-orchestrator שולח את סוד הסביבה הקיים שלו, והוא מנסה שוב אוטומטית עם השהיה מעריכית, עם תקרה של 30 שניות בתוספת jitter.
#הגדרות דרך משתני סביבה בלבד
הגדרות runner אלה נקראות מהסביבה בלבד ומכסות התנהגות שרוב הפריסות משאירות בברירת המחדל:
| משתנה סביבה | ברירת מחדל | תיאור |
|---|---|---|
SELF_HOSTED_RUNNER_BG_RESULT_GRACE_MS | 30000 | כמה זמן ה-runner מחשיב סשן כעסוק אחרי שמשימת רקע מסתיימת, בזמן שתור ההמשך שקורא את התוצאה עוד לא התחיל. השורות של --drain-wait-sec ושל --release-idle-session-min מתארות איפה ההחזקה חלה בניקוז ובשחרור של חוסר פעילות, ומחזור חיי runner מתאר איפה היא חלה בפרישה לפי --retire-at. 0 או ערך לא שמיש חוזרים לברירת המחדל, ולכן אי אפשר לכבות את ההחזקה. נדרש Claude Code v2.1.228 או חדש יותר. |
SELF_HOSTED_RUNNER_HOST_CONFIG_DIR | ~/.claude | ספרייה שנלכדת בתמונת ההפעלה של ה-runner ונזרעת אל CLAUDE_CONFIG_DIR של כל סשן. שינויים בדיסק חלים אחרי הפעלה מחדש של ה-runner. הגדרת המשתנה גם מעבירה את המקום שממנו ה-runner קורא את .claude.json עבור זריעת MCP, ולכן הגדרה שלו, כולל לברירת המחדל של המשתנה עצמו, מעבירה את החיפוש הזה. הצביעו על ספרייה ריקה כדי לבטל את הזריעה לגמרי. |
SELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MS | 900000 | כמה זמן ה-runner ממתין, אחרי שסשן מגיע למגבלת --kill-session-after-min שלו, לסיום של תור שרץ או להשלמת השחרור, לפני שהוא מסיים את הסשן |
SELF_HOSTED_RUNNER_POST_TURN_SETTLE_MS | 7000 | תקרה למשך הזמן שבו ה-runner סופר סשן כעסוק לצורך ניקוז --drain-wait-sec אחרי שתור מסתיים, בזמן שתהליך הסשן מדווח ל-Anthropic על סיום התור. 0 או ערך לא שמיש חוזרים לברירת המחדל, ולכן אי אפשר לכבות את ההחזקה. נדרש Claude Code v2.1.275 או חדש יותר. |
SELF_HOSTED_RUNNER_SIGKILL_GRACE_MS | 30000 | כמה זמן ה-runner ממתין שמערכת ההפעלה תמסור SIGKILL לילד שתקוע ב-I/O שאי אפשר להפריע לו, לפני שהוא יוצא בעצמו. הרצפה היא --post-session-hook-timeout-sec ועוד 15 שניות, ועוד 30 שניות כש---push-outcome-on-release מוגדר, ולכן המינימום בפועל הוא 75 שניות בברירות המחדל. |
CLAUDE_RUNNER_FETCH_DEPTH | 50 | עומק ה-fetch של Git עבור שכפולים חדשים. הגדירו מספר שלם חיובי, או full או 0, ל-fetch מלא. עבור שכפול שכבר נמצא במרחב העבודה, ראו שימוש חוזר ב-checkout שחומם מראש. |
CLAUDE_RUNNER_FETCH_SERVER_PROGRESS_CAP_MS | 600000 | כמה זמן, במילישניות ולכל ניסיון, fetch של git רשאי לחכות לנתונים הראשונים שלו בזמן שמספרי ההתקדמות של שרת ה-git עצמו ממשיכים לעלות, כמו כשהשרת מכין את ה-pack למאגר גדול. 0 או off מכבים את ההמתנה. fetch כזה נחתך אז אחרי שתי דקות בלי נתונים. כל מספר שלם אחר מוגבל לטווח שבין 120000 ל-1800000, 2 עד 30 דקות. נדרש Claude Code v2.1.295 או חדש יותר. |
CLAUDE_RUNNER_SKIP_GIT_VERIFY | לא מוגדר | כאשר הערך הוא 1, מדלגים על בדיקת קיום .git אחרי שרץ hook של checkout. הגדירו זאת כשה-hook שלכם מממש מקור שאינו git. |
FORCE_AUTOUPDATE_PLUGINS | לא מוגדר | כאשר הערך הוא 1, מאפשרים לשוקי התוספים להתעדכן אוטומטית גם כשהבינארי מקובע |
CLAUDE_CODE_DISABLE_ARTIFACT | לא מוגדר | כאשר הערך הוא 1, משביתים את כלי Artifact בסשנים בלי קשר להגדרת המנהל של הארגון, ומסירים את דרישת היציאה של *.frame.claudeusercontent.com |
#טלמטריה
ילדי הסשן שולחים טלמטריה תפעולית ל-Anthropic אלא אם תכבו אותה. לא נשלח קוד ולא נשלח תוכן של מאגר. הגדירו את משתני הטלמטריה על תהליך ה-runner. ה-runner מחיל אותם מחדש אחרי שהוא מחיל משתני סביבה שסיפק השרת, ולכן ההגדרה של המפעיל תמיד גוברת.
בקרה אחת ייחודית לסביבות באירוח עצמי: CLAUDE_CODE_BYOC_ENABLE_DATADOG=1 מפעיל הצטרפות למדדים תפעוליים של Datadog, שכבויים כברירת מחדל בסביבות באירוח עצמי. בקרי הטלמטריה הכלליים של Claude Code, DISABLE_TELEMETRY, DO_NOT_TRACK, DISABLE_ERROR_REPORTING ו-CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC, חלים על ילדי הסשן כפי שמתועד בהפניה למשתני סביבה. DISABLE_GROWTHBOOK קשור אבל שונה: הגדרת DISABLE_GROWTHBOOK=1 משביתה שליפה של דגלי תכונות, והטלמטריה נשארת פעילה אלא אם מוגדר גם DISABLE_TELEMETRY.
CLAUDE_CODE_ENABLE_TELEMETRY אינו קשור: הוא מפעיל ייצוא OpenTelemetry אל האספן שלכם, כפי שמתואר בניטור, ואינו שולט באנליטיקה של Anthropic.
#נקודת קצה לתקינות
ה-runner מגיש GET /healthz בפורט התקינות שהוגדר. התגובה היא 200 OK בכל פעם שהתהליך חי, בכל מצב שבו נמצאת לולאת ה-poll, ולכן בדיקת HTTP על נקודת הקצה הזו מזהה רק תהליך מת. גוף ה-JSON מתאר את המצב הנוכחי:
{
"status": "ok",
"runner_id": "ccrunner_...",
"active_sessions": 2,
"last_poll_at": "2026-03-31T18:04:11.220Z",
"last_poll_age_ms": 842
}התריעו על last_poll_age_ms, ואל תשתמשו בו בבדיקת חיות. השאירו את הבדיקה הזו על קוד המצב של HTTP. הערך הוא הזמן שעבר מאז ה-poll המוצלח האחרון, ולכן הוא עולה גם כשה-runner לא יכול להגיע אל Anthropic. גם last_poll_at וגם last_poll_age_ms הם null עד שה-poll הראשון מצליח. כדי לתפוס polls שנכשלים כבר מההתחלה, התריעו גם על claude_code_self_hosted_runner_poll_errors_total, שרשום תחת מדדי Prometheus.
נקודת /healthz של ה-orchestrator עצמו, על פורט התקינות שלו, תמיד מחזירה 200. הגוף כולל שדה connected שמדווח אם ה-poll האחרון הצליח, ובנוסף ספירות של תור spawn לפי מצב ב-queue_counts. כדי לראות למה connected הוא false, קראו את השדה last_error ברמה העליונה. כל poll מוצלח מאפס אותו ל-null. התנו מוכנות והתראות לפי connected ולא לפי קוד המצב.
כשמחבר SCM מוגדר, גוף /healthz של ה-orchestrator כולל גם את scm_connector_connected ואובייקט scm_connector עם connected, last_connected_at, last_error, reconnects ו-requests_forwarded. שני השדות הם null כש---scm-connector-host אינו מוגדר.
#מדדי Prometheus
כל runner מגיש מדדי Prometheus ב-GET /metrics על אותה יציאה כמו /healthz. סדרות מרכזיות:
| סדרה | הערות |
|---|---|
claude_code_self_hosted_runner_info{runner_id,version,client_label} | תמיד 1. שימושי למלאי הצי ולזיהוי סטיית גרסאות |
claude_code_self_hosted_runner_capacity | ה---capacity שהוגדר |
claude_code_self_hosted_runner_active_sessions | סשנים שרצים כרגע |
claude_code_self_hosted_runner_locked_account{email} | מופיעה ברגע שה-runner ננעל למשתמש והונפק אסימון סשן שנושא claim בשם act.email. הסדרה נעדרת ב-runner שננעל לסוכן Claude Tag, שאסימוני הסשן שלו אינם נושאים act.email. ערך התווית הוא כתובת הדוא"ל של החשבון. אם מאגר המדדים שלכם קריא לקהל רחב, השמיטו או בצעו hash לתווית בזמן ה-scrape, למשל עם metric_relabel_configs של Prometheus. |
claude_code_self_hosted_runner_last_poll_age_seconds | שניות מאז ה-poll המוצלח האחרון. התריעו אם מעל 60. |
claude_code_self_hosted_runner_poll_errors_total{error_kind} | כשלי PollWork מצטברים לפי סוג: transport, timeout, 5xx, 429, או 4xx. כל חמש הסדרות קיימות מתחילת התהליך. התריעו על rate(...[5m]) > 0. |
claude_code_self_hosted_runner_sessions_started_total{client_platform} | תהליכי בן של סשנים שהופעלו לאורך חיי ה-runner, סדרה אחת לכל מקור סשן כגון web_claude_ai, ios, android, desktop_app, או claude_code_cli, או unknown כשהשרת לא שלח מקור. סשני Slack נושאים claude_in_slack או claude-in-slack, לפי אינטגרציית Slack שיצרה אותם, ולכן התאימו את שניהם עם בורר regex כגון {client_platform=~"claude[-_]in[-_]slack"}. השתמשו ב-sum() לסך של הצי. |
claude_code_self_hosted_runner_sessions_completed_total{client_platform} | סשנים שהסתיימו בצורה נקייה, עם אותן תוויות. רחב יותר מיציאה נקייה רגילה: ראו סמנטיקה של מוני מחזור חיי סשן לגבי מה נספר. |
claude_code_self_hosted_runner_sessions_failed_total{client_platform} | סשנים שהסתיימו בכשל, עם אותן תוויות. אותה הסתייגות: ראו סמנטיקה של מוני מחזור חיי סשן. |
claude_code_self_hosted_runner_sessions_interrupted_total{client_platform} | סשנים שה-runner סיים מסיבה תפעולית ולא בגלל תוצאת הסשן, עם אותן תוויות. ראו סמנטיקה של מוני מחזור חיי סשן. |
claude_code_self_hosted_runner_initializing_sessions | סשנים שנמצאים כרגע בשלב ה-init, מההקצאה ועד אירוע ה-init של תהליך הבן |
claude_code_self_hosted_runner_session_init_duration_seconds | היסטוגרמה של משכי init של סשן |
claude_code_self_hosted_runner_session_init_errors_total | סשנים שנכשלו לפני שהגיעו ל-init: כשל של checkout hook, הכנת git, בעיה באסימון, או קריסת תהליך בן לפני init |
claude_code_self_hosted_runner_session_start_hook_errors_total | hooks של SessionStart שדיווחו על תוצאת שגיאה, אחד לכל הרצת hook שנכשלה |
claude_code_self_hosted_runner_session_idle_seconds{session_id,client_platform} | gauge לכל סשן של שניות מאז שהסשן עבר למצב idle. שימושי לסיום סשנים שנתקעו על בקשת הרשאה שלא נענתה. |
ה-orchestrator מגיש סדרות משלו ב-GET /metrics על אותה יציאה כמו ה-/healthz שלו:
| סדרה | הערות |
|---|---|
claude_code_self_hosted_orchestrator_info{version,pool_id,orchestrator_uuid,hostname} | תמיד 1 |
claude_code_self_hosted_orchestrator_connected | 1 כשה-poll האחרון הצליח. יורד ל-0 אחרי כל poll שנכשל, מכל סוג כשל |
claude_code_self_hosted_orchestrator_last_poll_age_seconds | שניות מאז ניסיון ה-poll האחרון, הצלחה או כשל, בניגוד למדד בעל אותו שם אצל ה-runner, שמודד את הזמן מאז ההצלחה האחרונה. שלבו עם connected כדי לתפוס polls שנכשלים. לולאת ה-poll של ה-orchestrator ממתינה לביצוע hook, ולכן התריעו מעל --hook-timeout בתוספת מרווח, בסביבות 90 שניות בברירות המחדל, במקום ערך קבוע של 60. |
claude_code_self_hosted_orchestrator_poll_errors_total{error_kind} | כשלי PollSpawnHints מצטברים לפי סוג: transport, timeout, 5xx, 429, או 4xx. כל חמש הסדרות קיימות מתחילת התהליך. התריעו על rate(...[5m]) > 0. |
claude_code_self_hosted_orchestrator_queue_pending_sessions | בקשות spawn שאפשר לתבוע עכשיו |
claude_code_self_hosted_orchestrator_queue_backing_off_sessions | בקשות spawn ב-backoff של ניסיון חוזר אחרי כשל hook שניתן לחזור עליו |
claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions | סשנים חסומים מ-spawn. כל אחד נשאר חסום עד שמשתמש שולח לו הודעה חדשה, או עד ש-Owner מנסה שוב מלשונית Activity של הסביבה. הספירה יכולה להישאר מעל אפס אחרי תיקון הסיבה. התריעו אם היא מעל אפס. |
claude_code_self_hosted_orchestrator_pool_pending_sessions | סך הסשנים שממתינים ל-runner עבור הסביבה הזו. צבירה לכל הסביבה, זהה בכל מופע של orchestrator: השתמשו ב-MAX ולא ב-SUM בין המופעים. |
claude_code_self_hosted_orchestrator_pool_active_sessions | סשנים שמוקצים כרגע ל-runner חי בסביבה הזו. צבירה לכל הסביבה, זהה בכל מופע של orchestrator: השתמשו ב-MAX ולא ב-SUM בין המופעים. |
claude_code_self_hosted_orchestrator_spawn_hooks_total{result} | תוצאות מצטברות של hook בשם spawn-runner: ok, retryable, non_retryable. סופר הפעלות hook של ה-orchestrator, לא תהליכי בן של סשן שה-runners מפעילים. אי אפשר להשוות ל-sessions_started_total, כי קיבולת גבוהה מאחת, מאגרי warm, ו-runners שמופעלים שוב לאותו סשן, כולם מרחיקים בין השניים. |
claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds | היסטוגרמה של משכי hook |
claude_code_self_hosted_orchestrator_warm_hints_dispatched_total | בקשות spawn במצב standby שנשלחו מאז תחילת התהליך |
claude_code_self_hosted_orchestrator_session_queue_wait_seconds | היסטוגרמה של מספר השניות שכל סשן המתין בתור לפני שה-orchestrator תבע אותו ל-spawn, נרשמת לפי חותמת הזמן של ההמתנה בתור שמישור הבקרה שולח עם בקשת ה-spawn של כל סשן. השתמשו להתראות על זמן תור ב-p50 וב-p99. הפעלות spawn של pre-warming אינן נדגמות. |
claude_code_self_hosted_orchestrator_clock_skew_seconds | הטיית שעון של מקומי פחות שרת. לצורכי אבחון, ומופיעה אחרי שנמדדה |
claude_code_self_hosted_orchestrator_scm_connector_connected | 1 כש-WebSocket של מחבר SCM פתוח. 0 בזמן חיוג או בזמן backoff. נעדרת כש---scm-connector-host אינו מוגדר. |
claude_code_self_hosted_orchestrator_scm_connector_requests_forwarded_total | בקשות HTTP מצטברות שתווכו אל מארח ה-SCM המוגדר מאז תחילת התהליך. נעדרת כש---scm-connector-host אינו מוגדר. |
לצורך autoscaling, בחרו את הסדרה שתואמת את סגנון ה-scaling שלכם, וסננו אותה לפני שהיא מזינה את ה-scaler:
- scaling לפי עומק תור: הזינו את
claude_code_self_hosted_orchestrator_pool_pending_sessionsל-scaler של HPA או של KEDA, ולא אתqueue_pending_sessions. - scaling לפי קיבולת: בצעו scaling לפי היחס בין
active_sessionsשל ה-runner לביןcapacity. - סינון לפי
connected: סננו את השאילתה עםclaude_code_self_hosted_orchestrator_connected == 1לכל מופע, כדי שערך מיושן של replica מנותק לא יזין את ה-scaler.
בזמן השבתה מלאה של poll, כשכל replica מנותק, השאילתה המסוננת לא מחזירה נתונים. HPA שומר על מספר ה-replicas הנוכחי כשהמדד חסר, אבל ה-Prometheus scaler של KEDA, בברירת המחדל ignoreNullValues: "true", קורא את התוצאה הריקה כאפס ומבצע scale in. הגדירו ignoreNullValues: "false" ב-ScaledObject, ואפשר גם עם רצפת replicas ב-fallback.
ה-PodMonitor הבא של Prometheus Operator מכסה את שני התהליכים. הוא בוחר pods לפי התווית app.kubernetes.io/part-of: claude-code-self-hosted-runner ולפי היציאה בשם health שמתכון Kubernetes מגדיר. התאימו את ה-namespaces לפריסה שלכם:
# Example Prometheus Operator PodMonitor for the Claude Code self-hosted
# runner + orchestrator. Adjust the namespace and label selectors to match
# your deployment. Both the runner and the orchestrator serve /metrics on
# their --health-port (default 8080).
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: claude-code-self-hosted-runner
namespace: monitoring
spec:
namespaceSelector:
matchNames:
- claude-runners
selector:
matchExpressions:
# Matches the runner Deployment from the Kubernetes recipe, plus any
# on-demand runner Jobs and orchestrator pods you label the same way
# and give a named 'health' containerPort.
- key: app.kubernetes.io/part-of
operator: In
values: [claude-code-self-hosted-runner]
podMetricsEndpoints:
- port: health
path: /metrics
interval: 30s#כללי התראה לדוגמה
כללי ההתראה לדוגמה האלה הם נקודת התחלה. כווננו את הספים לגודל הצי שלכם:
# Example Prometheus alert rules for the Claude Code self-hosted runner
# + orchestrator. Tune thresholds for your fleet size and SLOs.
groups:
- name: claude-code-self-hosted-runner
rules:
- alert: ClaudeRunnerPollStale
expr: claude_code_self_hosted_runner_last_poll_age_seconds > 60
for: 2m
labels: {severity: warning}
annotations:
summary: "Runner {{ $labels.pod }} has not polled in >60s"
- alert: ClaudeRunnerVersionDrift
expr: count(count by (version) (claude_code_self_hosted_runner_info)) > 1
for: 30m
labels: {severity: info}
annotations:
summary: "Runners are running mixed versions"
- alert: ClaudeRunnerInitErrorsHigh
expr: sum by (namespace) (increase(claude_code_self_hosted_runner_session_init_errors_total[10m])) > 3
for: 5m
labels: {severity: warning}
annotations:
summary: "Sessions are failing before init (checkout hook / git / token / pre-init crash)"
- alert: ClaudeRunnerPollErrors
expr: sum by (pod) (rate(claude_code_self_hosted_runner_poll_errors_total[5m])) > 0
for: 2m
labels: {severity: warning}
annotations:
summary: "Runner {{ $labels.pod }}: PollWork failing ({{ $value | humanize }}/s over 5m)"
- alert: ClaudeRunnerSessionStartHookErrors
expr: sum by (namespace) (increase(claude_code_self_hosted_runner_session_start_hook_errors_total[10m])) > 3
for: 5m
labels: {severity: warning}
annotations:
summary: "SessionStart hooks are failing"
- name: claude-code-self-hosted-orchestrator
rules:
- alert: ClaudeOrchestratorDisconnected
expr: claude_code_self_hosted_orchestrator_connected == 0
for: 2m
labels: {severity: critical}
annotations:
summary: "Orchestrator {{ $labels.pod }} cannot reach the Anthropic control plane"
- alert: ClaudeOrchestratorPollStale
expr: claude_code_self_hosted_orchestrator_last_poll_age_seconds > 90
for: 2m
labels: {severity: warning}
annotations:
summary: "Orchestrator {{ $labels.pod }} has not polled in >90s (poll loop waits on hook execution)"
- alert: ClaudeOrchestratorCircuitBroken
expr: max by (namespace) (claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions and on (instance) max_over_time(claude_code_self_hosted_orchestrator_connected[2m]) == 1) > 0
for: 1m
labels: {severity: critical}
annotations:
summary: "Sessions blocked from spawning: {{ $value }}. Read each one's error in the Activity tab, fix the cause, then select Retry"
- alert: ClaudeOrchestratorPollErrors
expr: sum by (pod) (rate(claude_code_self_hosted_orchestrator_poll_errors_total[5m])) > 0
for: 2m
labels: {severity: warning}
annotations:
summary: "Orchestrator {{ $labels.pod }}: PollSpawnHints failing ({{ $value | humanize }}/s over 5m)"
- alert: ClaudeOrchestratorSpawnHookFailing
expr: sum by (pod) (increase(claude_code_self_hosted_orchestrator_spawn_hooks_total{result!="ok"}[5m])) > 3
for: 5m
labels: {severity: warning}
annotations:
summary: "Orchestrator {{ $labels.pod }}: >3 spawn-runner hook failures in 5m"#התראה על runners שאבדו ועל סשנים ממתינים
כדי לקבל התראה כש-runners אבדו, סשנים ממתינים, או שה-orchestrator לא פעיל, טענו את כללי ההתראה האלה של Prometheus לצד כללי ההתראה לדוגמה:
- צי קבוע:
ClaudeRunnersBelowFloor - runners לפי דרישה:
ClaudeOrchestratorSessionsWaiting,ClaudeOrchestratorQueueWaitHighו-ClaudeOrchestratorAbsent
#התראה כשצי קבוע מאבד runners
ClaudeRunnersBelowFloor מופעל כשמספר ה-runners הרשומים שנגרדו נמוך מהרצפה במשך 10 דקות:
groups:
# Fixed fleets only. With on-demand runners the count follows demand,
# so ClaudeRunnersBelowFloor would fire whenever demand is low.
- name: claude-code-self-hosted-fixed-fleet-capacity
rules:
- alert: ClaudeRunnersBelowFloor
expr: (count(claude_code_self_hosted_runner_info{namespace="claude-runners"}) or vector(0)) < 2
for: 10m
labels: {severity: critical, namespace: claude-runners}
annotations:
summary: "Runners registered and scraped: {{ $value }}, below the floor. Check the runner workloads first, then the scrape targets if all are running."- רצפה: הגדירו את
2ב-exprלכמחצית מספר ה-replicas, מעוגל כלפי מעלה. עם שלושה replicas השאירו2, וההתראה מופעלת כשנותר runner אחד או אף אחד. - Namespace: החליפו את
claude-runnersב-matcher וב-labels, והעתיקו את ההתראה לכל namespace נוסף. אם ליעדים שלכם אין תוויתnamespace, הסירו את ה-matcher ואת התווית, אחרת ההתראה קוראת 0 ומופעלת. ClaudeRunnerPollStaleו-ClaudeRunnerPollErrors: השאירו אותם טעונים מתוך כללי ההתראה לדוגמה, כיClaudeRunnersBelowFloorעדיין סופר runner שלא יכול לבצע poll
#התראה כשסשנים ממתינים ל-runners לפי דרישה
ClaudeOrchestratorSessionsWaiting מופעל כשמספר הסשנים שממתינים ל-runner נשאר מעל 0 במשך 10 דקות. ClaudeOrchestratorQueueWaitHigh מופעל כשיותר מ-1% מההמתנות בתור ב-10 הדקות האחרונות חרגו מ-160 שניות, וזה נמשך 5 דקות:
groups:
# On-demand runners only. Needs no edit for the namespace.
- name: claude-code-self-hosted-on-demand-capacity
rules:
- alert: ClaudeOrchestratorSessionsWaiting
expr: |
max by (namespace) (
claude_code_self_hosted_orchestrator_pool_pending_sessions
and on (instance)
max_over_time(claude_code_self_hosted_orchestrator_connected[2m]) == 1
) > 0
for: 10m
labels: {severity: warning}
annotations:
summary: "Sessions waiting for a runner: {{ $value }}, above the threshold for 10 minutes. Check claude_code_self_hosted_orchestrator_spawn_hooks_total by result, then runner workloads that don't start."
- alert: ClaudeOrchestratorQueueWaitHigh
expr: |
histogram_quantile(0.99, sum by (namespace, le) (
rate(claude_code_self_hosted_orchestrator_session_queue_wait_seconds_bucket[10m])
)) > 160
for: 5m
labels: {severity: warning}
annotations:
summary: "Over 1% of queue waits in the last 10 minutes exceeded 160 seconds. Check whether ClaudeOrchestratorDisconnected is firing, then claude_code_self_hosted_orchestrator_spawn_hooks_total by result and claude_code_self_hosted_orchestrator_spawn_hook_duration_seconds."- סף: אם סשן כלשהו תמיד ממתין, העלו את
> 0ב-ClaudeOrchestratorSessionsWaitingמעל המספר שאתם רואים בדרך כלל ClaudeOrchestratorDisconnected: השאירו אותו טעון מתוך כללי ההתראה לדוגמה, כיClaudeOrchestratorSessionsWaitingמפסיק להיות מופעל כ-2 דקות אחרי שה-orchestrator האחרון ב-namespace מתנתק
#התראה כשה-orchestrator לא פעיל
כדי לדעת שה-orchestrator עצמו לא פעיל, טענו את ClaudeOrchestratorAbsent. הוא מופעל כשאף orchestrator ב-namespace לא נגרד במשך 5 דקות:
groups:
# On-demand runners only. Replace claude-runners with the orchestrator's namespace.
- name: claude-code-self-hosted-on-demand-orchestrator
rules:
- alert: ClaudeOrchestratorAbsent
expr: absent(claude_code_self_hosted_orchestrator_connected{namespace="claude-runners"})
for: 5m
labels: {severity: critical}
annotations:
summary: "No orchestrator has been scraped for 5 minutes. If it's down, no on-demand runner starts, and sessions wait. Check the orchestrator workload first, then its scrape target if it's running."- Namespace: החליפו את
claude-runnersב-namespace של ה-orchestrator, והעתיקו את ההתראה לכל namespace נוסף שמריץ orchestrator. אם ליעדים שלכם אין תוויתnamespace, הסירו את ה-matcher, אחרת ההתראה מופעלת אחרי 5 דקות ונשארת פעילה. - שרתי Prometheus שלא גורדים את ה-orchestrator: השאירו את ההתראה מחוץ לקובצי הכללים שלהם, כי בשרת כזה היא מופעלת אחרי 5 דקות ונשארת פעילה
- אל תסתמכו על ההתראות האחרות של ה-orchestrator: הן קוראות מדדים שה-orchestrator עצמו מגיש.
ClaudeOrchestratorSessionsWaiting,ClaudeOrchestratorQueueWaitHighוכללי ההתראה לדוגמה של ה-orchestrator מפסיקים כולם להיות מופעלים בתוך כ-10 דקות מרגע שה-orchestrator יורד.
#העברת מדדי תהליך בן של סשן
כל סשן רץ בתהליך בן משלו עם מדדי OpenTelemetry משלו. כש---capacity מעל אחד, ה-runner משכתב את אופן החשיפה של מדדי הבן האלה. הגדרת OTEL_METRICS_EXPORTER=prometheus על מארח ה-runner ו-CLAUDE_CODE_ENABLE_TELEMETRY=1 בסביבת הסשן, למשל מתוך סקריפט העטיפה או מסביבת ה-runner עצמו, שסשנים יורשים, חושפת מחדש את מכשירי ה-counter וה-gauge של כל בן בנקודת הקצה /metrics של ה-runner עצמו, לצד הסדרות של ה-runner. ה-runner משכתב את ה-exporter של הבן כך שידחוף ב-OTLP למקלט על loopback בלבד בפורט הבריאות, מתייג כל סדרה בתוויות session_id ו-client_platform, ומפנה את הסדרות של סשן כשהסשן מסתיים. היסטוגרמות לא עוברות, ומדד בן ששמו היה מתנגש עם הקידומת של ה-runner עצמו מושמט.
ברירת המחדל --capacity 1, השכתוב לא חל: תהליך הבן של הסשן קושר נקודת קצה Prometheus משלו בפורט 9464 כרגיל.
#צירוף מדדי סשן למדדי ה-runner
כדי לראות מה עלו סשנים במצב idle, צרפו את claude_code_self_hosted_runner_session_idle_seconds של ה-runner למדד העלות של Claude Code על ccr_session_id. למדד של ה-runner אין את התווית הזאת, אז תנו לו אחת עם label_replace, כמו בשאילתה הזאת:
sum by (ccr_session_id) (claude_code_cost_usage_total)
and on (ccr_session_id)
label_replace(
claude_code_self_hosted_runner_session_idle_seconds > 600,
"ccr_session_id", "cse_$1", "session_id", "session_(.*)"
)השאילתה מחזירה תוצאה אחת לכל סשן ב-idle יותר מעשר דקות: העלות בדולר אמריקאי שתהליך Claude Code שלו ספר עד כה. כדי לצרף מדד Claude Code אחר, החליפו את claude_code_cost_usage_total בשאילתה. השאילתה עובדת בכל --capacity.
session_id: בפורט 9464, התווית הזאת על מדדי Claude Code מחזיקה אתsession.idשל Claude Code עצמו, שלא תואם לאף סדרה של ה-runner. צירוף עליה לא מחזיר כלום, אז צרפו עלccr_session_id.- למדדי Claude Code אין
ccr_session_id: בדקו ש-OTEL_METRICS_INCLUDE_SESSION_IDלא מוגדר ל-false
#סמנטיקה של מוני מחזור חיי סשן
המונים sessions_started_total, sessions_completed_total, sessions_failed_total ו-sessions_interrupted_total מסווגים כל סשן לפי אופן הסיום שלו. כל תהליך בן של סשן שנוצר מגדיל את sessions_started_total בזמן ה-spawn, ובדיוק אחד משלושת האחרים גדל ביציאה, כך ש-sessions_started_total פחות סכום שלושת האחרים שווה למספר תהליכי הבן של סשנים שרצים כרגע.
completed: הסשן הסתיים בצורה נקייה. זה מכסה יציאה עצמית של הבן עם קוד0, ארכוב או מחיקה של הסשן בזמן שהבן עדיין היה מחובר, והחזרה נקייה של המשבצת על ידי ה-runner: שחרור הסשן ב-timeout של idle, בזמן ה-retire, או במגבלת--kill-session-after-min, timeout של הפעלה, או deassign מצד השרת שלולאת ה-poll הבחינה בו לפני שהבן יצא. מגדיל אתsessions_completed_total.failed: הבן יצא בעצמו עם קוד שאינו אפס, קריסה או כשל הגדרה אחרי spawn. מגדיל אתsessions_failed_total.interrupted: ה-runner סיים את הבן מסיבה תפעולית שהיא לא הצלחת סשן ולא תקלה של ה-runner, למשל drain, או סיום סשן שעדיין היה על ה-runner כשחלון החסדSELF_HOSTED_RUNNER_MAX_LIFETIME_GRACE_MSאחרי מגבלת--kill-session-after-minשלו הסתיים. הפעלה מחדש מתגלגלת ב-Kubernetes ששולחתSIGTERMהיא דוגמה אחת ל-drain. מגדיל אתsessions_interrupted_total.
לפני v2.1.260, ה-runner סיים כל סשן שהגיע למגבלת --kill-session-after-min שלו וספר אותו ב-sessions_interrupted_total.
CLAUDE_RUNNER_EXIT_REASON של ה-hook מסוג post-session מסווג מסירות נקיות אחרת. ה-hook מדווח על אלה כ-interrupted, כי ה-runner עצר את הבן: שחרור, timeout של הפעלה, deassign מהשרת, וארכוב או מחיקה שה-poll הבחין בהם קודם. המונים האלה רושמים את אותם אירועים כ-completed, כי המשבצת הוחזרה בצורה נקייה.
אם משווים קבלות של ה-hook מול sessions_completed_total ישירות, סופרים פחות השלמות. השתמשו ב-hook לערבויות לכל סשן ובמונים לשיעורים מצטברים.
בסביבה חד פעמית, --capacity 1 עם ברירת המחדל --drain-grace-sec 0, כל תהליך runner יוצא רגעים אחרי שהסשן היחיד שלו מסתיים. sessions_completed_total, sessions_failed_total ו-sessions_interrupted_total גדלים רק בסוף הסשן, ממש לפני היציאה הזאת, כך ש-scrape של Prometheus כל 15 עד 60 שניות כמעט לא תופס את ההגדלה לפני שסדרות ה-runner נעלמות. שלושת מוני סוף הסשן האלה הם המונים הסופיים ששאר הסעיף הזה מתייחס אליהם. sessions_started_total גדל ב-spawn ונשאר גלוי למשך חיי הסשן, ולכן הוא מופיע באופן אמין, אבל בסביבה חד פעמית הוא קרוב יותר ל"סשנים שרצים כרגע" מאשר לספירה מצטברת.
השתמשו בסדרות בטבלה הזאת למטרה המתאימה במקום במונים הסופיים:
| מטרה | שימוש |
|---|---|
| תפוקה | claude_code_self_hosted_orchestrator_spawn_hooks_total{result="ok"}, מונה על ה-orchestrator ארוך החיים שגדל פעם אחת לכל hook מוצלח מסוג spawn-runner ונשאר משמעותי תחת rate(). הוא סופר הפעלות hook ולא סשנים, ולכן חימום מראש ו-spawn חוזר לאותו סשן מרחיקים אותו מספירות הסשנים. |
| ניצולת | sum(claude_code_self_hosted_runner_active_sessions) מול sum(claude_code_self_hosted_runner_capacity), שני gauges תקפים בכל scrape בלי קשר למשך חיי ה-runner |
| צבר | claude_code_self_hosted_orchestrator_pool_pending_sessions לעומק התור, ו-claude_code_self_hosted_orchestrator_queue_circuit_broken_sessions, עם התראה אם מעל אפס |
| כשלים | claude_code_self_hosted_runner_sessions_failed_total, במאמץ סביר: קריסות אמיתיות אחרי spawn כן מגדילות אותו, ו-rate() משמעותי על runners שמאריכים ימים אחרי הסשנים שלהם עם --drain-grace-sec מעל 0. לסביבה חד פעמית יש אותה בעיית חלון scrape כמו למונים הסופיים האחרים, אז התייחסו לכל ערך שאינו אפס שכן רואים כדבר שכדאי לחקור. כשלים לפני spawn, כמו כשל hook של checkout, הכנת git, או בעיית token, מופיעים רק ב-session_init_errors_total. |
שורות orchestrator_* קיימות רק בסביבות שמריצות את ה-orchestrator לפי דרישה. בצי קבוע שה-runners שלו מאריכים ימים אחרי הסשנים, עם --drain-grace-sec מעל 0, השתמשו ב-sum(rate(claude_code_self_hosted_runner_sessions_started_total[5m])) לתפוקה. בצי חד פעמי לסדרה הזאת יש אותה בעיית חלון scrape כמו למונים הסופיים, אז הסתמכו במקום זאת על ספירת הסשנים בתור. בדקו צבר בלשונית Activity של הסביבה, בדף הניהול Cloud environments: ה-runners לא מייצאים סדרת עומק תור.
לדיווח תוצאה לכל סשן, השתמשו ב-hook מסוג post-session: הוא מופעל בכל סוף סשן שבו נוצר תהליך בן, מלבד סיום פתאומי של ה-runner כמו preemption של VM, לפי החוזה של ה-hook עצמו.
#מה הלאה
- סביבות self-hosted: מודל הסביבה, ה-runner והסשן. ההתחלה המהירה ו-פריסה לייצור מכילים הקמה ותפעול
- התאמת סשנים: סקריפטי עטיפה, hooks של מחזור חיים, ו-runners לפי דרישה
- אימות זהות סשן: טוקן הסשן, ה-claims שלו, ואיך לאמת אותו