首頁 > 後端開發 > C++ > 主體

使用 docker_userid_fixer 修復 docker 容器中的使用者 ID 的優雅方法

王林
發布: 2024-08-15 18:42:02
原創
619 人瀏覽過

an elegant way to fix user IDs in docker containers using docker_userid_fixer

這是關於什麼的?

這是一個使用 docker 容器與 docker 主機互動的相當技術性的問題,通常與使用容器內的主機檔案系統有關。
這種情況尤其發生在可重複的研究背景下。
我開發了一個開源實用程式來幫助解決這個問題。

docker 容器作為執行環境

docker 容器的初始和主要用例:一個獨立的應用程序,僅透過某些網路連接埠與主機系統互動。
考慮一個 Web 應用程式:docker 容器通常包含一個 Web 伺服器和一個 Web 應用程序,例如在連接埠 80(容器內部)上運行。然後,透過將容器內部連接埠 80 綁定到主機連接埠(例如 8000),容器在主機上執行。
那麼容器化應用程式和主機系統之間的唯一互動就是透過這個綁定的網路連接埠。

容器作為執行環境是完全不同的:

  • 容器化的不是應用程序,而是應用程式建置系統
    • 它可以是編譯器、IDE、筆記型引擎、Quarto 發布系統...
  • 目標是:
    • 擁有標準、易於安裝和共享的環境
      • 想像一個複雜的建置環境,其中包含固定版本的 R、Python 和無數的外部套件。 安裝正確版本的所有內容可能是一項非常困難且耗時的任務。 透過共用包含已安裝和預先配置的所有內容的 docker 映像,可以真正節省時間。
    • 擁有一個可重現的環境
      • 透過使用它,您可以重現一些分析結果,因為您使用的是完全相同的受控環境
      • 您也可以輕鬆重現錯誤,這是修復錯誤的第一步

但是,為了使用這些執行環境,這些容器必須有權利存取主機系統,特別是主機使用者檔案系統。

docker 容器和主機檔案系統

假設您已經容器化了一個 IDE,例如工作室。
您的 Rstudio 安裝並在 docker 容器內運行,但它需要讀取和編輯專案資料夾中的檔案。

為此,您使用 docker run --volume 選項綁定掛載
您的專案資料夾(在主機檔案系統中)。

然後您的檔案就可以從 docker 容器中存取。

現在的挑戰是檔案權限。假設您的主機使用者的使用者 ID 1001,並假設在容器中擁有 Rsudio 進程的使用者是 0(root)或 1002

如果容器使用者是root
,那麼它在讀取你的檔案時不會有任何問題。 但是,一旦您編輯一些現有文件,生成新文件(例如 pdf、html),這些文件將屬於主機文件系統上的根
.

這意味著您的本機主機使用者將無法使用它們或刪除它們,因為它們屬於 root。

現在,如果容器使用者 ID 為 1002
,Rstudio 可能無法讀取您的檔案、編輯它們或產生新檔案。

即使可以,透過設定一些非常寬鬆的權限,您的本機主機用戶可能無法使用它們。

當然,解決該問題的一種強力方法是在主機上和 docker 容器中都以 root 身份運行。這並不總是可行,並且會引發一些明顯的關鍵安全問題。

解決檔案擁有者問題第 1 部分:docker run --user 選項

因為我們無法事先知道主機的使用者ID(這裡1001
),所以我們無法預先設定

docker 容器使用者的 userid。

docker run 現在提供了一個 --user 選項,可以使用提供的用戶 ID 建立一個

用戶 在運行時。例如, docker run --user 1001 ... 將建立一個運行進程的 docker 容器 屬於用戶 ID 1001

.

的用戶

那我們還在討論這個問題什麼呢?沒解決嗎?

這裡有一些關於動態創建的用戶的怪癖:
  • 這是一個偽用戶
  • 它沒有主目錄 (/home/xxx)
  • 它沒有出現在/etc/passwd中
  • 它無法預先配置,例如使用 bash 設定檔、一些環境變數、應用程式預設值等...

我們可以解決這些問題,但這可能會很乏味且令人沮喪。
我們真正想要的是預先配置一個 docker 容器用戶,並且能夠在 runtime... 動態更改他的 userid

解決檔案擁有者問題第2部分:輸入docker_userid_fixer

docker_userid_fixer 是一個開源實用程序,旨在用作 docker 入口點 來修復我剛剛提出的用戶 ID 問題。

讓我們看看如何使用它:將其設定為 docker ENTRYPOINT,指定應使用哪個使用者並動態修改他的 userid

ENTRYPOINT ["/usr/local/bin/docker_userid_fixer","user1"]
登入後複製

讓我們準確地說:

  • 目標用戶,是向docker_userid_fixer請求的用戶,這裡是user1
  • 請求的用戶,是由docker run配置的用戶,即(最初)擁有第一個進程(PID 1)的用戶

然後,在容器運行時建立時,有兩個選項:

  • 請求的用戶ID(已經)與目標用戶ID匹配,則無需更改
  • 或沒有。例如,請求的用戶ID是1001目標用戶ID是100。 然後,docker_userid_fixer 會直接在容器主進程中將 target 使用者 user1 的 userid 從 1000 修正為 1001。

所以在實務上這解決了我們的問題:

  • 如果您不需要修復容器使用者ID,只需使用通常的方式執行 docker run (不含 --user 選項)
  • 或您使用--user 選項,那麼除了使用您要求的使用者ID 執行主進程之外,它還會將您的預先設定使用者修改為您要求的使用者ID,以便您的容器以您的預期用戶和預期運行用戶ID。

docker_userid_fixer 設定

您可以在此處找到有關設定的說明。

但歸結為:

  • 建置或下載小型執行檔 (17k)

  • 將其複製到您的 Docker 映像中

  • 使其作為 setuid root 可執行

  • 將其配置為您的入口點

血淋淋的細節

我寫了一些簡短的註解 https://github.com/kforner/docker_userid_fixer#how-it-works
但我會嘗試改寫。

實作的關鍵是容器中 docker_userid_fixer 執行檔的 setuid root
我們需要 root 權限來更改 userid,而此 setuid 只能為
啟用特權執行 docker_userid_fixerprogram,並且持續很短的時間。

一旦需要修改userid,docker_userid_fixer就會切換主程序
發送給請求的用戶(和用戶 ID!)。

如果您對這些主題(docker、可重複研究、R 套件開發、演算法、效能最佳化、並行性...)感興趣,請隨時與我聯繫,討論工作和商業機會。

以上是使用 docker_userid_fixer 修復 docker 容器中的使用者 ID 的優雅方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!