Requirements
This page lists what an install requires before you run any command. Most failed installs are caused by a missing prerequisite on this page, not by a broken command.
Node zero
There is no install media. You prepare the founder by hand. Every other
machine network-boots from the founder. Before tritonadm setup bootstrap
runs, the founder needs:
| Prerequisite | Checked by bootstrap |
|---|---|
| A SmartOS platform image booted | No |
A zones ZFS pool | No. Bootstrap runs no zpool command. It adopts an existing pool without changes. |
| A nic tag for every network the answers document declares | No |
| An admin IP, netmask, and default route on the founder | Yes. The plan preview reads them as facts. |
Check all four on the founder, in the global zone, as root:
uname -a
zpool list zones
nictagadm list
ipadm show-addr
netstat -rn -f inet
A founder that carries all three networks on one LACP bond shows admin,
external, and underlay on aggr0 in the output of nictagadm list.
Whether the admin network can use a bond on the founder depends on the
switch. See
Troubleshooting an install.
Do not give the founder an address inside a declared range, and never inside
cn_range. The founder never network-boots, so no boot record reserves its
address. Only the founder's own compute-node registration marks the address
as used, and that happens late in genesis. A founder on the first cn_range
address can receive the same IP as the first enrolling node.
Networks
| Network | Carries | Notes |
|---|---|---|
admin | control plane, enrollment, agents | Untagged in most deployments. Must be one layer-2 segment for every machine. |
external | tenant-facing and DNS addresses | Tagged. Needs a real gateway. |
underlay | VXLAN and Geneve between compute nodes | Tagged. Optional until there is more than one compute node. |
The answers document divides the admin network into four ranges. The
ranges must not overlap:
| Range | Holds |
|---|---|
infra_range | Control-plane zone addresses |
cn_range | Addresses for admitted compute nodes |
join_dhcp_range | Temporary leases for machines during enrollment |
rendezvous.admin_vip | The cluster's stable address |
Check that the external VLAN reaches its gateway from the founder before you
install. A tagged VNIC and one ping is sufficient. On the founder, as root:
dladm create-vnic -l aggr0 -v <VLAN_ID> probe0
ipadm create-if probe0
ipadm create-addr -T static -a <FREE_IP>/<PREFIX> probe0/v4
ping <EXTERNAL_GATEWAY>
ipadm delete-addr probe0/v4
ipadm delete-if probe0
dladm delete-vnic probe0
DNS delegation
If the answers document has a dns block with ACME, the cluster serves its
own subdomain and gets certificates over DNS-01. The parent zone must
delegate to the cluster before you install. The delegation needs both the
NS records and their in-zone glue. For a domain <DC_DOMAIN> the parent
zone needs:
<DC_DOMAIN>. NS ns0.<DC_DOMAIN>.
<DC_DOMAIN>. NS ns1.<DC_DOMAIN>.
ns0.<DC_DOMAIN>. A <NS0_IP>
ns1.<DC_DOMAIN>. A <NS1_IP>
The nameserver names are under the delegated name. Without the A records
the delegation is lame. Authoritative servers then answer SERVFAIL for
every query at and below that name, and resolvers cache the failure. A lame
delegation causes more failures than no delegation.
Two errors are common here:
- Registrar host records are not this glue. Resolvers consult them only when
the registry refers to those hosts. When a third party serves the parent
domain, the glue that matters is an ordinary
Arecord in the parent zone. - A record declared in Terraform is not applied until Terraform runs. Check the live answer.
Check the records against the parent's authoritative servers, not against a recursive resolver:
PARENT_NS=$(dig +short NS <PARENT_ZONE> | head -1)
dig +norecurse @"$PARENT_NS" NS <DC_DOMAIN>
dig +norecurse @"$PARENT_NS" A ns0.<DC_DOMAIN>
NOERROR with records is correct. SERVFAIL means the delegation is lame.
NXDOMAIN means the records are absent.
You do not choose the nameserver addresses. The installer allocates one
address per dns.nameservers entry from the low end of the external
infra_range, and skips reserved addresses. ns0 and ns1 get the first
two free addresses. The plan preview prints the exact records to create. Run
the preview and copy them.
The answers document
Start from the example examples/answers/lab-production.json in the
mariana-trench repository. It describes a real nine-node, two-rack
cluster. Validate the document each time you edit it. In a checkout of that
repository:
cargo run -p triton-config-core --example validate -- <ANSWERS_FILE>
The parts that matter most:
- Identity. Each node's
matchblock pairs a declaration with a physical machine. The precedence isserver_uuid, thenserial, thenmac, then unconditional. Preferserver_uuid. It survives a NIC replacement. Read it on the machine withsysinfo | grep UUID. A CMDB asset tag is often not the chassis serial thatsysinforeports. - Failure domains. The control plane enforces
spread.min_domainsagainst thefailure_domainof each node. The failure domains decide whether the loss of one rack also removes the control plane. - Eligibility.
control-plane,compute, andstoragename the roles a machine may take. The founder needscontrol-planeeligibility. Without it the founder cannot hold a seat after the cluster grows. - Storage.
storage.layoutdeclares the pool layout that you confirm at setup approval. - Networks. See Networks. The preview renders an address map for each network.
A declared serial that disagrees with the hardware is not reported when a
higher-precedence key matched. A wrong serial stays unnoticed until a later
match uses it. The installer validates and displays the
secrets block but never uses it. The installer generates its own
credentials and writes a handoff file.
What to have at hand
- SSH access to the founder as
root. - The release channel reachable over HTTPS from the founder, or a local
artifact directory for an air-gapped install (
--image-dir). - Control of the parent DNS zone, if the answers document requests DNS.
- Access to the BMC of each other machine, to set it to network boot once.
- A place to record the credentials that genesis prints. Genesis shows them once.
The install script
install.sh reads uname -s and uname -m and supports exactly four pairs.
uname -s | uname -m | Target triple | Default install directory |
|---|---|---|---|
SunOS | i86pc | x86_64-unknown-illumos | /opt/triton/bin |
Darwin | arm64 | aarch64-apple-darwin | $HOME/.local/bin |
Darwin | x86_64 | x86_64-apple-darwin | $HOME/.local/bin |
Linux | x86_64 | x86_64-unknown-linux-gnu | $HOME/.local/bin |
The release pipeline publishes tritonadm only for x86_64-unknown-illumos.
On the other three pairs the script exits with
channel has no tritonadm entry for <TARGET>.
The script needs curl, a tar, and one of sha256sum, gsha256sum,
shasum, or digest. jq is optional.
| Variable | Default | Effect |
|---|---|---|
TRITON_CHANNEL | stable | Named channel. Expands to https://tritoncloud.nyc3.digitaloceanspaces.com/channels/<NAME>.json. |
TRITON_CHANNEL_URL | Unset | Full manifest URL. Takes precedence over TRITON_CHANNEL. |
TRITON_INSTALL_DIR | Platform default above | Directory the tarball extracts into. |
No stable channel has been published yet, so TRITON_CHANNEL=edge is
required today. The script prints this when the default fetch returns 404.
Ports the installer expects to reach
| Port | Zone | Probe or endpoint |
|---|---|---|
| 8080 | tritond | http://<IP>:8080/v1/health, a required gate |
| 8081 | tritond | Operator console |
| 8123 | triton-clickhouse | http://<IP>:8123/ping, best effort |
| 7443 | triton-mantad<N> | http://<IP>:7443/, best effort |
| 80 | triton-booter0 | http://<IP>/healthz, a required gate |
Operator CLI state
| Item | Value |
|---|---|
| Config file | $TRITONADM_CONFIG_DIR/config.json when set, else <user config dir>/triton/tritonadm/config.json |
| Endpoint resolution | --endpoint, then TRITONADM_ENDPOINT, then the config file |
| Credential resolution | --api-key, then TRITONADM_API_KEY, then TRITONADM_ACCESS_TOKEN, then the stored token pair |