【问题标题】:Setting POSIX message queues RLIMIT_MSGQUEUE to unlimited from Go for a Kubernetes container从 Go 为 Kubernetes 容器将 POSIX 消息队列 RLIMIT_MSGQUEUE 设置为无限制
【发布时间】:2020-09-07 06:56:13
【问题描述】:

我们有一个使用 POSIX 消息队列在进程之间传递数据的库,并且需要将 msgqueue 内核参数设置为无限制,否则该进程将返回错误 too many open files。通常我们使用ulimit -qulimit -q unlimited 来查看/设置它,但是对于一些Kubernetes 容器,我们希望能够通过go 代码直接设置它。

我们已经确认 pod 规范允许更改 mqueue 设置(通过 Kubernetes 1.14+ 的 securityContext)并且特定容器可以调整资源设置:

...
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 来调整我们代码中的限制值呢?

【问题讨论】:

    标签: go message-queue setrlimit


    【解决方案1】:

    看起来 syscall 包在没有 RLIMIT_MSGQUEUE = 0xC 常量的情况下被冻结,并且它还定义了 syscall.RLIM_INFINITY = -0x1,这会在尝试使用该值时导致错误:

    系统调用:Rlimit 常量 -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}

    无限

    【讨论】:

      猜你喜欢
      • 2014-11-06
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      • 2011-07-10
      • 2020-11-27
      • 1970-01-01
      • 1970-01-01
      • 2020-04-18
      相关资源
      最近更新 更多