Docker 執行時的使用者與組管理的方法

2022-02-22 13:08:27 字數 3903 閱讀 6533

docker 以程序為核心, 對系統資源進行隔離使用的管理工具. 隔離是通過 cgroups (control groups 程序控制組) 這個作業系統核心特性來實現的. 包括使用者的引數限制、 帳戶管理、 資源(cpu,記憶體,磁碟i/o,網路)使用的隔離等. docker 在執行時可以為容器內程序指定使用者和組. 沒有指定時預設是 root .但因為隔離的原因, 並不會因此喪失安全性. 傳統上, 特定的應用都以特定的使用者來執行, 在容器內程序指定執行程式的所屬使用者或組並不需要在 host 中事先建立.

程序控制組cgroups主要可能做以下幾件事:

與 cgroups(控制程序組) 相關聯的概念是 namespaces (命令空間).

命名空間主要有六種名稱隔離型別:

雖然新命名空間與其他同級物件隔離, 但其 "父 " 命名空間中的程序仍會看到子命名空間中的所有程序 (儘管具有不同的 pid 編號)。

普通使用者 docker run 容器內 root

如 busybox, 可以在 docker 容器中以 root 身份執行軟體. 但 docker 容器本身仍以普通使用者執行.

考慮這樣的情況

echo test | docker run -i busybox cat
前面的是當前使用者當前系統程序,後面的轉入容器內使用者和容器內程序執行.

當在容器內 pid 以1執行時, linux 會忽略訊號系統的預設行為, 程序收到 sigint 或 sigterm 訊號時不會退出, 除非你的程序為此編碼. 可以通過 dockerfile stopsignal signal指定停止訊號.

如:

stopsignal sigkill
建立乙個 dockerfile

from alpine:latest

run apk add --update htop && rm -rf /var/cache/apk/*

cmd ["htop"]

$ docker build -t myhtop . #構建映象

$ docker run -it --rm --pid=host myhtop #與 host 程序執行於同乙個命名空間

普通使用者 docker run 容器內指定不同使用者 demo_user

docker run --user=demo_user:group1 --group-add group2
這裡的 demo_user 和 group1(主組), group2(副組) 不是主機的使用者和組, 而是建立容器映象時建立的.

當dockerfile裡沒有通過user指令指定執行使用者時, 容器會以 root 使用者執行程序.

docker 指定使用者的方式

dockerfile 中指定使用者執行特定的命令

user [:] #或

user [:]

docker run -u(--user)[user:group] 或 --group-add 引數方式

$ docker run busybox cat /etc/passwd

root:x:0:0:root:/root:/bin/sh

...www-data:x:33:33:www-data:/var/www:/bin/false

nobody:x:65534:65534:nobody:/home:/bin/false

$ docker run --user www-data busybox id

uid=33(www-data) gid=33(www-data)

docker 容器內使用者的許可權

對比以下情況, host 中普通使用者建立的檔案, 到 docker 容器下對映成了 root 使用者屬主:

$ mkdir test && touch test/a.txt && cd test

$ docker run --rm -it -v `pwd`:/mnt -w /mnt busybox /bin/sh -c 'ls -al /mnt/*'

-rw-r--r-- 1 root root 0 oct 22 15:36 /mnt/a.txt

而在容器內卷目錄中建立的檔案, 則對應 host 當前執行 docker 的使用者:

$ docker run --rm -it -v `pwd`:/mnt -w /mnt busybox  /bin/sh -c 'touch b.txt'

$ ls -al

-rw-r--r-- 1 xwx staff 0 10 22 23:36 a.txt

-rw-r--r-- 1 xwx staff 0 10 22 23:54 b.txt

docker volume 檔案訪問許可權

建立和使用卷, docker 不支援相對路徑的掛載點, 多個容器可以同時使用同乙個卷.

$ docker volume create hello #建立卷

hello

$ docker run -it --rm -v hello:/world -w /world busybox /bin/sh -c 'touch /world/a.txt && ls -al' #容器內建個檔案

total 8

drwxr-xr-x 2 root root 4096 oct 22 16:38 .

drwxr-xr-x 1 root root 4096 oct 22 16:38 ..

-rw-r--r-- 1 root root 0 oct 22 16:38 a.txt

$ docker run -it --rm -v hello:/world -w /world busybox /bin/sh -c 'rm /world/a.txt && ls -al' #從容器內刪除

total 8

drwxr-xr-x 2 root root 4096 oct 22 16:38 .

drwxr-xr-x 1 root root 4096 oct 22 16:38 ..

外部建立檔案, 容器內指定使用者去刪除

$ touch c.txt && sudo chmod root:wheel c.txt

$ docker run -u 100 -it --rm -v `pwd`:/world -w /world busybox /bin/sh -c 'rm /world/c.txt && ls -al'

實際是可以刪除的

rm: remove '/world/c.txt'? y

total 4

drwxr-xr-x 4 100 root 128 oct 23 16:09 .

drwxr-xr-x 1 root root 4096 oct 23 16:09 ..

-rw-r--r-- 1 100 root 0 oct 22 15:36 a.txt

-rw-r--r-- 1 100 root 0 oct 22 15:54 b.txt

docker 普通使用者的1024以下埠許可權

$ docker run -u 100 -it --rm -p 70:80 busybox /bin/sh -c 'nc -l -p 80'

nc: bind: permission denied #使用者id 100 時, 不能開啟80埠

$ docker run -u 100 -it --rm -p 70:8800 busybox /bin/sh -c 'nc -l -p 8800' #容器埠大於1024時則可以

...$ docker run -it --rm -p 70:80 busybox /bin/sh -c 'nc -l -p 80' #容器內是 root 也可以

...

您可能感興趣的文章:

文章同步發布: 

Docker修改JDK執行時間

cpus 6 rm m 8192m v opt tomcat catalina.sh usr local tomcat bin catalina.sh v usr share zoneinfo asia shanghai etc localtime ro v etc timezone etc tim...

過程呼叫與執行時棧

過程是程式的一種抽象,以一組引數和返回值實現對乙個功能的封裝,過程包含的形式有 函式 方法 處理函式等 過程呼叫必須解決的三大機器級別問題 控制轉移 過程p呼叫過程q,進入過程q時,程式計數器設定為q的 起始位址,在q執行完成返回時,需要把程式計數器設定為p呼叫q位置的下一條指令位址。引數傳遞 p必...

java執行時異常和非執行時異常的區別

建議使用執行時異常和編譯時異常叫法,便於區分和理解 非執行時異常是什麼異常?很懵逼 編譯時異常 程式沒有通過編譯器的編譯,必須處理掉這個異常程式才能正常執行,比如檔案路徑找不到異常,類找不到異常,io異常,必須用try catch或是throwable處理掉才能編譯通過 可以理解為一種特殊的語法錯誤...