使用 Docker 和 Vetiver 将 tidymodel 模型部署到 GCP

The*_*oat 5 r docker google-cloud-platform tidymodels vetiver

我正在尝试观看Julia Silge MLOps视频,其中她使用 Vetiver 和 Tidymodels 部署到 AWS Sagemaker,但是在 AWS 上花费了数百美元的账单后:( 我已转向 GCP,因为他们提供 300 美元的免费积分。

我正处于尝试创建 docker 映像以推送到 GCP 的阶段,但是当我运行时:

docker run --env-file C:/Users/John/Documents/.Renviron --rm -p 8000:8000 penguins
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

在此输入图像描述

我有点困惑,因为我已将 .Renviron 设置为包含服务帐户 json 文件,如下所示:

在此输入图像描述

根据 VonC 的回复,我添加了/path/in/container“/documents/”

在此输入图像描述

在下面的屏幕截图中,我可以看到该路径/in/container已被推送到图像:

在此输入图像描述

由于我可以运行gcs_list_buckets(projectId = "my-project-id")并查看我创建的存储桶,因此看起来好像我已完全连接到我的云环境。

经过几天的研究,我似乎必须提供环境变量的完整路径才能启用身份验证,我是否遗漏了什么?

Von*_*onC 5

您提到您已在.Renviron文件中设置了环境变量。但是,当您运行 Docker 容器时,它无法找到或正确使用GCE_AUTH_FILE环境变量中指定的凭据文件。

为了进行测试,在 Docker 容器中,您可以尝试正确设置环境变量。
修改 Dockerfile 以包含环境变量:

# Use the appropriate base image
FROM r-base:latest

# Set environment variables
ENV GCE_AUTH_FILE /path/to/your-service-account-file.json
ENV GCE_DEFAULT_PROJECT_ID your-project-id
ENV GCS_DEFAULT_BUCKET your-bucket-name

# (other Dockerfile commands)
Run Code Online (Sandbox Code Playgroud)

运行 Docker 容器时,您应该使用卷将包含服务帐户文件的目录挂载到 Docker 容器。您的docker run命令可能如下所示:

# Use the appropriate base image
FROM r-base:latest

# Set environment variables
ENV GCE_AUTH_FILE /path/to/your-service-account-file.json
ENV GCE_DEFAULT_PROJECT_ID your-project-id
ENV GCS_DEFAULT_BUCKET your-bucket-name

# (other Dockerfile commands)
Run Code Online (Sandbox Code Playgroud)

/path/to/directory/with/credentials主机上包含服务帐户 JSON 文件的目录的路径,也是/path/in/container要挂载此目录的 Docker 容器内的路径。

仍用于测试,在尝试在 R 脚本中进行身份验证之前,打印环境变量以确保它们设置正确。

docker run --env-file C:/Users/John/Documents/.Renviron -v C:/path/to/directory/with/credentials:/path/in/container --rm -p 8000:8000 penguins
Run Code Online (Sandbox Code Playgroud)

/path/in/container指的是 Docker 容器内您希望访问您的.json文件的路径.Renviron。该路径在您创建之前并不存在;docker run当您使用该选项运行命令时,由您来定义它-v。该-v选项创建一个绑定挂载,它允许您指定主机系统(即您的个人计算机或运行 Docker 守护程序的任何地方)上的文件或目录,以及 Docker 容器中可访问该文件或目录的路径。

print(Sys.getenv("GCE_AUTH_FILE"))
print(Sys.getenv("GCE_DEFAULT_PROJECT_ID"))
print(Sys.getenv("GCS_DEFAULT_BUCKET"))
Run Code Online (Sandbox Code Playgroud)
  • C:/path/to/your/project/directory/.json是主机系统上您的和.Renviron文件所在的路径。
  • /path/in/container是 Docker 容器内可访问这些文件的路径。您可以随意命名它;它只是 Docker 容器的 Linux 文件系统中的一个路径。

在 R 脚本中,或者在 Docker 容器内使用这些文件的任何位置,您可以使用 来/path/in/container引用这些文件。例如,在.RenvironDocker 容器内的文件中,您可以GCE_AUTH_FILE这样设置:

GCE_AUTH_FILE=/path/in/container/your-service-account-file.json
Run Code Online (Sandbox Code Playgroud)

这样,在 Docker 容器内运行的 R 进程将能够找到并使用服务帐户文件进行身份验证。


OP TheGoat在评论中添加

我实际上正在一个 R 项目中工作,上面的代码指向了错误的.Renviron文件:我的 R 项目文件夹的目录中实际上有一个文件,我使用您的建议打印环境变量来解决这个问题。

我修改了 docker 文件以包含 3 参数,并且我的 docker run 语句如下所示:docker run --env-file C:/MLOps-in-R/.Renviron -v C:/MLOps-in-R:/documents --rm -p 8000:8000 penguins,其中容器中的路径为/documents

使用docker桌面,我可以看到my的ENV GCE_AUTH_FILE前缀是“ /documents”。
运行docker run命令后出现错误如下:No .httr-oauth file exists in current working directory. Do library authentication steps to provide credentials

错误消息“ No .httr-oauth file exists in current working directory. Do library authentication steps to provide credentials”来自googleAuthR,表明尚未在 Docker 容器的 R 环境中正确设置httr包身份验证。

要解决此问题,您需要使用包中的gar_auth_service()函数googleAuthR通过服务帐户 JSON 文件进行身份验证,并使用环境变量指定该文件的路径GCE_AUTH_FILE

在 Dockerfile 中,确保已安装必要的 R 包。您将需要googleAuthRhttr软件包。以下是将它们安装到 Dockerfile 中的方法:

# other Dockerfile commands

RUN R -e "install.packages(c('googleAuthR', 'httr'), dependencies=TRUE)"
Run Code Online (Sandbox Code Playgroud)

在与管道工一起使用的 R 脚本中(可能plumber.R给出错误消息),您应该在进行任何 GCP API 调用之前设置身份验证googleAuthR::gar_auth_service()
例如:

docker run --env-file C:/path/to/your/project/directory/.Renviron -v C:/path/to/your/project/directory:/path/in/container --rm -p 8000:8000 penguins
Run Code Online (Sandbox Code Playgroud)

在 R 脚本的开头包含上述行,以便在进行任何 API 调用之前使用服务帐户文件进行身份验证。

在部署应用程序之前,请在本地测试身份验证以确保其正常工作。在本地 R 会话中运行 R 脚本并检查您是否能够在没有任何错误的情况下进行身份验证。

确保文件GCE_AUTH_FILE中的.Renviron指向 Docker 容器中的正确路径,如下所示:

GCE_AUTH_FILE=/documents/your-service-account-file.json
Run Code Online (Sandbox Code Playgroud)

我的帐户“身份验证”仍然存在问题。我感觉好像我已经倒退了几步,当我尝试时,gcs_list_buckets即使.Renviron我的服务帐户拥有包含正确 JSON 文件的文件,我现在也会收到 403 权限不足错误。

“403 权限不足”错误通常表示您正在使用的服务帐户没有执行您尝试执行的操作所需的权限。这不仅仅是GCE_AUTH_FILE正确设置变量;与该文件关联的服务帐户还必须具有足够的权限才能与 Google Cloud Storage (GCS) 交互。

首先验证您的服务帐户权限

  1. 转到 GCP Console 并导航至“ IAM & Admin" > "Service accounts”。
  2. 找到与您的项目关联的服务帐户并检查其拥有的权限。它应该具有授予与 GCS 交互权限的角色。如果没有,您将需要编辑角色以包含必要的权限,例如“ Storage Admin”或“ Storage Object Admin”。

确保GCE_AUTH_FILE您使用的服务帐户 JSON 密钥文件 ( ) 与您在步骤 1 中验证的服务帐户相对应。如果您有多个服务帐户,则很容易将它们混淆。

在处理 Docker 之前,请确保您的本地 R 会话可以gcs_list_buckets()使用当前.Renviron设置成功调用。这可以帮助您隔离问题。

GCE_AUTH_FILE=/path/in/container/your-service-account-file.json
Run Code Online (Sandbox Code Playgroud)

并仔细检查.Renviron

# other Dockerfile commands

RUN R -e "install.packages(c('googleAuthR', 'httr'), dependencies=TRUE)"
Run Code Online (Sandbox Code Playgroud)

如果它在本地工作但在 Docker 中失败,请考虑在 Docker 容器内的 R 代码中添加调试语句。记录环境变量值以确保正确获取它们。

另外,重新尝试身份验证:运行googleAuthR::gar_auth_service(Sys.getenv("GCE_AUTH_FILE"))以手动进行身份验证。如果失败,它应该提供更详细的错误消息,这对调试很有用。