GitLab Runner执行Poetry install偶发连接、证书报错排查
问题根因
两类随机报错均和Python依赖本身无关,是CentOS 7环境下Docker执行器的底层兼容性问题,具体原因如下:
- 第一类
Name or service not known连接错误:CentOS 7默认搭载的Docker版本老旧,默认bridge网络模式下,容器DNS请求经过宿主机docker0网桥转发时,会因conntrack连接表项冲突、宿主机dnsmasq服务端口监听冲突,出现概率性域名解析失败。故障发生在网络层,因此会随机在不同依赖包的下载阶段触发,无固定关联依赖。 - 第二类
找不到cacert.pem证书错误:CentOS 7下Docker默认使用的老版本overlay/devicemapper存储驱动,和Poetry 1.1.x默认开启的多进程并行安装机制存在竞态冲突。多进程同时写入镜像层时,会偶发出现小文件写入后立即可见性丢失的问题,certifi包安装完成后无法读取到cacert.pem文件就属于这类故障,同样是随机触发。
两类故障都属于概率性问题,因此多次重试后总能碰到故障不触发的窗口,最终跑通流程。
可行解决方案
按落地成本从低到高、修复效果从好到差排序:
- 关闭Poetry并行安装,解决文件竞态问题
在Poetry安装依赖前添加配置,将安装并行度设为1,彻底规避多进程写入导致的存储层文件可见性问题,修改后的before_script片段如下:
该调整可以100%解决第二类证书找不到的报错。before_script: - pip install poetry==1.1.7 - poetry config virtualenvs.create false - poetry config installer.parallel false - poetry install - 调整Docker基础配置,修复DNS和存储驱动稳定性问题
编辑Runner所在宿主机的/etc/docker/daemon.json文件,添加固定DNS配置、将存储驱动切换为更稳定的overlay2,配置示例:
配置完成后执行{ "dns": ["114.114.114.114", "223.5.5.5"], "storage-driver": "overlay2" }systemctl daemon-reload && systemctl restart docker重启Docker服务生效,注意切换存储驱动后,宿主机上存量的本地镜像需要重新拉取。该调整可以解决绝大多数偶发DNS解析失败的问题。 - 配置国内PyPI镜像源,降低网络请求失败概率
替换默认的官方PyPI源为国内镜像源,减少跨境网络请求带来的解析、连接超时风险,修改后的before_script片段如下:before_script: - pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple - pip install poetry==1.1.7 - poetry config virtualenvs.create false - poetry config installer.parallel false - poetry source add tsinghua https://pypi.tuna.tsinghua.edu.cn/simple --default - poetry install - 添加安装步骤重试逻辑作为兜底
如果不方便修改宿主机Docker配置,可以在CI脚本中添加自动重试逻辑,碰到偶发故障时自动重跑安装步骤,无需人工触发重试,配置示例:before_script: - pip install poetry==1.1.7 - poetry config virtualenvs.create false - poetry config installer.parallel false - | for retry in {1..3}; do poetry install && exit 0 echo "install failed, retry $retry after 5s" sleep 5 done exit 1
内容的提问来源于stack exchange,提问作者RoyalGoose
相关产品推荐
相关产品推荐

