|
| 1 | +--- |
| 2 | +# cSpell:ignore interconnectivity |
| 3 | + |
| 4 | +id: clusters |
| 5 | +title: Clusters |
| 6 | +description: This document describes Clusters in Pomerium Zero. |
| 7 | +keywords: [clusters, pomerium zero] |
| 8 | +sidebar_label: Clusters |
| 9 | +sidebar_position: 1 |
| 10 | +--- |
| 11 | + |
| 12 | +import Tabs from '@theme/Tabs'; |
| 13 | +import TabItem from '@theme/TabItem'; |
| 14 | + |
| 15 | +# Clusters in Pomerium Zero |
| 16 | + |
| 17 | +This document provides an overview of Clusters in Pomerium Zero. |
| 18 | + |
| 19 | +## Overview |
| 20 | + |
| 21 | +When you install Pomerium Zero, you get your own **Cluster**. A cluster consists of one or more replicas of [Pomerium Core](/docs/core), the primary server component that secures your services. Clusters are deployed locally and managed through Pomerium Zero's hosted control plane. |
| 22 | + |
| 23 | +## Why clusters? |
| 24 | + |
| 25 | +A cluster model reduces the complexity of managing Pomerium: All of a cluster's configuration, including settings, routes, policies, and certificates, are managed from a central control plane hosted in the Pomerium Zero cloud. This allows you to manage multiple isolated Pomerium Core deployments, each with its own configuration. |
| 26 | + |
| 27 | +Configuration changes applied in the hosted control plane are communicated over a streaming connection to your local cluster. Each cluster is connected to its own storage backend, which synchronizes state across replicas. |
| 28 | + |
| 29 | +  |
| 30 | + |
| 31 | +Each replica runs Pomerium Core in an all-in-one mode, meaning the services that comprise Core are deployed together and share session state. Similarly, replicas communicate with each other to synchronize state across a cluster. The interconnectivity between replicas enables you to horizontally scale your cluster to support multiple workloads and higher availability. |
| 32 | + |
| 33 | +This model affords the following benefits: |
| 34 | + |
| 35 | +- Simplified configuration |
| 36 | +- Enhanced data privacy |
| 37 | +- Improved scalability |
| 38 | + |
| 39 | +## Cluster benefits |
| 40 | + |
| 41 | +### Simplified configuration |
| 42 | + |
| 43 | +Cluster configuration is fully managed in Pomerium Zero. Configuration changes applied in Pomerium Zero are fetched and applied locally by your cluster. |
| 44 | + |
| 45 | +This model ensures that: |
| 46 | + |
| 47 | +- Your cluster remains synchronized with Pomerium Zero as changes are applied |
| 48 | +- You don't have to manage cluster configuration files or environment variables |
| 49 | +- Pomerium Zero persists your cluster's last-known configuration |
| 50 | + |
| 51 | +### Enhanced data privacy |
| 52 | + |
| 53 | +Pomerium can't monitor your organization's traffic or collect private user data. However, Pomerium does need to store configuration details required to maintain the hosted control plane. |
| 54 | + |
| 55 | +Pomerium also stores deployment and configuration details required to control access to your services, such as routes, policies, TLS certificates, and sensitive encrypted data when appropriate. |
| 56 | + |
| 57 | +### Improved scalability |
| 58 | + |
| 59 | +Replicas within a cluster synchronize records over a streaming connection, which keeps the cluster abreast of configuration changes. In this way, you can deploy multiple replicas to meet the needs of your infrastructure and organization. |
| 60 | + |
| 61 | +See [**Persistence and scalability**](#persistence-and-scalability) below for more information. |
| 62 | + |
| 63 | +## Deploy your cluster |
| 64 | + |
| 65 | +### Cluster token |
| 66 | + |
| 67 | +When you deploy a cluster in Pomerium Zero, a **Cluster Token** is generated for you. The cluster token environment variable instructs Pomerium to run in a special "Zero-managed" mode, wherein your cluster connects to the Pomerium Zero cloud. |
| 68 | + |
| 69 | +You can generate a new cluster token at any time. See the [**Rotate cluster token**](#rotate-cluster-token) steps below for more information. |
| 70 | + |
| 71 | +#### Rotate cluster token |
| 72 | + |
| 73 | +A cluster token does not have a set expiration time. However, you may want to rotate the cluster token for security reasons. For example: |
| 74 | + |
| 75 | +- A cluster token was accidentally exposed |
| 76 | +- You may lose track of the existing token, and want a new one |
| 77 | + |
| 78 | +:::caution |
| 79 | + |
| 80 | +Rotating the cluster token invalidates the current token, and shuts your cluster down. |
| 81 | + |
| 82 | +::: |
| 83 | + |
| 84 | +To rotate your cluster token: |
| 85 | + |
| 86 | +<Tabs> |
| 87 | +<TabItem label="Zero Console" value="zero-console"> |
| 88 | + |
| 89 | +1. From the navigation bar dropdown, select **Manage Clusters** |
| 90 | +1. Under **Actions**, select the **edit** icon |
| 91 | +1. Select the **Advanced** tab |
| 92 | +1. In the **Cluster Token** field, select **Rotate Token** |
| 93 | +1. In the confirmation modal, select **Confirm** |
| 94 | +1. Copy the token value and store it somewhere safe |
| 95 | + |
| 96 | + |
| 97 | + |
| 98 | +</TabItem> |
| 99 | +<TabItem label="Zero API" value="zero-api"> |
| 100 | + |
| 101 | +Send a `POST` request to the `/token` endpoint: |
| 102 | + |
| 103 | +```curl |
| 104 | +curl 'https://console.pomerium.app/api/v0/organizations/{organizationId}/clusters/{clusterId}/token' \ |
| 105 | +--header 'Authorization: Bearer {ID-TOKEN}' |
| 106 | +``` |
| 107 | + |
| 108 | +You'll receive a response with a new cluster `refreshToken`: |
| 109 | + |
| 110 | +```json |
| 111 | +{ |
| 112 | + "refreshToken": "token" |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +</TabItem> |
| 117 | +</Tabs> |
| 118 | + |
| 119 | +After rotating the cluster token, you must pass it into your configuration and run Pomerium. See the steps below for your deployment environment. |
| 120 | + |
| 121 | +<Tabs> |
| 122 | +<TabItem value="linux" label="Linux"> |
| 123 | + |
| 124 | +In the shell script below, replace `<cluster_token>` with your new cluster token before running the command: |
| 125 | + |
| 126 | +```bash |
| 127 | +curl https://console.pomerium.app/install.bash | env POMERIUM_ZERO_TOKEN=<cluster_token> bash -s install |
| 128 | +``` |
| 129 | + |
| 130 | +</TabItem> |
| 131 | +<TabItem value="docker" label="Docker"> |
| 132 | + |
| 133 | +1. In your `docker-compose.yaml` file, replace `<CLUSTER_TOKEN>` with your new token: |
| 134 | + |
| 135 | +```yaml title="docker-compose.yaml" {8} showLineNumbers |
| 136 | +services: |
| 137 | + pomerium: |
| 138 | + image: pomerium/pomerium:v0.27.0 |
| 139 | + ports: |
| 140 | + - 443:443 |
| 141 | + restart: always |
| 142 | + environment: |
| 143 | + POMERIUM_ZERO_TOKEN: <CLUSTER_TOKEN> |
| 144 | + XDG_CACHE_HOME: /var/cache |
| 145 | + volumes: |
| 146 | + - pomerium-cache:/var/cache |
| 147 | + networks: |
| 148 | + main: {} |
| 149 | + |
| 150 | +networks: |
| 151 | + main: {} |
| 152 | + |
| 153 | +volumes: |
| 154 | + pomerium-cache: |
| 155 | +``` |
| 156 | +
|
| 157 | +1. Run `docker compose up -d` |
| 158 | + |
| 159 | +</TabItem> |
| 160 | +<TabItem value="kubernetes" label="Kubernetes"> |
| 161 | + |
| 162 | +1. Run the following command, replacing `cluster_token` with your new cluster token: |
| 163 | + |
| 164 | +```bash |
| 165 | +$ export POMERIUM_ZERO_TOKEN=<cluster_token> |
| 166 | +``` |
| 167 | + |
| 168 | +1. Then, to write the new cluster token to the Kubernetes secret, run: |
| 169 | + |
| 170 | +```bash |
| 171 | +kubectl -n pomerium patch secret pomerium-zero-token -p "{\"stringData\":{\"pomerium_zero_token\":\"${POMERIUM_ZERO_TOKEN}\"}}" |
| 172 | +``` |
| 173 | + |
| 174 | +</TabItem> |
| 175 | +</Tabs> |
| 176 | + |
| 177 | +### Detected and Override IP Address |
| 178 | + |
| 179 | +When you first deploy a cluster, it connects itself to the Pomerium Zero cloud, and Pomerium Zero automatically assigns the cluster a unique [**Starter Domain**](#starter-domain). During this process, Pomerium Zero attempts to detect the cluster’s outbound IP address to connect to it. |
| 180 | + |
| 181 | +Once Pomerium Zero successfully connects to the cluster’s **Detected IP Address**, it sets A (IPv4) or AAAA (IPv6) records for the starter domain. Depending on your environment, the detected IP address may not be reachable by you, the end-user. This could be the case if, for example, you're running a cluster: |
| 182 | + |
| 183 | +- Locally from your laptop behind a NAT-enabled router |
| 184 | +- Inside a corporate intranet |
| 185 | +- Behind a firewall |
| 186 | +- In a Kubernetes server where the ingress load balancer IP address doesn't match the egress IP address |
| 187 | + |
| 188 | +In such cases, you may see one of the following errors: |
| 189 | + |
| 190 | +- `ERR_CONNECTION_REFUSED` |
| 191 | +- `DNS_PROBE_FINISHED_NXDOMAIN` (when accessing a route) |
| 192 | + |
| 193 | +The `ERR_CONNECTION_REFUSED` error means that your cluster is running, but Pomerium Zero can't reach it with the detected IP address. The `DNS_PROBE_FINISHED_NXDOMAIN` error means that there is no DNS record available for the domain. This could mean that the domain name changes haven't finished propagating yet, or that the cluster never connected to Pomerium Zero because the IP address couldn't be detected. |
| 194 | + |
| 195 | +As a workaround, we've provided the **Override IP Address** field, which allows you to manually set the IP address so that Pomerium Zero can connect to your cluster. |
| 196 | + |
| 197 | + |
| 198 | + |
| 199 | +## Manage cluster configuration |
| 200 | + |
| 201 | +### Starter domain |
| 202 | + |
| 203 | +Pomerium Zero generates and assigns a unique **Starter Domain** to your cluster. A starter domain is a randomly generated domain name that follows this format: |
| 204 | + |
| 205 | +`<CLUSTER-SUBDOMAIN-XXXX>.pomerium.app` |
| 206 | + |
| 207 | +For example: `voracious-ape-1578.pomerium.app` |
| 208 | + |
| 209 | +The starter domain comes with its own DNS records and TLS certificates so you can quickly test Pomerium Zero before adding your own custom domain. |
| 210 | + |
| 211 | +:::info Add Custom Domain |
| 212 | + |
| 213 | +See the [**Custom Domains**](/docs/capabilities/custom-domains) page for more information on how to add custom domains to a cluster. |
| 214 | + |
| 215 | +::: |
| 216 | + |
| 217 | +### Cluster name |
| 218 | + |
| 219 | +The **Cluster Name** is a customizable identifier for your cluster. It defaults to the randomly generated subdomain of your cluster domain, but you can change it at any time. Changing the cluster name does not affect your starter domain. |
| 220 | + |
| 221 | +If you want to change the cluster name, you can update it in your cluster settings: |
| 222 | + |
| 223 | +1. From the navigation bar dropdown, select **Manage Clusters** |
| 224 | +1. Under **Actions**, select the **edit** icon |
| 225 | +1. In the **Cluster Name** field, enter your preferred cluster name |
| 226 | +1. Save your changes and apply the changeset |
| 227 | + |
| 228 | + |
| 229 | + |
| 230 | +### Routes, policies, and certificates |
| 231 | + |
| 232 | +Routes and policies defined in a cluster are scoped only to that cluster, and are not available in other clusters. |
| 233 | + |
| 234 | +Pomerium Zero automatically provisions and renews wildcard TLS certificates issued by ZeroSSL for each cluster. Like routes and policies, certificates are scoped to a cluster and are not available in other clusters. |
| 235 | + |
| 236 | +:::info |
| 237 | + |
| 238 | +To learn more about routing, policies, and certificates in Pomerium, see the following docs: |
| 239 | + |
| 240 | +- [**Routing**](/docs/capabilities/routing) |
| 241 | +- [**Policy Language**](/docs/capabilities/ppl) |
| 242 | +- [**Certificates**](/docs/reference/certificates) |
| 243 | + |
| 244 | +::: |
| 245 | + |
| 246 | +## Persistence and scalability |
| 247 | + |
| 248 | +### Persistence |
| 249 | + |
| 250 | +By default, Pomerium uses an in-memory storage backend to synchronize a cluster's configuration and session state. This is suitable for test environments, but not for production. In the event of a service outage, your cluster can't fetch its configuration from the cloud, so it can't serve traffic. |
| 251 | + |
| 252 | +To avoid service outages, we recommend that you deploy a PostgreSQL database to persist your cluster's configuration state. Since all replicas share the same storage connection, the database will persist cluster state if a replica restarts due to a service outage. |
| 253 | + |
| 254 | +To configure a database connection in Pomerium Zero: |
| 255 | + |
| 256 | +1. Select **Settings** |
| 257 | +1. Go to the **General** tab |
| 258 | +1. Enter the connection string in the [**Databroker Storage Connection String**](/docs/reference/databroker#databroker-storage-connection-string) field |
| 259 | + |
| 260 | + |
| 261 | + |
| 262 | +### Replicas |
| 263 | + |
| 264 | +To deploy a replica, run the Pomerium Zero installation script using the same [cluster token](#cluster-token) you used to deploy your cluster. This will generate another replica, which you can verify on the [**Status**](https://console.pomerium.app/app/reports/status) page. |
| 265 | + |
| 266 | +:::note |
| 267 | + |
| 268 | +Replicas left inactive for over 24 hours will not appear on the Status page. |
| 269 | + |
| 270 | +::: |
| 271 | + |
| 272 | + |
0 commit comments