我正在尝试设置在 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 已列入白名单。
当前配置:
这是我应用的
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
遇到的问题:
尽管进行了上述设置,Express 应用程序仍无法连接到 MongoDB Atlas。日志表明这是一个连接问题,可能与 IP 未列入白名单有关,尽管我已经确认出口 Droplet 的 IP 位于白名单中。
具体问题:
任何见解、建议或进一步的诊断步骤将不胜感激!
确保您的网络策略 (
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
)