如何在 docker 中的节点前为 Cloud Run 设置 nginx?

Posted

技术标签:

【中文标题】如何在 docker 中的节点前为 Cloud Run 设置 nginx?【英文标题】:How to setup nginx in front of node in docker for Cloud Run? 【发布时间】:2019-11-15 07:47:30 【问题描述】:

我需要在需要部署在谷歌云运行的nodejs应用程序前面设置反向代理nginx

用例 - 需要通过 nginx 提供 gzip 压缩的资产(我不想开销节点进行 gzip 压缩) - 阻止小型 DDOS 攻击

我没有找到任何在云运行中设置 nginx 和节点的教程。

我还需要为节点安装 PM2。

如何在 docker 中进行此设置?还有如何在部署之前配置 nginx?

提前致谢

【问题讨论】:

【参考方案1】:

我需要在需要的 nodejs 应用程序前面设置反向代理 nginx 部署在谷歌云运行中。

Cloud Run 已经提供了反向代理 - Cloud Run Proxy。这是为 Cloud Run 提供负载平衡、提供自定义域、身份验证等的服务。但是,Cloud Run 的设计并没有阻止您在容器内使用 Nginx 作为反向代理。 Cloud Run 的设计中没有任何内容可以阻止您将 Nginx 用作另一个 Cloud Run 服务的独立容器前端。请注意,在最后一种情况下,您需要支付的费用是您需要两个 Cloud Run 服务的两倍,一个用于 Nginx 服务 URL,另一个用于节点应用程序。

用例 - 需要提供通过 nginx 压缩的资产(我不想 gzip 压缩的开销节点) - 阻止小型 DDOS 攻击

您可以在节点应用程序或 Nginx 中执行压缩。结果是一样的。性能影响是一样的。 Nginx 不提供任何开销节省。 Nginx 在某些情况下可能更方便。

您对阻止小型 DDOS 攻击的评论。 Cloud Run 自动缩放,这意味着每个 Cloud Run 实例都将有限地暴露于 DOS。随着 DDOS 流量的增加,Cloud Run 将启动更多容器实例。在没有您事先请求的情况下,Cloud Run 将停止扩展至 1000 个实例。 Nginx 不会提供任何我能想到的减轻 DDOS 攻击的好处。

我没有找到任何在云运行中设置 nginx 和节点的教程。

我不知道有关 Nginx 和 Cloud Run 的特定文档。但是,您不需要一个。任何涵盖 Nginx 和 Docker 的文档都可以。如果您想在与节点应用程序相同的容器中运行 Nginx,则需要编写自定义脚本来启动 Nginx 和 Node。

我还需要为节点安装 PM2。

不可能。 PM2 具有用户界面和 GUI。 Cloud Run 仅通过 HTTP 从 Cloud Run 实例公开 $PORT。

如何在 docker 中进行此设置?还有我之前如何配置nginx 部署?

网上有很多设置 Nginx 和 Docker 的教程。

以下两个例子。网上有数百个例子。

How to run NGINX as a Docker container Deploying NGINX and NGINX Plus on Docker

我已经回答了你的每一个问题。现在给点建议:

    将 Nginx 与 Cloud Run 结合使用对 Node.js 应用程序没有任何意义。只需运行您的节点应用程序,让 Cloud Run Proxy 完成它的工作。 压缩是 CPU 密集型的。 Cloud Run 专为小型、快速和紧凑的 HTTP 样式微服务而设计。您将为增加的 CPU 时间付费。如果您有需要压缩的内容,请先将其压缩并提供压缩的内容。在某些情况下,Cloud Run 中的压缩很有用和/或正确,但请查看您的设计并在可能的情况下进行优化。例如,静态内容应由 Cloud Storage 提供。

只要您遵循其设计标准和目的,Cloud Run 就可以轻松处理具有出色性能和可扩展性的 Node.js 应用程序。

要记住的关键因素:

成本低,您只需为请求付费。重叠请求与一个请求的成本相同。

无状态。容器在不需要时会关闭,这意味着您必须针对重启进行设计。将状态存储在其他位置,例如数据库。

仅提供端口 $PORT 上的流量,今天是 8080。

公共流量可以是 HTTP 或 HTTPS。从 Cloud Run 代理到容器的流量是 HTTP。

自定义域名。 Cloud Run 让 URL 的 HTTPS 变得非常简单。

更新:公共端点(公共流量)现在仅支持 HTTPS。

【讨论】:

感谢您的描述性答案以及您为此付出的努力。我读过 NodeJs 不适合 gzipping,即使压缩是位 cpu 密集型任务,对吧?这就是为什么我需要 nginx 在前面。但是PM2不能在云上运行吗?那么当节点因未处理的异常或类似情况而崩溃时,如何重新启动节点?再次感谢 如果您的容器崩溃,Cloud Run 将终止它并启动一个新容器。我认为您对 Cloud Run 提供的服务感到困惑。它在收到 HTTP 请求时启动一个容器,并在空闲期后没有更多请求要处理时关闭。 Cloud Run 不是“始终运行”的服务,除非有 HTTP 流量让容器保持忙碌。关于压缩,你从哪里读到 node.js 不能有效地压缩数据?错误的假设。 Nginx 获得的好处不会抵消拥有两个容器(一个用于压缩)的复杂性。 我找不到任何关于“Cloud Run Proxy”的文档。您的意思是“Cloud Run 的端点”吗? @DaNeSh - 不,我不是说Endpoints。 Cloud Run Poxy 内置于 Cloud Run(托管)服务中。我在回答中描述了它的功能。 @JohnHanley 您能否提供有关 DDoS 攻击部分的更多详细信息。 NGINX 没有办法在这方面帮助阻止轻微的 DoS 攻击吗?我假设至少我们可以以更低的成本在 NGINX 级别上进行速率限制。不是吗?【参考方案2】:

我认为您应该考虑使用不同的方法。

在单个容器中运行多个进程并不是最佳做法。正如您所描述的,更常见的代理实现是使用 2 个容器(代理通常称为边车),但这在 Cloud Run 中是不可能的。

Google App Engine 可能更合适。

App Engine Flexible 允许部署由 Nginx 代理(在幕后)的容器。您可以将静态内容与 Flexible 一起使用,并且可以合并 CDN。 App Engine Standard 也能满足您的需求。

https://cloud.google.com/appengine/docs/flexible/nodejs/serving-static-files https://cloud.google.com/appengine/docs/standard/nodejs/runtime

与 Cloud Run 一样,App Engine 是无服务器的,但提供了更大的灵活性并且是一项更成熟的服务。 App Engine 也集成了更多(全部?)GCP 服务,而 Cloud Run 仅限于一个子集。

或者,您可以考虑使用 Kubernetes(引擎)。这提供了几乎无限的灵活性,但需要更多的操作。您可能知道,有一个 Cloud Run 实现在 Kubernetes、Istio 和 Knative 上运行。

Cloud Run 是一项引人注目的服务,但仅当您能够满足其(当前)受限要求时才适用。

【讨论】:

感谢您的回答和为撰写本文所付出的努力。我曾同时尝试过应用引擎和云运行,我注意到的是 1. 应用引擎部署较慢 2. 处理请求的时间比云运行要长(应用引擎需要约 700 毫秒的请求和云运行服务相同的请求在 300-400 毫秒)。这促使我开始使用云运行。 不客气!是的,Cloud Run 部署速度非常快。除了烦人之外,这应该主要影响您而不是您的客户。第一反应的时间令人失望。鉴于您无法优雅地解决 Cloud Run 的 sidecar 问题,您可能别无选择,只能向 Google 提交 FR【参考方案3】:

我要告诉你一个好消息。我已经写了一篇博客文章,详细介绍了您对示例代码的需求。

此示例将 NGINX 放在前面(Cloud Run 上的端口 8080),同时选择性地将流量代理到在同一容器中运行的另一个服务(端口 8081)。

阅读博文:https://ahmet.im/blog/cloud-run-multiple-processes-easy-way/ 源代码:https://github.com/ahmetb/multi-process-container-lazy-solution

【讨论】:

很棒的例子,感谢您通过正确/不同的初始化过程。你说它“不是超级生产就绪”。有哪些技巧、方向和需要注意的事项以使其更适合生产? 也刚刚尝试了解决方案。在本地工作,但不能在 Cloud Run 中工作。任何洞察为什么?我得到 502 Bad Gateway。似乎网络应用程序很难启动(在我的例子中是 node.js)。我看到它试图启动服务器,但之后没有常规或错误日志。【参考方案4】:

谷歌云计算系统

要了解GCP Computing,请先看下图:

对于您的情况,我完全建议您使用 App Engine Flex 来部署您的应用程序。它支持 docker 容器,nodejs,...了解如何将 nodejs 部署到 GAE Flex,请访问此页面https://cloud.google.com/appengine/docs/flexible/nodejs/quickstart

您可以根据需要安装一些第三方库。此外,GCP 支持全局/内部负载均衡器,您可以将其应用到您的 GAE 服务中。

【讨论】:

他们有文件吗?你能把它们放在这里吗?

以上是关于如何在 docker 中的节点前为 Cloud Run 设置 nginx?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Cloud Functions (Typescript) 在 Firebase 实时数据库中的 .ref(/path) 之外创建新的父节点?

部署到 Google Cloud Run 时 Docker 容器无法启动

Spring Cloud Config 自动刷新所有节点 架构改造

如何避免我的 Firebase Cloud Function 中的嵌套承诺 [重复]

docker-compose 发布 spring cloud

如何使用nodejs获取节点docker容器中的主机主目录路径?