go - 将Go设置为Kubernetes容器的POSIX消息队列RLIMIT_MSGQUEUE为无限

标签 go message-queue setrlimit

我们有一个库,该库使用POSIX消息队列在进程之间传递数据,并且需要将msgqueue内核参数设置为Unlimited,否则该进程将返回错误too many open files。通常我们使用ulimit -qulimit -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/

相关文章:

architecture - 发布订阅模型与主题交换

java - 使用 JMS 的 WebSphere MQ

c - 期望在 Linux 中 fd < 最大打开文件描述符数是否合理?

memory - POSIX 限制 : What exactly can we assume about RLIMIT_DATA?

go - 如何解析 "2019-09-19 04:03:01.770080087 +0000 UTC"时间戳

unit-testing - 用于文件创建的表驱动测试

java - 从 Jboss-as 7.1.1 中的 standalone.xml 外部化资源适配器配置

带有虚假身份或用户代理的 HTTP 请求

go - 如何在 Golang 程序中找到流氓写入 stderr 的位置?