Debo estar haciendo algo terriblemente mal. Tengo un conjunto de réplicas configurado con el operador de la comunidad MongoDB, implementado en GKE y expuesto a través de LoadBalancers.
Este conjunto de réplicas tiene 3 miembros. He definido replicaSetHorizons así:
replicaSetHorizons: - mongo-replica: document-0.mydomain.com:30000 - mongo-replica: document-1.mydomain.com:30001 - mongo-replica: document-2.mydomain.com:30002
Luego uso mongosh desde una fuente externa (computadora local fuera de GKE) para conectar:
mongosh "mongodb://<credentials>@document-0.mydomain.com:30000,document-1.mydomain.com:30001,document-2.mydomain.com:30002/admin?ssl=false&replicaSet=document"
No uso SSL por ahora porque estoy probando esta implementación. Lo que encontré es mongosh siempre devuelve este error:
MongoNetworkError: getaddrinfo ENOTFOUND document-0.document-svc.mongodb.svc.cluster.local
¿Alguien puede explicarme qué estoy haciendo mal? ¿Por qué mi nombre de clúster interno se le da a mongosh para intentar la conexión?
Si trato de conectarme a un solo miembro del conjunto de réplicas, la conexión se realizará correctamente. Si ejecuto rs.conf()
, veo lo siguiente (¿que parece correcto?):
{ _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") } }
La función ReplicaSetHorizons no funciona sin usar certificados SSL/TLS. Citando la referencia del operador de Kubernetes:
Este método para usar horizontes divididos requiere la extensión de indicación de nombre de servidor del protocolo TLS
Para que esto funcione, debe incluir
El certificado TLS debe contener los nombres DNS de todos sus conjuntos de réplicas en la sección Nombre alternativo del sujeto (SAN)
Hay un tutorial en las páginas del operador github. Debe completar todos los pasos, la emisión del certificado no se puede omitir .
Recurso de certificado (usando 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"
Extracto de recursos de la comunidad MongoDB
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 será del tipo tls y contendrá los campos ca.crt, tls.crt y tls.key que representan el certificado de la autoridad certificadora, el certificado TLS y la clave TLS, respectivamente.
ConfigMap ca-config-map contendrá solo el campo ca.crt
Más información en: mongodb-operator-secure-tls