Kubernetes中MongoDB集群无法通过集群域名连接问题排查
问题描述
使用以下Terraform配置创建单节点MongoDB StatefulSet及对应Service后,无法通过集群内部域名或外部CLI连接MongoDB:
- 进入Pod内部用
localhost:27017可正常连接 - 同Pod内用集群域名
mongodb.default.svc.cluster.local:27017连接时提示连接拒绝 - MongoDB日志显示已绑定
0.0.0.0
附带配置代码:
locals { labels = { "app" = "mongo" } volume_config_name = "mongo-config" } module "mongo" { source = "terraform-iaac/stateful-set/kubernetes" version = "1.4.2" image = "mongo:4.4" name = "mongodb" namespace = kubernetes_namespace.cmprimg.metadata[0].name custom_labels = local.labels volume_host_path = [ { volume_name = "data" path_on_node = "/data/db" }, ] volume_mount = [ { mount_path = "/data/db" volume_name = "data" }, { mount_path = "/etc/mongod.conf.orig" volume_name = "mongodb-conf" sub_path = "configfile" // Key from configmap } ] volume_config_map = [{ mode = "0777" volume_name = "mongodb-conf" name = "mongodb-confmap" }] # volume_claim = [ # { # name = "mongo" # namespace = kubernetes_namespace.cmprimg.metadata[0].name # access_modes = ["ReadWriteOnce"] # requests_storage = "4Gi" # persistent_volume_name = "mongo" # storage_class_name = "linode-block-storage-retain" # } # ] env = { "MONGO_INITDB_ROOT_USERNAME" = var.username, "MONGO_INITDB_ROOT_PASSWORD" = var.password, } command = [ "mongod", "--bind_ip", "0.0.0.0", ] internal_port = [ { name = "mongo" internal_port = 27017 } ] resources = { request_cpu = "100m" request_memory = "800Mi" limit_cpu = "120m" limit_memory = "900Mi" } replicas = 1 } module "mongo_service" { source = "terraform-iaac/service/kubernetes" version = "1.0.4" app_name = module.mongo.name app_namespace = kubernetes_namespace.cmprimg.metadata[0].name port_mapping = [ { name = "mongo" internal_port = 27107 external_port = 27017 } ] custom_labels = local.labels } resource "kubernetes_persistent_volume_claim" "example" { metadata { name = "mongo" namespace = kubernetes_namespace.cmprimg.metadata[0].name labels = local.labels } spec { access_modes = ["ReadWriteOnce"] resources { requests = { storage = "20Gi" } } storage_class_name = "linode-block-storage-retain" } } resource "kubernetes_config_map" "mongodb_conf" { metadata { name = "mongodb-confmap" namespace = kubernetes_namespace.cmprimg.metadata[0].name labels = local.labels } data = { "configfile" = yamlencode({ storage : { dbPath : "/data/db", }, net : { port : 27017, bindIp : "0.0.0.0", } }) } }
问题分析与修复方案
1. Service端口映射错误(核心问题)
你的mongo_service模块中,port_mapping的internal_port写成了27107,但MongoDB实际监听的是27017,导致Service转发到了错误的端口,直接引发连接拒绝。
修复:将internal_port改为27017:
port_mapping = [ { name = "mongo" internal_port = 27017 external_port = 27017 } ]
2. Service与Pod标签选择器不匹配风险
检查terraform-iaac/service/kubernetes模块的标签选择逻辑:
- 你的StatefulSet Pod标签是
app: mongo(来自local.labels) - Service模块的
app_name设置为module.mongo.name(即mongodb),如果该模块默认用app: ${app_name}作为选择器,那么Service会去匹配app: mongodb的Pod,但你的Pod标签是app: mongo,导致Service找不到后端Pod。
验证方法:执行kubectl describe service mongodb -n <你的命名空间>查看Selector字段,确认是否和Pod标签一致。
修复:如果模块支持自定义选择器,显式指定匹配Pod的标签:
# 参考模块文档,添加selector配置(如果支持) selector = local.labels
或者调整StatefulSet的custom_labels为app: mongodb,保持和Service选择器一致。
3. 未启用PersistentVolumeClaim(非连接问题,但建议修复)
你定义了kubernetes_persistent_volume_claim.example,但StatefulSet模块中注释掉了volume_claim配置,当前使用的是hostPath存储,Pod迁移后数据会丢失。建议启用PVC:
volume_claim = [ { name = "mongo" namespace = kubernetes_namespace.cmprimg.metadata[0].name access_modes = ["ReadWriteOnce"] requests_storage = "20Gi" storage_class_name = "linode-block-storage-retain" } ]
同时删除volume_host_path配置,避免存储冲突。
4. 验证修复步骤
- 应用修改后的Terraform配置:
terraform apply - 确认Service后端Pod状态:
kubectl get endpoints mongodb -n <你的命名空间>,查看是否有READY的Pod - 在Pod内重新测试集群域名连接:
mongosh mongodb.default.svc.cluster.local:27017 -u <用户名> -p <密码>
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

