docker容器如何獲取host外設數據


1.查看設備號

Linux的設備管理是和文件系統緊密結合的,把設備和文件關聯起來,這樣系統調用可以直接用操作文件一樣的方法來操作設備。各種設備都以文件的形式存放在/dev目錄下,稱為設備文件。應用程序可以打開、關閉和讀寫這些設備文件,完成對設備的操作,就像操作普通的數據文件一樣。為了管理這些設備,系統為設備編了號,每個設備號又分為主設備號和次設備號。主設備號用來區分不同種類的設備,而次設備號用來區分同一類型的多個設備。對於常用設備,Linux有約定俗成的編號,如硬盤的主設備號是3。

查看主設備號
:  cat /proc/devices
查看當前設備的主次設備號
: ls -l /dev

2. devices cgroup說明
d evices cgroup用於控制分組對設備的使用權限——包括read,write和mknod權限。
查看cgroup下的devices.list文件可以獲取當前分組的設備權限
$ cat devices.list
c 1:5 rwm
b *:* m
其每一行的格式為:type(設備類型) major:minor access(訪問權限)。

設備類型有三種:  
a 表示所有設備,包括字符設備和塊設備。
b 表示塊設備。
c 表示字符設備。
major:minor在blkio中已介紹過,在這里可以使用*作為通配符表示所有的編號,例如*:*表示所有設備號。

訪問權限是一個字符串,包含一個或多個代表不同權限的字母
r 讀權限。
w 寫權限。
m 創建設備文件的權限。

除去一些特殊虛擬設備,docker默認禁止容器訪問主機的任何設備。可以通過--devices參數為容器添加設備權限,或者使用--privileged參數開啟 privileged模式,使用--privileged參數啟動的容器會獲得主機所有設備的所有權限
參考:
https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
$ container_id=$(docker run -d --privileged nginx)
$ cat /sys/fs/cgroup/devices/docker/$container_id/devices.list
a *:* rwm <--- 所有設備的所有權限

by default, most potentially dangerous kernel capabilities are dropped; including cap_sys_admin (which is required to mount filesystems). However, the --privileged flag will allow it to run:

$ docker run -t -i --privileged ubuntu bash root@50e3f57e16e6:/# mount -t tmpfs none /mnt root@50e3f57e16e6:/# df -h Filesystem Size Used Avail Use% Mounted on none 1.9G 0 1.9G 0% /mnt 

The --privileged flag gives all capabilities to the container, and it also lifts all the limitations enforced by the device cgroup controller. In other words, the container can then do almost everything that the host can do. This flag exists to allow special use-cases, like running Docker within Docker.


3.--device解釋

Runtime privilege, Linux capabilities, and LXC configuration

--cap-add: Add Linux capabilities --cap-drop: Drop Linux capabilities --privileged=false: Give extended privileges to this container --device=[]: Allows you to run devices inside the container without the --privileged flag. --lxc-conf=[]: (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"

  默認情況下,Docker的container是沒有特權的。例如不能再container里面再啟動一個container。這是因為默認情況下container是不能訪問任何其他設備的。但是通過"privileged",container就擁有了訪問任何其他設備的權限。

  當操作者執行docker run --privileged時,Docker將擁有訪問host所有設備的權限,同時Docker也會在apparmor或者selinux做一些設置,使container可以容易的訪問那些運行在container外部的設備。你可以訪問Docker blog來獲取更多關於--privileged的用法。

  同時,你也可以限制container只能訪問一些指定的設備。下面的命令將允許container只訪問一些特定設備:

 $ sudo docker run --device=/dev/snd:/dev/snd ...

  默認情況下,container擁有對設備的讀,寫,創建設備文件的權限。使用:rwm來配合--device,你可以控制這些權限。


 $ sudo docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk /dev/xvdc  $ sudo docker run --device=/dev/sda:/dev/xvdc:r --rm -it ubuntu fdisk /dev/xvdc You will not be able to write the partition table. $ sudo docker run --device=/dev/sda:/dev/xvdc:w --rm -it ubuntu fdisk /dev/xvdc crash.... $ sudo docker run --device=/dev/sda:/dev/xvdc:m --rm -it ubuntu fdisk /dev/xvdc fdisk: unable to open /dev/xvdc: Operation not permitted

 

  使用--cap-add和--cap-drop,配合--privileged,你可以更細致的控制container。默認使用這兩個參數的情況下,container擁有一系列的內核修改權限。


這兩個參數都支持all值,如果你想讓某個container擁有除了MKNOD之外的所有內核權限,那么可以執行下面的命令:

 $ sudo docker run --cap-add=ALL --cap-drop=MKNOD ...

  

如果需要修改網絡接口數據,那么就建議使用--cap-add=NET_ADMIN,而不是使用--privileged。

$ docker run -t -i --rm ubuntu:14.04 ip link add dummy0 type dummy RTNETLINK answers: Operation not permitted $ docker run -t -i --rm --cap-add=NET_ADMIN ubuntu:14.04 ip link add dummy0 type dummy

  

如果要掛載一個FUSE文件系統,那么就需要--cap-add和--device了。


$ docker run --rm -it --cap-add SYS_ADMIN sshfs sshfs sven@10.10.10.20:/home/sven /mnt fuse: failed to open /dev/fuse: Operation not permitted
 $ docker run --rm -it --device /dev/fuse sshfs sshfs sven@10.10.10.20:/home/sven /mnt fusermount: mount failed: Operation not permitted
 $ docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs

成功運行進入到容器內部 # sshfs sven@10.10.10.20:/home/sven /mnt The authenticity of host '10.10.10.20 (10.10.10.20)' can't be established. ECDSA key fingerprint is 25:34:85:75:25:b0:17:46:05:19:04:93:b5:dd:5f:c6. Are you sure you want to continue connecting (yes/no)? yes sven@10.10.10.20's password: root@30aa0cfaf1b5:/# ls -la /mnt/src/docker total 1516 drwxrwxr-x 1 1000 1000 4096 Dec 4 06:08 . drwxrwxr-x 1 1000 1000 4096 Dec 4 11:46 .. -rw-rw-r-- 1 1000 1000 16 Oct 8 00:09 .dockerignore -rwxrwxr-x 1 1000 1000 464 Oct 8 00:09 .drone.yml drwxrwxr-x 1 1000 1000 4096 Dec 4 06:11 .git -rw-rw-r-- 1 1000 1000 461 Dec 4 06:08 .gitignore
復制代碼

4.linux權能
1,基本概念
傳統UNIX的訪問控制模型非常簡單,就是“超級用戶對普通用戶”模型。在這種模型中,一個進程或帳戶要么什么都能做即具有全部的系統權限,要么幾乎什么也不能做即只有很小的權限,這取決於進程的UID。例如,如果一個進程需要加載/卸載內核模塊以及管理文件系統等操作時,就需要完全的root權限。很顯然這樣做對系統安全存在很大的威脅。
2,進程權能
Linux是如何使用POSIX capabilities代替傳統的信任狀模型的?每個進程有三個和能力有關的位圖:inheritable(I)、permitted(P)和effective(E),對應進程描述符 task_struct(include/linux/sched.h)里面的cap_effective, cap_inheritable, cap_permitted。每種能力由一位表示,1表示具有某種能力,0表示沒有。
 cap_effective。當一個進程要進行某個特權操作時,操作系統會檢查 cap_effective的對應位是否有效,而不再是檢查進程的有效UID是否為0。例如,如果一個進程要設置統的時鍾,Linux的內核就會檢查 cap_effective的CAP_SYS_TIME位(第25位)是否有效,
 cap_permitted表示進程能夠使用的能力。在cap_permitted中可以包含cap_effective中沒有的能力,這些能力是被進程自己臨時放棄的,也可以說cap_effective是cap_permitted的一個子集。進程放棄沒有必要的能力對於提高安全性大有助益。例如,ping只需要CAP_NET_RAW,如果它放棄除這個能力之外的其它能力,即使存在安全缺陷,也不會對系統造成太大的損害。
 cap_inheritable表示能夠被當前進程執行的程序繼承的能力。
能力 編號 解釋
CAP_CHOWN 0 允許改變文件的所有權
CAP_DAC_OVERRIDE 1 忽略對文件的所有DAC訪問限制
CAP_DAC_READ_SEARCH 2 忽略所有對讀、搜索操作的限制
CAP_FOWNER 3 如果文件屬於進程的UID,就取消對文件的限制
CAP_FSETID 4 允許設置setuid位
CAP_KILL 5 允許對不屬於自己的進程發送信號
CAP_SETGID 6 允許改變組ID
CAP_SETUID 7 允許改變用戶ID
CAP_SETPCAP 8 8 允許向其它進程轉移能力以及刪除其它進程的任意能力
CAP_LINUX_IMMUTABLE 9 允許修改文件的不可修改(IMMUTABLE)和只添加(APPEND-ONLY)屬性
CAP_NET_BIND_SERVICE 10 允許綁定到小於1024的端口
CAP_NET_BROADCAST 11 允許網絡廣播和多播訪問
CAP_NET_ADMIN 12 允許執行網絡管理任務:接口、防火牆和路由等,詳情請參考/usr/src/linux/include/linux/capability.h文件
CAP_NET_RAW 13 允許使用原始(raw)套接字
CAP_IPC_LOCK 14 允許鎖定共享內存片段
CAP_IPC_OWNER 15 忽略IPC所有權檢查
CAP_SYS_MODULE 16 插入和刪除內核模塊
CAP_SYS_RAWIO 17 允許對ioperm/iopl的訪問 
CAP_SYS_CHROOT 18 允許使用chroot()系統調用
CAP_SYS_PTRACE 19 允許跟蹤任何進程
CAP_SYS_PACCT 20 允許配置進程記帳(process accounting)
CAP_SYS_ADMIN 21 允許執行系統管理任務:加載/卸載文件系統、設置磁盤配額、開/關交換設備和文件等。詳情請參考/usr/src/linux/include/linux/capability.h文件。
CAP_SYS_BOOT 22 允許重新啟動系統
CAP_SYS_NICE 23 允許提升優先級,設置其它進程的優先級//
CAP_SYS_RESOURCE 24 忽略資源限制
CAP_SYS_TIME 25 允許改變系統時鍾
CAP_SYS_TTY_CONFIG 26 允許配置TTY設備
CAP_MKNOD 27 允許使用mknod()系統調用
CAP_LEASE 28 Allow taking of leases on files

5.使用主機網絡棧
 host  網絡實際上和宿主機共享了同一  Network Namespace。

6.實例

需要在docker里面獲取usb的狀態和數據

使用如下命令:

docker run --rm --device /dev/snd:/dev/snd:rwm --device-cgroup-rule="c 189:*rwm" 

--cap-add=SYS_ADMIN -v /dev:/dev --network=host -it <img id> /bin/bash

參數--device-cgroup-rule,可以添加你需要的規則 比如'c 13:* rwm' 這里的13是設備的major number, 那么在容器里面通過udev的規則執行添加/刪除設備的腳本比如mknod/rm, 就可以實現動態添加和刪除設備的功能啦。
       



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM