我们有一个库,该库使用POSIX消息队列在进程之间传递数据,并且需要将msgqueue内核参数设置为Unlimited,否则该进程将返回错误too many open files
。通常我们使用ulimit -q
和ulimit -q unlimited
查看/设置此属性,但是对于某些Kubernetes容器,我们希望能够通过go代码直接设置。
我们已经确认pod规范允许更改队列设置(通过securityContext for 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 message queues: cannot modify limit: Operation not permitted
但是,我们将如何使用syscall.Setrlimit来调整代码中的极限值?
最佳答案
似乎syscall程序包被冻结而没有RLIMIT_MSGQUEUE = 0xC
常量,并且它还定义了syscall.RLIM_INFINITY = -0x1
,当尝试使用该值时会导致错误:
syscall: Rlimit constant -1 overflows 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}
unlimited
关于go - 将Go设置为Kubernetes容器的POSIX消息队列RLIMIT_MSGQUEUE为无限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61921052/