ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Docker安全管理

2026/9/24 17:33:19 拓冰建站 浏览量
Docker安全管理 目录一.Docker安全介绍1.1概述二.容器资源控制——Cgroup2.1概述2.2CPU资源限制2.3CPU优先级2.4内存资源限制2.4.1简单介绍2.4.2手动创建内存资源控制组2.4.3使用工具创建内存资源控制组2.4.4永久保存内存资源控制组2.4.5将内存资源限制赋予给用户2.4.6出现问题2.5 磁盘IO限制Block IO2.5.1限制容器的下载速率2.5.2查看容器的设备帮助三.lxcfs隔离3.1概述3.2安装软件3.3完成lxcfs资源隔离3.4查看容器资源四.容器特权——privileged4.1概述4.2使用特权进入容器五.容器白名单——cap5.1概述5.2添加白名单六.容器集群——docker swarm6.1概述一.Docker安全介绍1.1概述Docker容器的安全性很大程度上依赖于Linux系统自身评估Docker的安全性时主要考虑以下几个方面Linux内核的命名空间机制提供的容器隔离安全Linux控制组机制对容器资源的控制能力安全。Linux内核的能力机制所带来的操作权限安全Docker程序特别是服务端本身的抗攻击性。其他安全增强机制对容器安全性的影响。1.Linux 内核命名空间安全让容器内的进程“看不到”其他容器和宿主机的进程、网络、挂载点等。2.Cgroups控制组资源安全限制容器能使用的 CPU、内存、磁盘 I/O、进程数等防止单个容器耗尽宿主机资源DoS。3.操作权限安全将 root 的“超级权限”拆分成几十种细粒度能力Docker 默认丢弃大部分危险能力。4.Docker 程序自身的抗攻击性Docker 架构中Docker Daemondockerd以 root 运行是最大的攻击面。5.其他安全特性在内核中启用GRSEC和PAX这将增加更多的编译和运行时的安全检查自定义更加严格的访问控制机制来定制安全策略使用一些有增强安全特性的容器模板 在文件系统挂载到容器内部时可以通过配置只读模式来避免容器内的应用通过文件系统破坏外部环境。二.容器资源控制——Cgroup2.1概述1.说明Cgorups是Linux 内核中的一个功能它的核心作用是完成限制、用户和管理进程组。Cgroups实现了对系统资源如CPU、I/O、内存、磁盘等的精细控制它允许系统管理员对一个进程的资源分配和限制该进程无法无限制地使用系统资源。容器本质上就是一个进程因此Cgroups也能够实现对容器的资源分配和限制。总的来说Cgroups能够限制一个进程使用资源的最大上限还能完成进程的优先级设置数量统计和资源控制等等。2.Linux Cgroups 的全称是Linux Control Group。限制一个进程组能够使用的资源上限包括CPU、内存、磁盘、网络带宽等等。对进程进行优先级设置、审计以及将进程挂起和恢复等操作。3.Linux Cgroups 给用户暴露出来的操作接口是文件系统它以文件和目录的方式组织在操作系统的/sys/fs/cgroup 路径下。执行此命令查看mount -t cgroup4/在/sys/fs/cgroup下面有很多诸如cpuset、cpu、memory 这样的子目录也叫子系统。在每个子系统下面为每个容器创建一个控制组即创建一个新目录。控制组下面的资源文件里填上什么值就靠用户执行docker run 时的参数指定。ll /sys/fs/cgroup2.2CPU资源限制1.作用创建一个交互式容器并限制CPU的使用量。docker run -it --cpu-period 100000 --cpu-quota 20000 --name web1 centos:7 #限制docker容器只能使用系统20%的CPU参数--cpu-period定义 CPU 调度的“时间周期”单位为微秒μs默认值为 100000即0.1 秒作用内核会在每个周期内分配 CPU 时间给容器周期越短调度越频繁资源分配越精细但会增加少量开销。取值范围1000 ~10000001 毫秒1 秒且必须是 1000 的倍数。--cpu-quota定义容器在一个周期内最多可使用的 CPU 时间单位同样为微秒。计算公式容器的 CPU 使用率限制 quota /period× 100% 20000 / 100000× 100% 20%。工作效率若 quota ≥ period如 quota 100000period 100000则容器可使用1 个完整 CPU 核心100%若 quota 200000则可使用 2 个核心200%。cpu_period 和cpu_quota 这两个参数需要组合使用用来限制进程在长度为cpu_period 的一段时间内只能被分配到总量为cpu_quota 的CPU 时间以上设置表示20%的cpu时间。2.测试同一个容器设置限制后不论在它内部启动多少个进程始终不会超过它的限制。2.1 在后台无限计算 /dev/zero 的 MD5 哈希值从而占满一个CPU核心。因为之前设置了docker容器只能占满20%CPU的限制所以docker容器只能占满20%CPU。md5sum /dev/zero ctrl p q #保持docker运行返回bash终端 top #查看系统进程2.2 再次执行无限计算MD5哈希值进程占满CPU核心可以发现系统20%的CPU备均分到两个进程中。docker exec -it web1 -- bash #再次进入docker 容器内部md5sum /dev/zero ctrl p q #保持docker运行返回bash终端 top #查看系统进程2.3释放资源说明fg会将后台暂停或正在运行的作业Job调回到前台继续在当前终端运行。docker attach web1 #进入容器内部 fg #释放资源 fg2.3CPU优先级1.概述CPU优先级是指当CPU资源竞争时优先级更高的进程能获得更多的CPU资源。docker run -it --rm --cpu-shares 100 centos:7--cpu-shares 100 设置容器权重为100默认权重是1024。2.测试当只有一个CPU时运行两个无限占用CPU的相同进程权重参数大的进程能够分到限制范围内更多的CPU资源2.1关闭虚拟机中的其他CPUcd /sys/devices/system/cpu #进入系统的CPU目录 ls | grep CPU #查看系统CPU个数 for c in cpu[1-9]*; do echo 0 $c/online; done #关闭除了CPU0外的其他CPU2.2开启两个消耗CPU的进程2.2.1正常执行容器拥有默认权重docker run -it --rm centos:7 #正常执行 md5sum /dev/zero ctrl p q #后台运行2.2.2设置容器权重为100docker run -it --rm --cpu-shares 100 centos:7 #设置容器权重 md5sum /dev/zero ctrl p q #后台运行结果如下第一个容器CPU为默认权重第二个CPU权重为100第一个容器的权重总占比为90%能够分配到一个CPU中90%的资源。top #查看容器内部的CPU使用情况2.4内存资源限制2.4.1简单介绍1.概述容器可用内存包括两个部分物理内存和swap交换分区。在对Docker容器进行设置时也是对这两个部分进行限额。限额后的容器内存资源不能超过这个阈值。2.基本语法作用设置一个容器的资源物理内存为200MB总内存资源为200MB,交换分区不分配内存资源。docker run -d --name demo --memory200M --memory-swap200M nginx参数--memory限制容器物理内存资源的使用量--memory-swap限制容器总内存物理内存swap交换分区的使用量若 memory-swap 未指定默认值则总上限为 memory × 2说明swap的使用量为总内存 - 物理内存3.测试说明限制容器只有物理内存资源为200MB,当在内存文件系统中创建一个大于200MB的文件时系统只会生成一个等于200MB的文件。3.1设置容器物理内存资源为200MBdocker run -d --name demo --memory200M --memory-swap200M nginx查看docker容器内部的内存资源docker inspect -f {{.HostConfig.Memory}} {{.HostConfig.MemorySwap}} demo参数--.HostConfig.Memory容器物理内存资源--.HostConfig.MemorySwap容器总内存资源3.2进入demo容器资源内部在内存文件系统中生成一个大文件说明这里数据为200MB没有写入成功是因为docker内存文件系统本身存在一些数据占用了一部分的内存资源。docker exec -it demo bash dd if/dev/zero of/dev/shm/bigfile bs1M count200 #在内存文件系统中生成一个200M的文件4.安装cgroup管理工具说明libcgroup-tools软件包它提供了一套管理 cgroup 的命令行工具方便你创建、删除 cgroup以及把进程加入 cgroup 或在指定 cgroup 中运行命令。yum install -y libcgroup-tools.x86_642.4.2手动创建内存资源控制组1.创建一个x1的内存资源系统cd /sys/fs/cgroup/memory mkdir x1 #创建一个cgroup控制组 cd x12.使用BC计算内存资源的字节数可选bc 200*1024*10243.添加内存资源限制说明这里提供两种方式使用字节数或者使用单位注意这里只限制了物理内存没有限制交换分区使用字节数echo 209715200 memory.limit_in_bytes #仅限制物理内存 echo 209715200 memory.memsw.usage_in_bytes #限制总内存使用内存单位echo 200M memory.limit_in_bytes #仅限制物理内存 echo 200M memory.memsw.usage_in_bytes #限制总内存4.使用x1内存文件系统生成一个300MB的文件说明由于之前对x1完成了资源限制该文件大小超出了x1的文件资源限制因此该进程最后会被杀死。但会在内存文件系统中留下一个与x1剩余资源大小相等的文件。cd /sys/fs/crgoup/memory/x1 cgexec -g memory:x1 dd if/dev/zero ofbigfile bs1M count300作用在内存 cgroupx1中运行dd把 300MB 的零数据写入当前目录下的bigfile文件。ll -h /dev/shm/bigfile #查看文件资源大小2.4.3使用工具创建内存资源控制组优点支持一次性创建出多个子系统1.使用 cgcreate 创建一个内存资源限制cgcreate -g memory:x1 cd /sys/fs/cgroup/memory ls2.添加内存资源限制cd x1 #进入x1控制组 echo 209715200 memory.limit_in_bytes #仅限制物理内存 echo 209715200 memory.memsw.usage_in_bytes #限制总内存3.使用x1资源组在内存文件系统下创建出一个300MB的大文件说明由于x1的资源限制该进程最后会被杀死cgexec -g memory:x1 dd if/dev/zero of/dev/shm/bigfile bs1M count3002.4.4永久保存内存资源控制组说明上面两种方式创建的资源控制组都是临时的。当重启系统后临时创建的资源控制组就会消失。因此我们需要把资源限制保存到文件中当系统重启后会读取该文件的内容自动创建资源组。1.创建文件vim /etc/cgconfig.conf #编辑资源配置文件添加以下内容group x1 { memory { memory.limit_in_bytes 209715200; #将物理内存设置成200MB memory.memsw.limit_in_bytes 209715200; #将资源组的总内存设置成200MB } }启动服务注意如果不设置开机自启重启后无法创建x1资源组systemctl enable --now cgconfig #设置开机自启2.测试说明系统重启后查看x1资源组是否被成功创建重启系统reboot #重启系统重启系统后查看资源组cd /sys/fs/cgroup/memory/ ls | grep x12.4.5将内存资源限制赋予给用户1.创建一个新用户useradd wzq2.编辑 cgrule 文件说明在这里将内存资源限制附加给特殊用户。路径/etc/cgrules.conf2.1进入文件内部vim /etc/cgrules.conf添加以下内容用户资源类型资源数据wzq memory x1/启动 cgrule 服务systemctl enable --now cgred3.完成测试说明切换进新用户在内存文件系统下创建一个200MB的文件查看能否创建成功。su - wzq #切换成wzq dd if/dev/zewro of/dev/shm/bigfile bs1M count200 ll /dev/shm/bigfile #查看文件大小2.4.6出现问题1.设备或资源繁忙无法写入资源限制原因简单来说已有的内存资源已经超出了你的资源限制你无法写入比你现有内存资源还小的资源限制。解决方法删除内存文件系统中之前存在的大内存文件写入成功2.5 磁盘IO限制Block IO2.5.1限制容器的下载速率说明限制容器的IO磁盘传输速率资源路径 /sys/fs/cgroup/blkiodocker run -it --name demo --derive-write-bps /dev/sda:30MB centos:7作用限制磁盘下载速率为30MBdd if/dev/zero ofbigfile bs1M count200 oflagdirect #指定使用磁盘下载如果不指定会出现下面的情况文件通过内存生成磁盘速率限制失败dd if/dev/zero ofbigfile bs1M count2002.5.2查看容器的设备帮助docker run --help | grep device三.lxcfs隔离3.1概述产生原因默认情况下由于docker容器使用的是Linux内核所以在容器内查看资源时只会看到系统资源无法看到容器中的资源情况如内存、cpu。概念Lxcfs提供了一个轻量级的用户态文件系统主要用于改善容器内部资源的可见性能够将容器内部使用的资源与系统的全部资源隔离解决容器中查看系统资源如 CPU、内存、负载等时显示宿主机资源信息的问题让容器内的资源视图更符合实际分配的限制。作用修正容器内的资源视图。lxcfs通过在容器内挂载特殊的文件系统替换 /proc 目录下的资源相关文件系统 如/proc/meminfo、/proc/cpuinfo等让容器内的命令读取到符合容器资源限制的信息而不是系统信息。lxcfs功能1.lxcfs用于管理一套基于容器资源限制生成的“虚拟资源文件”2.启动容器时通过挂载将容器内部的文件/proc/meminf等替换为lxcfs提供的虚拟文件3.容器内部执行的top、free等命令实际上读取的是容器内部的虚拟文件查看容器内部分配的资源3.2安装软件安装软件并启动服务yum install -y lxcfssystemctl start lxcfs systemctl enable lxcfs # 设置开机自启3.3完成lxcfs资源隔离docker run -it -m 256m \ #限制只能使用 256MB 物理内存 -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \ -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \ -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \ -v /var/lib/lxcfs/proc/stat:/proc/stat:rw \ -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \ -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \ centos:7参数:/proc/cpuinfo: CPU信息/proc/diskstats: 磁盘IO统计/proc/meminfo: 内存信息/proc/stat: 系统统计/proc/swaps: 交换分区信息/proc/uptime: 运行时间3.4查看容器资源说明: 在容器内部,查看容器的资源情况free -m四.容器特权——privileged4.1概述说明:默认情况下,我们进入容器时使用的是普通用户无权对容器做出太多改变。因此为了提高用户进入容器时的权限我们会使用特权进入容器将普通用户提高成root用户。4.2使用特权进入容器说明使用特权进入容器访问磁盘情况。普通用户无权访问只有加入容器特权才能看到。docker run -it --rm --privilegedtrue busybox--privileged添加容器特权fdisk -l #查看磁盘数据如果不使用特权进入容器会出现下面的情况docker run -it --rm busybox fdisk -l五.容器白名单——cap5.1概述说明由于--privilegedtrue 的权限非常大接近于宿主机的权限为了防止用户的滥用需要增加限制只提供给容器必须的权限。此时Docker 提供了权限白名单的机制使用--cap-add添加必要的权限。作用赋予容器某一个具体的权限而不是像privileged的全部权限--cpa-add #添加某一个权限 --cpa-drop #删除某一个权限设置权限如下NET_BIND_SERVICE 绑定 1024 以下端口NET_ADMIN 网络管理员CHOWN 改文件属主SETUID / SETGID 切换用户/组FOWNER 绕过文件属主检查FSETID 保留 setuid/setgid 位KILL 杀其他进程MKNOD 创建设备节点SETFCAP 设置文件 capabilitySETPCAP 修改进程 capabilitySYS_CHROOT chrootAUDIT_WRITE 写审计日志DAC_OVERRIDE 绕过文件权限检查5.2添加白名单说明添加网络管理员权限并为容器添加新网络docekr run -it --rm --cap-addNET_ADMIN busybox #添加网络管理员权限容器内部添加网络ip a a 10.0.0.1/24 dev eth0 #添加网络 ip a六.容器集群——docker swarm6.1概述它能把多台安装了 Docker 的机器组成一个集群让你像操作一台机器一样统一部署、扩缩容和管理容器。不过docker swarm仅适合中小规模的集群使用适用于简单的场景。更多的情况下我们会使用kubernetesk8s部署容器集群