Kubernetes node.js 容器无法连接到 MongoDB Atlas
Posted
技术标签:
【中文标题】Kubernetes node.js 容器无法连接到 MongoDB Atlas【英文标题】:Kubernetes node.js container cannot connect to MongoDB Atlas 【发布时间】:2019-10-17 12:56:55 【问题描述】:所以我整个下午都在为此苦苦挣扎。我根本无法让我的 NodeJS 应用程序在 kubernetes 上运行以连接到我的 MongoDB Atlas 数据库。
在我的应用程序中我尝试过运行
mongoose.connect('mongodb+srv://admin:<password>@<project>.gcp.mongodb.net/project_prod?retryWrites=true&w=majority', useNewUrlParser: true )
但我只是得到错误
UnhandledPromiseRejectionWarning: Error: querySrv ETIMEOUT _mongodb._tcp.<project>.gcp.mongodb.net
at QueryReqWrap.onresolve [as oncomplete] (dns.js:196:19)
(node:32) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 17)
我也尝试过设置 ExternalName 服务,但是使用 URL 或 ExternalName 会导致我无法连接到数据库。
我已将我的 IP 在 MongoDB Atlas 上列入白名单,所以我知道这不是问题。
它似乎也适用于我的本地机器,但不适用于 kubernetes pod。我做错了什么?
【问题讨论】:
你能允许所有的 IP 地址都被列入白名单,然后尝试同样的吗? 似乎没有什么区别,这是有道理的,因为它似乎是一个 DNS 错误。如果您从无效主机连接,Mongoose 将给出错误提示,说明您的 IP 未列入白名单。 【参考方案1】:首先,Pod 部署在集群中的节点上,而不是您的服务上(因此 Mongo 不会识别您的服务端点例如;负载均衡器 IP)。基于此,有两种解决方案:
解决方案 A
将Kubernetes集群的endpoint加入MongoDB网络访问IP白名单。
在您的 k8s pod(或部署)清单的 pod 规范下,添加一个 dnsPolicy 字段,其值设置为 Default。因此,您的 Pod(基本上是您的容器)将通过主节点的名称解析配置连接到 mongo。
解决方案 B
将你的 k8s 集群中的所有节点端点添加到 MongoDB 网络访问 IP 白名单中。
在您的 k8s pod(或部署)清单的 pod 规范下,添加一个 dnsPolicy 字段,其值设置为 ClusterFirstWithHostNet。由于 pod 与您的主机网络一起运行,因此它们可以访问在 localhost 上侦听的服务。
Kubernetes documentation
【讨论】:
【参考方案2】:我发现了问题,我的 pod DNS 没有配置为允许外部连接,所以我在 YML 中设置了dnsPolicy: Default
,因为奇怪的是Default
实际上不是默认值
【讨论】:
【参考方案3】:我使用 Kubernetes 的 MongoDB Atlas,但在 AWS 上。尽管出于测试目的,您可以启用所有 IP 地址并进行测试,但以下是生产设置的方法:
MongoDB Atlas 支持网络对等 在网络访问下 > 新建对等连接 对于 AWS,必须指定 VPC ID、CIDR 和区域。对于 GCP,它应该是用于 VPC 对等互连的标准程序。【讨论】:
所以我已经在谷歌云平台上设置了这一切,但我似乎无法弄清楚一旦我使用它应该如何连接我的应用程序。你是怎么做到的? 首先,您能否验证您的应用是否能够从应用的本地 Docker 映像中连接到服务? 太棒了。您能否在与您的 K8s 集群相同的 VPC 中创建临时 VM 并连接到 Atlas?这是为了验证对等互连以上是关于Kubernetes node.js 容器无法连接到 MongoDB Atlas的主要内容,如果未能解决你的问题,请参考以下文章
无法在 node.js 或 react 中访问 Gitlab env 变量