Skip to content

Conversation

nastena1606
Copy link
Contributor

modified:   docs/glossary.md
new file:   docs/horizon-setup.md
new file:   docs/horizon.md
modified:   mkdocs-base.yml

	modified:   docs/glossary.md
	new file:   docs/horizon-setup.md
	new file:   docs/horizon.md
	modified:   mkdocs-base.yml
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds comprehensive documentation for the horizons feature in Percona Server for MongoDB, which enables replica set members to advertise different hostnames for internal and external network access.

Key changes:

  • Added detailed explanation of the horizons feature and its use cases
  • Provided step-by-step setup instructions with Docker Compose configuration
  • Added glossary definition for the horizons concept

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
mkdocs-base.yml Added navigation entries for the new horizon documentation pages
docs/horizon.md Created overview document explaining what horizons are and when to use them
docs/horizon-setup.md Created detailed configuration guide with Docker setup examples
docs/glossary.md Added horizons definition to the glossary

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@it-percona it-percona temporarily deployed to PSMDB-1750-Horizons-7.0 - psmdb-docs-7.0 PR #1070 October 10, 2025 21:10 — with Render Destroyed
Copy link
Member

@igroene igroene left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@radoslawszulgo radoslawszulgo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please improve the description of environments that benefit from horizons. This will help user to understand the feature and examples better.

Moreover, let's agree on using "Horizons" or "MongoDB Horizons" (with a capital letter) to refer to this feature to not confuse with a literal meaning of a "horizon".

@@ -0,0 +1,362 @@
# Configure horizons in Percona Server for MongoDB
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I miss here the introduction sentence -> that to configure connection from the external network we need to configure Horizons (+ link to the glossary).

@@ -0,0 +1,362 @@
# Configure horizons in Percona Server for MongoDB

This document focuses on configuring horizons in Percona Server for MongoDB deployed in Docker.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why on docker only? What about non-containerized environments?

I think we need to introduce here an example of environments we are talking about - when it makes sense to use Horizons. For non-containerized environments:

Imagine a company running its infrastructure on Virtual Machines (VMs) in a cloud provider (like AWS, Azure, GCP) or on-premise. They have a standard network setup:

  • a private network (e.g. VPC) where their database servers reside and within which members communicate with each other over internal DNS names like rs101.internal.perconalabs.com.
  • a public internet, from which external services like analytics tools or developers connect to databases. These connections must use a public DNS names like rs101.percona.com

In that case Horizons help to avoid setting up complicated VPNs or SSH tunnels for external access or exposing the entire MongoDB cluster over the internal which is insecure.

Here's a mermaid diagram we could use:

graph TD
    subgraph "External World"
        CLIENT_EXT[External Client/BI Tool]
    end

    subgraph "Cloud Provider / On-Premise"
        subgraph "Virtual Private Cloud (VPC)"
            subgraph "Public Subnet"
                NLB(Network Load Balancer/Proxy <br/> Public IP: 52.45.100.200 <br/> Public DNS: mongo.public.mycorp.com)
            end

            subgraph "Private Subnet"
                APP[Internal Application Server <br/> Private IP: 10.0.1.100]

                subgraph "MongoDB Replica Set (rs0)"
                    MON1(MongoDB Node 1 <br/> Primary <br/> 10.0.1.10 <br/> mongo-1.internal.mycorp.local)
                    MON2(MongoDB Node 2 <br/> Secondary <br/> 10.0.1.11 <br/> mongo-2.internal.mycorp.local)
                    MON3(MongoDB Node 3 <br/> Secondary <br/> 10.0.1.12 <br/> mongo-3.internal.mycorp.local)
                end
            end
        end
    end

    CLIENT_EXT -- 1. Connects to Public DNS (SNI: mongo.public.mycorp.com) --> NLB
    NLB -- 2. Forwards to Primary --> MON1
    MON1 -- 3. Horizons Reply (mongo.public.mycorp.com) --> NLB
    NLB -- 4. Routes Reply --> CLIENT_EXT

    APP -- 1. Connects to Internal DNS (SNI: mongo-1.internal.mycorp.local) --> MON1
    MON1 -- 2. Normal Reply (internal hostnames) --> APP

    APP -- Connects to other nodes directly --> MON2
    APP -- Connects to other nodes directly --> MON3

    MON1 <--> MON2
    MON1 <--> MON3
    MON2 <--> MON3
Loading

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot_20251014_201226 What if we simplify it and go with something like the attached mockup?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest leaving out backup and monitoring from the diagram, since they are not relevant to this topic. We should emphasize the difference between clients connecting from the same network vs clients connecting from remote sites, which might use a different FQDN to get to mongo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, will do. It is a quick AI generated mockup. My point is the initial mermaid diagram is too complicated. I'd like to have smth simpler. And move it out of the setup doc:)


* **You must use TLS in your deployment**. Horizons rely entirely on the Server Name Indication (SNI) during the TLS handshake. Connections without TLS will not allow the server to determine the correct identity via SNI, and horizons will not function.

* **TLS certificates** must be Multi-SAN (Subject Alternative Name) certificates that cover both the internal hostname (e.g., `mongo1`) and the external hostname (e.g., `external.domain.com`).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* **TLS certificates** must be Multi-SAN (Subject Alternative Name) certificates that cover both the internal hostname (e.g., `mongo1`) and the external hostname (e.g., `external.domain.com`).
* **TLS certificates** must be Multi-SAN (Subject Alternative Name) certificates that cover both the internal hostname (e.g., `internal.perconalabs.com`) and the external hostname (e.g., `external.percona.com`).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we want to use percona-specific domains?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to show a real-life scenario with valid domains. In most cases such domains are used by other organizations.


* **All-or-nothing configuration**. If one member defines a horizon, all other members must define one too. You cannot mix members with and without horizons.

## Configuration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Configuration
## Configuration example

processId: ObjectId('68e786bf0223ec7011474d9b'),
counter: Long('40')
},
hosts: [ 'mongo1:27017', 'mongo2:27017', 'mongo3:27017' ],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hosts: [ 'mongo1:27017', 'mongo2:27017', 'mongo3:27017' ],
hosts: [ 'rs101.internal.perconalabs.com:27017', 'rs102.internal.perconalabs.com:27017', 'rs103.internal.perconalabs.com:27017' ],

1. Connect to the replica set from the MongoDB client (Compass or `mongosh`) using the external hostnames you defined in horizons:
```{.bash data-prompt="$"}
$ mongosh "mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0" --tls --tlsCertificateKeyFile /certs/mongo1-combined.pem --tlsCAFile /certs/ca.pem
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$ mongosh "mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0" --tls --tlsCertificateKeyFile /certs/mongo1-combined.pem --tlsCAFile /certs/ca.pem
$ mongosh "mongodb://rs101.percona.com:27017,rs102.percona.com:27018,rs103.percona.com:27019/?replicaSet=rs1" --tls --tlsCertificateKeyFile /certs/rs1-combined.pem --tlsCAFile /certs/ca.pem

```{.text .no-copy}
Current Mongosh Log ID: 68e90919857364d663248377
Connecting to: mongodb://mongo1:27017,mongo2:27017,mongo3:27017/?replicaSet=rs0&tls=true&tlsCertificateKeyFile=%2Fcerts%2Fmongo1-combined.pem&tlsCAFile=%2Fcerts%2Fca.pem&appName=mongosh+{{mongosh}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Connecting to: mongodb://mongo1:27017,mongo2:27017,mongo3:27017/?replicaSet=rs0&tls=true&tlsCertificateKeyFile=%2Fcerts%2Fmongo1-combined.pem&tlsCAFile=%2Fcerts%2Fca.pem&appName=mongosh+{{mongosh}}
Connecting to: mongodb://rs101.percona.com:27017,rs102.percona.com:27018,rs103.percona.com:27019/?replicaSet=rs1&tls=true&tlsCertificateKeyFile=%2Fcerts%2Frs1-combined.pem&tlsCAFile=%2Fcerts%2Fca.pem&appName=mongosh+{{mongosh}}

processId: ObjectId('68e786bf0223ec7011474d9b'),
counter: Long('40')
},
hosts: [ 'localhost:27017', 'localhost:27018', 'localhost:27019' ],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hosts: [ 'localhost:27017', 'localhost:27018', 'localhost:27019' ],
hosts: [ 'rs101.percona.com:27017', 'rs102.percona.com:27018', 'rs103.percona.com:27019' ],


This overview explains the horizons feature in Percona Server for MongoDB. If you're familiar with the concept and want to use it, switch to the [Configure horizons in Percona Server for MongoDB](horizon-setup.md).

When you deploy Percona Server for MongoDB in Docker, Kubernetes, or other containerized environments, you may come across the issue that clients within the same network can reach the replica set just fine. However, backup or monitoring tools outside your cluster can't connect. Why does this happen?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not only containerized environments - also any other private, hybrid, or public cloud deployments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants