我在GCP Cloud Run中设置了一个由nginx前端的web应用程序,它工作得很好。我试图使用nginx代理请求到某个路由到另一个GCP云运行服务。例如,我希望对https://my-cloud-run-frontend.app.run
的请求解析为https://my-cloud-run-frontend.run.app
,但是我希望对https://my-cloud-run-frontend.run.run/api/*
的请求被代理为https://my-cloud-run-backend.run.app
。
两个云运行服务都使用IAM Auth。
当我在本地docker容器中运行服务时,代理工作得很好。同样,如果我在我的云运行设置中从frontend
应用程序中删除IAM认证,事情似乎有效。
然而,启用IAM认证后,对https://my-cloud-run-frontend.run.app
的请求成功,但对https://my-cloud-run-frontend.run.app/api/
的请求因未经授权而失败(具体来说,错误是从frontend
云运行应用程序抛出的)。
我已经确认,通过使用相同的认证令牌并直接向https://my-cloud-run-backend.run.app
和https://my-cloud-run-frontend.run.app
发出请求,验证工作,它工作得很好。
做一些研究,我看到我可能需要设置一个Host
标题,所以我尝试将标题Host
设置为我的目的地(https://my-cloud-run-backend.run.app
url)。这将导致调用https://my-cloud-run-frontend.run.app/api
返回一个400错误。
我的nginx.conf.template
文件:
server {
access_log /dev/stdout;
listen 8080;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_pass_request_headers on;
}
location /api/ {
proxy_pass https://my-cloud-run-backend.run.app/;
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_set_header Host https://my-cloud-run-backend.run.app;
proxy_pass_request_headers on;
rewrite ^/api(.*)$ $1 break;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
您可以在没有后端身份验证的情况下实现您的用例。实际上,您可以在未经过身份验证的情况下部署API Cloud Run,但将入口设置为仅内部
然后,在您的反向代理Cloud Run上,您必须添加无服务器VPC连接器并将出口设置为all
这种设计只接受反向代理上经过身份验证和授权的请求,并且使API后端只能由反向代理(或VPC中的其他内部资源)访问。
这个设计可以工作,但是有几个权衡:
- 你不能定义谁可以访问你的API后端。它是"内部的":项目中的任何内部资源都可以访问它。此外,如果您可以访问反向代理,那么您也可以访问后端,这里不可能有不同级别的授权(至少对于Google Cloud服务是这样)。您可以在代码中添加自制授权检查)
- 无服务器VPC连接器成本高于负载均衡器
- 设计是复杂的,只有一个重定向