testcontainers - 无法连接到通用容器的公开端口

tru*_*ekr 3 java junit docker dockerfile testcontainers

我正在尝试使用 GenericContainer 启动自定义 docker 容器。\n容器启动后,我想从测试类执行 http 请求。\n我看到此错误:

\n
INFO: Exposed ports: 9000\n\njava.net.ConnectException: Failed to connect to localhost/0:0:0:0:0:0:0:1:9000\n    at org.testcontainers.shaded.okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:265)\n\nCaused by: java.net.ConnectException: Connection refused (Connection refused)\n    at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)\n\n
Run Code Online (Sandbox Code Playgroud)\n

该端口似乎已绑定:

\n
docker ps -a\nCONTAINER ID   IMAGE                                            COMMAND                  CREATED              STATUS              PORTS                                                                                      NAMES\nf311467dbd25   foo.bar.com/abc-def/testcontainer:4.30.65   "/bin/sh -c 'exec /o\xe2\x80\xa6"   About a minute ago   Up About a minute   0.0.0.0:55164->9000/tcp, :::55164->9000/tcp, 0.0.0.0:55163->9001/tcp, :::55163->9001/tcp   happy_jepsen\n
Run Code Online (Sandbox Code Playgroud)\n

我正在使用以下代码创建容器:

\n
        myContainerInstance = new GenericContainer<>(MY_CONTAINER_IMAGE)\n                .withNetworkAliases("foo")\n                .withCreateContainerCmdModifier(createContainerCmd -> createContainerCmd.withHostName("foo"))\n                .waitingFor(new WaitAllStrategy().withStrategy(new LogMessageWaitStrategy().withRegEx(".*Listening for HTTP on.*"))\n                        .withStartupTimeout(Duration.ofMinutes(4)))\n                .withExposedPorts(9000)\n
Run Code Online (Sandbox Code Playgroud)\n

客户端代码:

\n
    OkHttpClient client = new OkHttpClient();\n        String url = "http://localhost:9000/testget";\n        String output = run(url);\n        logger.info("Response is: " + output);\n\n    }\n    String run(String url) throws IOException {\n        Request request = new Request.Builder()\n                .url(url)\n                .addHeader("Content-type", "application/json")\n                .build();\n\n        try (Response response = client.newCall(request).execute()) {\n            return response.body().string();\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

额外细节:

\n
    \n
  1. lsof -i :9000 在我的本地计算机上不显示任何绑定端口
  2. \n
  3. waitForHttpPort的等待策略不起作用(容器启动超时)
  4. \n
\n

我将不胜感激任何帮助找出原因的帮助。

\n

小智 5

如果你说 testcontainers 公开端口 9000,这意味着将容器内的端口 9000 绑定到本地计算机上的某个空闲端口,但这并不意味着本地端口 9000 绑定到某些东西。

您可以询问容器暴露的容器端口绑定到哪个本地端口(例如containerinstance.getMappedPort(9000)

如果您的客户端不在容器中,则它必须连接到本地端口。如果它位于容器内部(或同一 docker 网络中的任何容器),请使用端口 9000。