GitLab CI运行Selenium测试访问DVWA出现DNS解析错误如何解决
跨阶段保留服务容器的需求说明
你期望的分三个阶段且run-dvwa、run-selenium阶段的容器不退出到run-python阶段的需求无法实现,因为GitLab CI中不同阶段的Job运行在完全独立的执行环境中,前一个阶段的所有资源(包括启动的容器)会在阶段结束后自动销毁,无法共享给后续阶段。你当前将dvwa、selenium都配置为python测试Job的services的思路是正确的,同一个Job下的所有services容器会在整个Job执行期间保持运行,完全满足你要求的服务不退出、顺序执行测试的需求。
报错根因
你遇到的dnsNotFound错误核心是GitLab CI的Service之间默认网络隔离:只有Job的主容器(你这里的python:3容器)的/etc/hosts中会写入所有Service的别名解析记录,其他Service容器(即selenium容器)的/etc/hosts中没有dvwa的别名解析配置,因此运行在selenium容器内的火狐浏览器无法解析dvwa这个主机名,触发访问失败。你之前在主容器内执行curl http://dvwa:80/login.php成功,就是因为主容器有对应的解析记录。
可行解决方案
提供两种可直接落地的方案,按需选择即可:
方案1:自定义容器网络(稳定性高,无需改业务代码)
通过docker in docker服务手动管理容器,让dvwa和selenium在同一个自定义网络内实现互通,CI配置示例如下:
stages: - run python-test: stage: run image: python:3 services: - name: docker:dind alias: docker variables: DOCKER_HOST: tcp://docker:2376 DOCKER_TLS_CERTDIR: "/certs" DOCKER_DRIVER: overlay2 before_script: # 安装docker客户端 - apt update && apt install -y --no-install-recommends docker.io # 创建自定义互通网络 - docker network create test-net # 启动dvwa并加入网络 - docker run -d --name dvwa --network test-net --network-alias dvwa registry.gitlab.com/xxxx-yyy-demo/zzzzz-demo/dvwa-devops-demo # 启动selenium并加入网络 - docker run -d --name selenium --network test-net --network-alias selenium selenium/standalone-firefox:latest # 等待服务启动完成(可根据实际情况调整等待时长) - sleep 15 script: - pip install selenium - python tests.py after_script: # 测试完成后清理资源 - docker stop dvwa selenium - docker rm dvwa selenium
你的tests.py代码不需要做任何修改即可正常运行。
方案2:IP直连(改造成本低,无需调整CI服务配置)
在主容器内先获取dvwa的实际IP,再传给测试脚本让selenium直接通过IP访问dvwa:
- 修改CI的script部分:
python-test: services: - name: registry.gitlab.com/xxxx-yyy-demo/zzzzz-demo/dvwa-devops-demo alias: dvwa entrypoint: ["/main.sh"] - name: selenium/standalone-firefox:latest alias: selenium stage: run image: python:3 script: # 获取dvwa服务的实际IP - export DVWA_IP=$(getent hosts dvwa | awk '{ print $1 }') - curl http://$DVWA_IP:80/login.php - curl http://selenium:4444/wd/hub - pip install selenium # 将IP作为参数传给测试脚本 - python tests.py $DVWA_IP
- 修改
tests.py接收IP参数:
import sys from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities # 读取传入的dvwa IP dvwa_ip = sys.argv[1] driver = webdriver.Remote("http://selenium:4444/wd/hub", DesiredCapabilities.FIREFOX) server = f'http://{dvwa_ip}:80' driver.get(server + '/login.php')
内容的提问来源于stack exchange,提问作者sqr
相关产品推荐
相关产品推荐

