問題起源
問題起源於一個開發BUG:正常運行一段時間的POD,突然有一天運行報錯了,錯誤是沒有操作目錄的權限,查其原因,原來是鏡像被更新了,鏡像添加了操作用戶,而被操作的目錄(NFS目錄)並不具備普通用戶操作的權限。
DOCKER容器如何控制用戶
容器的操作用戶其實是鏡像控制的,打造鏡像的時候有一個USER選項,運行USER [uid:gid] 就可以指定用什么用戶來運行該鏡像,這方面知識可以查看一下DOCKFILE編寫語法。如果沒有添加該語句,鏡像默認使用root權限運行,而添加了該語句,DOCKFILE后面的命令就使用該用戶權限運行。那么問題就來了,鏡像里面的用戶跟操作系統有什么關系,或者說,跟NFS目錄權限有什么關系?
DOCKER-LINUX的用戶映射
在這個BUG的基礎上做個簡單的測試,當文件系統某個目錄只能允許ROOT操作的時候,啟動一個運行用戶為ROOT的容器,使他來操作該目錄,結果是成功的。
這時候可以推理出,DOCKER中的運行用戶與文件系統用戶是存在某種關聯的。這大概也是安裝DOCKER需要使用ROOT用戶或者ROOT組權限的原因之一,因為需要修改一些用戶映射配置。
拜讀了一下這篇文章,可以對這些用戶管理有一個清晰的認識:
https://medium.com/@mccode/understanding-how-uid-and-gid-work-in-docker-containers-c37a01d01cf
作者通過例子驗證得到了幾個結論:
1.linux主機通過uid和gid來控制用戶對目錄的操作權限,docker容器中也是如此。
2.當docker容器中的操作用戶為root時,他相當於宿主機上的root
3.當docker容器中的操作用戶為非root時,根據其uid在宿主機上的權限限制獲取對應權限
第三個結論是這么說的:
限制容器的使用權限會同時對主機的用戶系統產生影響 1.如果使用已知的uid運行容器,那他可以直接獲取該uid在宿主機上的權限來限制容器 2.最好使用已知的uid去啟動容器(使用用戶名也可以,但是這只是友好的方式,其本質還是提供uid),這樣去限制容器權限 3.由於uid和gid以及用戶名的的映射關系,容器內的進程在容器外看起來像是屬於不同用戶
看完這些之后又看到有一篇文章說可以修改docker和宿主機之間的映射規則,改變運行用戶的權限,雖然用處不大,但是可以蠻了解下:
https://blog.csdn.net/lsysafe/article/details/90437811
其操作系統為Ubuntu,所以我沒有跟着驗證:
編輯/etc/default/docker,添加: DOCKER_OPTS="--userns-remap=default" 或 DOCKER_OPTS="--userns-remap=自定義的用戶名" 此時會在/etc/subuid和/etc/subgid添加用戶的映射ID system@system-virtual-machine:~$ cat /etc/subuid /etc/subgid system:100000:65536 dockremap:165536:65536 apps:231072:65536 system:100000:65536 dockremap:165536:65536 apps:231072:65536 如dockremap這一行表示,從操作系統UID為165536用戶開始直到UID為165536+65536映射容器的UID0至65535,0為容器的ROOT用戶,/etc/default/docker文件這一行DOCKER_OPTS="--userns-remap=default"指定了引用 /etc/subuid,/etc/subgid文件的哪個用戶,用戶組,default一般指dockremap
另一個bug
容器內指定的用戶在宿主機上不存在也是不影響運行的,但是會引起另一個問題:
當該容器第一次運行時使用了一些操作對目錄增刪改之后,如果該容器(注意是pod,如果僅僅是容器重啟不一定有這個問題)被重啟,那么該容器會運行報錯拒絕訪問。
原因在於,第一個POD的運行用戶為某個“野雞”用戶,當再一次運行該POD時,雖然其UID和第一次運行的一樣,但是對於宿主機來說,其又是另一個“野雞”用戶,操作失敗。