Fer*_*mac 5 python apache django google-cloud-platform google-secret-manager
我有一个由 Apache 在 Google Compute Engine VM 上提供的 Django 应用程序。
我想在我的 Python 代码中访问来自 Google Secret Manager 的秘密(当 Django 应用程序初始化时)。
当我执行“python manage.py runserver”时,成功检索到秘密。但是,当我让 Apache 运行我的应用程序时,它会在向秘密管理器发送请求时挂起。
我遵循了这个问题的答案GCP VM Instance is not able to access Secrets from Secret Manager 尽管有适当的 Roles。我创建了一个服务帐户(不是默认帐户),并为其指定了“云平台”范围。我还在 Web 控制台中为其授予了“Secret Manager Admin”角色。
最初遇到麻烦后,我从 Web 控制台下载了服务帐户的 json 密钥,并将 GOOGLE_APPLICATION_CREDENTIALS env-var 设置为指向它。
当我直接在虚拟机上运行 django 服务器时,一切正常。当我让 Apache 运行应用程序时,我可以从日志中看到服务帐户凭据 json 已成功加载。
但是,当我通过 google.cloud.secretmanager.SecretManagerServiceClient.list_secret_versions 进行第一次 API 调用时,应用程序挂起。我的浏览器中甚至没有出现 500 错误,只有一个永恒的加载图标。我追踪执行情况如下:
grpc._channel._UnaryUnaryMultiCallable._blocking,第 926 行:'call = self._channel.segrelated_call(...'
它永远不会越过那条线。我无法弄清楚该调用去了哪里,因此我无法进一步检查它。
我不太了解 GCP 服务帐户/API 访问。我无法理解为什么 django 开发服务器和 apache 之间会出现这种差异,因为它们都使用来自 json 的相同服务帐户凭据。我还感到惊讶的是,该应用程序只是挂在谷歌库中而不是抛出异常。发送请求时甚至有一个超时选项,但更改此选项没有任何区别。
我想知道这是否与我在自己的帐户下运行 django 服务器,但 apache 正在使用它使用的任何用户帐户这一事实有关?
我尝试更改 apache 运行的用户/组以匹配我自己的用户/组。不用找了。
我为 gRPC 本身启用了日志记录。当我使用 apache 和 django 开发服务器运行时,有明显的区别。
关于姜戈:
secure_channel_create.cc:178] grpc_secure_channel_create(creds=0x17cfda0,target=secretmanager.googleapis.com:443,args=0x7fe254620f20,保留=(nil)) init.cc:167] grpc_init(void) client_channel.cc:1099] chand=0x2299b88: 为通道堆栈 0x2299b18 创建 client_channel ... timer_manager.cc:188] 睡眠 1001 毫秒 ... client_channel.cc:1879] chand=0x2299b88 调用=0x229e440: 创建呼叫 ... call.cc:1980] grpc_call_start_batch(call=0x229daa0,ops=0x20cfe70,nops=6,tag=0x7fe25463c680,保留=(nil)) call.cc:1573] ops[0]: SEND_INITIAL_METADATA... call.cc:1573] ops[1]: SEND_MESSAGE ptr=0x21f7a20 ...
因此,创建了一个通道,然后创建了一个调用,然后我们看到 gRPC 开始执行该调用的操作(据我所知)。
在阿帕奇上:
secure_channel_create.cc:178] grpc_secure_channel_create(creds=0x7fd5bc850f70,target=secretmanager.googleapis.com:443,args=0x7fd583065c50,保留=(nil)) init.cc:167] grpc_init(void) client_channel.cc:1099] chand=0x7fd5bca91bb8: 为通道堆栈 0x7fd5bca91b48 创建 client_channel ... timer_manager.cc:188] 睡眠 1001 毫秒 ... timer_manager.cc:188] 睡眠 1001 毫秒 ...
所以,我们创建了一个频道......然后就什么也没有了。没有通话,没有操作。因此,Python 代码坐在那里等待 gRPC 进行此调用,但它永远不会这样做。
问题似乎是 Apache 的分叉行为以某种方式破坏了 gRPC。我无法确定确切的原因,但在我开始怀疑分叉是问题所在之后,我发现这个旧的 gRPC 问题表明分叉是一个有点棘手的领域。
我尝试重新配置 Apache 以使用不同的“多处理模块”,但由于我在这方面的经验有限,我无法让 gRPC 在其中任何一个下工作。
最后,我改用 nginx/uwsgi 而不是 Apache/mod_wsgi,并且没有遇到同样的问题。如果您正在尝试解决这样的问题并且必须使用 Apache,我建议您进一步研究 Apache 分叉、gRPC 如何处理分叉以及可用于 Apache 的不同 MPM。