如何在 Kubernetes 中配置 Express 应用程序以使用出口 Droplet 进行 MongoDB Atlas 连接

问题描述 投票:0回答:1

我正在尝试设置在 Kubernetes pod 中运行的 Express.js 应用程序以连接到 MongoDB Atlas 数据库。我设置了一个出口 Droplet 来控制和记录来自集群的出站流量。出口Droplet的IP已在MongoDB Atlas中列入白名单,但应用程序仍然无法连接到数据库。我正在寻找有关如何正确配置 Express 应用程序或 Kubernetes 集群以通过出口 Droplet 路由流量的指南。

环境详情:

Express App:在 Kubernetes Pod 中运行。 Egress Droplet: 设置以控制 Kubernetes 集群的出站流量。 数据库: MongoDB Atlas,出口 Droplet 的 IP 已列入白名单。

当前配置:

  1. 网络策略:我有一个网络策略,旨在允许从 Pod 到出口 Droplet 的出口流量。

这是我应用的

allow-egress-via-gateway.yaml

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-egress-via-gateway
spec:
  podSelector:
    matchExpressions:
      - {
        key: app, 
        operator: In, 
        values: [
          express-app
        ]
      }
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 153.000.000.000/32  # The egress gateway IP
  # Additional rules for DNS traffic
  - ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53

这是我的

express-deployment.yaml
,它创建了express-app pod:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: express-app-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: express-app
  template:
    metadata:
      labels:
        app: express-app
      annotations:
        kubectl.kubernetes.io/restartedAt: "$(date +%s)"
    spec:
      containers:
      - name: express-app
        image: mydockerhub/myexpress-backend:latest
        ports:
        - containerPort: 8000
        envFrom:
        - secretRef:
            name: express-env-secret
      imagePullSecrets:
      - name: my-docker-credentials

  1. IP伪装:在出口droplet上,我在iptables中设置了IP伪装规则来修改传出数据包的源IP。
  2. 数据库连接: Express 应用程序配置为使用 Atlas 提供的连接字符串连接到 MongoDB Atlas。

遇到的问题:

尽管进行了上述设置,Express 应用程序仍无法连接到 MongoDB Atlas。日志表明这是一个连接问题,可能与 IP 未列入白名单有关,尽管我已经确认出口 Droplet 的 IP 位于白名单中。

具体问题:

  1. 我应该如何配置 Express 应用程序或 Kubernetes Pod 以确保其通过出口 Droplet 路由流量?
  2. 在为 Kubernetes 集群设置出口控制器时,是否有任何常见的陷阱或需要考虑的额外步骤?
  3. 出口 Droplet 是否需要任何额外配置以确保其正确路由和记录来自 Kubernetes Pod 的流量?

任何见解、建议或进一步的诊断步骤将不胜感激!

node.js mongodb kubernetes digital-ocean
1个回答
0
投票

确保您的网络策略 (

allow-egress-via-gateway.yaml
) 正确允许流量到达出口 Droplet。您提供的策略看起来是正确的,但请仔细检查出口 Droplet IP(cidr 部分
cidr: <Egress-Droplet-IP>/32
)。

确保部署 (

kubectl apply -f express-deployment.yaml
) 成功且 Pod 正在运行。

在出口 Droplet 上,您可以使用如下命令来设置 IP 伪装

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

确认在出口 Droplet 上正确设置了 IP 伪装。该步骤对于确保 MongoDB Atlas 的响应路由回正确的 Pod 非常重要。 因此,请检查

iptables
配置中是否存在 IP 伪装规则:
sudo iptables -t nat -L POSTROUTING
,查找类似于以下内容的行:
MASQUERADE  all  --  anywhere  anywhere

验证出口 Droplet 是否正确地将流量路由到 MongoDB Atlas 并记录该流量。确保出口 Droplet 上的防火墙或安全规则没有阻止流向 MongoDB Atlas 的流量。

在 Express 应用程序中,使用环境变量安全地存储 MongoDB 连接字符串:

const mongoUri = process.env.MONGO_URI;

确保 Express 应用程序使用正确的 MongoDB Atlas 连接字符串。该连接字符串应安全存储,例如存储在 Kubernetes Secret 中。

验证必要的环境变量是否已通过 Kubernetes 机密或配置映射正确传递到 Express 应用程序中。

envFrom:
- secretRef:
    name: express-env-secret

确保在 Express 应用程序中包含用于 MongoDB 连接的错误处理,例如:

mongoose.connect(mongoUri, { useNewUrlParser: true, useUnifiedTopology: true })
    .then(() => console.log('MongoDB connected'))
    .catch(err => console.error('MongoDB connection error:', err));

您还可以在 Express 应用程序中实现重试逻辑,以防出现暂时性网络问题:

mongoose.connection.on('error', (err) => {
    console.log('Retrying MongoDB connection...');
    setTimeout(() => mongoose.connect(mongoUri, { useNewUrlParser: true, useUnifiedTopology: true }), 5000);
});

完成所有这些之后,测试 pod 内的连接(从 Express 应用程序到 MongoDB Atlas)

kubectl exec -it <pod-name> -- /bin/bash
curl http://<mongodb-atlas-url>

并检查 pod 的日志:

kubectl logs <pod-name>

在 Pod 内部,使用网络工具进行诊断:

kubectl exec -it <pod-name> -- /bin/bash
ping <mongodb-atlas-url>
traceroute <mongodb-atlas-url>

(更重要的是,

tracepath
mtr

© www.soinside.com 2019 - 2024. All rights reserved.