:::

Docker的rootless模式特別麻煩 / Take More Careful When You Running Docker in Rootless Mode

5月 08, 2023 , , 5 Comments Edit Copy Download

2023-0319-112709.png

host網路不能連?開啟與關閉指令不能用?gpu抓不到?那大概都是rootless的問題。


Docker的非root模式 / Rootless Mode of Docker

2023-0318-171512.png

https://docs.docker.com/engine/security/rootless/

我在Ubuntu環境中很多工具都已經轉換成Docker容器運作。如果要在Linux中用非root帳號運作,那必須用「rootless」模式來安裝Docker。

經過了複雜的安裝手續後,我們就能用非root帳號來執行docker。

操作 / Controll

用rootless模式操作Docker跟一般的模式有很大的差別。

一般模式下,重新啟動Docker服務的指令如下:

systemctl restart docker

但在rootless模式底下,千萬不能執行這個指令,不然會把原本的檔案權限弄壞。

在rootless底下要重新Docker服務,指令如下:

systemctl --user restart docker

所以看到其他Docker教學的時候,請務必注意到兩者的差別。

其他跟rootless模式相關的指令還有:

  • systemctl --user stop docker.service
  • systemctl --user stop docker
  • systemctl --user stop container
    在Rootless mode下關閉docker相關服務
  • systemctl --user start docker.service
  • systemctl --user start docker
    在Rootless mode下啟動docker相關服務

開啟啟動 / Auto startup

原本的設定是用root身份啟動Docker服務。在安裝了rootless模式後,通常它會改成用user的身份啟動。但還是有可能因為各種原因,導致你修改了設定,使得Docker服務又變回原本以root身份啟動的狀態。

此時我們要先關閉以root身份啟動的Docker服務:

sudo systemctl disable docker.service
sudo systemctl disable docker.socket

接著以rootless模式設定開機啟動Docker服務:

sudo systemctl --user enable docker.service

修復儲存空間的權限 / Change the owner of stroage drive

如果在rootless模式下改用root啟動了Docker,系統會將原本屬於user權限的Docker儲存空間,擁有者改為root權限。這導致後來使用rootless模式啟動Docker的失敗。

最簡單的方法就是修改相關目錄的擁有者權限,把它改回現在的擁有者:

sudo chown $USER:$USER /var/lib/docker/
sudo chown $USER:$USER /var/lib/docker/*

除了Docker最外層的目錄外,還有Docker內層的目錄需要修改。

設定 / Configuration

https://www.facebook.com/blog.pulipuli.info/posts/pfbid02FudDtkeBK8NkzLi1wsiqbp5jHbB8vY8Xu6VThLAX3A8Cf1DA4BSm2PH6SmHwcHuml 

這個問題我在之前Facebook也有提到過。不過Facebook的文章真的很難找,還是寫在Blog的好。

預設情況下,Docker的設定檔位置在下面路徑:

/etc/docker/daemon.json

在rootless模式下,設定檔路徑就是在使用者自己的家目錄底下了:

~/.config/docker/daemon.json

如果要修改Docker儲存資料的路徑,則需要在設定檔裡進行修改。我的修改內容如下,僅供參考:

{
    "data-root": "/mnt/microsd/ext4/docker/"
}

限制 / Limitation

儘管如此,rootless模式本身就帶有很多限制。根據Docker的安裝說明,rootless的限制包括了:

  • 僅能使用部分儲存裝置類型,包括overlay2、fuse-overlayfs、btrfs、vfs。現在Docker預設是使用overlay2,所以不太算是問題。
  • Cgroup只有在cgroup v2跟systemd模式下可以使用。這是一種隔離處理程序(process)的工具,細節請參考「第一千零一篇的 cgroups 介紹」。
  • 不支援以下功能:AppArmor、Checkpoint、Overlay network、暴露SCTP連結埠。不能用AppArmor影響很大,這樣就不能用snaps底下的工具了。
  • 很多發行版預設不能使用ping,除非加上特別設定。詳細請看Routing ping packets說明。
  • 預設不能暴露低於1024的TCP或UDP連結埠,除非加上特別設定。詳情請看Exposing privileged ports這個限制影響了很多用來架站的Docker,需要特別注意。
  • 在「docker inspect」的IPAddress其實是RootlessKit網路名稱空間下的名稱空間。這意思是此時容器的IPAddress所在的網路名稱空間無法讓其他人直接連線,除非使用nsenter進入RootlessKit的網路名稱空間。
  • 網路模式(network_mode)用host的時候,實際上沒辦法讓其他人連線。
  • 同樣道理,Host網路模式(docker run --net=host)無法直接連線。
  • NFS掛載作為Docker的「data-root」無法使用。不過這點並不限於rootless模式。

Nvidia顯示卡的rootless模式 / Rootless Containers Setup

如果要在rootless模式中運作需要Nvidia顯示卡資源的Docker,一樣有額外的安裝手續。

https://ttyusb0978.medium.com/nvidia-container-runtime-%E5%AE%89%E8%A3%9D-b5df27020762 

如果要讓Docker使用Nvidia顯示卡的資源,需要安裝nvidia-container-runtime。安裝方法如下:

curl -s -L https://nvidia.github.io/nvidia-container-runtime/gpgkey | \
  sudo apt-key add -
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-container-runtime/$distribution/nvidia-container-runtime.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-container-runtime.list
sudo apt-get update
sudo apt-get install nvidia-container-runtime -y

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#step-3-rootless-containers-setup

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#step-3-rootless-containers-setup

如果是在rootless模式中,直接使用需要GPU資源的Docker,會出現錯誤訊息:

nvidia-container-cli: mount error: failed to add device rules: unable to find any existing device filters attached to the cgroup: bpf_prog_query(BPF_CGROUP_DEVICE) failed: operation not permitted: unknown

請根據Nvidia的說明加上額外設定:

sudo sed -i 's/^#no-cgroups = false/no-cgroups = true/;' /etc/nvidia-container-runtime/config.toml

這樣才能正常執行。


你用rootless模式的時候還遇到什麼問題嗎?

歡迎在下面一起討論喔。

總共5 則留言 ( 我要發問 , 隱藏留言 顯示留言 )

  1. 你好: 剛好在逛網頁的時候逛到您的網誌

    覺得學習的部分相當重疊,不過我還滿菜的

    希望有機會可以一同討論交流,目前我的docker 都還是使用預設的root場景

    想請教 rootless 除了較安全之外,會有其他的特殊用途嗎?

    謝謝

    回覆刪除
    回覆
    1. 忘記登入了,補一下留言

      刪除
    2. To Jason,

      rootless主要是不用再額外輸入密碼。

      我使用Docker的場景跟很多人不太一樣。
      你知道的情況,大多都是在伺服器的終端機介面來啟動Docker。
      但我自己大多時候都是跟GUI結合。

      https://blogger.googleusercontent.com/img/a/AVvXsEhKUruhiAbTTzD__XBpZ26frdn_to8o6az05izqp61-xNQ9SZL77KdicCVJDUYFWTLz6P4T-aFqUqqGmHYu5zGS2eOxS3Zg1Kpt_0lSZujuUEdWPmT9SX0aDF0_qP_2bXLhQjOSdlSKasS8j6I96Ag9unUSBFBWtH5yfNGp4S9e3rzmIRYwfZU
      上圖是在Linux KDE中使用Dolphin按右鍵處理圖片的操作,其中「image trim」和部分工具,其實都是啟動Docker來處理圖片。
      這類型的工具我叫它Docker APP。

      如果你沒有桌面端的使用需求,單純只是在伺服器運作;
      或著是你是在Windows環境下安裝Docker Desktop;
      這些情況你都可以不用設定rootless。
      設了也是自找麻煩而已。



      刪除
    3. 好奇有什麼有趣的這種 docker app

      刪除
    4. To 2qbx,

      https://github.com/pulipulichen?tab=repositories&q=docker-app&type=&language=&sort=

      我自己做的都放在Docker上
      不過目前主要都是給Linux環境使用而已
      Windows還是會有點問題

      刪除