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

4
我正在尝试跟随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

我遇到了以下错误:

enter image description here

我有点困惑,因为我已经在.Renviron文件中设置了包含服务账号JSON文件的路径,如下所示:

enter image description here

我可以运行 gcs_list_buckets(projectId = "my-project-id") 并查看我创建的存储桶,所以似乎我已经完全连接到我的云环境。

在进行了多天的研究后,我发现我必须提供环境变量的完整路径来启用身份验证,我是否遗漏了什么?

1个回答

4
你提到你已经在.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)

在运行Docker容器时,您应该使用卷将包含服务帐户文件的目录挂载到Docker容器中。您的docker run命令可能如下所示:
docker run --env-file C:/Users/John/Documents/.Renviron -v C:/path/to/directory/with/credentials:/path/in/container --rm -p 8000:8000 penguins

使用/path/to/directory/with/credentials作为主机上包含服务账号JSON文件的目录路径,以及/path/in/container作为Docker容器内要挂载此目录的路径。
在尝试在您的R脚本中进行身份验证之前,仍需进行测试,打印环境变量以确保它们被正确设置。
print(Sys.getenv("GCE_AUTH_FILE"))
print(Sys.getenv("GCE_DEFAULT_PROJECT_ID"))
print(Sys.getenv("GCS_DEFAULT_BUCKET"))

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

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
  • C:/path/to/your/project/directory/ 是您主机系统上存放 .json.Renviron 文件的路径。
  • /path/in/container 是 Docker 容器内部的路径,这些文件将在其中可访问。您可以随意命名此路径,它只是 Docker 容器中 Linux 文件系统中的一个路径。

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

GCE_AUTH_FILE=/path/in/container/your-service-account-file.json

通过这种方式,运行在Docker容器内的R进程将能够找到并使用服务账户文件进行身份验证。

OP TheGoat评论中添加了

实际上,我正在进行一个R项目,上面的代码指向了错误的.Renviron文件:实际上,在我的R项目文件夹中有一个,我通过您的建议打印环境变量找到了这个问题。

我修改了我的Docker文件,包括3个参数,并且我的Docker运行语句如下所示:docker run --env-file C:/MLOps-in-R/.Renviron -v C:/MLOps-in-R:/documents --rm -p 8000:8000 penguins,其中容器中的路径为/documents
使用Docker桌面版,我可以看到我的ENV GCE_AUTH_FILE前缀为'/documents'。 一旦我运行docker run命令,错误如下:当前工作目录中不存在.httr-oauth文件。请执行库认证步骤以提供凭据
"

错误信息“当前工作目录中不存在.httr-oauth文件。请执行库认证步骤以提供凭据”,来自googleAuthR,表示在Docker容器中的R环境中未正确设置httr的认证。

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

"
在您的Dockerfile中,确保已安装必要的R包。您将需要安装googleAuthRhttr包。以下是在Dockerfile中安装它们的方法:
# other Dockerfile commands

RUN R -e "install.packages(c('googleAuthR', 'httr'), dependencies=TRUE)"

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

# Authenticate using the service account file specified in the GCE_AUTH_FILE environment variable
gar_auth_service(Sys.getenv("GCE_AUTH_FILE"))

在您的R脚本开头包含上述行,以在进行任何API调用之前使用服务账号文件进行身份验证。
在部署应用程序之前,本地测试身份验证以确保其正常工作。在本地R会话中运行您的R脚本,并检查是否能够成功进行身份验证,没有任何错误。
确保您的.Renviron文件中的GCE_AUTH_FILE指向Docker容器中的正确路径,如下所示:
GCE_AUTH_FILE=/documents/your-service-account-file.json

我仍然在与我的帐户进行“身份验证”方面遇到问题。我觉得我已经退了几步,现在当我尝试使用gcs_list_buckets时,我会得到一个403权限不足的错误,尽管我有正确的JSON文件的.Renviron文件用于我的服务帐户。
“403权限不足”错误通常表示您正在使用的服务帐户没有执行您尝试执行的操作所需的权限。这不仅仅是正确设置GCE_AUTH_FILE变量;与该文件关联的服务帐户还必须具有与Google Cloud Storage(GCS)交互所需的足够权限。
首先验证您的服务帐户权限
1. 转到GCP控制台,导航到“IAM和管理”>“服务帐户”。 2. 找到与您的项目关联的服务帐户,并检查它拥有的权限。它应该具有授予与GCS交互的权限的角色。如果没有,您需要编辑角色以包括所需的权限,例如“存储管理员”或“存储对象管理员”。
确保您使用的服务帐号JSON密钥文件(GCE_AUTH_FILE)与您在第一步中验证的服务帐号相对应。如果您有多个服务帐号,很容易混淆它们。
在处理Docker之前,请确保您的本地R会话可以成功使用当前的.Renviron设置调用gcs_list_buckets()。这可以帮助您隔离问题。
# Load googleCloudStorageR library
library(googleCloudStorageR)

# Test list buckets
gcs_list_buckets("your-project-id")

并且仔细检查一下 .Renviron 文件:
# Print the current value to verify
print(Sys.getenv("GCE_AUTH_FILE"))

如果在本地运行正常但在Docker中失败,请考虑在Docker容器内的R代码中添加调试语句。记录环境变量的值以确保它们被正确获取。
另外,重新尝试身份验证:运行googleAuthR::gar_auth_service(Sys.getenv("GCE_AUTH_FILE"))进行手动身份验证。如果失败,它应该提供一个更详细的错误消息,有助于调试。

嗨@VonC,谢谢回复。我实际上正在进行一个R项目,上面的代码指向了错误的Renviron文件,实际上我的R项目文件夹中有一个,我用你的建议打印环境变量找到了这个问题,谢谢。关于挂载,我的.json文件和.Renviron文件都在同一个目录下,但我不明白关于/container中的路径,这是什么路径? - undefined
1
@TheGoat 太棒了,好发现!我已经在答案中包含了你的解决方案,还添加了一个新的部分来解释/path/in/container的含义。 - undefined
我采纳了您上面的建议,但不幸的是仍然没有成功。我修改了我的Docker文件,包括了3个参数,并且我的Docker运行语句如下所示:docker run --env-file C:/MLOps-in-R/.Renviron -v C:/MLOps-in-R:/documents --rm -p 8000:8000 penguins,其中容器中的路径是/documents。使用Docker桌面版,我可以看到我的ENV GCE_AUTH_FILE前缀为'/documents'。当我运行docker run命令时,出现以下错误:当前工作目录中不存在.httr-oauth文件。请执行库身份验证步骤以提供凭据。 - undefined
@TheGoat 好的。我已经编辑了答案以回应你的评论。 - undefined
非常感谢您提供的所有反馈,我会接受您的答案,但是我仍然在与我的账户进行“认证”时遇到问题。我感觉自己又退了几步,当我尝试使用gcs_list_buckets时,我现在遇到了403权限不足的错误,尽管我已经在.Renviron文件中正确地配置了我的服务账户的JSON文件。我会继续努力解决问题,再次感谢您的帮助。 - undefined
@TheGoat 没问题,谢谢你的反馈。我已经编辑了答案,提出了一些调试的步骤。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接