我们有一个库,它使用POSIX消息队列在进程之间传递数据,并要求将msgqueue内核参数设置为无限,否则进程将返回一个错误too many open files
。通常我们使用ulimit -q
和ulimit -q unlimited
来查看/设置它,但是对于一些Kubernetes容器,我们希望能够通过go代码直接设置它。
我们已经确认,pod规范允许更改mqueue设置(通过securityContext对Kubernetes 1.14+),并且特定容器可以调整资源设置:
...
kind: Deployment
...
spec:
template:
spec:
securityContext:
sysctls:
- name: fs.mqueue.msg_max
value: "10000"
- name: fs.mqueue.msgsize_max
value: "102400"
containers:
- name: testing
securityContext:
capabilities:
add:
- SYS_RESOURCE
...
如果没有这些设置,即使ulimit -q unlimited
也会得到一个错误:
bash: ulimit: POSIX消息队列:无法修改限制:不允许操作
但是我们如何使用syscall.Setrlimit来调整代码中的限值呢?
发布于 2020-05-20 11:10:32
看起来,syscall包是在没有RLIMIT_MSGQUEUE = 0xC
常量的情况下被冻结的,它还定义了syscall.RLIM_INFINITY = -0x1
,在尝试使用该值时会导致错误:
syscall:限制常数-1溢出uint64
因此,您必须手动定义常量。
const RLIMIT_MSGQUEUE int = 0xC
const RLIM_INFINITY uint64 = 0xffffffffffffffff // https://github.com/golang/go/issues/22731
err = syscall.Setrlimit(RLIMIT_MSGQUEUE, &syscall.Rlimit{RLIM_INFINITY,RLIM_INFINITY}))
或者切换到使用https://godoc.org/golang.org/x/sys/unix中的方法
err = unix.Setrlimit(unix.RLIMIT_MSGQUEUE, &unix.Rlimit{Cur: unix.RLIM_INFINITY, Max: unix.RLIM_INFINITY})
还请注意,仅为该进程及其子进程设置了限制值,因此要确认您必须从代码中检查/proc/<pid>/limits
或调用Getrlimit/ulimit:
var rLimit syscall.Rlimit
err := syscall.Getrlimit(0xC, &rLimit)
if err != nil {
fmt.Println("Error Getting Rlimit ", err)
}
fmt.Println(rLimit)
// construct bash command
cmd := &exec.Cmd {
Path: "/bin/bash",
Args: []string{ "/bin/bash", "-c", "ulimit -q"},
Stdout: os.Stdout,
Stderr: os.Stdout,
}
// run `cmd` in background and wait for it to finish
cmd.Start()
cmd.Wait()
{18446744073709551615 18446744073709551615} 无限制
https://stackoverflow.com/questions/61921052
复制相似问题