211工程院校贵州大学管理学院硕士研究生、全国百强城商行资讯科技部五级专技工程师、互联网金融行业资深DevOps研发工程师、金融科技运维自动化平台研发项目经理。曾在国内多家知名互联网公司 平安科技、微众银行、顺丰科技、魅族任职. 具有多年国内一线互联网公司自动化运维平台设计与开发经验。
1
前言
默认情况下,宿主机对运行中的容器能占用多少系统资源是没有限制的,因此运行中的容器可以使用宿主机内核调度程序所允许的尽可能多的系统资源。Docker提供了一种用来控制能够使用多少内存和CPU的方法——即在使用docker run命令启动容器时通过指定配置标识来实现。本节内容主要讲解的内容包括,何时应启用资源限制以及设置这些限制可能会产生的影响两部分。Docker通过cgroup来控制容器使用的资源配额,cgroup是Linux系统内核提供的一种用来限制、记录、隔离进程组所使用的物理资源的机制,能够实现对进程的分组化管理。2
CPU资源限制
Docker在创建容器时所支持的CPU限制选项包括:[root@localhost ~]# docker run --help | grep cpu--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period --cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota -c, --cpu-shares int CPU shares (relative weight) --cpus decimalNumber of CPUs --cpuset-cpus string CPUs in which to allow execution (0-3, 0,1) --cpuset-mems string MEMs in which to allow execution (0-3, 0,1)说明:--cpus:用来限制cpu的使用上限--cpu-period和--cpu-quota:组合起来限制cpu的使用上限,可以使用cpus替代--cpu-shares:用来设置CPU发生竞争时的权重比例,资源充足时没有效果--cpset-cpus:设置容器只能使用某个或某几个核心--cpuset-mems:设置容器使用的内存节点,只有在NUMA架构下才支持,有关NUMA架构的相关知识可参考文档:http://cenalulu.github.io/linux/numa/2.1
限制CPU的使用率
通过参数--cpus可限制容器可用的CPU使用率上限,若不做限制而直接启动容器,通过stress工具对容器的CPU使用做压力测试,那么最终宿主机的CPU资源将被耗尽,启动压测工具,如下所示:
[root@localhost ~]# docker run --rm -it polinux/stress stress --cpu 2 注:在stress压测工具中配置使用2个CPU,是因为笔者宿主机环境就是2个CPU。在Docker宿主机上使用htop工具,观察CPU使用情况,如下图所示:综上,由于未对容器做资源限制,运行了stress压测工具的容器,将会占满宿主机的两个CPU,每个CPU资源的使用率均为100%,合计为200%;接下来重新启动容器,在docker run命令中附加--cpus参数并设置其值为1.5,此时容器的CPU使用率被限制为150%,再次启动压测工具,如下所示:[root@localhost ~]# docker run --rm --cpus=1.5 -it polinux/stress stress --cpu 2 在Docker宿主机上使用htop工具,观察CPU使用情况,如下图所示:综上,2个CPU核心的使用率求和约为150%,这与预期相符合。在旧版v1.13之前不支持--cpus参数,限制容器CPU使用率可以通过参数--cpu-quota和--cpu-period配合实现,两个参数的单位均为微秒,其中--cpu-period是指调度周期,默认值为100ms;CPU使用率上限可通过公式--cpus = --cpu-quota --cpu-period 求得,在宿主机上与容器CPU使用率限制策略对应的cgroup配置位于/sys/fs/cgroup/cpu/docker路径下,目录结构如下所示:[root@localhost ~]# ls -l sys/fs/cgroup/cpu/docker/ total 0drwxr-xr-x 2 root root 0 Jun 21 18:15 7aad8ce1cd05f7a72d5cdac59bd1666e68b1eb831842ac2cd54a9c3fd3485798-rw-r--r-- 1 root root 0 Jun 20 11:37 cgroup.clone_children--w--w--w- 1 root root 0 Jun 20 11:37 cgroup.event_control-rw-r--r-- 1 root root 0 Jun 20 11:37 cgroup.procs-r--r--r-- 1 root root 0 Jun 20 11:37 cpuacct.stat-rw-r--r-- 1 root root 0 Jun 20 11:37 cpuacct.usage-r--r--r-- 1 root root 0 Jun 20 11:37 cpuacct.usage_percpu-rw-r--r-- 1 root root 0 Jun 20 11:37 cpu.cfs_period_us-rw-r--r-- 1 root root 0 Jun 20 11:37 cpu.cfs_quota_us-rw-r--r-- 1 root root 0 Jun 20 11:37 cpu.rt_period_us-rw-r--r-- 1 root root 0 Jun 20 11:37 cpu.rt_runtime_us-rw-r--r-- 1 root root 0 Jun 20 11:37 cpu.shares-r--r--r-- 1 root root 0 Jun 20 11:37 cpu.stat-rw-r--r-- 1 root root 0 Jun 20 11:37 notify_on_release-rw-r--r-- 1 root root 0 Jun 20 11:37 tasks在当前目录中,名为 7aad8ce1cd05f7a72d5cdac59bd1666e68b1eb831842ac2cd54a9c3fd3485798的目录是正在运行的stress服务容器的容器ID,该目录中存在文件cpu.cfs_period_us和cpu_quota_us,数值如下所示:[root@localhost 7aad8ce1cd05f7a72d5cdac59bd1666e68b1eb831842ac2cd54a9c3fd3485798]# cat cpu.cfs_period_us 100000[root@localhost 7aad8ce1cd05f7a72d5cdac59bd1666e68b1eb831842ac2cd54a9c3fd3485798]# cat cpu.cfs_quota_us 150000以上两个值相除得到的结果正好为1.5,与容器启动时指定的—cpus=1.5一致。
2.2
限制使用指定CPU
通过参数--cpuset-cpus可限制容器始终在某一个或某几个CPU上运行,这是非常有意义的,因为当前的CPU多核架构中,每个CPU核心都有自己的独占缓存,如果频繁的将进程调度在不同的核心上执行,会带来