docker18.09.6-dind(Alpine)pip安装awscli的Cython依赖报错排查
Jenkins Pod 容器awscli安装异常问题排查
异常基本信息
- 触发场景:基于Jenkins Pod模板运行构建任务时,搭载
docker:18.09.6-dind(基于Alpine Linux)的常规构建容器,执行预设的awscli安装流程触发失败 - 初始执行的安装命令序列:
apk add curl apk add py-pip pip install --user awscli
- 实际执行现象:
- 容器内
py-pip可正常完成安装,环境自带pip版本为18.1,对应Python2.7运行时 - 执行
pip install --user awscli阶段流程中断:拉取PyYAML 5.4.1源码包、初始化构建依赖环节时,系统自动拉取Cython源码包执行本地编译,最终因容器未预装gcc编译器报错,核心报错信息为:
unable to execute 'gcc': No such file or directory
error: command 'gcc' failed with exit status 1 - 容器内
异常关键特征
- 相同环境、相同操作流程在问题发生前可正常完成awscli安装,问题首次出现后,在同版本dind镜像上重新复现操作可正常跑通流程
- 问题触发当日,PyYAML、awscli、Cython均有新版本正式发布(对应版本为awscli 1.19.51、Cython 0.29.23)
- 相同pip 18.1版本在
docker:18.06.1-ce-dind等其他dind版本环境下可正常完成awscli安装,仅在docker:18.09.6-dind环境下稳定复现该编译报错
基于pip依赖解析逻辑的根因梳理
pip 18.1版本的依赖解析逻辑存在明确的设计特征,是本次异常触发的核心原因:
- 该版本未实现跨平台wheel可用性的提前校验逻辑,当匹配不到当前系统(Alpine musl libc + Python2.7)适配的预编译wheel包时,会自动降级为拉取对应包的sdist源码分发包,触发本地编译流程
- 该版本的依赖选择优先级仅匹配版本约束,只要包版本号满足声明要求,就会优先选择最高版本的包,不会主动规避需要编译的版本、自动选择可无编译安装的低版本wheel包
结合版本适配差异的叠加影响,具体触发链路为:
- PyYAML 5.4.1针对Python2.7仅提供glibc平台的cp27 wheel包,未提供Alpine musl环境下的对应wheel包,pip 18.1在该环境下找不到可用的预编译包,只能拉取sdist源码包
- PyYAML 5.4.1的sdist构建依赖强制要求拉取Cython 0.29.x版本执行扩展模块编译,问题触发当日Cython 0.29.23正式发布,拉取到的Cython源码包同样因为没有匹配的Alpine cp27 wheel,需要本地编译,最终因为容器内无gcc直接报错
- 同版本镜像后续复现正常的原因:PyPI边缘节点的索引缓存存在同步延迟,最初拉取到的PyYAML 5.4.1索引存在元数据错配,pip 18.1误判存在可用的Alpine环境适配wheel;缓存同步完成后,pip可正确识别无对应wheel的事实,自动降级选择可直接安装的旧版本PyYAML完成安装,流程恢复正常
- 其他dind版本环境不受影响的原因:
docker:18.06.1-ce-dind的基础Alpine版本对应的Python2.7运行时,PyYAML 5.4.1提供了匹配的musl cp27 wheel,pip可直接拉取预编译包完成安装,不会触发本地编译流程
可落地的解决方案
- 安装awscli时手动指定适配的PyYAML稳定版本,绕过源码编译流程,执行命令为
pip install --user awscli PyYAML==5.3.1,强制使用Alpine环境适配的预编译wheel版本,避免触发Cython编译流程 - 提前在容器内安装编译依赖后再执行awscli安装,对应apk命令为
apk add --no-cache gcc musl-dev python2-dev libffi-dev openssl-dev,满足Cython和PyYAML的本地编译要求 - 升级容器内pip版本至20.3及以上,新版pip的依赖解析逻辑会优先检索可直接安装的wheel包,仅在无可用wheel时才触发源码编译,可减少同类无必要的编译报错
- 跳过pip安装流程,直接通过Alpine仓库提供的
awscli包完成安装,避免Python生态依赖版本波动带来的构建失败
内容的提问来源于stack exchange,提问作者Ashley
相关产品推荐
相关产品推荐

