【问题标题】:Access IP of docker container at runtime运行时访问docker容器的IP
【发布时间】:2021-01-13 09:33:13
【问题描述】:

我有使用 selenium 编写的跨浏览器测试。因为我想在多个平台上测试多个浏览器,所以我使用 docker 虚拟化和 selenium 网格。我可以在没有 docker 的情况下通过 localhost:4444 使用 docker-compose.yml 执行我的测试

version: "3"
services:
  hub:
    image: selenium/hub
    ports:
      - "4444:4444"
    environment:
      GRID_MAX_SESSION: 16
      GRID_BROWSER_TIMEOUT: 3000
      GRID_TIMEOUT: 3000

  chrome:
    image: selenium/node-chrome
    container_name: web-automation_chrome
    depends_on:
      - hub
    environment:
      HUB_PORT_4444_TCP_ADDR: hub
      HUB_PORT_4444_TCP_PORT: 4444
      NODE_MAX_SESSION: 4
      NODE_MAX_INSTANCES: 4
    volumes:
      - /dev/shm:/dev/shm
    ports:
      - "9001:5900"

  firefox:
    image: selenium/node-firefox
    container_name: web-automation_firefox
    depends_on:
      - hub
    environment:
      HUB_PORT_4444_TCP_ADDR: hub
      HUB_PORT_4444_TCP_PORT: 4444
      NODE_MAX_SESSION: 2
      NODE_MAX_INSTANCES: 2
    volumes:
      - /dev/shm:/dev/shm
    ports:
      - "9002:5900"

  opera:
    image: selenium/node-opera
    container_name: web-automation_opera
    depends_on:
      - hub
    environment:
      HUB_PORT_4444_TCP_ADDR: hub
      HUB_PORT_4444_TCP_PORT: 4444
      NODE_MAX_SESSION: 2
      NODE_MAX_INSTANCES: 2
    volumes:
      - /dev/shm:/dev/shm
    ports:
      - "9003:5900"

我刚刚用 maven 执行了我的测试,它们会成功。然后我计划将我的浏览器 JUnit 测试也容器化并创建了这个 Dockerfile:

FROM openjdk:11 as build
WORKDIR /workspace/app

COPY .git .git
COPY mvnw .
COPY .mvn .mvn
COPY wait-for-it.sh .
RUN ["chmod", "+x", "wait-for-it.sh"]
COPY pom.xml .
COPY src src

RUN ./wait-for-it.sh hub:4444 -- ./mvnw clean package

FROM openjdk:11
VOLUME /tmp
COPY --from=build /workspace/app/target/*.jar app.jar

这也应该可以正常工作并将这部分添加到我的docker-compose.yml

  app:
    build: .
    ports:
      - "80:8080"
    depends_on:
      - "hub"

只要我运行docker-compose up,maven 就会成功构建测试,并且 selenium 网格设置成功,但我收到以下错误:

[ERROR] loginUserNotExistentFirefox  Time elapsed: 0.033 s  <<< ERROR!
org.openqa.selenium.remote.UnreachableBrowserException: 
Could not start a new session. Possible causes are invalid address of the remote server or browser start-up failure.
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: '7e67c412b3c0', ip: '172.17.0.2', os.name: 'Linux', os.arch: 'amd64', os.version: '4.19.121-linuxkit', java.version: '11.0.9.1'
Driver info: driver.version: RemoteWebDriver
        at org.seleniumtests.frontendtests.tests.TestLogin.loginUserNotExistentFirefox(TestLogin.java:29)
Caused by: java.net.UnknownHostException: hub
        at org.seleniumtests.frontendtests.tests.TestLogin.loginUserNotExistentFirefox(TestLogin.java:29)

这就是我计划从我的app 容器访问服务的方式。

    driver = new RemoteWebDriver(new URL("http://hub:4444/wd/hub"),
                                                             DesiredCapabilities.operaBlink());

【问题讨论】:

  • Failed to connect to localhost/127.0.0.1:4444 - 没有尝试访问hub,您似乎没有正确配置主机名。
  • 但是我哪里没有正确配置主机名?在我的测试中,我只是尝试达到http://localhost:4444/wd/hub,当我删除测试版本并手动docker-compose -f docker-compose.yml up -d 然后mvn clean install 时,测试运行得非常好。
  • 你的意思是如果你在外部 compose网络运行测试? localhost:4444 在该网络之外工作,因为ports: - "4444:4444" 会从您主机上的容器中公开该端口,但您需要在网络内部使用服务名称 (hub) 作为主机名.
  • 好的,我将案例中的 URL 更改为 driver = new RemoteWebDriver(new URL("http://hub:4444/wd/hub"),现在我收到了未知主机异常

标签: docker docker-compose selenium-grid docker-networking


【解决方案1】:

第一个问题:无法连接到 localhost:4444

你的服务之间有一个桥接器(默认情况下在 Docker Compose 中),你可以通过&lt;service_name&gt;:&lt;service_port&gt; 访问另一个服务,因此你可以通过hub:4444 访问 hub 服务。

第二个问题,解决第一个问题可能就是结果

来自官方 Docker Compose 文档,您可以阅读here

您可以使用 depends_on 选项控制服务启动和关闭的顺序。 Compose 总是按依赖顺序启动和停止容器,其中依赖由depends_on、links、volumes_from 和network_mode 确定:“service:...”。

就像你对depends_on所做的那样,但是

但是,对于启动,Compose 不会等到容器“准备好”(无论这对您的特定应用程序意味着什么)——只等到它运行。这是有充分理由的。

Docker Compose 官方解决方案

使用wait-for-itdockerize、sh 兼容wait-for 等工具,或 RelayAndContainers 模板。这些是您可以使用的小型包装脚本 可以包含在应用程序的映像中以轮询给定的主机和端口 直到它接受 TCP 连接。

他们建议你这样做:

version: "3"
services:
  hub:
    image: selenium/hub
    ports:
      - "4444:4444"
    environment:
      GRID_MAX_SESSION: 16
      GRID_BROWSER_TIMEOUT: 3000
      GRID_TIMEOUT: 3000

  app:
    build: .
    ports:
      - "80:8080"
    depends_on:
      - "hub"
    command: ["./wait-for-it.sh", "hub:4444", "--", "java", "-jar", "app.jar"]

【讨论】:

  • 我已将 testcontainer 替换为您的 app 容器,并替换了 docker 版本和集线器。我保留了我提供的 Dockerfile,然后尝试从我的容器访问hub:4444/wd/hub,但我得到了 UnknownHostException 集线器。我也下载了wait-for-it.sh
  • 感谢您注意到版本,将您的版本更改为 2 并不是故意的。我编辑了答案。你能给我们新的堆栈跟踪吗?
  • Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03' System info: host: '12bf5131313e', ip: '172.17.0.2', os.name: 'Linux', os.arch: 'amd64', os.version: '4.19.121-linuxkit', java.version: '11.0.9.1' Driver info: driver.version: RemoteWebDriver at org.seleniumtests.frontendtests.tests.TestLogin.loginUserNotExistentOpera(TestLogin.java:61) Caused by: java.net.UnknownHostException: hub: Name or service not known at org.seleniumtests.frontendtests.tests.TestLogin.loginUserNotExistentOpera(TestLogin.java:61)
  • 我认为这可能与docker package在等待执行之前执行测试有关。 docker是先执行命令还是先构建?
  • 如果你只运行docker-compose up,问题是你必须运行docker-compose build来重建你的镜像,然后再运行docker-compose up
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-07
  • 2020-12-23
  • 2021-12-10
  • 2016-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多