打包依赖包后PySpark提交任务出现TLS CA证书找不到错误
你的问题核心在于certifi库在Spark分发依赖包时的路径解析错误:当你把certifi打包进dependencies.zip后,Spark会将这个zip解压到临时运行目录,但certifi的where()方法返回的仍是zip包内部的虚拟路径(带dependencies.zip/前缀),而实际运行时这个路径并不存在,导致requests找不到CA证书文件。
可行的解决方案:
1. 不将certifi打包进依赖包
如果你的Spark运行环境(本地或集群)已经安装了certifi库,完全没必要把它放进dependencies.zip。这样requests会自动调用系统/环境中已安装的certifi提供的证书路径,避开路径解析问题。
- 操作:从依赖包中移除certifi,重新打包
dependencies.zip - 前置:确保Spark环境的Python已安装certifi(执行
pip install certifi即可)
2. 手动指定CA证书的实际路径
在你的requests请求代码中,显式指定Spark解压后certifi证书的真实路径,替代certifi自动返回的错误路径:
import os import requests # 获取certifi模块解压后的实际目录 cert_module_dir = os.path.dirname(__import__('certifi').__file__) # 拼接出证书文件的真实路径 real_cert_path = os.path.join(cert_module_dir, 'cacert.pem') # 在请求中使用这个真实路径 response = requests.get('https://your-target-endpoint.com', verify=real_cert_path)
你也可以直接指定系统默认的CA证书路径(比如Linux的/etc/ssl/certs/ca-certificates.crt、macOS的/usr/local/etc/openssl/cert.pem),跳过certifi的路径问题。
3. 通过环境变量强制指定证书路径
提交spark-submit时,通过--conf参数给驱动和执行器设置REQUESTS_CA_BUNDLE环境变量,直接指向正确的证书文件:
spark-submit --master local[*] \ --conf spark.driverEnv.REQUESTS_CA_BUNDLE="/path/to/valid/cacert.pem" \ --conf spark.executorEnv.REQUESTS_CA_BUNDLE="/path/to/valid/cacert.pem" \ --py-files dependencies.zip job.py
这里的路径可以是系统默认CA证书路径,也可以是你手动拷贝到集群节点的certifi证书文件路径。
为什么boto3能正常工作?
boto3的证书处理逻辑和requests不同:它要么直接调用系统默认的证书存储,要么AWS SDK内部自带了证书文件,不需要依赖certifi的路径解析逻辑,所以即使certifi路径出错,它也能正常运行。
内容的提问来源于stack exchange,提问作者scarecrow

