You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Fix subnet scheme to use SUBNET_INDEX 0-based allocation (10.8.0.0/18,
10.8.64.0/18, ...) matching the deploy script behavior
- Add SUBNET_INDEX mapping table for quick reference
- Add cluster sync and peer discovery section explaining bootnode vs
auto-discovery mechanisms
- Add image version note about sync enable logic differences
- Fix gateway-1 config to use empty bootnode (first node doesn't need one)
- Expand verify section with Status API and health check criteria
- Add Cloudflare DNS:Edit permission note for API token setup
- Each node's Client IP range should not overlap (used for allocating IPs to different CVMs)
84
-
- bootnode is configured as another node's RPC URL, used for cluster discovery at startup
82
+
- Each node's `node_id` must be unique and greater than 0
83
+
- Each node's Client IP range must not overlap (used for allocating IPs to different CVMs)
84
+
-`bootnode` is optional — it speeds up initial peer discovery but is not required. Without a bootnode, a node will auto-discover peers when they connect via sync RPC
85
+
- If a bootnode is set, its hostname must be resolvable before cluster bootstrap
85
86
86
87
### 2.2 CIDR Description
87
88
88
89
Client IP range (/18):
89
90
- /18 means the first 18 bits are the network prefix
90
-
- For example, 10.8.128.0/18 covers the address range 10.8.128.0 ~ 10.8.191.255
91
+
- For example, 10.8.0.0/18 covers the address range 10.8.0.0 ~ 10.8.63.255
91
92
- Each Gateway's /18 range does not overlap, so each Gateway can allocate IPs locally without syncing with other Gateways
93
+
- With 4 possible /18 ranges in a /16 network, a cluster supports up to 4 gateway nodes
92
94
93
95
Gateway IP (/16):
94
96
- Gateway IP uses /16 netmask to allow network routing to cover the larger 10.8.0.0/16 address space
95
97
- This way, when another Gateway allocates an address in a /18 subnet, traffic can still be correctly routed
96
98
99
+
Subnet mapping:
100
+
101
+
| SUBNET_INDEX | Gateway IP | Client IP range | Address range | Usable IPs |
-`ip`: Gateway's own WireGuard address in CIDR format (e.g., 10.8.128.1/16)
102
-
-`client_ip_range`: Address pool range for allocating to CVMs (e.g., 10.8.128.0/18)
103
-
-`reserved_net`: Reserved address range that will not be allocated to CVMs (e.g., 10.8.128.1/32, reserving the gateway's own address)
112
+
-`ip`: Gateway's own WireGuard address in CIDR format (e.g., 10.8.0.1/16)
113
+
-`client_ip_range`: Address pool range for allocating to CVMs (e.g., 10.8.0.0/18)
114
+
-`reserved_net`: Reserved address range that will not be allocated to CVMs (e.g., 10.8.0.1/32, reserving the gateway's own address)
104
115
105
116
Recommendation: Design client_ip_range and reserved_net to ensure clear address pool planning for each Gateway, avoiding address conflicts.
106
117
107
-
### 2.4 Configuration File Examples
118
+
### 2.4 Cluster Sync and Peer Discovery
119
+
120
+
> **Image version note**: The sync enable logic varies by gateway image version. In `dstacktee/dstack-gateway:0.5.8`, sync is enabled when `NODE_ID > 0` (regardless of `BOOTNODE_URL`). In some custom-built images, sync may only be enabled when `BOOTNODE_URL` is non-empty. Check your image's `entrypoint.sh` to confirm the behavior. When in doubt, set `NODE_ID > 0` and provide a `BOOTNODE_URL` on at least one node.
121
+
122
+
Gateway nodes discover each other through two mechanisms:
123
+
124
+
1.**Bootnode discovery** (active): A node with `bootnode` configured will fetch the peer list from the bootnode at startup, then periodically retry until peers are found.
125
+
126
+
2.**Auto-discovery** (passive): When a remote node sends a sync request, the local node automatically adds it as a peer. This means the first node in a cluster does not need a bootnode — it will be discovered when the second node connects to it.
127
+
128
+
This allows a simple deployment order:
129
+
1. Start gateway-1 with `bootnode = ""` (no bootnode)
130
+
2. Start gateway-2 with `bootnode = "https://rpc.gateway-1:9012"`
131
+
3. Gateway-2 fetches peers from gateway-1 and starts syncing
132
+
4. Gateway-1 auto-discovers gateway-2 from the incoming sync request
133
+
134
+
> Note: `bootnode` is only used for initial discovery. Once peers are discovered, they are persisted in the KV store and survive restarts.
- Each node appears in every other node's `.nodes` array
263
+
-`last_seen` timestamps are recent (within the sync interval)
264
+
-`peer_ack` values are close to `local_ack` (no large lag)
265
+
228
266
## 3. Adding Reverse Proxy Domains
229
267
230
268
Gateway supports automatic TLS certificate management via the ACME protocol.
@@ -245,6 +283,8 @@ curl -X POST "http://localhost:9016/prpc/Admin.SetCertbotConfig" \
245
283
246
284
Gateway uses DNS-01 validation, which requires configuring DNS provider API credentials.
247
285
286
+
The Cloudflare API token needs the **DNS:Edit** permission on the target zone. Create one at [Cloudflare API Tokens](https://dash.cloudflare.com/profile/api-tokens) with the "Edit zone DNS" template.
0 commit comments