如何阻止 Undertow 在 Cloud 运行 中触发来自 gVisor 的警告

How to stop Undertow triggering warnings from gVisor in Cloud Run

最近我的 Undertow 应用程序正在触发 Cloud 运行 报告以下内容:

Container Sandbox Limitation: Unsupported syscall setsockopt(0x13,0x1,0xa,0x3e05747fe5a0,0x4,0xfc1abc10). Please, refer to https://gvisor.dev/c/linux/amd64/setsockopt for more information.

我已经执行了 strace,似乎启用带外内联 (SO_OOBINLINE) 的套接字选项正在由 Undertow 发送。我已经明确告诉它不要在配置中这样做(两种方式),但它仍在发生。将 Undertow 与 Cloud 运行 一起使用似乎是一个合理的用例,但由于没有更深入地了解 Undertow 的带外内联是什么以及 gVisor 为何不支持这一点,我被阻止了哪个程序不合理。是 Undertow 做了其他网络服务器没有做的事情,还是 gVisor 太不成熟,无法处理这个特定的套接字功能?也许gVisor以后会支持,我只需要等待?

  def main(args: Array[String]): Unit = {
    val server = Undertow.builder
      .addHttpListener("8080", "0.0.0.0")
      .setHandler(defaultHandler)
      .setSocketOption[java.lang.Boolean](XnioOptions.TCP_OOB_INLINE, false)
      .setWorkerOption[java.lang.Boolean](XnioOptions.TCP_OOB_INLINE, false)
      .build
    server.start()
  }

我的回答涉及云 运行 托管容器中的服务 "listening"。我的回答不包括您的容器通过 TCP、gRPC 或 WebSockets 连接到 Cloud 运行 外部的 Anthos 或自定义应用程序。在您的问题中,您的示例是一个 HTTP 服务器,它是一个侦听器而不是客户端。

这不是 gVisor 的问题。第一步是了解 SO_OOBINLINE 的作用。

如果启用此选项,带外数据将包含在接收数据流中。否则,您必须在 recv() 调用期间使用标志 MSG_OOB 来获取带外数据。

现在,谁将向您发送带外 (msg) 数据? Google Cloud 运行 托管的前端是 Google 前端 (GFE)。这是 Google 用于云 运行 托管(以及许多其他 Google 服务)的代理和负载平衡器。 GFE 的接口是 HTTP/HTTPS。 client/browser 无法生成带外数据。客户端连接到 GFE。 GFE 连接到云 运行.

中的服务 运行

如果 gVisor 支持 SO_OOBINLINE,谁可以发送带外数据? Nobody/nothing 在 TCP/IP 链中,您可以 control/manage.

有一个 Internet 草案 Out-Of-Band' Content Coding for HTTP。我一直在关注这份文件。未来 HTTP 可能会支持这一点,但现在不会。

在您的问题中,您将 SO_OOBINLINE 设置为 false。这是默认情况 (false),因此不需要将其设置为 false。

注意:使用 OOB 有几个很好的理由,但它们很少见。 OOB 只是一个字节的数据。在 HTTP 世界中,如果出现问题,标准期望是一个状态代码来指示问题或重试情况。

How to stop Undertow triggering warnings from gVisor in Cloud Run

不要调用 API setSocketOption() 等价物。没有禁用 gVisor 警告的方法。