如何配置Kubernetes中Express应用通过出口Droplet连接MongoDB Atlas
通过出口Droplet路由Kubernetes Pod流量连接MongoDB Atlas问题排查与配置方案
环境详情
- Express应用:运行在Kubernetes Pod中
- 出口Droplet:用于管控Kubernetes集群的出站流量
- 数据库:MongoDB Atlas,已将出口Droplet的IP加入白名单
当前配置
1. 网络策略(Network Policy)
已配置网络策略允许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
2. Express应用部署配置
express-deployment.yaml内容如下:
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
3. 其他配置
- IP Masquerading:出口Droplet上已通过iptables配置IP伪装规则,修改出站数据包的源IP
- 数据库连接:Express应用通过MongoDB Atlas提供的连接字符串配置数据库连接
遇到的问题
尽管完成上述配置,Express应用仍无法连接MongoDB Atlas,日志显示连接问题,疑似IP未加入白名单,但已确认出口Droplet的IP在白名单中。
具体疑问
- 应如何配置Express应用或Kubernetes Pod,确保流量通过出口Droplet路由?
- 搭建Kubernetes集群出口控制器时,有哪些常见陷阱或额外步骤需注意?
- 出口Droplet是否需额外配置,以正确路由并记录Kubernetes Pod的流量?
解决方案与诊断步骤
一、确保Pod流量强制路由至出口Droplet
当前Network Policy仅做访问控制,未强制所有出站流量走出口Droplet,需补充路由规则:
- 节点级静态路由配置
在所有Kubernetes工作节点上添加路由,将MongoDB Atlas网段的流量指向出口Droplet:
# 替换为MongoDB Atlas的实际网段(可从控制台获取) ATLAS_CIDRS="18.205.93.0/24,13.236.229.0/24" # 替换为出口Droplet的IP EGRESS_GW_IP=153.000.000.000 for cidr in $(echo $ATLAS_CIDRS | tr ',' ' '); do ip route add $cidr via $EGRESS_GW_IP done
将命令添加到/etc/rc.local或使用netplan/networkd持久化,避免节点重启后失效。
- CNI插件Egress网关配置(规范方案)
若使用Calico等支持Egress网关的CNI,定义EgressGateway和EgressPolicy资源,将express-app的流量绑定到出口Droplet,强制流量走向网关。
二、验证IP伪装规则有效性
检查出口Droplet的iptables规则是否覆盖Pod网段:
- 查看当前伪装规则:
iptables -t nat -L POSTROUTING -n -v
确认存在针对Pod网段的MASQUERADE规则,例如:
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 MASQUERADE all -- * eth0 10.0.0.0/16 0.0.0.0/0
其中10.0.0.0/16需替换为集群实际Pod CIDR。
- 若规则缺失,添加并持久化:
POD_CIDR=10.0.0.0/16 OUT_IFACE=eth0 iptables -t nat -A POSTROUTING -s $POD_CIDR -o $OUT_IFACE -j MASQUERADE # Debian/Ubuntu持久化 iptables-save > /etc/iptables/rules.v4
三、流量路径验证
- 在Express Pod中追踪路由:
kubectl exec -it <express-pod-name> -- traceroute <mongodb-atlas-hostname>
若第一跳不是出口Droplet IP,说明路由规则未生效。
- 在出口Droplet抓包确认流量到达:
tcpdump -i any host <mongodb-atlas-ip> and src <pod-ip>
若未抓到包,检查Network Policy和节点路由是否正确。
四、常见陷阱与注意事项
- Network Policy不负责路由:仅做访问控制,必须配合路由规则强制流量走向出口Droplet
- DNS解析完整性:确保Pod的DNS请求要么走出口Droplet,要么允许访问集群DNS服务(当前配置已开放53端口,需确认解析结果正确)
- 出口Droplet防火墙规则:允许来自Kubernetes Pod网段的入站流量,以及到MongoDB Atlas 27017端口的出站流量
- IP伪装网段覆盖:必须包含所有Pod网段,否则部分流量仍会使用节点IP出站
- 配置持久化:节点路由和iptables规则需持久化,避免重启失效
五、出口Droplet额外配置
- 开启IP转发:
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf sysctl -p
这是路由转发和IP伪装的前提。
- 流量记录:
使用tcpdump记录MongoDB流量到文件,或部署日志工具收集:
tcpdump -i any port 27017 -w /var/log/mongodb-traffic.pcap
- 防火墙加固:
配置Droplet防火墙(如ufw、云安全组):
- 入站:允许Kubernetes集群节点/Pod网段的所有流量
- 出站:允许到MongoDB Atlas网段的27017端口、DNS 53端口
内容的提问来源于stack exchange,提问作者rom
相关产品推荐
相关产品推荐

