当多个容器在 AWS Batch 上并行运行时,带有 Selenium 和 Chrome Webdriver 的 Doc



我们正在运行AWS Batch作业,这些作业启动Docker容器以运行Selenium和Chrome与python 3.6。 当我们将其设置为每个服务器运行多个容器时,作业通常会启动,运行几分钟,然后崩溃并显示chrome not reachable

File "/home/seluser/.local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 597, in find_element_by_css_selector
return self.find_element(by=By.CSS_SELECTOR, value=css_selector)
File "/home/seluser/.local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 966, in find_element
'value': value})['value']
File "/home/seluser/.local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 320, in execute
self.error_handler.check_response(response)
File "/home/seluser/.local/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: chrome not reachable
(Session info: chrome=79.0.3945.117)

当我们更改 Batch 配置以确保每个服务器只有一个容器时,所有作业都已成功通过。

似乎在同一服务器上运行的多个作业相互干扰。它们应该隔离在自己的 Docker 容器中,那么会发生什么?我们如何找出问题所在并加以预防?

配置允许每个服务器有多个容器,以便我们可以在更少的服务器上运行更多作业。尝试访问 Chrome 时,许多作业使用此配置运行时都会崩溃。

批处理作业定义 - 每个服务器多个容器:

  • 虚拟处理器 1
  • 内存 3072 MiB

批处理计算环境 - 每个服务器多个容器:

  • 最小 vCPU 数 0
  • 所需的 vCPU 0
  • 最大 vCPU 数 20
  • 最佳实例类型
  • 分配策略BEST_FIT

允许每个服务器使用单个容器的配置。所有工作都成功,但我们需要更多的服务器。

批处理作业定义 - 每个服务器一个容器:

  • 虚拟处理器 2
  • 内存 7168 MiB

计算环境 - 每个服务器一个容器:

  • 最小 vCPU 数 0
  • 所需的 vCPU 0
  • 最大 vCPU 数 20
  • 实例规格 m4.large
  • 分配策略BEST_FIT

这会强制每个服务器使用一个容器,因为 m4.large 有 2 个 vCPU,并且作业定义指定了 2 个 vCPU。

AWS Batch 环境:ECS Docker:版本 18.09.9-ce,内部版本 039a7df

这些是 ECS 运行容器时使用的标志:

root       4824      1  8 19:04 ?        00:00:39 /usr/bin/dockerd 
--default-ulimit nofile=1024:4096 --storage-driver devicemapper 
--storage-opt dm.thinpooldev=/dev/mapper/docker-docker--pool 
--storage-opt dm.use_deferred_removal=true --storage-opt dm.use_deferred_deletion=true 
--storage-opt dm.fs=ext4 --storage-opt dm.use_deferred_deletion=true

以下是我们如何设置硒/铬:

import pyvirtualdisplay
from selenium import webdriver
pyvirtualdisplay.Display(visible=False, size=(1900, 1200))
options = webdriver.ChromeOptions()
prefs = {}
prefs["download.default_directory"] = self.download_dir
prefs["plugins.always_open_pdf_externally"] = True
prefs["profile.default_content_setting_values.automatic_downloads"] = 1
prefs["plugins.plugins_list"] = [{"enabled": False, "name": "Chrome PDF Viewer"}]
options.add_experimental_option("prefs", prefs)
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--no-sandbox")
driver = webdriver.Chrome(
chrome_options=self._options(),
service_log_path=os.path.join(config.WORKING_DIRECTORY, "driver.log"))

我们已经尝试过但现在未使用的其他开关:

  • --headless- 改用 pyvirtualdisplay 来解决与等待文件以无头 chrome 显示download_dir相关的超时
  • 问题
  • --disable-gpu- 不适用,因为我们在 Linux 上运行
  • --disable-setuid-sandbox- 与--no-sandbox重叠

问题是 AWS Batch 创建了具有host网络的 docker 容器,当我们尝试运行多个 Xvfb 实例时,这会导致端口冲突。

更多详情:

http://elementalselenium.com/tips/38-headless 听起来像我们看到的:

如果您在同一时间跨不同版本无头运行测试 时间(例如,并行(在您的 CI 服务器上,然后作业将开始 意外中断。这是因为显示端口与 Xvfb(例如,两个或多个 Xvfb 会话尝试在同一设备上运行 同时显示端口(。

https://forums.aws.amazon.com/thread.jspa?threadID=254487

AWS Batch 通过 ECS 代理与计算资源通信,该代理 被指示在网络模式设置为"主机"的情况下启动作业,就像您一样 已经确定。目前,该服务不适用于运行作业 正在侦听容器中的外部网络请求 实例。

https://docs.docker.com/network/host/

如果对容器使用主机网络模式,则该容器的 网络堆栈未与 Docker 主机(容器(隔离 共享主机的网络命名空间(,并且容器不共享 分配自己的 IP 地址。例如,如果您运行一个容器 绑定到端口 80 并且您使用主机网络,容器的 应用程序在主机 IP 地址上的端口 80 上可用。

man Xserver

:d播放号码 X 服务器作为给定的显示编号运行,默认情况下 为 0。 如果多个 X 服务器要同时在 主机,每个主机都必须具有唯一的显示编号。

我们使用PyVirtualDisplay来包装Xvfb。但是 PyVirtualDisplay 在启动 Xvfb 时不会添加显示参数(即 :123(。我尝试添加check_startup=True,但失败了XStartTimeoutError('No display number returned by X server',)

xvfbwrapper"随机选择一个显示号码,并试图获取这个号码的锁"。Xvfb 命令行看起来像 Xvfb :35877838 -screen 0 1900x1200x24

使用此配置,我们成功地运行了每个服务器具有多个容器的作业。

相关内容

  • 没有找到相关文章

最新更新