docker(四)docker安全

    技术2023-11-02  106

    文章目录

    docker(四)docker安全理解docker安全容器与资源的关系对docker容器进程进行控制(资源方面)

    docker(四)docker安全

    为什么资源的隔离和限制在云时代更加重要?在默认情况下,一个操作系统里所有运行的进程共享CPU和内存资源,如果程序设计不当,最极端的情况,某进程出现死循环可能会耗尽CPU资源,或者由于内存泄漏消耗掉大部分系统资源,这在企业级产品场景下是不可接受的,所以进程的资源隔离技术是非常必要的 Linux操作系统本身从操作系统层面就支持虚拟化技术,叫做Linux container,也就是大家到处能看到的LXC的全称

    LXC的三大特色:cgroup,namespace和unionFS Cgroup Cgroup是control group,又称为控制组,它主要是做资源控制。原理是将一组进程放在放在一个控制组里,通过给这个控制组分配指定的可用资源,达到控制这一组进程可用资源的目的。 Namespace Namespace又称为命名空间,它主要做访问隔离。其原理是针对一类资源进行抽象,并将其封装在一起提供给一个容器使用,对于这类资源,因为每个容器都有自己的抽象,而他们彼此之间是不可见的,所以就可以做到访问隔离 unionFS: 顾名思义,unionFS可以把文件系统上多个目录(也叫分支)内容联合挂载到同一个目录下,而目录的物理位置是分开的。 要理解unionFS,我们首先要认识bootfs和rootfs。 1.boot file system (bootfs):包含操作系统boot loader 和 kernel。用户不会修改这个文件系统。 一旦启动完成后,整个Linux内核加载进内存,之后bootfs会被卸载掉,从而释放出内存。 同样内核版本的不同的 Linux 发行版,其bootfs都是一致的。 2.root file system (rootfs):包含典型的目录结构,包括 /dev, /proc, /bin, /etc, /lib, /usr, and /tm 实际上这就是Docker容器镜像分层实现的技术基础。如果我们浏览Docker hub,能发现大多数镜像都不是从头开始制作,而是从一些base镜像基础上创建,比如debian基础镜像。

    理解docker安全

    docker容器的安全性,很大程度上依赖于linux系统自身,评估Docker的安全性时,主要考虑以下几个方面 Linux内核的命令空间(namespace)机制提供的容器隔离安全 Linux控制组机制对容器资源的控制能力安全 Linux内核的能力机制所带来的操作权限安全 Docker程序(特别是服务端)本身的抗攻击性 其他安全增强机制对容器安全性的影响 命名空间隔离安全 当docker run启动一个容器时,Docker将在后台为容器创建一个独立的命名空间,命名空间提供了最基础也最直接的隔离 与虚拟机方式相比,通过Linux namespace来实现的隔离不是那么彻底 容器只是运行在宿主机上的一种特殊的进程,那么多个容器之间使用的还是同一个宿主机的操作系统内核 在Linux内核中,有很多资源和对象是不能被Namespace化的 比如 时间

    容器与资源的关系

    # 不能停掉容器 与资源会被释放掉 [root@docker docker]# docker run -it --name vm1 ubuntu root@06a3c366c16b:/# root@06a3c366c16b:/# [root@docker docker]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 06a3c366c16b ubuntu "/bin/bash" 14 seconds ago Up 13 seconds vm1 [root@docker docker]# docker inspect vm1 | grep Pid "Pid": 1504, "PidMode": "", "PidsLimit": 0, [root@docker docker]# ps aux |grep 1504 root 1504 0.0 0.1 18164 1960 pts/0 Ss+ 10:43 0:00 /bin/bash root 1589 0.0 0.1 112704 1024 pts/0 R+ 10:44 0:00 grep --color=auto 1504 [root@docker docker]# cd /proc/1504 [root@docker 1504]# ls attr cwd map_files oom_adj schedstat task autogroup environ maps oom_score sessionid timers auxv exe mem oom_score_adj setgroups uid_map cgroup fd mountinfo pagemap smaps wchan clear_refs fdinfo mounts patch_state stack cmdline gid_map mountstats personality stat comm io net projid_map statm coredump_filter limits ns root status cpuset loginuid numa_maps sched syscall [root@docker 1504]# cd ns/ # namespace """ namespace 主要用作环境的隔离,主要有以下namespace: UTS: 主机名与域名 IPC: 信号量、消息队列和共享内存 PID: 进程编号 Network:网络设备、网络栈、端口等等 Mount: 挂载点 User: 用户和用户组 """ [root@docker ns]# ls ipc mnt net pid user uts 控制组资源控制安全 当docker run启动一个容器时,Docker将在后台为容器创建一个独立的控制组策略集合 Linux Cgroup提供了很多有用的特性,确保各容器可以公平地分享主机的内存,cpu,磁盘io等资源 确保当发生在容器内的资源压力不会影响到本地主机系统和其他容器,它在防止拒绝服务DDos方面必不可少 [root@docker ns]# mount -t cgroup cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd) cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event) cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices) cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpuacct,cpu) cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb) cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory) cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer) 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/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_prio,net_cls) cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset) [root@docker ns]# cd /sys/fs/cgroup/ [root@docker cgroup]# ls blkio cpu,cpuacct freezer net_cls perf_event cpu cpuset hugetlb net_cls,net_prio pids cpuacct devices memory net_prio systemd [root@docker cgroup]# cd cpu [root@docker cpu]# ls cgroup.clone_children cpuacct.usage cpu.rt_runtime_us release_agent cgroup.event_control cpuacct.usage_percpu cpu.shares system.slice cgroup.procs cpu.cfs_period_us cpu.stat tasks cgroup.sane_behavior cpu.cfs_quota_us docker user.slice cpuacct.stat cpu.rt_period_us notify_on_release [root@docker cpu]# cd docker/ [root@docker docker]# ls 06a3c366c16be682286ca31da43026615db1b053d394fb0f8b08dc9c9126ae47 cgroup.clone_children cgroup.event_control cgroup.procs cpuacct.stat cpuacct.usage cpuacct.usage_percpu cpu.cfs_period_us cpu.cfs_quota_us cpu.rt_period_us cpu.rt_runtime_us cpu.shares cpu.stat notify_on_release tasks 内核能力机制 能力机制(Capability)是linux内核一个强大的特性,可以提供细粒度的访问权限控制 大部分情况下,容器并不需要“真正的”root权限,容器只需要少数的能力即可 默认情况下,docker采用“白名单”机制,禁用“必需功能”之外的其他权限 [root@docker docker]# docker container attach vm1 root@06a3c366c16b:/# root@06a3c366c16b:/# root@06a3c366c16b:/# id #你所看到的root并不具备真正的root身份权限 uid=0(root) gid=0(root) groups=0(root) root@06a3c366c16b:/# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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 4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 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 root@06a3c366c16b:/# ip link set down eth0 #真正的root是具备这样的权限的 所以在容器内 你不是真正的root RTNETLINK answers: Operation not permitted Docker服务端防护 使用Docker容器的核心是Docker服务端,确保只有可信的用户才能访问Docker服务 将容器的root用户映射到本地主机上的非root用户,减轻容器和主机之间因权限提升而引起的安全问题 允许Docker服务端在非root权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作,这些子进程只允许在特定的范围内进行操作 其他安全特性 在内核中启用GRSEC和PAX 这将增加更多的编译和运行时的安全检查,并且通过地址随机化机制来避免恶意探测等(启用该特性不需要Docker进行任何配置) 使用一些有增强安全特性的容器模板 用户可以自定义更加严格的访问控制机制来定制安全策略 在文件系统挂载到容器内部时,可以通过配置只读模式来避免容器内的应用通过文件系统外部环境,特别是一些系统运行状态相关的目录 容器资源控制 linux cgroup?? # 其他资源控制 cat /etc/security/limits.conf Linux cgroup给用户暴露出来的操作接口是文件系统 它以文件和目录的方式组织在操作系统的/sys/fs/cgroup路径下 执行此命令查看:mount -t cgroup 在/sys/fs/cgroup下面有诸多如cpuset cpu memory这样的子目录,也叫子系统 在每个子系统下面,为每个容器创建一个控制组(即创建一个新的目录) 控制组下面的资源文件里填什么值,就靠用户执行docker run时所加的参数 ##资源控制的方式 #docker与linux内核无缝连接 ###cpu限制 [root@docker cgroup]# ls blkio(控制磁盘IO的) cpu,cpuacct freezer net_cls perf_event cpu cpuset hugetlb net_cls,net_prio pids cpuacct devices memory net_prio systemd [root@docker cgroup]# pwd /sys/fs/cgroup [root@docker cpu]# ls cgroup.clone_children cpuacct.usage cpu.rt_runtime_us release_agent cgroup.event_control cpuacct.usage_percpu cpu.shares system.slice cgroup.procs cpu.cfs_period_us cpu.stat tasks cgroup.sane_behavior cpu.cfs_quota_us docker user.slice cpuacct.stat cpu.rt_period_us notify_on_release [root@docker cpu]# mkdir x1 #是上级目录的子目录(带有复制的资源) [root@docker cpu]# cd x1/ [root@docker x1]# ls cgroup.clone_children cpuacct.usage_percpu cpu.shares cgroup.event_control cpu.cfs_period_us cpu.stat cgroup.procs cpu.cfs_quota_us notify_on_release cpuacct.stat cpu.rt_period_us tasks cpuacct.usage cpu.rt_runtime_us # 如不做修改 与父级目录内容是一样的 # 除了在容器中使用还可以控制我们操作系统本身的一些东西 [root@docker x1]# cat cpu.cfs_period_us #使用cpu的时间100毫秒 100000(微秒) [root@docker x1]# cat cpu.cfs_quota_us #不做限制 给100就用100 -1 # 以上两个文件需要配合使用 [root@docker x1]# echo 20000 > cpu.cfs_quota_us #100毫秒只用20% 注意:只能用非交互的echo方式改写 [root@docker x1]# cat cpu.cfs_quota_us 20000 # 测试 top命令观察发现 与我们的限制之间并没有什么联系 [root@docker x1]# dd if=/dev/zero of=/dev/null & #此命令不占内存 只耗费cpu [1] 12572 12572 root 20 0 107992 608 516 R 99.9 0.1 0:13.84 dd #通过TOP命令查看 并没有发生什么变化 # 怎么建立联系 [root@docker x1]# ls cgroup.clone_children cpuacct.usage_percpu cpu.shares cgroup.event_control cpu.cfs_period_us cpu.stat cgroup.procs cpu.cfs_quota_us notify_on_release cpuacct.stat cpu.rt_period_us tasks cpuacct.usage cpu.rt_runtime_us [root@docker x1]# echo 12572 > tasks 12572 root 20 0 107992 608 516 R 20.0 0.1 1:40.57 dd # 看到结果开始生效

    对docker容器进程进行控制(资源方面)

    [root@docker ~]# docker run --help|grep cpu --cpu-period int Limit CPU CFS (Completely Fair --cpu-quota int Limit CPU CFS (Completely Fair --cpu-rt-period int Limit CPU real-time period in --cpu-rt-runtime int Limit CPU real-time runtime in -c, --cpu-shares int CPU shares (relative weight) --cpus decimal Number of CPUs --cpuset-cpus string CPUs in which to allow execution --cpuset-mems string MEMs in which to allow execution [root@docker ~]# docker run -it --name vm2 --cpu-period 100000 --cpu-quota 20000 ubuntu root@d3b1336b2adb:/# [root@docker docker]# cd d3b1336b2adb72c766227795eaa03dde575143abcbfda939c9b79a19b8839622/ [root@docker d3b1336b2adb72c766227795eaa03dde575143abcbfda939c9b79a19b8839622]# ls cgroup.clone_children cpuacct.usage_percpu cpu.shares cgroup.event_control cpu.cfs_period_us cpu.stat cgroup.procs cpu.cfs_quota_us notify_on_release cpuacct.stat cpu.rt_period_us tasks cpuacct.usage cpu.rt_runtime_us [root@docker d3b1336b2adb72c766227795eaa03dde575143abcbfda939c9b79a19b8839622]# cat cpu.rt_period_us 1000000 [root@docker d3b1336b2adb72c766227795eaa03dde575143abcbfda939c9b79a19b8839622]# cat cpu.cfs_quota_us 20000 [root@docker d3b1336b2adb72c766227795eaa03dde575143abcbfda939c9b79a19b8839622]# # 测试是否生效 [root@docker ~]# docker run -it --name vm2 --cpu-period 100000 --cpu-quota 20000 ubuntu # 使其还是占用的是物理cpu的资源 root@d3b1336b2adb:/# dd if=/dev/zero of=/dev/null & 12877 root 20 0 4364 360 280 R 20.0 0.0 0:03.65 dd # 在物理机top查看 因为容器其实还是占用真实物理机的cpu ##内存限制 容器可用内存包括两个部分:物理内存(优先使用)和swap交换分区[root@docker ~]# cd /sys/fs/cgroup/ [root@docker cgroup]# [root@docker cgroup]# ls blkio cpu,cpuacct freezer net_cls perf_event cpu cpuset hugetlb net_cls,net_prio pids cpuacct devices memory net_prio systemd [root@docker cgroup]# cd memory/ [root@docker memory]# pwd /sys/fs/cgroup/memory [root@docker memory]# ls cgroup.clone_children memory.memsw.failcnt cgroup.event_control memory.memsw.limit_in_bytes cgroup.procs memory.memsw.max_usage_in_bytes cgroup.sane_behavior memory.memsw.usage_in_bytes docker memory.move_charge_at_immigrate memory.failcnt memory.numa_stat memory.force_empty memory.oom_control memory.kmem.failcnt memory.pressure_level memory.kmem.limit_in_bytes memory.soft_limit_in_bytes memory.kmem.max_usage_in_bytes memory.stat memory.kmem.slabinfo memory.swappiness memory.kmem.tcp.failcnt memory.usage_in_bytes memory.kmem.tcp.limit_in_bytes memory.use_hierarchy memory.kmem.tcp.max_usage_in_bytes notify_on_release memory.kmem.tcp.usage_in_bytes release_agent memory.kmem.usage_in_bytes system.slice memory.limit_in_bytes tasks memory.max_usage_in_bytes user.slice [root@docker memory]# mkdir x2 [root@docker memory]# cd x2/ [root@docker x2]# ls #内容从父级目录直接复制过来 cgroup.clone_children memory.memsw.failcnt cgroup.event_control memory.memsw.limit_in_bytes cgroup.procs memory.memsw.max_usage_in_bytes memory.failcnt memory.memsw.usage_in_bytes memory.force_empty memory.move_charge_at_immigrate memory.kmem.failcnt memory.numa_stat memory.kmem.limit_in_bytes memory.oom_control memory.kmem.max_usage_in_bytes memory.pressure_level memory.kmem.slabinfo memory.soft_limit_in_bytes memory.kmem.tcp.failcnt memory.stat memory.kmem.tcp.limit_in_bytes memory.swappiness memory.kmem.tcp.max_usage_in_bytes memory.usage_in_bytes memory.kmem.tcp.usage_in_bytes memory.use_hierarchy memory.kmem.usage_in_bytes notify_on_release memory.limit_in_bytes tasks memory.max_usage_in_bytes [root@docker x2]# cat memory.limit_in_bytes #默认没有控制 有多少用多少 9223372036854771712 #字节 # 控制:只能使用256M """ 字节的转换 [root@foundation0 ~]# bc bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 256 * 1024 * 1024 268435456 """ [root@docker x2]# cat memory.limit_in_bytes 9223372036854771712 [root@docker x2]# echo 268435456 > memory.limit_in_bytes [root@docker x2]# cat memory.limit_in_bytes 268435456 [root@docker x2]# df Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/rhel-root 17811456 5025844 12785612 29% / devtmpfs 495544 0 495544 0% /dev tmpfs 507780 0 507780 0% /dev/shm tmpfs 507780 13228 494552 3% /run tmpfs 507780 0 507780 0% /sys/fs/cgroup /dev/sda1 1038336 132704 905632 13% /boot tmpfs 101560 0 101560 0% /run/user/0 [root@docker x2]# free -m total used free shared buff/cache available Mem: 991 138 176 12 676 652 Swap: 2047 0 2047 [root@docker x2]# cd /dev/shm #注意 一定要在这个目录下 才会占用你的内存 [root@docker shm]# dd if=/dev/zero of=bigfile bs=1M count=100 100+0 records in 100+0 records out 104857600 bytes (105 MB) copied, 0.0328056 s, 3.2 GB/s [root@docker shm]# free -m total used free shared buff/cache available Mem: 991 138 77 112 776 553 Swap: 2047 0 2047 [root@docker shm]# dd if=/dev/zero of=bigfile bs=1M count=200 200+0 records in 200+0 records out 209715200 bytes (210 MB) copied, 0.101575 s, 2.1 GB/s [root@docker shm]# free -m total used free shared buff/cache available Mem: 991 135 72 210 783 458 Swap: 2047 2 2045 [root@docker shm]# dd if=/dev/zero of=bigfile bs=1M count=300 300+0 records in 300+0 records out 314572800 bytes (315 MB) copied, 0.135642 s, 2.3 GB/s # 我们看到并没有生效??? [root@docker shm]# free -m total used free shared buff/cache available Mem: 991 134 83 309 773 363 Swap: 2047 3 2044 [root@docker shm]# id root uid=0(root) gid=0(root) groups=0(root) [root@docker shm]# cd /sys/fs/cgroup/memory/ [root@docker memory]# cd x2/ [root@docker x2]# cd - /sys/fs/cgroup/memory # 怎么发生联系 # 因为这个命令不是持续运行的 就不能往task里面去写 [root@docker memory]# cd /dev/shm [root@docker shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M count=100 100+0 records in 100+0 records out 104857600 bytes (105 MB) copied, 0.0366051 s, 2.9 GB/s [root@docker shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M count=200 200+0 records in 200+0 records out 209715200 bytes (210 MB) copied, 0.0755738 s, 2.8 GB/s # 为什么还是可以呢??超过了我们的256M的限制 [root@docker shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M count=300 300+0 records in 300+0 records out 314572800 bytes (315 MB) copied, 0.352022 s, 894 MB/s [root@docker shm]# free -m total used free shared buff/cache available Mem: 991 191 126 209 674 405 Swap: 2047 103 1944 [root@docker shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M count=400 400+0 records in 400+0 records out 419430400 bytes (419 MB) copied, 0.33249 s, 1.3 GB/s [root@docker shm]# free -m total used free shared buff/cache available Mem: 991 134 126 266 730 405 Swap: 2047 146 1901 [root@docker shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M count=450 450+0 records in 450+0 records out 471859200 bytes (472 MB) copied, 0.411024 s, 1.1 GB/s [root@docker shm]# free -m total used free shared buff/cache available Mem: 991 134 125 267 731 405 # 在物理内存不够的情况下 使用了swap分区 [root@docker x2]# cat memory.limit_in_bytes 268435456 [root@docker x2]# echo 268435456 >memory.memsw.limit_in_bytes -bash: echo: write error: Device or resource busy [root@docker x2]# cd - /sys/fs/cgroup/memory [root@docker memory]# ls cgroup.clone_children memory.memsw.limit_in_bytes cgroup.event_control memory.memsw.max_usage_in_bytes cgroup.procs memory.memsw.usage_in_bytes cgroup.sane_behavior memory.move_charge_at_immigrate docker memory.numa_stat memory.failcnt memory.oom_control memory.force_empty memory.pressure_level memory.kmem.failcnt memory.soft_limit_in_bytes memory.kmem.limit_in_bytes memory.stat memory.kmem.max_usage_in_bytes memory.swappiness memory.kmem.slabinfo memory.usage_in_bytes memory.kmem.tcp.failcnt memory.use_hierarchy memory.kmem.tcp.limit_in_bytes notify_on_release memory.kmem.tcp.max_usage_in_bytes release_agent memory.kmem.tcp.usage_in_bytes system.slice memory.kmem.usage_in_bytes tasks memory.limit_in_bytes user.slice memory.max_usage_in_bytes x2 memory.memsw.failcnt [root@docker memory]# cd /dev/shm/ [root@docker shm]# ls bigfile [root@docker shm]# rm -rf bigfile #报错的解决 [root@docker shm]# cd - /sys/fs/cgroup/memory [root@docker memory]# ls cgroup.clone_children memory.memsw.limit_in_bytes cgroup.event_control memory.memsw.max_usage_in_bytes cgroup.procs memory.memsw.usage_in_bytes cgroup.sane_behavior memory.move_charge_at_immigrate docker memory.numa_stat memory.failcnt memory.oom_control memory.force_empty memory.pressure_level memory.kmem.failcnt memory.soft_limit_in_bytes memory.kmem.limit_in_bytes memory.stat memory.kmem.max_usage_in_bytes memory.swappiness memory.kmem.slabinfo memory.usage_in_bytes memory.kmem.tcp.failcnt memory.use_hierarchy memory.kmem.tcp.limit_in_bytes notify_on_release memory.kmem.tcp.max_usage_in_bytes release_agent memory.kmem.tcp.usage_in_bytes system.slice memory.kmem.usage_in_bytes tasks memory.limit_in_bytes user.slice memory.max_usage_in_bytes x2 memory.memsw.failcnt [root@docker memory]# cd x2/ [root@docker x2]# echo 268435456 >memory.memsw.limit_in_bytes # 这两个文件的意义:物理内存和swap加起来一共可用256M 以上设置表明:物理内存和swap分区共同只能使用256M ####此时实验成功 [root@docker shm]# cgexec -g memory:x2 dd if=/dev/zero of=bigfile bs=1M count=300 Killed [root@docker shm]# free -m total used free shared buff/cache available Mem: 991 133 126 267 731 405 Swap: 2047 0 2047 docker run -it --memory 256M --memory-swap=256M ubuntu #如果在启动容器时只指定 -m 而不指定 --memory-swap,那么--memory-swap 默认为-m的两倍 block io #对磁盘的读写限制 # 每s读/写的数据量 blkio.throttle.read_bps_device blkio.throttle.write_bps_device # 每s读/写的操作次数 blkio.throttle.write_iops_device blkio.throttle.write_bps_device [root@docker blkio]# docker run --help |grep device --blkio-weight-device list Block IO weight (relative device --device list Add a host device to the container --device-cgroup-rule list Add a rule to the cgroup allowed devices list --device-read-bps list Limit read rate (bytes per second) from a device (default []) --device-read-iops list Limit read rate (IO per second) from a device (default []) --device-write-bps list Limit write rate (bytes per second) to a device (default []) --device-write-iops list Limit write rate (IO per second) to a device (default []) [root@docker blkio]# ll /dev/vda brw-rw---- 1 root disk 252, 0 Oct 24 15:41 /dev/vda [root@docker blkio]# ll /dev/vda brw-rw---- 1 root disk 252, 0(设备号) Oct 24 15:41 /dev/vda [root@docker blkio]# echo "252:0 1048576" > blkio.throttle.write_bps_device [root@docker blkio]# cat blkio.throttle.write_bps_device 252:0 1048576 ##1Mbps 1024* 1024 # 测试:好像没有生效 # 注意:当前block io限制只对direct io 有效(不适用文件系统缓存) [root@docker ~]# cgexec -g blkio:x3 dd if=/dev/zero of=testfile bs=1M count=10 10+0 records in 10+0 records out 10485760 bytes (10 MB) copied, 0.00381529 s, 2.7 GB/s [root@docker blkio]# ll /dev/vda brw-rw---- 1 root disk 252, 0 Oct 24 15:48 /dev/vda [root@docker blkio]# echo "252:0 1048576" > blkio.throttle.write_bps_device [root@docker blkio]# cgexec -g blkio:x3 dd if=/dev/zero of=/mnt/westosfile bs=1M count=10 oflag=direct 10+0 records in 10+0 records out 10485760 bytes (10 MB) copied, 10.0025 s, 1.0 MB/s #控制非常精准 [root@docker blkio]# docker run -it --name vm2 --device-write-bps /dev/sda:1MB ubuntu root@b9e61aad4a99:/# dd if=/dev/zero of=westos bs=1M count=10 oflag=direct #oflag=direct将跳过内存缓存 """ direct 模式就是把写入请求直接封装成io 指令发到磁盘 非direct 模式,就把数据写入系统缓存,然后就认为io 成功,并由操作系统决定缓存中的数据什么时候被写入磁盘 """ 10+0 records in 10+0 records out 10485760 bytes (10 MB) copied, 10.0021 s, 1.0 MB/s [root@docker ~]# cd /sys/fs/cgroup/ [root@docker cgroup]# ls blkio cpu,cpuacct freezer net_cls perf_event cpu cpuset hugetlb net_cls,net_prio pids cpuacct devices memory net_prio systemd [root@docker cgroup]# cd blkio/ [root@docker blkio]# ls blkio.io_merged blkio.throttle.read_bps_device blkio.io_merged_recursive blkio.throttle.read_iops_device blkio.io_queued blkio.throttle.write_bps_device blkio.io_queued_recursive blkio.throttle.write_iops_device blkio.io_service_bytes blkio.time blkio.io_service_bytes_recursive blkio.time_recursive blkio.io_serviced blkio.weight blkio.io_serviced_recursive blkio.weight_device blkio.io_service_time cgroup.clone_children blkio.io_service_time_recursive cgroup.event_control blkio.io_wait_time cgroup.procs blkio.io_wait_time_recursive cgroup.sane_behavior blkio.leaf_weight docker blkio.leaf_weight_device notify_on_release blkio.reset_stats release_agent blkio.sectors system.slice blkio.sectors_recursive tasks blkio.throttle.io_service_bytes user.slice blkio.throttle.io_serviced x3 [root@docker blkio]# cd docker/ [root@docker docker]# ls b9e61aad4a99aedcb42c9e827c82909a2ff6efac705055b6d5fbedc990eb9e07 blkio.io_merged blkio.io_merged_recursive blkio.io_queued blkio.io_queued_recursive blkio.io_service_bytes blkio.io_service_bytes_recursive blkio.io_serviced blkio.io_serviced_recursive blkio.io_service_time blkio.io_service_time_recursive blkio.io_wait_time blkio.io_wait_time_recursive blkio.leaf_weight blkio.leaf_weight_device blkio.reset_stats blkio.sectors blkio.sectors_recursive blkio.throttle.io_service_bytes blkio.throttle.io_serviced blkio.throttle.read_bps_device blkio.throttle.read_iops_device blkio.throttle.write_bps_device blkio.throttle.write_iops_device blkio.time blkio.time_recursive blkio.weight blkio.weight_device cgroup.clone_children cgroup.event_control cgroup.procs notify_on_release tasks [root@docker docker]# cd b9e61aad4a99aedcb42c9e827c82909a2ff6efac705055b6d5fbedc990eb9e07 [root@docker b9e61aad4a99aedcb42c9e827c82909a2ff6efac705055b6d5fbedc990eb9e07]# ls blkio.io_merged blkio.sectors_recursive blkio.io_merged_recursive blkio.throttle.io_service_bytes blkio.io_queued blkio.throttle.io_serviced blkio.io_queued_recursive blkio.throttle.read_bps_device blkio.io_service_bytes blkio.throttle.read_iops_device blkio.io_service_bytes_recursive blkio.throttle.write_bps_device blkio.io_serviced blkio.throttle.write_iops_device blkio.io_serviced_recursive blkio.time blkio.io_service_time blkio.time_recursive blkio.io_service_time_recursive blkio.weight blkio.io_wait_time blkio.weight_device blkio.io_wait_time_recursive cgroup.clone_children blkio.leaf_weight cgroup.event_control blkio.leaf_weight_device cgroup.procs blkio.reset_stats notify_on_release blkio.sectors tasks [root@docker b9e61aad4a99aedcb42c9e827c82909a2ff6efac705055b6d5fbedc990eb9e07]# cat blkio.throttle.write_bps_device 8:0 1048576 [root@docker b9e61aad4a99aedcb42c9e827c82909a2ff6efac705055b6d5fbedc990eb9e07]# """ [root@docker ~]# ll /dev/sda brw-rw---- 1 root disk 8, 0 Oct 24 15:48 /dev/sda """ 限制用户 [root@docker shm]# cat /etc/cgrules.conf # /etc/cgrules.conf #The format of this file is described in cgrules.conf(5) #manual page. # # Example: #<user> <controllers> <destination> #@student cpu,memory usergroup/student/ #peter cpu test1/ #% memory test2/ # End of file # 这个用户所占用的内存 dd memory x2/ [root@docker ~]# systemctl start cgred [root@docker ~]# systemctl status cgred ● cgred.service - CGroups Rules Engine Daemon Loaded: loaded (/usr/lib/systemd/system/cgred.service; disabled; vendor preset: disabled) Active: active (running) since Thu 2019-10-24 16:17:27 CST; 5s ago Process: 13737 ExecStart=/usr/sbin/cgrulesengd $OPTIONS (code=exited, status=0/SUCCESS) Main PID: 13738 (cgrulesengd) Tasks: 1 Memory: 3.1M CGroup: /system.slice/cgred.service └─13738 /usr/sbin/cgrulesengd -s -g cgred Oct 24 16:17:27 docker systemd[1]: Starting CGroups Rules Engine Daemon... Oct 24 16:17:27 docker systemd[1]: Started CGroups Rules Engine Daemon. [root@docker ~]# su - dd [dd@docker ~]$ id dd uid=1000(dd) gid=1000(dd) groups=1000(dd) [dd@docker ~]$ cd /dev/shm/ [dd@docker shm]$ ls [dd@docker shm]$ dd if=/dev/zero of=dd bs=1M count=100 100+0 records in 100+0 records out 104857600 bytes (105 MB) copied, 0.0361387 s, 2.9 GB/s [dd@docker shm]$ dd if=/dev/zero of=dd bs=1M count=200 200+0 records in 200+0 records out 209715200 bytes (210 MB) copied, 0.0688063 s, 3.0 GB/s [dd@docker shm]$ dd if=/dev/zero of=dd bs=1M count=300 Killed ##隔离并不彻底 [root@docker x2]# docker run -it --memory-swap 256M --memory 256M ubuntu root@b6b9af37fc2f:/# free -m total used free shared buffers cached Mem: 991 871 119 266 6 614 -/+ buffers/cache: 250 740 Swap: 2047 1 2046 root@b6b9af37fc2f:/# exit exit [root@docker x2]# free -m total used free shared buff/cache available Mem: 991 140 143 266 707 400 Swap: 2047 1 2046
    Processed: 0.011, SQL: 9