【问题标题】:How to access a Dockerized R image trough Lambda|API Gateway?如何通过 Lambda|API Gateway 访问 Dockerized R 镜像?
【发布时间】:2021-03-23 20:14:17
【问题描述】:

这个问题的第一个版本可能没有我想的那么清楚,因为它有很多部分,问题出在过程的一个部分。

尽可能简单: 我有一个 dockerized R 应用程序暴露给管道工的 http 访问,我想在 aws lambda 中使用它。

Dockerfile 非常简单:

FROM rstudio/plumber:latest

WORKDIR /opt/ml

# system libraries of general use
RUN apt-get update && apt-get install -y --no-install-recommends \
    autoconf \
    automake \
    wget \
    libcurl4-openssl-dev\
    libsodium-dev \
    ca-certificates

# r pkgs (https://rstudio.github.io/renv/articles/docker.html)
RUN R -e "install.packages('renv', repos = c(CRAN = 'https://cloud.r-project.org'))"

# renv (https://nicd.ncl.ac.uk/blog/posts/deploying-model-predictions-using-plumber-and-docker/)
COPY . .
RUN R -e "renv::restore()" # uncomment to create docker image with renv

# plumber
ENTRYPOINT ["Rscript", "run_plumber.R"] # uncomment to create docker image with renv
EXPOSE 8080/tcp
docker build -t image-name:0.0.1 .
docker run --name sandbox --restart=always -p 8080:8080 -v C:\Users\User\Downloads\aws_s3:/data image-name:0.0.1

当我运行这个命令时,我会得到一个可以使用 curl 访问的容器,如下所示:

curl -X POST "http://127.0.0.1:8080/functionName?param1=/data/archive.json&param2=/data/archive.csv"

或者按照文档的建议,我有这个功能

# plumber.R

#* Echo back the input
#* @param msg The message to echo
#* @get /echo
function(msg="") {
  list(msg = paste0("The message is: '", msg, "'"))
}

我得到结果(这只是为了确认工作流程有效

curl -X GET"http://127.0.0.1:8080/echo?msg=hi"

到这里为止一切都还好;一旦图像被标记并推送到 ECR 并在其上创建一个 lambda 函数,我通过 API Gateway 访问它

在API网关中我设置了一个Resource和一个方法,resource是curl和function指定的函数名“echo”;部署后,我知道管道工库暴露在 8080 端口

当我通过 API 网关调用我的函数时:我在云手表中得到这个日志:


Error: failed to create directory at path '/home/sbx_user1051/.local/share/renv'
In addition: Warning message:
In dir.create(rownames(info), recursive = TRUE) :
cannot create dir '/home/sbx_user1051/.local', reason 'No such file or directory'
Traceback (most recent calls last):
19: source("renv/activate.R")
18: withVisible(eval(ei, envir))
17: eval(ei, envir)
16: eval(ei, envir)
15: local(...)
14: eval.parent(substitute(eval(quote(expr), envir)))
13: eval(expr, p)
12: eval(expr, p)
11: eval(quote(...), new.env())
10: eval(quote(...), new.env())
9: renv_bootstrap_load(project, libpath, version)
8: renv::load(project)
7: renv_load_renviron(project)
6: renv_paths_root(".Renviron")
5: Sys.getenv("RENV_PATHS_ROOT", unset = NA) %NA% renv_paths_root_default()
4: renv_paths_root_default()
3: ensure_directory(path)
2: stopf("failed to create directory at path '%s'", rownames(info))
1: stop(sprintf(fmt, ...), call. = call.)
Execution halted

【问题讨论】:

    标签: r amazon-web-services docker amazon-ecr plumber


    【解决方案1】:

    这里的问题是/home/sbx_user1051/.local 不可写,另见docker-lambda #103。在 renv 部分之前的 Dockerfile 中,将 RENV_PATHS_ROOT 设置为默认用户具有写入权限的目录以绕过错误,例如。

    ENV RENV_PATHS_ROOT="/tmp/.local/share/renv"
    # ENV RENV_PATHS_ROOT="${LAMBDA_TASK_ROOT}/.local/share/renv" # works similarly
    

    另请参阅renv docs,了解有关路径自定义的更多详细信息。此外,请注意,如果没有在 renv/settings.dcf 中禁用 use.cache,您可能会在 AWS Lambda 上遇到 L2 缓存大小问题:

    【讨论】:

    • 是的,确实是权限错误,在 /tmp 文件夹中定义路径确实可以解决问题。谢谢!
    • 我正在尝试自己完成这个过程。我在配置 lambda 函数时遇到了一些挑战。您如何确保 Lambda 或 API Gateway 从管道工 API 转到正确的端点?我已经通过 ECR 部署了容器,导入了 swagger 文档,并将容器映像添加到 Lambda,然后在 API 网关中添加了 Lambda
    • @thus__ 需要一些 docker 端口映射,但我绕过管道工选项所做的是通过 python 执行 R,所以我将 dockerized lambda 函数配置为使用子进程,这样我执行 Popen在 R 脚本上并在标准输出中捕获响应。
    猜你喜欢
    • 2017-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 2017-04-13
    • 1970-01-01
    • 2019-10-20
    相关资源
    最近更新 更多