跳轉到

Docker K8s Init Script Permission Inheritance

概念概覽

根因模式

核心知識

根因模式

當 Kubernetes container 的 init script(如 init-all.sh)以 root 身份執行並觸發應用程式框架(PHP Monolog、Python logging 等),框架自動建立的目錄(如 logs/batch/<date>/)會繼承 root:root owner。等到 runtime user(www-data, uid 1000)要寫入時,就會爆出 Permission denied。

關鍵觀察:Dockerfile 預建目錄並 chown 只能保護目錄本身,無法阻止 init script 執行後 Monolog 在子目錄下建出的 root:root 日期子目錄。Phase 2 kubectl exec 輸出直接佐證此點。

雙層修正(缺一不可)

Layer 1 — Dockerfile:
RUN mkdir -p /var/www/html/app/logs/batch \
    && chown -R 1000:1000 /var/www/html/app/logs

Layer 2 — Jenkins Pipeline(init-all.sh exec 之後):
kubectl exec $POD -- chown -R 1000:1000 /var/www/html/app/logs
  • Layer 1 確保 image 內目錄初始 owner 正確
  • Layer 2 修正 init script 執行後被 Monolog 建出的 root:root 子目錄
  • 若 Layer 2 受 restartServer=true 參數控制,執行 pipeline 時須確認此參數已啟用

診斷驗證方法

  1. 排除 EFS 持久化假說kubectl describe pod 確認 volumeMounts 中是否有 EFS/PVC,若無則 rebuild 必然生效
  2. 確認根因:手動刪除 root:root 的日期目錄後觀察 cron 重建的 owner——若 cron(www-data)自行建出的目錄 owner 正確,即確認問題只在 init script 觸發 Monolog 的那一刻
  3. 嚴禁:不要使用 chmod -R 777 作為永久解,違反最小權限原則

經驗教訓

  • init script 以 privileged user 執行並觸發應用程式框架,框架自動建立的目錄繼承了 root owner,是 Docker + K8s 環境中的隱藏地雷

  • 雙層修正(Dockerfile + Pipeline chown)缺一不可,Phase 2 kubectl 輸出是最有力的佐證

  • 懷疑 rebuild 沒用時,優先用 volumeMount 確認是否有 EFS/PVC 持久化,可快速排除假說

  • 此模式可套用到所有「init 由 root 執行、runtime 由非 root 執行」的 PHP/Python/Node.js 容器場景

常見陷阱

  • Dockerfile 預建目錄 + chown 只保護目錄本身,無法保護 init script 執行後 framework 自動建立的子目錄

  • chmod 777 是錯誤的永久解,只適合緊急救火

  • Layer 2 chown 若綁定在受參數控制的 stage(restartServer=true),忘記勾選參數會導致修正不生效

  • 同版號 ECR image tag 不會自動覆蓋,Dockerfile 修改後必須遞增版號才能讓 deploy 拿到新 image

最佳實踐

  • Dockerfile 中預建所有 runtime 需要寫入的目錄並 chown 給 runtime user(uid)

  • Jenkins pipeline 在執行 init script 後補 chown,作為第二層防護

  • 建議在 init-all.sh 末尾自行補 chown,使邏輯自包含,避免只能靠 pipeline 補救

  • 使用 chown 1000:1000 而非 chmod 777,遵循最小權限原則

相關概念

來源 Sessions

日期 Session 貢獻摘要

| 2026-04-10 | 2915f12c-2e40-49a6-9734-a50edf42bc3a | 揭示 init script 以 root 執行並觸發 PHP framework(Monolog)時,自動建立的子目錄繼承 root:root owner 導致 runtime user 無法寫入的根因,並驗證雙層修正的必要性 |


本概念頁面由 Semi-Brain Wiki 系統自動維護

最後更新: 2026-04-10