背景:
我正在做一个接口自动化测试项目,使用到 docker + + jenkins + pytest 等, docker 中有三个容器,1是 jenkins,2是 mariadb 容器, 3是 jenkins 容器拉代码生成的 python 容器
希望实现的步骤是::
代码上传到 github ==> docker jenkins 容器拉下来, jekins 运行项目中的 build.sh 脚本, 启动 python 容器读取 db 容器的数据,执行后生成报告并上传。
现在遇到的问题是:
卡在了读取 db 容器这一步, 报错了
/usr/local/lib/python3.12/site-packages/pymysql/connections.py:352: in __init__
self.connect()
/usr/local/lib/python3.12/site-packages/pymysql/connections.py:668: in connect
raise exc
E pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 99] Cannot assign requested address)")
https://github.com/lhl02531/python-auto-test 测试代码仓库
http://testingpai.com/article/1644570535388 我参考这个 docker + jenkins 自动化教程
第一次问问题,有什么遗漏的地方请告诉我, 谢谢
做过的尝试:
- 怀疑是创建的 python 容器不能连接 db 容器,所以我又创建了 python 容器测试我的代码, 可是这个容器能连接上 db 容器, 也能正常执行 sql 语句
怀疑是 docker 网络模式,
docker network ls NETWORK ID NAME DRIVER SCOPE 1b86530159c4 bridge bridge local 97c9da1a063a host host local 9bda0cd1c26c none null local docker network inspect 1b86530159c4 [ { "Name": "bridge", "Id": "1b86530159c426c2dcc9f0b85ea032950e50935039378a8040c6bfc474761afa", "Created": "2024-01-24T11:36:19.039842097+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "2a653a1372fa4d2cfabde0d6f60d074d061cb5f512a90981be44c5bd3fb322e9": { "Name": "p2", "EndpointID": "c7733bbd68a089db6f6ed19d01255c75ab7a2374cb55a2f5dc0b52f658238239", "MacAddress": "02:42:ac:11:00:05", "IPv4Address": "172.17.0.5/16", "IPv6Address": "" }, "35c927b9ce8aa00b5f42b15c56d812bfef0608ed0f0ac339da7fc6dc499c20ef": { "Name": "jenkins-4", "EndpointID": "e46f91261633e52cf0c07996be2f40a1a1535a58cbebdcdc044290580392d6a0", "MacAddress": "02:42:ac:11:00:02", "IPv4Address": "172.17.0.3/16", "IPv6Address": "" }, "97b8d1d6db32cb7beb001063e73c34b45b014c87071131e931bfcda76124259b": { "Name": "mariadb", "EndpointID": "9cd7e596d784b718163198ada61da12c0ff5fc1d3247860ddad3e54d724fc88d", "MacAddress": "02:42:ac:11:00:03", "IPv4Address": "172.17.0.2/16", "IPv6Address": "" }, "d509d6c92cd9847e1c3b69a8814fcf5291b673736dc5c63ec649b6c616b84c3b": { "Name": "p1", "EndpointID": "d60b193c09f7b951ccd434f12ae731c4363ea1305569244b5a9268805c340916", "MacAddress": "02:42:ac:11:00:04", "IPv4Address": "172.17.0.4/16", "IPv6Address": "" } }, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ]
- 怀疑是代码的数据库配置问题, 修改了好多次数据库 host 配置, 试过
host:mariadb
,host:localhost
,host:172.17.0.2
, 怀疑是连接的端口太多,尝试写了个数据库单例模式,
import os import pymysql import yaml from utils.singleton import singleton # db 连接,db/db.py @singleton class DB: def __init__(self): print('初始化') # 读取配置文件 current_path = os.getcwd() with open( current_path + "/config/db.yaml", "r") as f: data = yaml.safe_load(f) # # 打开数据库连接 self.db = pymysql.connect(**data) # 数据库执行 SQL def executeSql(self, SQL): # 使用 execute() 执行 SQL 查询 cursor = self.db.cursor() cursor.execute(SQL) # 获取所有记录列表 results = cursor.fetchall() return results # 数据库连接关闭 def close(self): print('关闭数据库') self.db.close() db = DB() # utils/singleton.py def singleton(cls): instance = {} def _singleton(*args, **kwargs): if cls not in instance: instance[cls] = cls(*args, **kwargs) return instance[cls] return _singleton
- 怀疑是识别不出来 hostname, 所以尝试修改了一下容器里的
/etc/host
,添加172.17.0.2 mariadb 97b8d1d6db32
, jenkins 容器可以 ping 通ping 172.17.0.2
也可以ping mariadb