因為本人平常喜歡以用戶身份啟動容器,這樣宿主機上顯示的任務進程便是我的名稱而不是root用戶,但是我偶爾也需要在容器中使用root權限,而直接以普通用戶身份進去又沒有管理員權限,所以就查了很多資料,才整理出一個簡單的方法。
(在找的過程中有人是使用docker的namespace功能,我詳細了解了之后感覺並不能滿足我的需求,而且也比較麻煩)
更多docker使用小建議參見我的個人主頁 https://www.yolomax.com/lab/skills/docker/
以非root用戶啟動容器
-
為什么要用非root用戶啟動容器
默認情況下,容器中的進程以 root 用戶權限運行,並且這個 root 用戶和宿主機中的 root 是同一個用戶。所以大家直接啟動容器,並在容器內部跑程序時,你在宿主機上用top等命令查看進程時,以及用nvidia-smi查看顯卡使用時,顯示的都是root用戶在運行。
這樣會帶來幾個問題。1. 你在容器中寫的文件,保存的文件的擁有者並不是你,而是root用戶,當你的容器被銷毀后,你在宿主機上是沒有權限對這些文件進行操作的。2. 對於其他用戶來說,他人無法通過nvidia-smi查看顯卡是誰在使用,因為通過進程ID查到的是root用戶在跑程序。這不方便同學之間進行顯卡利用的溝通,也不方便管理員監管。當部分進程有問題時,管理員不知道找誰。
-
怎么以非root用戶啟動容器。
docker run --user $(id -u ${USER}):$(id -g ${USER}) <其他參數>
通過
--user $(id -u ${USER}):$(id -g ${USER})
的參數可以指定以當前宿主機用戶的身份啟動容器。–-user
是用來指定docker容器中用戶的id的,$(id -u ${USER}):$(id -g ${USER})
是自動解析id命令返回的uid和組id,這樣就不用自己去查詢id了。所以相比於之間大家使用docker,唯一的改變就是在啟動容器的時候加上
--user $(id -u ${USER}):$(id -g ${USER})
這一段話就可以了。 -
如何以非root身份啟動容器,但是能在容器中獲得root權限。
要實現這個功能,需要兩步,一步是修改dockerfile文件,另一步是在啟動容器時添加一段命令。
-
修改dockerfile
修改的目標是安裝sudo包和給某個你所在的組添加管理員權限。這樣你就能在容器中使用sudo獲得管理員權限。在介紹完修改命令后我會給出一個完整的dockerfile幫助大家理解。
1.1 第一段命令
apt-get update && apt-get install sudo
可見這一段話的意思是安裝sudo命令的,以方便你在獲得管理員權限后能通過sudo操作。當然,如果你的當前鏡像已經安裝了sudo命令,可以不執行這一段話。可以通過在基礎鏡像開啟的容器中執行sudo操作來試試自否有安裝sudo命令。
1.2. 第二段命令
cp /etc/sudoers /etc/sudoers.new && \ echo "%docker ALL=(ALL:ALL) ALL" >> /etc/sudoers.new && \ visudo -c -f /etc/sudoers.new && \ cp /etc/sudoers.new /etc/sudoers && \ rm /etc/sudoers.new
/etc/sudoers這個文件是管理sudo權限的,從名字就可以看出來。這一段命令的意思是給docker組內的所有成員添加管理員權限,如果你不是在docker組里,可以換成別的你在的組,將組名替換第二行的docker這個單詞就行了。
加上這兩段話后就可以構建鏡像並啟動容器了。
dockerfile的例子 : https://github.com/yolomax/docker/blob/pytorch1.7.0/pytorch
-
啟動容器時添加的命令
docker run --user $(id -u ${USER}):$(id -g ${USER}) -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro -v /etc/shadow:/etc/shadow:ro <其他參數>
這一段參數的意思是將宿主機上的用戶組以及密碼以只讀的形式全部掛在到容器中。
為什么要做這個映射呢。在第一部修改dockerfile時,我們已經給容器中的某個用戶組添加了管理員權限(比如我上面命令中的docker組)。但是直接啟動容器時是沒有組和用戶的信息的,所以你要把宿主機上的組合用戶的信息映射到容器中。
-
下面我講一個在容器中以管理員權限開啟ssh服務的例子
這樣我就可以在容器中開啟ssh服務,可以遠程登錄此容器,也可讓本機的pycharm通過ssh獲得容器中的python解釋器。
在容器中我可以執行
sudo /etc/init.d/ssh start
輸完命令后系統會讓你輸入密碼,因為我們已經將宿主機上的用戶和密碼都映射進來了,所以這里輸入的密碼就是你宿主機上的密碼
-