如何解决容器中nginx worker process自动设置的问题

栏目: IT技术 · 发布时间: 5年前

内容简介:nginx容器化时,有一个普遍会遇到的问题:如何自动设置nginx worker process的数量?nginx官方容器镜像的nginx.conf配置文件中,会有一条worker process配置:它会配置nginx仅启动1个worker。这在nginx容器为1核时,可以良好的工作。

问题描述

nginx容器化时,有一个普遍会遇到的问题:如何自动设置nginx worker process的数量?

nginx官方容器镜像的nginx.conf配置文件中,会有一条worker process配置:

worker_processes  1;

它会配置nginx仅启动1个worker。这在nginx容器为1核时,可以良好的工作。

当我们希望nginx给更高的配置,例如4c或者16c,我们需要确保nginx也能启动响应个数的worker process。有两个办法:

  1. 修改nginx.conf,将worker_processes的个数调整为对应的cpu核数。
  2. 修改nginx.conf,将worker_processes修改为auto。

第一个方法可行,但是需要修改配置文件,nginx需要reload。实际部署时,必须将nginx.conf作为配置文件挂载,对一些不太熟悉nginx的用来说,心智负担会比较重。

第二个方法,在Kubernetes上会遇到一些问题。通过在容器中观察可以发现,nginx启动的worker process,并没有遵循我们给Pod设置的limit,而是与Pod所在node的cpu核数保持一致。

这在宿主机的cpu核数比较多,而Pod的cpu配置较小时,会因为每个worker分配的时间片比较少,带来明显的响应慢的问题。

问题原因

我们知道,在Kubernetes为容器配置cpu的limits为2时,容器其实并不是真正的“分配了”2个cpu,而是通过cgroup进行了限制。

resources:
          limits:
            cpu: 500m
            memory: 256Mi
          requests:
            cpu: 500m
            memory: 256Mi

我们到这个Pod所在宿主机上去查看相关信息。

# docker inspect 17f5f35c3500|grep -i cgroup
            "Cgroup": "",
            "CgroupParent": "/kubepods/burstable/podb008ccda-9396-11ea-bc20-ecf4bbd63ee8",
            "DeviceCgroupRules": null,
# cd /sys/fs/cgroup/cpu/kubepods/burstable/podb008ccda-9396-11ea-bc20-ecf4bbd63ee8
# cat cpu.cfs_quota_us
200000
# cat cpu.cfs_period_us
100000

可以看到,实际是通过 cpu.cfs_quota_us/cpu.cfs_period_us 来限制该Pod能使用的cpu核数的。

但是nginx的worker_processes,是通过 sysconf(_SC_NPROCESSORS_ONLN) 来查询宿主机上的cpu个数的(getconf _NPROCESSORS_ONLN),我们通过strace来观察下这个过程。

# strace getconf _NPROCESSORS_ONLN
execve("/bin/getconf", ["getconf", "_NPROCESSORS_ONLN"], [/* 23 vars */]) = 0
brk(0)                                  = 0x606000
...
open("/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3
read(3, "0-31\n", 8192)                 = 5
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 5), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6a922a0000
write(1, "32\n", 332

可见, getconf _NPROCESSORS_ONLN 实际是通过读取文件 /sys/devices/system/cpu/online 来获取cpu个数的。

默认Kubernetes上, /sys/devices/system/cpu/online 文件实际就是宿主机的,因此,nginx启动的worker process个数,与宿主机cpu个数一致,也就不奇怪了。

解决方案

解决方案实际也不难想到,修改容器中的 /sys/devices/system/cpu/online 就行了。

社区的lxcfs已经解决了这个问题。

lxcfs

LXCFS是一个小型的FUSE文件系统,其目的是让 Linux 容器感觉更像一个虚拟机。LXCFS会关注的procfs中的关键文件:

/proc/cpuinfo
/proc/diskstats
/proc/meminfo
/proc/stat
/proc/swaps
/proc/uptime
/sys/devices/system/cpu/online

可以看到,我们需要的 /sys/devices/system/cpu/online 文件,也在lxcfs关注列表中。

lxcfs的使用方法也比较简单,只要将宿主机的 /var/lib/lxc/lxcfs/proc/online 挂载到容器的 /sys/devices/system/cpu/online 就可以了。

containers:
      - args:
        - infinity
        command:
        - sleep
        volumeMounts:
        - mountPath: /sys/devices/system/cpu/online
          name: lxcfs-2
          readOnly: true
      volumes:
      - hostPath:
          path: /var/lib/lxc/lxcfs/proc/online
          type: ""
        name: lxcfs-2

当我们在容器中读取 /sys/devices/system/cpu/online 文件时,由于kubelet将该文件绑定了 /var/lib/lxc/lxcfs/proc/online ,该read请求会交给lxcfs daemon来处理。

lxcfs实际处理的函数如下。

int max_cpu_count(const char *cg)
{
	__do_free char *cpuset = NULL;
	int rv, nprocs;
	int64_t cfs_quota, cfs_period;
	int nr_cpus_in_cpuset = 0;

	read_cpu_cfs_param(cg, "quota", &cfs_quota);
	read_cpu_cfs_param(cg, "period", &cfs_period);

	cpuset = get_cpuset(cg);
	if (cpuset)
		nr_cpus_in_cpuset = cpu_number_in_cpuset(cpuset);

	if (cfs_quota <= 0 || cfs_period <= 0){
		if (nr_cpus_in_cpuset > 0)
			return nr_cpus_in_cpuset;

		return 0;
	}

	rv = cfs_quota / cfs_period;

	/* In case quota/period does not yield a whole number, add one CPU for
	 * the remainder.
	 */
	if ((cfs_quota % cfs_period) > 0)
		rv += 1;

	nprocs = get_nprocs();
	if (rv > nprocs)
		rv = nprocs;

	/* use min value in cpu quota and cpuset */
	if (nr_cpus_in_cpuset > 0 && nr_cpus_in_cpuset < rv)
		rv = nr_cpus_in_cpuset;

	return rv;
}

根据前面的信息,可以看到最终返回的值为 200000/100000 = 2。

结论

因此,当有lxcfs的加持时,nginx可以放心的将worker_processes配置为 auto ,不需要担心启动了过多的worker processes。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning Processing

Learning Processing

Daniel Shiffman / Morgan Kaufmann / 2008-08-15 / USD 49.95

Book Description Teaches graphic artists the fundamentals of computer programming within a visual playground! Product Description This book introduces programming concepts in the context of c......一起来看看 《Learning Processing》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

随机密码生成器
随机密码生成器

多种字符组合密码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具