MongoDB 复制集外部访问 - 不断获取内部集群名称

MongoDB replicaset external access - keep getting internal cluster names

我一定是做错了什么。我有一个使用 MongoDB 社区运营商配置的副本集,部署在 GKE 中,并通过 LoadBalancers 公开。

这个副本集有 3 个成员。我已经像这样定义了 replicaSetHorizo​​ns:

  replicaSetHorizons:
  - mongo-replica: document-0.mydomain.com:30000
  - mongo-replica: document-1.mydomain.com:30001
  - mongo-replica: document-2.mydomain.com:30002

然后我使用来自外部源(GKE 之外的本地计算机)的 mongosh 进行连接:

mongosh "mongodb://<credentials>@document-0.mydomain.com:30000,document-1.mydomain.com:30001,document-2.mydomain.com:30002/admin?ssl=false&replicaSet=document"

我暂时不使用 SSL,因为我正在测试此部署。我发现的是 mongosh 总是 returns 这个错误:

MongoNetworkError: getaddrinfo ENOTFOUND document-0.document-svc.mongodb.svc.cluster.local

有人可以向我解释我做错了什么吗?为什么我的内部集群名称被提供给 mongosh 以尝试连接?

如果我尝试连接到副本集的单个成员,连接将会成功。如果我 运行 rs.conf(),我会看到以下内容(看起来正确??):

{
  _id: 'document',
  version: 1,
  term: 1,
  members: [
    {
      _id: 0,
      host: 'document-0.document-svc.mongodb.svc.cluster.local:27017',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 1,
      tags: {},
      horizons: { 'mongo-replica': 'document-0.mydomain.com:30000' },
      secondaryDelaySecs: Long("0"),
      votes: 1
    },
    {
      _id: 1,
      host: 'document-1.document-svc.mongodb.svc.cluster.local:27017',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 1,
      tags: {},
      horizons: { 'mongo-replica': 'document-1.mydomain.com:30001' },
      secondaryDelaySecs: Long("0"),
      votes: 1
    },
    {
      _id: 2,
      host: 'document-2.document-svc.mongodb.svc.cluster.local:27017',
      arbiterOnly: false,
      buildIndexes: true,
      hidden: false,
      priority: 1,
      tags: {},
      horizons: { 'mongo-replica': 'document-2.mydomain.com:30002' },
      secondaryDelaySecs: Long("0"),
      votes: 1
    }
  ],
  protocolVersion: Long("1"),
  writeConcernMajorityJournalDefault: true,
  settings: {
    chainingAllowed: true,
    heartbeatIntervalMillis: 2000,
    heartbeatTimeoutSecs: 10,
    electionTimeoutMillis: 10000,
    catchUpTimeoutMillis: -1,
    catchUpTakeoverDelayMillis: 30000,
    getLastErrorModes: {},
    getLastErrorDefaults: { w: 1, wtimeout: 0 },
    replicaSetId: ObjectId("62209784e8aacd8385db1609")
  }
}

ReplicaSetHorizo​​ns 功能在没有 使用SSL/TLS 证书的情况下不起作用。 引用自 Kubernetes Operator reference:

This method to use split horizons requires the Server Name Indication extension of the TLS protocol

为了完成这项工作,您需要包含

  • TLS 证书
  • TLS 密钥
  • CA 密钥

TLS 证书必须包含主题备用名称 (SAN) 部分中所有副本集的 DNS 名称

运营商 github 页有一个 tutorial。您需要完成所有步骤,无法跳过证书颁发

证书资源(使用cert-manager.io CRD)

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: cert-manager-certificate
spec:
  secretName: mongodb-tls
  issuerRef:
    name: ca-issuer
    kind: Issuer
  duration: 87600h
  commonName: "*.document-svc.mongodb.svc.cluster.local"
  dnsNames:
    - "*.document-svc.mongodb.svc.cluster.local"
    - "document-0.mydomain.com"
    - "document-1.mydomain.com"
    - "document-2.mydomain.com"

MongoDBCommunity 资源摘录

spec:
  type: ReplicaSet
  ...
  replicaSetHorizons:
    - mongo-replica: document-0.mydomain.com:30000
    - mongo-replica: document-0.mydomain.com:30001
    - mongo-replica: document-0.mydomain.com:30002
  security:
    tls:
      enabled: true
      certificateKeySecretRef:
        name: mongodb-tls
      caConfigMapRef:
        name: ca-config-map

Secret mongodb-tls 将属于 tls 类型并包含 ca.crt, tls.crttls.key 字段分别表示证书颁发机构证书、TLS 证书和 TLS 密钥。
ConfigMap ca-config-map 将仅包含 ca.crt 字段

更多信息位于:mongodb-operator-secure-tls