Production

This commit is contained in:
2026-11-01 17:11:07 -05:00
parent 885f4160a7
commit dc194b8168
7 changed files with 362 additions and 40 deletions
+48 -3
View File
@@ -81,7 +81,7 @@ An empty list deliberately starts an **isolated validator**. There is no automat
discovery, bootnode list, or automatic reciprocal configuration: configure the
other operators' nodes too. All nodes must run the same network/genesis/consensus.
For mainnet, application startup additionally requires at least two distinct
public HTTPS peer origins, an arrived image-pinned genesis time, the exact chain-ID
peer origins (public HTTPS by default), an arrived image-pinned genesis time, the exact chain-ID
approval, and explicit unaudited-risk acceptance. These switches are not launch
approval from this role; the project currently records a NO-GO decision. The role
does not discover or verify peer independence.
@@ -102,7 +102,8 @@ HTTPS peer origins on another port, add that port to
rules. Browser Wikimedia image fetches are client-side; validators no longer
fetch random Wikipedia articles.
For an explicitly private testnet only, set `wikideck_allow_private_peers: true`
For an explicitly private testnet or operator-controlled mainnet candidate cluster,
set `wikideck_allow_private_peers: true`
and provide `wikideck_network_policy_peer_egress` rules with destination selectors
and numeric TCP ports. This opt-in permits **both private addresses and HTTP** in
the application; it does not automatically open network policy. For example:
@@ -128,7 +129,12 @@ wikideck_network_policy_peer_egress:
The receiving node must separately allow the sender through its ingress policy.
Service DNAT handling depends on the CNI; the example selects the destination pod
and its target port 3001 rather than opening all destinations on Service port 80.
Do not enable private-peer exceptions for public peer configuration.
Do not enable private-peer exceptions for public peer configuration. Updated
mainnet candidate images advertise `privatePeersSupported: true` in their manifest;
older images reject the private opt-in. Browser HTTPS, chain approval, risk
acknowledgment and arrived genesis remain mandatory. Private HTTP RPC is not
authenticated or encrypted; keep it within a trusted cluster boundary or add
independently configured mesh transport protection.
Deploy multiple validators as **separate role instances with different names and
PVCs** (and separate hostnames if using ingress), not by scaling one Deployment.
@@ -136,6 +142,45 @@ Sharing a machine/cluster/storage failure domain does not provide independent
operator security. Empty local chains can synchronize from configured peers;
never seed a second running node by sharing its writable PVC.
### Three-node latest candidate playbook
[playbooks/wikideck.yaml](playbooks/wikideck.yaml) configures the public `wikideck`
node plus `wikideck-peer-a` and `wikideck-peer-b` within the same namespace. Each
uses its own Service and 2 TiB PVC (6 TiB requested in total), reciprocal internal
DNS peer URLs, scoped validator-pod ingress/egress, and public TCP 443 egress for
Wikipedia article and Wikimedia statistics requests used by mining templates.
Standard NetworkPolicy cannot select FQDNs; private address ranges remain excluded
from that public HTTPS rule. Only the public node gets
the `wikideck.eom.dev` TLS ingress. All three are created before readiness waits.
This deploys validators, not miners, and does not establish independent operators.
The playbook uses this role checkout directly, not a separately installed older
Galaxy role. It defaults to `ericomeehan/wikideck:latest` with pull policy `Always`
and `wikideck_candidate_risk_ack: operator-accepts-unaudited-risk`. This explicit
candidate workflow is not the digest-pinned public-launch example. Before creating
ledger resources, a short-lived hardened Kubernetes Job runs the image's
`--network-manifest` command. The playbook generates `wikideck_candidate_chain_id`
from its output and rejects older images without private-peer support, non-mainnet
images, or a future image-baked genesis. The Job is removed even on failure; it
mounts no ledger, wallet secrets, or service-account token.
Rebuild and publish `latest` from the updated application before running this
playbook. The default Dockerfile genesis is November 1, 2026, 00:00 UTC
(`1793491200`), so a normal rebuild can start now without custom genesis arguments.
Older images retain their old genesis; publishing updated source is required.
Never change the chain identity of an existing ledger without a deliberate backup
and migration plan. Do not move `latest` while inspection/deployment is in progress:
all nodes must pull the same image. For reproducible public releases use the
digest-pinned [examples/playbook.yml](examples/playbook.yml) instead. A mutable tag
with `Always` is pulled when pods start. The playbook records the inspected
container image ID in a pod-template annotation, so rerunning after publishing a
new `latest` triggers a rollout; unchanged image IDs do not force a restart.
Preserve existing data and keep the same genesis for updates to an operating chain.
The controller needs Job creation/deletion and Pod/log reads in addition to the
role's permissions. Manifest inspection needs a live cluster, so this playbook
rejects check mode; the role's offline render tests require no cluster credentials.
## Variables
All defaults are in [defaults/main.yml](defaults/main.yml).