Docker 的安全优化Docker容器的安全性很大程度上依赖于Linux系统自身评估Docker的安全性时主要考虑以下几个方面Linux内核的命名空间机制提供的容器隔离安全Linux控制组机制对容器资源的控制能力安全。Linux内核的能力机制所带来的操作权限安全Docker程序特别是服务端本身的抗攻击性。其他安全增强机制对容器安全性的影响#在rhel9中默认使用cgroup-v2 但是cgroup-v2中不利于观察docker的资源限制情况所以推荐使用cgroup-v1 [rootdocker-node1 ~]# grubby --update-kernel/boot/vmlinuz-$(uname -r) \ --argssystemd.unified_cgroup_hierarchy0 systemd.legacy_systemd_cgroup_controller1 命名空间隔离的安全当docker run启动一个容器时Docker将在后台为容器创建一个独立的命名空间。命名空间提供了最基础也最直接的隔离。与虚拟机方式相比通过Linux namespace来实现的隔离不是那么彻底。容器只是运行在宿主机上的一种特殊的进程那么多个容器之间使用的就还是同一个宿主机的操作系统内核。在 Linux 内核中有很多资源和对象是不能被 Namespace 化的比如磁盘等等[rootdocker-node1 ~]# docker run -d --name web nginx 3c6b649a200fc56afafe9f47494903fe56e71cabcd534d6c9e6f8b5854f29cac [rootdocker ~]# docker inspect web | grep Pid Pid: 4328, PidMode: , PidsLimit: null, [rootdocker-node1 ~]# cd /proc/4328/ns/ #进程的namespace [rootdocker-node1 ns]# ls cgroup ipc mnt net pid pid_for_children time time_for_children user uts [rootdocker-node1 ns]# ls -d /sys/fs/cgroup/memory/docker/3c6b649a200fs省略部分854f29cac/ #资源隔离信息 /sys/fs/cgroup/system.slice/docker-ecb8abbbfc85bf3d62fc82afb3950ab6b6a2e80092738274a233bbb8db0c5ce2.scope /sys/fs/cgroup/system.slice/docker.service /sys/fs/cgroup/system.slice/docker.socket2 控制组资源控制的安全当docker run启动一个容器时Docker将在后台为容器创建一个独立的控制组策略集合。Linux Cgroups提供了很多有用的特性确保各容器可以公平地分享主机的内存、CPU、磁盘IO等资源。确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器它在防止拒绝服务攻击DDoS方面必不可少[rootdocker-node1 ~]# docker run -it --name test busybox #内存资源默认没有被隔离 / # free -m total used free shared buff/cache available Mem: 3627 648 516 16 2463 2678 Swap: 2063 1 2062 / # exit [rootdocker-node1 ~]# free -m total used free shared buff/cache available Mem: 3627 907 557 15 2463 2719 Swap: 2062 1 20613 内核能力机制能力机制Capability是Linux内核一个强大的特性可以提供细粒度的权限访问控制。大部分情况下容器并不需要“真正的”root权限容器只需要少数的能力即可。默认情况下Docker采用“白名单”机制禁用“必需功能”之外的其他权限。4 Docker服务端防护使用Docker容器的核心是Docker服务端确保只有可信的用户才能访问到Docker服务。将容器的root用户映射到本地主机上的非root用户减轻容器和主机之间因权限提升而引起的安全问题。允许Docker 服务端在非root权限下运行利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程只允许在特定范围内进行操作。[rootdocker-node1 ~]# ls -ld /var/lib/docker/ #默认docker是用root用户控制资源的 drwx--x--- 12 root root 171 8月 20 13:21 /var/lib/docker/Docker的资源限制Linux Cgroups 的全称是 Linux Control Group。是限制一个进程组能够使用的资源上限包括 CPU、内存、磁盘、网络带宽等等。对进程进行优先级设置、审计以及将进程挂起和恢复等操作。Linux Cgroups 给用户暴露出来的操作接口是文件系统它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。执行此命令查看mount -t cgroup[rootdocker-node1 ~]# mount -t cgroup #在rhel9中默认使用cgroup2 cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent/usr/lib/systemd/systemd-cgroups-agent,namesystemd) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio) cgroup on /sys/fs/cgroup/misc type cgroup (rw,nosuid,nodev,noexec,relatime,misc) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) 在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录也叫子系统。在每个子系统下面为每个容器创建一个控制组即创建一个新目录。控制组下面的资源文件里填上什么值就靠用户执行 docker run 时的参数指定。限制cpu使用1.限制cpu的使用量[rootdocker-node1 ~]# docker run -it --rm --name test \ --cpu-period 100000 \ #设置 CPU 周期的长度单位为微秒通常为 100000即 100 毫秒 --cpu-quota 20000 ubuntu #设置容器在一个周期内可以使用的 CPU 时间单位也是微秒。 root5797d76b20f5:/# dd if/dev/zero of/dev/null [1] 8 root5797d76b20f5:/# top top - 11:53:22 up 1 day, 1:58, 0 user, load average: 0.00, 0.00, 0.00 Tasks: 3 total, 2 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 4.4 us, 6.0 sy, 0.0 ni, 89.5 id, 0.0 wa, 0.2 hi, 0.0 si, 0.0 st MiB Mem : 3627.1 total, 558.1 free, 899.4 used, 2471.0 buff/cache MiB Swap: 2063.0 total, 2062.0 free, 1.0 used. 2727.7 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 8 root 20 0 2736 1536 1536 R 20.0 0.0 0:00.92 dd #使用cpu的百分比 1 root 20 0 4588 3968 3456 S 0.0 0.1 0:00.03 bash 9 root 20 0 8856 5248 3200 R 0.0 0.1 0:00.00 top #在cgroup中查看docker的资源限制 [rootdocker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/“docker id所要查看容器的id”/cpu.cfs_period_us #cpu总量划分 [rootdocker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/“docker id所要查看容器的id”/cpu.cfs_quota_us #cpu限制 [rootDocker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/9c912463da72f1d66678716bb0966c4aa728e05632a4dd0174c95486338427a4/cpu.cfs_period_us 100000 [rootDocker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/9c912463da72f1d66678716bb0966c4aa728e05632a4dd0174c95486338427a4/cpu.cfs_quota_us 200002.限制cpu的优先级#关闭cpu的核心当cpu都不空闲下才会出现争抢的情况为了实验效果我们可以关闭一个cpu核心 rootdocker ~]# echo 0 /sys/devices/system/cpu/cpu1/online [rootdocker ~]# cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 58 model name : Intel(R) Core(TM) i7-3770K CPU 3.50GHz stepping : 9 microcode : 0x21 cpu MHz : 3901.000 cache size : 8192 KB physical id : 0 siblings : 1 core id : 0 cpu cores : 1 ##cpu核心数为1 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm pti ssbd ibrs ibpb stibp fsgsbase tsc_adjust smep arat md_clear flush_l1d arch_capabilities bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds mmio_unknown bogomips : 7802.00 clflush size : 64 cache_alignment : 64 address sizes : 45 bits physical, 48 bits virtual power management: #开启容器时如果指定了cpu使用优先级那么设定文件为 [rootdocker ~]# cat /sys/fs/cgroup/cpu/docker/“docker id所要查看容器的id”/cpu.shares [rootDocker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/d9bbff808893f2f275ef5949480ab3be8c4744c82634a4c7b6c6dc3f6dd61219/cpu.shares 100 #开启容器并限制资源 [rootDocker-node1 ~]# docker run -it --rm --cpu-shares 100 ubuntu #设定cpu优先级最大为1024值越大优先级越高 rootdc066aa1a1f0:/# dd if/dev/zero of/dev/null [1] 8 rootdc066aa1a1f0:/# top top - 12:16:56 up 1 day, 2:22, 0 user, load average: 1.20, 0.37, 0.20 Tasks: 3 total, 2 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 37.3 us, 61.4 sy, 0.0 ni, 0.0 id, 0.0 wa, 1.0 hi, 0.3 si, 0.0 st MiB Mem : 3627.1 total, 502.5 free, 954.5 used, 2471.7 buff/cache MiB Swap: 2063.0 total, 2062.3 free, 0.7 used. 2672.6 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 8 root 20 0 2736 1536 1536 R 3.6 0.0 0:16.74 dd #cpu有限制被限制 1 root 20 0 4588 3968 3456 S 0.0 0.1 0:00.03 bash 9 root 20 0 8856 5248 3200 R 0.0 0.1 0:00.00 top #开启另外一个容器不限制cpu的优先级 [rootDocker-node1 ~]# docker run -it --rm ubuntu:latest root17f8c9d66fde:/# dd if/dev/zero of/dev/null [1] 8 root17f8c9d66fde:/# top top - 12:17:55 up 1 day, 2:23, 0 user, load average: 1.84, 0.70, 0.32 Tasks: 3 total, 2 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 36.2 us, 62.1 sy, 0.0 ni, 0.0 id, 0.0 wa, 1.3 hi, 0.3 si, 0.0 st MiB Mem : 3627.1 total, 502.3 free, 954.6 used, 2471.7 buff/cache MiB Swap: 2063.0 total, 2062.3 free, 0.7 used. 2672.5 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 8 root 20 0 2736 1408 1408 R 94.0 0.0 1:09.34 dd #cpu为被限制 1 root 20 0 4588 3968 3456 S 0.0 0.1 0:00.02 bash 9 root 20 0 8848 5248 3200 R 0.0 0.1 0:00.01 top限制内存使用#安装检测工具 [rootdocker-node1 ~]# rpm -ivh libcgroup-0.41-19.el8.x86_64.rpm [rootdocker-node1 ~]# rpm -ivh libcgroup-tools-0.41-19.el8.x86_64.rpm #开启容器并限制容器使用内存大小 [rootDocker-node1 ~]# docker run -d --name test --memory 200M --memory-swap 200M nginx:1.23 ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b #查看容器内存使用限制 [rootDocker-node1 ~]# cd /sys/fs/cgroup/memory/docker/ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b/ [rootDocker-node1 ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b]# cat memory.limit_in_bytes 209715200 [rootDocker-node1 ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b]# cat memory.memsw.limit_in_bytes 209715200 #测试容器内存限制在容器中我们测试内存限制效果不是很明显可以利用工具模拟容器在内存中写入数据 #在系统中/dev/shm这个目录被挂在到内存中 [rootdocker cgroup]# docker run -d --name test --rm --memory 200M --memory-swap 200M nginx f5017485d69b50cf2e294bf6c65fcd5e679002e25bd9b0eaf9149eee2e379eec [rootDocker-node1 ~]# cgexec -g memory:docker/ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b dd if/dev/zero of/dev/shm/bigfile bs1M count150 记录了1500 的读入 记录了1500 的写出 157286400字节157 MB150 MiB已复制0.67287 s234 MB/s [rootDocker-node1 ~]# cgexec -g memory:docker/ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b dd if/dev/zero of/dev/shm/bigfile bs1M count120 记录了1200 的读入 记录了1200 的写出 125829120字节126 MB120 MiB已复制0.0548637 s2.3 GB/s [rootDocker-node1 ~]# cgexec -g memory:docker/ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b dd if/dev/zero of/dev/shm/bigfile bs1M count200 已杀死 #也可以自建控制器 [rootdocker ~]# mkdir -p /sys/fs/cgroup/memory/x1/ [rootdocker ~]# ls /sys/fs/cgroup/memory/x1/ cgroup.clone_children memory.kmem.tcp.max_usage_in_bytes memory.oom_control cgroup.event_control memory.kmem.tcp.usage_in_bytes memory.pressure_level cgroup.procs memory.kmem.usage_in_bytes memory.soft_limit_in_bytes memory.failcnt memory.limit_in_bytes memory.stat memory.force_empty memory.max_usage_in_bytes memory.swappiness memory.kmem.failcnt memory.memsw.failcnt memory.usage_in_bytes memory.kmem.limit_in_bytes memory.memsw.limit_in_bytes memory.use_hierarchy memory.kmem.max_usage_in_bytes memory.memsw.max_usage_in_bytes notify_on_release memory.kmem.slabinfo memory.memsw.usage_in_bytes tasks memory.kmem.tcp.failcnt memory.move_charge_at_immigrate memory.kmem.tcp.limit_in_bytes memory.numa_stat [rootdocker ~]# echo 209715200 /sys/fs/cgroup/memory/x1/memory.limit_in_bytes #内存可用大小限制 [rootdocker ~]# cat /sys/fs/cgroup/memory/x1/tasks #此控制器被那个进程调用 [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count100 记录了1000 的读入 记录了1000 的写出 104857600字节105 MB100 MiB已复制0.0388935 s2.7 GB/s [rootdocker ~]# free -m total used free shared buff/cache available Mem: 3627 1038 1813 109 1131 2589 Swap: 2062 0 2062 [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count300 记录了3000 的读入 记录了3000 的写出 314572800字节315 MB300 MiB已复制0.241256 s1.3 GB/s [rootdocker ~]# free -m total used free shared buff/cache available Mem: 3627 1125 1725 181 1203 2501 Swap: 2062 129 1933 #内存溢出部分被写入swap交换分区 [rootdocker ~]# rm -fr /dev/shm/bigfile [rootdocker ~]# echo 209715200 /sys/fs/cgroup/memory/x1/memory.memsw.limit_in_bytes #内存swap控制 [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count200 已杀死 [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count199 已杀死 [rootdocker ~]# rm -fr /dev/shm/bigfile [rootdocker ~]# [rootdocker ~]# rm -fr /dev/shm/bigfile [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count180 记录了1800 的读入 记录了1800 的写出 188743680字节189 MB180 MiB已复制0.0660052 s2.9 GB/s [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count190 记录了1900 的读入 记录了1900 的写出 199229440字节199 MB190 MiB已复制0.0682285 s2.9 GB/s [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count200 已杀死[!NOTE]cgexec -g memory:doceker/容器id -g表示使用指定控制器类型限制docker的磁盘io[rootDocker-node1 ~]# df 文件系统 1K-块 已用 可用 已用% 挂载点 devtmpfs 4096 0 4096 0% /dev tmpfs 886884 199892 686992 23% /dev/shm tmpfs 354756 5260 349496 2% /run tmpfs 4096 0 4096 0% /sys/fs/cgroup /dev/nvme0n1p3 101640192 12967304 88672888 13% / /dev/nvme0n1p1 983040 258908 724132 27% /boot /dev/sr0 10281784 10281784 0 100% /rhel9 tmpfs 177376 0 177376 0% /run/user/0 overlay 101640192 12967304 88672888 13% /var/lib/docker/overlay2/8cedf5a1770f99fd111546f4af9f1be2e0f36e93840698a90e81e024feefd19a/merged [rootDocker-node1 ~]# fdisk -l Disk /dev/nvme0n1100 GiB107374182400 字节209715200 个扇区 磁盘型号VMware Virtual NVMe Disk 单元扇区 / 1 * 512 512 字节 扇区大小(逻辑/物理)512 字节 / 512 字节 I/O 大小(最小/最佳)512 字节 / 512 字节 磁盘标签类型dos 磁盘标识符0x2b13f8de 设备 启动 起点 末尾 扇区 大小 Id 类型 /dev/nvme0n1p1 * 2048 2099199 2097152 1G 83 Linux /dev/nvme0n1p2 2099200 6303743 4204544 2G 82 Linux swap / Solaris /dev/nvme0n1p3 6303744 209715199 203411456 97G 83 Linux [rootDocker-node1 ~]# docker run -it --rm \ --device-write-bps \ #指定容器使用磁盘io的速率 /dev/nvme0n1:30M \ #/dev/nvme0n1是指定系统的磁盘30M即每秒30M数据 ubuntu root5574de564169:/# dd if/dev/zero ofbigfile #开启容器后会发现速度和设定不匹配是因为系统的缓存机制 ^C5928960 records in 5928950 records out 303562240 bytes (304 MB, 289 MiB) copied, 2.91061 s, 104 MB/s root5574de564169:/# dd if/dev/zero ofbigfile bs1M count100 1000 records in 1000 records out 104857600 bytes (105 MB, 100 MiB) copied, 0.0515779 s, 2.0 GB/s root5574de564169:/# dd if/dev/zero of/bigfile bs1M count100 oflagdirect 1000 records in 1000 records out 104857600 bytes (105 MB, 100 MiB) copied, 3.35107 s, 31.3 MB/s容器特权在容器中默认情况下即使我是容器的超级用户也无法修改某些系统设定比如网络[rootDocker-node1 ~]# docker run --rm -it busybox / # whoami root / # ip a 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 27: eth0if28: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever / # ip a a 192.168.0.100/24 dev eth0 ip: RTNETLINK answers: Operation not permitted这是因为容器使用的很多资源都是和系统真实主机公用的如果允许容器修改这些重要资源系统的稳定性会变的非常差但是由于某些需要求容器需要控制一些默认控制不了的资源如何解决此问题这时我们就要设置容器特权[[rootDocker-node1 ~]# docker run --rm -it --privileged busybox:latest / # id root uid0(root) gid0(root) groups0(root),10(wheel) / # ip a 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0if24: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueue link/ether d6:a2:e5:6d:8c:ff brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever / # fdisk -l Disk /dev/nvme0n1: 100 GB, 107374182400 bytes, 209715200 sectors 411206 cylinders, 255 heads, 2 sectors/track Units: sectors of 1 * 512 512 bytes Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type /dev/nvme0n1p1 * 4,4,1 1023,254,2 2048 2099199 2097152 1024M 83 Linux /dev/nvme0n1p2 1023,254,2 1023,254,2 2099200 6303743 4204544 2053M 82 Linux swap /dev/nvme0n1p3 1023,254,2 1023,254,2 6303744 209715199 203411456 96.9G 83 Linux #如果添加了--privileged 参数开启容器容器获得权限近乎于宿主机的root用户容器特权的白名单--privilegedtrue 的权限非常大接近于宿主机的权限为了防止用户的滥用需要增加限制只提供给容器必须的权限。此时Docker 提供了权限白名单的机制使用--cap-add添加必要的权限capabilities手册地址http://man7.org/linux/man-pages/man7/capabilities.7.html#限制容器对网络有root权限 [rootDocker-node1 ~]# docker run --rm -it --cap-add NET_ADMIN busybox:latest / # ip a 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0if22: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueue link/ether ca:9f:c7:7c:09:da brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever / # ip a a dev eth0 172.17.0.3/24 #网络可以设定 / # ip a 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0if22: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueue link/ether ca:9f:c7:7c:09:da brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever inet 172.17.0.3/24 scope global eth0 valid_lft forever preferred_lft forever / # fdisk -l / # #无法管理磁盘
Docker 的安全优化
Docker 的安全优化Docker容器的安全性很大程度上依赖于Linux系统自身评估Docker的安全性时主要考虑以下几个方面Linux内核的命名空间机制提供的容器隔离安全Linux控制组机制对容器资源的控制能力安全。Linux内核的能力机制所带来的操作权限安全Docker程序特别是服务端本身的抗攻击性。其他安全增强机制对容器安全性的影响#在rhel9中默认使用cgroup-v2 但是cgroup-v2中不利于观察docker的资源限制情况所以推荐使用cgroup-v1 [rootdocker-node1 ~]# grubby --update-kernel/boot/vmlinuz-$(uname -r) \ --argssystemd.unified_cgroup_hierarchy0 systemd.legacy_systemd_cgroup_controller1 命名空间隔离的安全当docker run启动一个容器时Docker将在后台为容器创建一个独立的命名空间。命名空间提供了最基础也最直接的隔离。与虚拟机方式相比通过Linux namespace来实现的隔离不是那么彻底。容器只是运行在宿主机上的一种特殊的进程那么多个容器之间使用的就还是同一个宿主机的操作系统内核。在 Linux 内核中有很多资源和对象是不能被 Namespace 化的比如磁盘等等[rootdocker-node1 ~]# docker run -d --name web nginx 3c6b649a200fc56afafe9f47494903fe56e71cabcd534d6c9e6f8b5854f29cac [rootdocker ~]# docker inspect web | grep Pid Pid: 4328, PidMode: , PidsLimit: null, [rootdocker-node1 ~]# cd /proc/4328/ns/ #进程的namespace [rootdocker-node1 ns]# ls cgroup ipc mnt net pid pid_for_children time time_for_children user uts [rootdocker-node1 ns]# ls -d /sys/fs/cgroup/memory/docker/3c6b649a200fs省略部分854f29cac/ #资源隔离信息 /sys/fs/cgroup/system.slice/docker-ecb8abbbfc85bf3d62fc82afb3950ab6b6a2e80092738274a233bbb8db0c5ce2.scope /sys/fs/cgroup/system.slice/docker.service /sys/fs/cgroup/system.slice/docker.socket2 控制组资源控制的安全当docker run启动一个容器时Docker将在后台为容器创建一个独立的控制组策略集合。Linux Cgroups提供了很多有用的特性确保各容器可以公平地分享主机的内存、CPU、磁盘IO等资源。确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器它在防止拒绝服务攻击DDoS方面必不可少[rootdocker-node1 ~]# docker run -it --name test busybox #内存资源默认没有被隔离 / # free -m total used free shared buff/cache available Mem: 3627 648 516 16 2463 2678 Swap: 2063 1 2062 / # exit [rootdocker-node1 ~]# free -m total used free shared buff/cache available Mem: 3627 907 557 15 2463 2719 Swap: 2062 1 20613 内核能力机制能力机制Capability是Linux内核一个强大的特性可以提供细粒度的权限访问控制。大部分情况下容器并不需要“真正的”root权限容器只需要少数的能力即可。默认情况下Docker采用“白名单”机制禁用“必需功能”之外的其他权限。4 Docker服务端防护使用Docker容器的核心是Docker服务端确保只有可信的用户才能访问到Docker服务。将容器的root用户映射到本地主机上的非root用户减轻容器和主机之间因权限提升而引起的安全问题。允许Docker 服务端在非root权限下运行利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程只允许在特定范围内进行操作。[rootdocker-node1 ~]# ls -ld /var/lib/docker/ #默认docker是用root用户控制资源的 drwx--x--- 12 root root 171 8月 20 13:21 /var/lib/docker/Docker的资源限制Linux Cgroups 的全称是 Linux Control Group。是限制一个进程组能够使用的资源上限包括 CPU、内存、磁盘、网络带宽等等。对进程进行优先级设置、审计以及将进程挂起和恢复等操作。Linux Cgroups 给用户暴露出来的操作接口是文件系统它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。执行此命令查看mount -t cgroup[rootdocker-node1 ~]# mount -t cgroup #在rhel9中默认使用cgroup2 cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent/usr/lib/systemd/systemd-cgroups-agent,namesystemd) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio) cgroup on /sys/fs/cgroup/misc type cgroup (rw,nosuid,nodev,noexec,relatime,misc) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct) cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio) cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids) cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) 在 /sys/fs/cgroup 下面有很多诸如 cpuset、cpu、 memory 这样的子目录也叫子系统。在每个子系统下面为每个容器创建一个控制组即创建一个新目录。控制组下面的资源文件里填上什么值就靠用户执行 docker run 时的参数指定。限制cpu使用1.限制cpu的使用量[rootdocker-node1 ~]# docker run -it --rm --name test \ --cpu-period 100000 \ #设置 CPU 周期的长度单位为微秒通常为 100000即 100 毫秒 --cpu-quota 20000 ubuntu #设置容器在一个周期内可以使用的 CPU 时间单位也是微秒。 root5797d76b20f5:/# dd if/dev/zero of/dev/null [1] 8 root5797d76b20f5:/# top top - 11:53:22 up 1 day, 1:58, 0 user, load average: 0.00, 0.00, 0.00 Tasks: 3 total, 2 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 4.4 us, 6.0 sy, 0.0 ni, 89.5 id, 0.0 wa, 0.2 hi, 0.0 si, 0.0 st MiB Mem : 3627.1 total, 558.1 free, 899.4 used, 2471.0 buff/cache MiB Swap: 2063.0 total, 2062.0 free, 1.0 used. 2727.7 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 8 root 20 0 2736 1536 1536 R 20.0 0.0 0:00.92 dd #使用cpu的百分比 1 root 20 0 4588 3968 3456 S 0.0 0.1 0:00.03 bash 9 root 20 0 8856 5248 3200 R 0.0 0.1 0:00.00 top #在cgroup中查看docker的资源限制 [rootdocker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/“docker id所要查看容器的id”/cpu.cfs_period_us #cpu总量划分 [rootdocker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/“docker id所要查看容器的id”/cpu.cfs_quota_us #cpu限制 [rootDocker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/9c912463da72f1d66678716bb0966c4aa728e05632a4dd0174c95486338427a4/cpu.cfs_period_us 100000 [rootDocker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/9c912463da72f1d66678716bb0966c4aa728e05632a4dd0174c95486338427a4/cpu.cfs_quota_us 200002.限制cpu的优先级#关闭cpu的核心当cpu都不空闲下才会出现争抢的情况为了实验效果我们可以关闭一个cpu核心 rootdocker ~]# echo 0 /sys/devices/system/cpu/cpu1/online [rootdocker ~]# cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 58 model name : Intel(R) Core(TM) i7-3770K CPU 3.50GHz stepping : 9 microcode : 0x21 cpu MHz : 3901.000 cache size : 8192 KB physical id : 0 siblings : 1 core id : 0 cpu cores : 1 ##cpu核心数为1 apicid : 0 initial apicid : 0 fpu : yes fpu_exception : yes cpuid level : 13 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm pti ssbd ibrs ibpb stibp fsgsbase tsc_adjust smep arat md_clear flush_l1d arch_capabilities bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds mmio_unknown bogomips : 7802.00 clflush size : 64 cache_alignment : 64 address sizes : 45 bits physical, 48 bits virtual power management: #开启容器时如果指定了cpu使用优先级那么设定文件为 [rootdocker ~]# cat /sys/fs/cgroup/cpu/docker/“docker id所要查看容器的id”/cpu.shares [rootDocker-node1 ~]# cat /sys/fs/cgroup/cpu/docker/d9bbff808893f2f275ef5949480ab3be8c4744c82634a4c7b6c6dc3f6dd61219/cpu.shares 100 #开启容器并限制资源 [rootDocker-node1 ~]# docker run -it --rm --cpu-shares 100 ubuntu #设定cpu优先级最大为1024值越大优先级越高 rootdc066aa1a1f0:/# dd if/dev/zero of/dev/null [1] 8 rootdc066aa1a1f0:/# top top - 12:16:56 up 1 day, 2:22, 0 user, load average: 1.20, 0.37, 0.20 Tasks: 3 total, 2 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 37.3 us, 61.4 sy, 0.0 ni, 0.0 id, 0.0 wa, 1.0 hi, 0.3 si, 0.0 st MiB Mem : 3627.1 total, 502.5 free, 954.5 used, 2471.7 buff/cache MiB Swap: 2063.0 total, 2062.3 free, 0.7 used. 2672.6 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 8 root 20 0 2736 1536 1536 R 3.6 0.0 0:16.74 dd #cpu有限制被限制 1 root 20 0 4588 3968 3456 S 0.0 0.1 0:00.03 bash 9 root 20 0 8856 5248 3200 R 0.0 0.1 0:00.00 top #开启另外一个容器不限制cpu的优先级 [rootDocker-node1 ~]# docker run -it --rm ubuntu:latest root17f8c9d66fde:/# dd if/dev/zero of/dev/null [1] 8 root17f8c9d66fde:/# top top - 12:17:55 up 1 day, 2:23, 0 user, load average: 1.84, 0.70, 0.32 Tasks: 3 total, 2 running, 1 sleeping, 0 stopped, 0 zombie %Cpu(s): 36.2 us, 62.1 sy, 0.0 ni, 0.0 id, 0.0 wa, 1.3 hi, 0.3 si, 0.0 st MiB Mem : 3627.1 total, 502.3 free, 954.6 used, 2471.7 buff/cache MiB Swap: 2063.0 total, 2062.3 free, 0.7 used. 2672.5 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 8 root 20 0 2736 1408 1408 R 94.0 0.0 1:09.34 dd #cpu为被限制 1 root 20 0 4588 3968 3456 S 0.0 0.1 0:00.02 bash 9 root 20 0 8848 5248 3200 R 0.0 0.1 0:00.01 top限制内存使用#安装检测工具 [rootdocker-node1 ~]# rpm -ivh libcgroup-0.41-19.el8.x86_64.rpm [rootdocker-node1 ~]# rpm -ivh libcgroup-tools-0.41-19.el8.x86_64.rpm #开启容器并限制容器使用内存大小 [rootDocker-node1 ~]# docker run -d --name test --memory 200M --memory-swap 200M nginx:1.23 ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b #查看容器内存使用限制 [rootDocker-node1 ~]# cd /sys/fs/cgroup/memory/docker/ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b/ [rootDocker-node1 ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b]# cat memory.limit_in_bytes 209715200 [rootDocker-node1 ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b]# cat memory.memsw.limit_in_bytes 209715200 #测试容器内存限制在容器中我们测试内存限制效果不是很明显可以利用工具模拟容器在内存中写入数据 #在系统中/dev/shm这个目录被挂在到内存中 [rootdocker cgroup]# docker run -d --name test --rm --memory 200M --memory-swap 200M nginx f5017485d69b50cf2e294bf6c65fcd5e679002e25bd9b0eaf9149eee2e379eec [rootDocker-node1 ~]# cgexec -g memory:docker/ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b dd if/dev/zero of/dev/shm/bigfile bs1M count150 记录了1500 的读入 记录了1500 的写出 157286400字节157 MB150 MiB已复制0.67287 s234 MB/s [rootDocker-node1 ~]# cgexec -g memory:docker/ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b dd if/dev/zero of/dev/shm/bigfile bs1M count120 记录了1200 的读入 记录了1200 的写出 125829120字节126 MB120 MiB已复制0.0548637 s2.3 GB/s [rootDocker-node1 ~]# cgexec -g memory:docker/ece68761e9e04778e61abdff3c64c7ad0971316cf8cfee0b259f8a55ecc6b44b dd if/dev/zero of/dev/shm/bigfile bs1M count200 已杀死 #也可以自建控制器 [rootdocker ~]# mkdir -p /sys/fs/cgroup/memory/x1/ [rootdocker ~]# ls /sys/fs/cgroup/memory/x1/ cgroup.clone_children memory.kmem.tcp.max_usage_in_bytes memory.oom_control cgroup.event_control memory.kmem.tcp.usage_in_bytes memory.pressure_level cgroup.procs memory.kmem.usage_in_bytes memory.soft_limit_in_bytes memory.failcnt memory.limit_in_bytes memory.stat memory.force_empty memory.max_usage_in_bytes memory.swappiness memory.kmem.failcnt memory.memsw.failcnt memory.usage_in_bytes memory.kmem.limit_in_bytes memory.memsw.limit_in_bytes memory.use_hierarchy memory.kmem.max_usage_in_bytes memory.memsw.max_usage_in_bytes notify_on_release memory.kmem.slabinfo memory.memsw.usage_in_bytes tasks memory.kmem.tcp.failcnt memory.move_charge_at_immigrate memory.kmem.tcp.limit_in_bytes memory.numa_stat [rootdocker ~]# echo 209715200 /sys/fs/cgroup/memory/x1/memory.limit_in_bytes #内存可用大小限制 [rootdocker ~]# cat /sys/fs/cgroup/memory/x1/tasks #此控制器被那个进程调用 [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count100 记录了1000 的读入 记录了1000 的写出 104857600字节105 MB100 MiB已复制0.0388935 s2.7 GB/s [rootdocker ~]# free -m total used free shared buff/cache available Mem: 3627 1038 1813 109 1131 2589 Swap: 2062 0 2062 [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count300 记录了3000 的读入 记录了3000 的写出 314572800字节315 MB300 MiB已复制0.241256 s1.3 GB/s [rootdocker ~]# free -m total used free shared buff/cache available Mem: 3627 1125 1725 181 1203 2501 Swap: 2062 129 1933 #内存溢出部分被写入swap交换分区 [rootdocker ~]# rm -fr /dev/shm/bigfile [rootdocker ~]# echo 209715200 /sys/fs/cgroup/memory/x1/memory.memsw.limit_in_bytes #内存swap控制 [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count200 已杀死 [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count199 已杀死 [rootdocker ~]# rm -fr /dev/shm/bigfile [rootdocker ~]# [rootdocker ~]# rm -fr /dev/shm/bigfile [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count180 记录了1800 的读入 记录了1800 的写出 188743680字节189 MB180 MiB已复制0.0660052 s2.9 GB/s [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count190 记录了1900 的读入 记录了1900 的写出 199229440字节199 MB190 MiB已复制0.0682285 s2.9 GB/s [rootdocker ~]# cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count200 已杀死[!NOTE]cgexec -g memory:doceker/容器id -g表示使用指定控制器类型限制docker的磁盘io[rootDocker-node1 ~]# df 文件系统 1K-块 已用 可用 已用% 挂载点 devtmpfs 4096 0 4096 0% /dev tmpfs 886884 199892 686992 23% /dev/shm tmpfs 354756 5260 349496 2% /run tmpfs 4096 0 4096 0% /sys/fs/cgroup /dev/nvme0n1p3 101640192 12967304 88672888 13% / /dev/nvme0n1p1 983040 258908 724132 27% /boot /dev/sr0 10281784 10281784 0 100% /rhel9 tmpfs 177376 0 177376 0% /run/user/0 overlay 101640192 12967304 88672888 13% /var/lib/docker/overlay2/8cedf5a1770f99fd111546f4af9f1be2e0f36e93840698a90e81e024feefd19a/merged [rootDocker-node1 ~]# fdisk -l Disk /dev/nvme0n1100 GiB107374182400 字节209715200 个扇区 磁盘型号VMware Virtual NVMe Disk 单元扇区 / 1 * 512 512 字节 扇区大小(逻辑/物理)512 字节 / 512 字节 I/O 大小(最小/最佳)512 字节 / 512 字节 磁盘标签类型dos 磁盘标识符0x2b13f8de 设备 启动 起点 末尾 扇区 大小 Id 类型 /dev/nvme0n1p1 * 2048 2099199 2097152 1G 83 Linux /dev/nvme0n1p2 2099200 6303743 4204544 2G 82 Linux swap / Solaris /dev/nvme0n1p3 6303744 209715199 203411456 97G 83 Linux [rootDocker-node1 ~]# docker run -it --rm \ --device-write-bps \ #指定容器使用磁盘io的速率 /dev/nvme0n1:30M \ #/dev/nvme0n1是指定系统的磁盘30M即每秒30M数据 ubuntu root5574de564169:/# dd if/dev/zero ofbigfile #开启容器后会发现速度和设定不匹配是因为系统的缓存机制 ^C5928960 records in 5928950 records out 303562240 bytes (304 MB, 289 MiB) copied, 2.91061 s, 104 MB/s root5574de564169:/# dd if/dev/zero ofbigfile bs1M count100 1000 records in 1000 records out 104857600 bytes (105 MB, 100 MiB) copied, 0.0515779 s, 2.0 GB/s root5574de564169:/# dd if/dev/zero of/bigfile bs1M count100 oflagdirect 1000 records in 1000 records out 104857600 bytes (105 MB, 100 MiB) copied, 3.35107 s, 31.3 MB/s容器特权在容器中默认情况下即使我是容器的超级用户也无法修改某些系统设定比如网络[rootDocker-node1 ~]# docker run --rm -it busybox / # whoami root / # ip a 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 27: eth0if28: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever / # ip a a 192.168.0.100/24 dev eth0 ip: RTNETLINK answers: Operation not permitted这是因为容器使用的很多资源都是和系统真实主机公用的如果允许容器修改这些重要资源系统的稳定性会变的非常差但是由于某些需要求容器需要控制一些默认控制不了的资源如何解决此问题这时我们就要设置容器特权[[rootDocker-node1 ~]# docker run --rm -it --privileged busybox:latest / # id root uid0(root) gid0(root) groups0(root),10(wheel) / # ip a 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0if24: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueue link/ether d6:a2:e5:6d:8c:ff brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever / # fdisk -l Disk /dev/nvme0n1: 100 GB, 107374182400 bytes, 209715200 sectors 411206 cylinders, 255 heads, 2 sectors/track Units: sectors of 1 * 512 512 bytes Device Boot StartCHS EndCHS StartLBA EndLBA Sectors Size Id Type /dev/nvme0n1p1 * 4,4,1 1023,254,2 2048 2099199 2097152 1024M 83 Linux /dev/nvme0n1p2 1023,254,2 1023,254,2 2099200 6303743 4204544 2053M 82 Linux swap /dev/nvme0n1p3 1023,254,2 1023,254,2 6303744 209715199 203411456 96.9G 83 Linux #如果添加了--privileged 参数开启容器容器获得权限近乎于宿主机的root用户容器特权的白名单--privilegedtrue 的权限非常大接近于宿主机的权限为了防止用户的滥用需要增加限制只提供给容器必须的权限。此时Docker 提供了权限白名单的机制使用--cap-add添加必要的权限capabilities手册地址http://man7.org/linux/man-pages/man7/capabilities.7.html#限制容器对网络有root权限 [rootDocker-node1 ~]# docker run --rm -it --cap-add NET_ADMIN busybox:latest / # ip a 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0if22: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueue link/ether ca:9f:c7:7c:09:da brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever / # ip a a dev eth0 172.17.0.3/24 #网络可以设定 / # ip a 1: lo: LOOPBACK,UP,LOWER_UP mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0if22: BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN mtu 1500 qdisc noqueue link/ether ca:9f:c7:7c:09:da brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever inet 172.17.0.3/24 scope global eth0 valid_lft forever preferred_lft forever / # fdisk -l / # #无法管理磁盘