選型前提:何時 Kaniko、何時 buildx
若流水線不能掛載 Docker socket、或必須在單一非特權容器內完成建置,Kaniko executor 通常是預設解;若你需要 BuildKit 的 RUN --mount=type=cache、secret、多平台 --platform 矩陣,或已在 Mac 上跑 Docker Desktop/Colima 並願意維護 builder,則 docker buildx 較省整合成本。兩條路都會在跨境場景撞同一組牆:建構上下文同步耗時、registry 連線數、快取索引與實際層 digest 不一致導致的 cache miss。下文假設你已有一臺固定規格的 Apple Silicon 遠端 Mac Runner,並以「先 rsync、再建置、最後推層」三段拆解 KPI。
Kaniko 與 buildx 決策矩陣(layer cache 與執行模型)
若搜尋意圖是「cache-repo 要不要獨立 repo」「buildx cache-to 用 inline 還是 registry」「跨境下要不要開 rsync -z」,請先用下表對齊語意,再落到可執行旗標。
| 維度 | Kaniko | Docker buildx(BuildKit) |
|---|---|---|
| Layer cache 載體 | --cache=true + --cache-repo 指向可讀寫的 快取映像 命名空間 | --cache-to type=registry,ref=...,mode=max 與對稱 --cache-from;亦可 type=local 落在 APFS 磁碟 |
| 上下文進入方式 | --context dir:///path 或 tarball/git;目錄需先於宿主準備好 | 預設本地目錄;遠端 builder 時須關注傳輸邊界 |
| 典型併發瓶頸 | 序列化 RUN 較多;瓶頸常在 push 層 與 digest 計算 | BuildKit 求解器可並行多階段;瓶頸常在 registry 吞吐 與 export cache |
| root/daemon 依賴 | 容器內執行,無需宿主 dockerd 建置 | 需可用 Docker CLI 與 builder;Mac 上注意資源配額 |
| 建議觀測指標 | 日誌中 cache miss 原因、--push-retry 觸發次數 | BUILDKIT_PROGRESS=plain 下 CACHED 比例、export 步驟耗時 |
rsync 參數與併發上限(建構上下文預熱)
跨境時常見模式:控制面在雲端,建構上下文放在物件儲存或內部 artifact 伺服器;Runner 以 rsync 拉到本機 SSD 再上傳給 Kaniko/buildx。原則:-a 保留權限與時間戳(有利於 COPY 層命中);--numeric-ids 降低跨系統映射意外;大倉可先 --dry-run 再帶 --delete,避免誤刪未納入清單的路徑。壓縮:-z 適合窄頻寬高延遲;若已是內網 10Gbps+大量已壓縮二進位,關閉 -z 常更快。併發上限:rsync 單進程不吃滿「層併發」,真正併發來自「同機同時跑幾條 image build」;建議起點為 每臺 Mac 同時 1–2 條重映像 job,觀察 df 與 registry 429 後再升。
# 預熱(示例;SRC 為 artifact 掛載或上一階段 checkout)
export RSYNC_PARTIAL_DIR="${TMPDIR:-/tmp}/rsync-partial"
mkdir -p "$RSYNC_PARTIAL_DIR" "${WORK}/context"
rsync -ah --partial-dir="$RSYNC_PARTIAL_DIR" --info=stats2,misc2 \
--numeric-ids "${SRC}/" "${WORK}/context/"
# 跨境窄頻寬可改為:rsync -azh ...(加 -z)
# 需鏡像刪除時:先 --dry-run,再 rsync -ah --delete ...
# Kaniko(片段;實際以你方 entrypoint 為準)
# --context dir://${WORK}/context
# --dockerfile Dockerfile
# --destination registry.example.com/app:${GIT_SHA}
# --cache=true
# --cache-repo registry.example.com/app/kaniko-cache
# --compressed-caching=false
# --push-retry=5
# buildx(registry cache 範例)
# docker buildx build --push \
# --cache-to type=registry,ref=registry.example.com/app:buildcache,mode=max \
# --cache-from type=registry,ref=registry.example.com/app:buildcache \
# -t registry.example.com/app:${GIT_SHA} "${WORK}/context"
registry 認證與逾時(含環境變數閾值)
無論 Kaniko 讀寫 --cache-repo 或 buildx 做 cache-to,401/403 多半是權杖 scope 或時鐘漂移;TLS handshake timeout 則常與跨境 MTU/Proxy 有關。建議在 CI 密文注入後寫入 DOCKER_CONFIG 目錄下的 config.json,並在步驟開頭 export:export DOCKER_CLIENT_TIMEOUT=300(秒級閾值,依客戶端版本調整)、export COMPOSE_HTTP_TIMEOUT=300(若同倉還跑 compose pull)。需走固定出口時同步設定 HTTPS_PROXY/NO_PROXY(含 .svc 與內部 registry host)。Kaniko 可視情況調高 --push-retry(預設 5),但勿以無上限重試掩蓋配置錯誤。
CI 快取鍵與失敗退避(layer 命中)
快取鍵應至少綁定:Dockerfile 與 docker/ 目錄的內容雜湊、會進 COPY 的 lockfile(如 package-lock.json)、以及基底映像 digest(避免上游 silent update 造成雪崩 miss)。命名空間上,建議 production cache 與實驗分支分開 tag,降低 metadata 競爭。退避:對 429、連線重設、暫時性 5xx,採 2/4/8 秒指數退避、最多 3 次;若連續命中 digest 衝突或 manifest invalid,應停重試改查權限與快取 repo 是否被清。併發層數經驗值:單 job 內不必硬撐過多 parallel pull;把「同機並行 build 數」壓在 ≤2 再觀察 registry 儀表板,通常比盲目加 CPU 更有效。
- DOCKER_CLIENT_TIMEOUT:180–300 秒作為跨境起點。
- df 可用空間:低於 15% 先清
docker builder prune/本機 cache 目錄再建置。 - 同機並行映像構建:預設 1–2;內網 registry 且監控無 429 再升到 3。
FAQ
Kaniko 的 --single-snapshot 會不會幫我省層反而害 cache?
它會改變層拆分方式,可能降低可重用層粒度;是否啟用應以「映像體積」與「快取命中」兩條 KPI 在固定 Runner 上做 A/B,而不是預設全開。
buildx 用 mode=max 會把什麼都塞進 cache tag 嗎?
mode=max 會輸出較多中間層 metadata,利於跨 stage 命中,但佔用 registry 配額與頻寬;若僅需 final stage 命中可評估較保守的 cache 策略並縮短保留天數。
rsync 預熱完仍整段 miss,第一個該查什麼?
先比對 docker buildx imagetools inspect/registry UI 中 base image digest 是否與 Dockerfile FROM 鎖定一致;再確認 COPY 來源檔時間戳是否在同步過程被批量改寫,必要時改為以內容雜湊命名 staging 目錄。
總結與購買引導:2026 年在 遠端 Mac CI 跑 Kaniko 或 buildx,決策核心是「rsync 預熱 是否穩定、registry layer cache 命名空間是否乾淨、同機併發 是否壓垮出口」。把上述閾值寫進 Runbook 後,建議在固定地域、固定 Apple Silicon 規格的租用上反覆壓測,再推廣到全團隊。下一步請瀏覽 定價方案 比較套餐,於 購買頁 下單租用遠端 Mac 作跨境構建節點;操作說明見 說明中心,產品總覽見 首頁;更多 CI 文請回 技術部落格列表。