170 170
171如果您的 Git 主機拒絕認證,或您沒有配置認證,執行器會重試幾次,然後失敗儲存庫準備當儲存庫是工作階段推送結果的儲存庫時。對於工作階段僅從中讀取的儲存庫,[Troubleshooting](#troubleshooting) 涵蓋執行器何時改為跳過它。執行器不會將這些設定傳遞到工作階段的環境中。171如果您的 Git 主機拒絕認證,或您沒有配置認證,執行器會重試幾次,然後失敗儲存庫準備當儲存庫是工作階段推送結果的儲存庫時。對於工作階段僅從中讀取的儲存庫,[Troubleshooting](#troubleshooting) 涵蓋執行器何時改為跳過它。執行器不會將這些設定傳遞到工作階段的環境中。
172 172
173保持您在 `GIT_SSH_COMMAND` 或 `GIT_ASKPASS` 中命名的任何程式,工作階段無法寫入它,就像[強化檢查清單](#harden-your-deployment)要求鉤子目錄和包裝器指令碼的方式一樣。該程式命令行上的任何金鑰或檔案也是如此。執行器自己的 Git 在複製或提取時執行該程式。
174
173如果簽出目錄由與執行器程序不同的 uid 擁有,Git 拒絕對其進行操作;添加 `safe.directory`:175如果簽出目錄由與執行器程序不同的 uid 擁有,Git 拒絕對其進行操作;添加 `safe.directory`:
174 176
175```dockerfile theme={null}177```dockerfile theme={null}
184 186
185代理需要 `--capacity 1`,因為代理 URL 是每個工作階段的,Git 2.32 或更新版本,因為較舊的 Git 忽略代理用來隔離工作階段的配置機制。如果任一要求未滿足,執行器拒絕啟動。因為代理從 Anthropic 端提取,您的 Git 主機必須可從 Anthropic 基礎設施到達,與 Anthropic 託管工作階段相同的要求;對於僅在您的網路內可路由的 Git 主機,改用 [`checkout` 生命週期鉤子](/docs/zh-TW/self-hosted-environments-configuration#checkout)。每個執行器程序一次處理一個工作階段,因此執行更多副本以實現並行性。啟用代理後,`--git-host-rewrite` 和 `--git-ssh-rewrite` 無效:代理 URL 指向 `api.anthropic.com`,而不是您的 Git 主機。187代理需要 `--capacity 1`,因為代理 URL 是每個工作階段的,Git 2.32 或更新版本,因為較舊的 Git 忽略代理用來隔離工作階段的配置機制。如果任一要求未滿足,執行器拒絕啟動。因為代理從 Anthropic 端提取,您的 Git 主機必須可從 Anthropic 基礎設施到達,與 Anthropic 託管工作階段相同的要求;對於僅在您的網路內可路由的 Git 主機,改用 [`checkout` 生命週期鉤子](/docs/zh-TW/self-hosted-environments-configuration#checkout)。每個執行器程序一次處理一個工作階段,因此執行更多副本以實現並行性。啟用代理後,`--git-host-rewrite` 和 `--git-ssh-rewrite` 無效:代理 URL 指向 `api.anthropic.com`,而不是您的 Git 主機。
186 188
189<Warning>
190 本頁上的 [Kubernetes](#kubernetes) 和 [Docker Compose](#docker-compose) 配方使用 `--capacity 4`。如果您在不將容量更改為 `1` 的情況下將 `--use-anthropic-git-proxy` 或 `CLAUDE_RUNNER_USE_GIT_PROXY=1` 添加到其中之一,每次您的協調器重新啟動執行器時,執行器都會在啟動時退出。設定 `--capacity 1` 並執行更多副本以實現並行性。[When the runner exits](#when-the-runner-exits) 顯示執行器列印的行。
191</Warning>
192
187執行器也會在註冊時向 Anthropic 報告選擇加入,在啟動時列印 `Registering as opted in to Anthropic-managed git (--use-anthropic-git-proxy)`。報告選擇加入需要 Claude Code v2.1.267 或更新版本,較早的版本接受該旗標而不報告它或列印該行。選擇加入執行器上的每個工作階段隨後使用 Anthropic 管理的 Git 或每個工作階段的代理 URL。當工作階段使用每個工作階段的代理 URL 時,執行器記錄一行 `[runner:warn]` 說明這一點。193執行器也會在註冊時向 Anthropic 報告選擇加入,在啟動時列印 `Registering as opted in to Anthropic-managed git (--use-anthropic-git-proxy)`。報告選擇加入需要 Claude Code v2.1.267 或更新版本,較早的版本接受該旗標而不報告它或列印該行。選擇加入執行器上的每個工作階段隨後使用 Anthropic 管理的 Git 或每個工作階段的代理 URL。當工作階段使用每個工作階段的代理 URL 時,執行器記錄一行 `[runner:warn]` 說明這一點。
188 194
195<h4 id="trust-a-private-certificate-authority-with-anthropic-managed-git">
196 使用 Anthropic 管理的 Git 信任私有憑證授權單位
197</h4>
198
199如果您在執行器的環境中設定 `GIT_SSL_CAINFO` 或 `GIT_SSL_NO_VERIFY`,其工作階段使用 Anthropic 管理的 Git,本部分適用。它描述的處理需要執行器執行 Claude Code v2.1.283 或更新版本。
200
201當執行器上的 Git 必須信任私有憑證授權單位 (CA)(例如 TLS 檢查代理簽署的憑證授權單位)時,通常的方法如下所示:
202
203* **系統憑證存放區**:在執行器主機的系統憑證存放區中安裝您的 CA,Git 無需任何變數即可信任它。
204* **`GIT_SSL_CAINFO`**:將其設定為您的 CA 的 PEM 檔案,例如 `GIT_SSL_CAINFO=/etc/ssl/corp-ca.pem`。
205* **`GIT_SSL_NO_VERIFY`**:在重新簽署代理後沒有幫助。執行器自己通過 Anthropic 管理的 Git 複製檢查憑證,即使設定了變數,因此複製失敗直到 Git 通過其他兩種方法之一信任您的 CA。
206
207對於將工作階段令牌傳遞到 Anthropic 管理的 Git 的 Git 連線,執行器應用這兩個變數如下。[`command` 鉤子](/docs/zh-TW/self-hosted-environments-configuration#command)以工作階段的環境開始,因此它獲得 Git 在工作階段內獲得的內容:
208
209* **`GIT_SSL_CAINFO`**:Git 檢查 Anthropic 管理的 Git 的內容取決於 Git 執行的位置:
210 * **執行器自己的複製和提取**:執行時不使用變數,並根據執行器寫入的每個工作階段憑證檔案檢查 Anthropic 管理的 Git。該檔案保存執行器主機的系統 CA 套件加上您的檔案中的憑證。
211 * **工作階段內的 Git**:獲得 `http.sslCAInfo` 配置,命名您的檔案代替變數,加上 `http.<url>.sslCAInfo` 項目,根據每個工作階段檔案檢查 Anthropic 管理的 Git。
212 * **`checkout` 和 `post-session` 鉤子**:繼承變數不變。
213* **`GIT_SSL_NO_VERIFY`**:哪些憑證檢查保持關閉取決於 Git 執行的位置:
214 * **執行器自己的複製和提取**:執行時不使用變數,並檢查它們呈現的憑證。
215 * **工作階段內的 Git**:獲得 `http.sslVerify=false` 配置代替變數,因此檢查對其他主機保持關閉。它也獲得 `http.<url>.sslVerify=true` 項目,為 Anthropic 管理的 Git 保持檢查開啟。
216 * **`checkout` 和 `post-session` 鉤子**:當工作階段在 Anthropic 管理的 Git 上有儲存庫時,獲得 `http.sslVerify=false` 配置代替變數。它們也獲得 `http.<url>.sslVerify=true` 項目,為 Anthropic 管理的 Git 保持檢查開啟。
217
218每個工作階段憑證檔案需要在執行器主機上的 `/etc/ssl/certs/ca-certificates.crt` 或 `/etc/pki/tls/certs/ca-bundle.crt` 處的系統 CA 套件。它也需要執行器的使用者可以讀取的 `GIT_SSL_CAINFO` 檔案,保存 PEM `CERTIFICATE` 區塊,最多 1 MiB。當執行器無法建立每個工作階段檔案時,它記錄包含 `did not build the certificate file` 和原因的 `[runner:warn]` 行。Git 隨後按原樣為 Anthropic 管理的 Git 使用您的檔案。修復該行命名的內容。
219
220對於使用 Anthropic 管理的 Git 的每個工作階段,執行器也記錄以 `governed git: GIT_SSL_CAINFO is set` 或 `governed git: GIT_SSL_NO_VERIFY is set` 開始的 `[runner:warn]` 行。該行說明執行器對其自己的 Git、工作階段內的 Git 和您的生命週期鉤子對該變數所做的操作。它以您是否需要更改任何內容結束。
221
189<h3 id="rewrite-git-urls-for-private-networks">222<h3 id="rewrite-git-urls-for-private-networks">
190 為私有網路重寫 Git URL223 為私有網路重寫 Git URL
191</h3>224</h3>
203 236
204Anthropic 不發佈預構建的執行器映像。在 `claude` 二進位檔案周圍構建您自己的,分層您的儲存庫需要的任何工具鏈:語言執行時、編譯器、套件管理器和 [MCP](/docs/zh-TW/mcp) 邊車。237Anthropic 不發佈預構建的執行器映像。在 `claude` 二進位檔案周圍構建您自己的,分層您的儲存庫需要的任何工具鏈:語言執行時、編譯器、套件管理器和 [MCP](/docs/zh-TW/mcp) 邊車。
205 238
206下面的配方使用 `--capacity 4`,因此一個容器服務來自同一鎖定所有者的最多四個並發工作階段。這不提供[強化部分](#harden-your-deployment)中的每個工作階段容器隔離:在將環境連接到生產系統之前,要麼以 `--capacity 1` 執行配方,每個工作階段一個容器,要麼使用[按需執行器](/docs/zh-TW/self-hosted-environments-configuration#on-demand-runners),它也將環境祕密保留在執行工作階段的主機之外。239下面的配方使用 `--capacity 4`,因此一個容器服務來自同一鎖定所有者的最多四個並發工作階段。這不提供[強化部分](#harden-your-deployment)中的每個工作階段容器隔離:在將環境連接到生產系統之前,要麼以 `--capacity 1` 執行配方,每個工作階段一個容器,要麼使用[按需執行器](/docs/zh-TW/self-hosted-environments-configuration#on-demand-runners),它也將環境祕密保留在執行工作階段的主機之外。如果您將[Anthropic git 代理](#use-the-anthropic-git-proxy)新增至其中一個配方,也請將 `--capacity` 變更為 `1`。
207 240
208此 Dockerfile 是一個最小的起點:241此 Dockerfile 是一個最小的起點:
209 242
336 Docker Compose369 Docker Compose
337</h2>370</h2>
338 371
339下面的 Compose 服務在執行器退出時重新啟動它,涵蓋崩潰和清空後的正常退出。Docker 重新啟動原則重新啟動同一容器及其可寫層,因此執行器以重複使用的檔案系統而不是[強化姿態](#harden-your-deployment)推薦的新鮮檔案系統回來;為評估使用此配方,對於生產環境,要麼每次執行時重新建立容器,要麼使用執行此操作的協調器。372下面的 Compose 服務會在執行器退出時重新啟動它,這涵蓋了崩潰和正常排空後的退出。Docker 重新啟動原則會使用其可寫層保持完整的方式重新啟動同一個容器,因此執行器會在重複使用的檔案系統上恢復,而不是[強化部署](#harden-your-deployment)建議的全新檔案系統;請使用此配方進行評估,而對於生產環境,請每次執行時重新建立容器,或使用執行協調器。
373
374Docker 在容器不斷退出時,會在每次重新啟動之前等待更長的時間,直到達到上限,因此無法啟動的執行器在此配方下不會在緊密迴圈中持續重新啟動。[當執行器退出時](#when-the-runner-exits)描述了發生這種情況時要檢查的內容。
340 375
341```yaml theme={null}376```yaml theme={null}
342services:377services:
451 486
452每個工作階段的子 Claude Code 程序執行執行器自己的二進位檔案,執行器在它生成的工作階段內關閉自動更新,因此每個工作階段執行您在主機上安裝或構建到映像中的版本。主機級更新在執行器下次啟動時生效。487每個工作階段的子 Claude Code 程序執行執行器自己的二進位檔案,執行器在它生成的工作階段內關閉自動更新,因此每個工作階段執行您在主機上安裝或構建到映像中的版本。主機級更新在執行器下次啟動時生效。
453 488
489您的工作階段使用的模型可能需要比它們執行的版本更新的 Claude Code 版本。伺服器隨後會以 [Claude Code 不支援此模型](/docs/zh-TW/errors#claude-code-does-not-support-this-model) 拒絕該模型的請求。在您固定版本之前,請檢查[模型所需的 Claude Code 版本](/docs/zh-TW/model-config#available-models),以確保您的工作階段使用的每個模型都符合要求。
490
454* **將群保持在一個版本上**:使用固定版本構建映像,或在裸主機上安裝特定版本並[禁用自動更新](/docs/zh-TW/setup#disable-auto-updates)491* **將群保持在一個版本上**:使用固定版本構建映像,或在裸主機上安裝特定版本並[禁用自動更新](/docs/zh-TW/setup#disable-auto-updates)
455* **升級**:安裝較新版本或重建映像,然後重新啟動執行器492* **升級**:安裝較新版本或重建映像,然後重新啟動執行器
456* **外掛程式**:外掛程式市場也不自動更新;在執行器的環境中設定 `FORCE_AUTOUPDATE_PLUGINS=1` 以讓外掛程式自動更新,同時二進位檔案保持固定493* **外掛程式**:外掛程式市場也不自動更新;在執行器的環境中設定 `FORCE_AUTOUPDATE_PLUGINS=1` 以讓外掛程式自動更新,同時二進位檔案保持固定
554 591
555每個工作階段的子程序寫入單獨的調試日誌。失敗時執行器在 claude.ai/code 中的工作階段旁邊顯示日誌的尾部。除非您使用 [`--remove-session-state`](/docs/zh-TW/self-hosted-environments-reference#runner-cli-flags) 啟動執行器,否則它也會在磁碟上保留失敗工作階段的日誌,並在執行器日誌中列印其路徑。592每個工作階段的子程序寫入單獨的調試日誌。失敗時執行器在 claude.ai/code 中的工作階段旁邊顯示日誌的尾部。除非您使用 [`--remove-session-state`](/docs/zh-TW/self-hosted-environments-reference#runner-cli-flags) 啟動執行器,否則它也會在磁碟上保留失敗工作階段的日誌,並在執行器日誌中列印其路徑。
556 593
594<h3 id="when-the-runner-exits">
595 當執行器退出時
596</h3>
597
598不要重新啟動[按需執行器](/docs/zh-TW/self-hosted-environments-configuration#on-demand-runners),因為其工作訂單是一次性的。執行器在啟動後立即退出需要與因任何其他原因退出的執行器不同的處理。
599
600* **正常退出**:執行器完成了其工作階段並清空、達到其退休時間或被告知停止。重新啟動它以便環境再次具有容量。[執行器生命週期](/docs/zh-TW/self-hosted-environments#runner-lifecycle)描述這些退出。
601* **失敗的啟動**:執行器無法使用給定的設定或主機啟動,因此它在啟動後幾秒鐘退出,每次您重新啟動它時都以相同的方式退出。更快地重新啟動它沒有幫助。有人需要閱讀其輸出並修復原因。
602
603配置您的監督程序以在執行器退出時重新啟動它,在執行器持續在啟動後立即退出時等待更長時間再重新啟動,並在這種情況持續發生時告知某人。
604
605<h4 id="recognize-a-failed-start">
606 識別失敗的啟動
607</h4>
608
609當執行器無法啟動時,它會列印一行說明原因,然後退出。對於大多數原因,該行包含 `[runner:fatal]`。對於某些原因,該行以 `error:` 開頭,包括當執行器無法解析其旗標、無法讀取環境祕密或無法建立或寫入基本目錄時。下一行然後指向 `--help`。
610
611大多數日誌行以時間戳和 `[self-hosted-runner]` 開頭,下面的範例省略了。例如,使用 Anthropic Git 代理和容量大於 1 啟動的執行器會列印如下一行:
612
613```text theme={null}
614[runner:fatal] --use-anthropic-git-proxy requires --capacity 1 (the proxy URL is per-session and linked worktrees share origin). Omit --use-anthropic-git-proxy or set --capacity 1.
615```
616
617在執行器的標準輸出和標準錯誤、您的平台的容器日誌或您使用 [`--log-file`](/docs/zh-TW/self-hosted-environments-reference#runner-cli-flags) 設定的檔案中尋找該行。執行器在打開日誌檔案之前列印 `error:` 行,因此在終端或您的容器日誌中尋找它,如[故障排除](#troubleshooting)所述。
618
619當您閱讀失敗的啟動時,這些也有幫助:
620
621* **根本沒有行**:主機殺死的執行器不會列印任何一個。如果輸出以沒有 `[runner:fatal]` 行和沒有 `error:` 行結束,檢查主機或您的協調器是否停止了程序,例如超過記憶體限制。
622* **退出代碼**:執行器不會為在每次啟動時重複的錯誤預留退出代碼。它對配置錯誤(例如不支援的旗標組合)和可以自行清除的失敗(例如 API 通過執行器自己的重試保持無法到達)以相同的代碼退出。根據執行器退出的速度快慢來決定是否等待更長時間,並閱讀執行器的輸出以了解原因。
623* **看起來健康的環境**:某些啟動步驟在執行器向您的環境註冊後執行,例如 [`--configure-git`](#let-the-runner-configure-git) 和 Anthropic Git 代理的認證設定。如果其中一個步驟失敗,環境可以在程序退出後幾分鐘內繼續列出該執行器,**雲端環境**頁面可以讀取**健康**,而沒有執行器拾取工作。如果工作階段在看起來健康的環境中保持排隊,檢查您的監督程序是否在重新啟動執行器。
624
625<h4 id="restart-with-a-wait-that-grows">
626 使用增長的等待時間重新啟動
627</h4>
628
629您如何獲得增長的等待時間取決於您的監督程序。
630
631* **Kubernetes**:此頁面上的 [Deployment](#kubernetes) 不需要更改。容器退出後,kubelet 預設會在重新啟動容器之前等待,並且等待時間在每次重新啟動時增長到上限。一旦容器運行了一段時間而沒有退出,等待時間就會重新開始。
632
633 kubelet 在容器運行時間很短時的正常退出後應用相同的等待。經常清空的執行器因此也可以顯示 `CrashLoopBackOff` 狀態,因此在得出執行器無法啟動的結論之前閱讀輸出。下面的命令從 Deployment 的一個 pod 讀取上次運行的輸出:
634
635 ```bash theme={null}
636 kubectl logs --previous -n claude-runners deploy/claude-runner
637 ```
638
639 當上次運行是失敗的啟動時,`[runner:fatal]` 或 `error:` 行在輸出的最後幾行中。要讀取另一個 pod 的上次運行,在 `deploy/claude-runner` 的位置命名該 pod。
640* **Docker 和 Docker Compose**:此頁面上的 [Compose 配方](#docker-compose)不需要更改。使用 `restart: always`,Docker 在持續退出的容器的每次重新啟動之前等待更長時間,直到上限。在下面的命令中用容器的名稱替換 `<container>`,該命令讀取 Docker 重新啟動容器的次數:
641
642 ```bash theme={null}
643 docker inspect --format '{{.RestartCount}}' <container>
644 ```
645
646 該命令列印一個數字。持續增長的數字意味著 Docker 持續重新啟動執行器。
647* **systemd 單位**:預設情況下,systemd 在每次重新啟動之前等待相同的 `RestartSec`,並且不會延長它,因此具有 `Restart=always` 的單位以相同的間隔重新啟動無法啟動的執行器。當啟動速度足夠快以達到單位的啟動速率限制時(預設為 10 秒內 5 次啟動),systemd 停止重新啟動該單位。該單位保持停止狀態,直到有人再次啟動它,systemd 允許在速率限制的間隔已過或在 `systemctl reset-failed` 之後。因為 `RestartSec` 適用於每次重新啟動,更長的值也會延遲正常退出後的重新啟動。選擇一個平衡兩者的值,並對單位的重新啟動計數發出警報。
648* **shell 迴圈或您自己的監督程序**:自己應用相同的規則。從 5 秒的等待開始。在每次在一分鐘內結束的運行之後,將下一次重新啟動的等待加倍,最多 5 分鐘。在運行持續一分鐘或更長時間後,回到 5 秒。
649
650<h4 id="check-why-the-runner-keeps-exiting">
651 檢查執行器為什麼持續退出
652</h4>
653
654當執行器連續多次在啟動後立即退出時,停止並在重新啟動之前檢查這些。
655
656* **最後的 `[runner:fatal]` 或 `error:` 行**:它說明執行器停止的原因。[故障排除](#troubleshooting)列出常見原因。
657* **旗標的組合**:[Anthropic Git 代理](#use-the-anthropic-git-proxy)需要 `--capacity 1`。此頁面上的配方使用更高的容量,因此在將代理添加到其中一個時降低它。
658* **服務的環境可以到達什麼**:如果執行器手動啟動並在您的監督程序下失敗,比較使用者、主目錄、`PATH` 和記憶體限制。`--configure-git` 和 Anthropic Git 代理需要 `PATH` 上的 Git 和可寫的 `~/.gitconfig`。
659* **環境祕密**:如果您撤銷了祕密或輸入錯誤,執行器會列印包含 `RegisterRunner auth failed` 的行。
660* **環境的活動標籤**:打開環境並選擇**活動**。如果新執行器持續出現在那裡,沒有任何執行器拾取工作,您的監督程序正在重新啟動執行器。
661
662為了在執行器主機上進行引導式診斷,執行 [doctor 子命令](#troubleshooting)。
663
557<h2 id="what’s-next">664<h2 id="what’s-next">
558 下一步665 下一步
559</h2>666</h2>