AWS Batch调用S3遇SSL证书匹配错误,求诊断方案
问题描述
本地使用rocker/r-base构建的R容器运行正常,但推送到ECR后在AWS Batch中执行时,出现SSL证书匹配错误:
Reading from: s3://greg-batch-test/input.csv
Writing to: s3://greg-batch-test/output.csv
Loading required package: aws.s3
Error in curl::curl_fetch_disk(url, x$path, handle = handle) :
SSL peer certificate or SSH remote key was not OK [s3-eu-west-3.amazonaws.com]:
SSL: no alternative certificate subject name matches target hostname 's3-eu-west-3.amazonaws.com'
Calls: s3read_using ... request_fetch.write_disk ->-> raise_libcurl_error
Execution halted
相关代码与配置
R脚本(myscript.R)
args <- commandArgs(trailingOnly=TRUE) # Default values (for local testing) input_s3 <- "s3://your-bucket/input.csv" output_s3 <- "s3://your-bucket/output.csv" if (length(args) >= 2) { for (i in seq(1, length(args), by=2)) { if (args[i] == "--input-s3") input_s3 <- args[i+1] if (args[i] == "--output-s3") output_s3 <- args[i+1] } } cat("Reading from:", input_s3, "\n") cat("Writing to:", output_s3, "\n") # Install/load aws.s3 if (!require("aws.s3")) install.packages("aws.s3", repos="http://cran.us.r-project.org") library(aws.s3) # Download and read CSV from S3 data <- s3read_using(read.csv, object = input_s3) # <---- throws an error cat("Data loaded:\n") print(data) # Do a simple transformation data$result <- data$value * 2 # Write back to S3 s3write_using(data, write.csv, object = output_s3) cat("Data written.\n")
Dockerfile
FROM rocker/r-base:4.3.1 RUN apt-get update && \ apt-get install -y \ libcurl4-openssl-dev \ libssl-dev \ libxml2-dev && \ rm -rf /var/lib/apt/lists/* RUN R -e "install.packages(c('aws.s3'), repos='https://cloud.r-project.org/')" # Add your R script COPY myscript.R /app/myscript.R WORKDIR /app # Default entrypoint ENTRYPOINT ["Rscript", "myscript.R"]
操作命令
# 构建镜像 docker build -t greg/r-batch-job . # 推送到ECR docker push 12345.dkr.ecr.eu-west-3.amazonaws.com/greg/r-batch-job:latest
诊断与解决步骤
1. 修正S3区域端点格式
报错中出现的s3-eu-west-3.amazonaws.com是旧的端点格式,当前S3标准区域端点为s3.eu-west-3.amazonaws.com(点分隔)。需强制指定正确端点:
- 在R脚本加载
aws.s3后添加环境变量配置:library(aws.s3) # 指定正确的S3区域端点 Sys.setenv("AWS_S3_ENDPOINT" = "s3.eu-west-3.amazonaws.com") - 或者在调用
s3read_using/s3write_using时显式指定区域:data <- s3read_using(read.csv, object = input_s3, region = "eu-west-3") s3write_using(data, write.csv, object = output_s3, region = "eu-west-3")
2. 验证Batch任务的IAM权限
虽然报错是SSL,但权限配置异常可能引发间接错误:
- 检查Batch任务执行角色是否包含以下权限:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::greg-batch-test/*" ] } ] } - 确认角色信任关系允许
batch.amazonaws.com和ecs-tasks.amazonaws.com扮演该角色。
3. 检查Batch任务的网络配置
若任务运行在VPC内,需确保网络能正常访问S3:
- 若使用公网访问:子网需关联NAT网关,且路由表指向NAT网关。
- 若使用S3 VPC端点:
- 创建网关型S3端点,关联任务所在子网和路由表。
- 启用端点的私有DNS选项,确保容器能解析正确的S3端点。
- 端点策略需允许任务角色访问目标桶。
4. 测试容器内的SSL连通性
修改Dockerfile添加curl工具,在脚本中先测试S3端点:
- 更新Dockerfile的
apt-get install命令,加入curl:RUN apt-get update && \ apt-get install -y \ libcurl4-openssl-dev \ libssl-dev \ libxml2-dev \ curl && \ rm -rf /var/lib/apt/lists/* - 在R脚本开头添加测试命令:
根据curl输出判断SSL握手是否正常。# 测试S3端点连通性 cat("Testing S3 endpoint connectivity:\n") system("curl -v https://s3.eu-west-3.amazonaws.com/greg-batch-test/input.csv")
5. 升级依赖包版本
旧版本的aws.s3、curl或httr可能存在端点处理bug,在Dockerfile中安装最新版本:
RUN R -e "install.packages(c('aws.s3', 'curl', 'httr'), repos='https://cloud.r-project.org/', type='source')"
内容的提问来源于stack exchange,提问作者Greg B

