Run a Notary cluster¶
This guide starts two Notary nodes that share one dqlite cluster. The commands match LXD: cluster add, start with --join, cluster list, and cluster remove.
HTTPS certificates (cert_path / key_path) stay per node or load balancer. Cluster TLS is a different pair used only for dqlite. The join token is a one-time ticket, not the cluster private key. notary start --join redeems that ticket over HTTPS (the existing API, pinned by the token fingerprint) and then joins dqlite. See Configuration file.
Prerequisites¶
Notary installed on each machine
Network connectivity on the dqlite port (
cluster.address, default9000) and on the HTTPS API port (port)The joiner must be able to reach an existing member’s HTTPS API. The token fingerprint is the SHA-256 of that member’s HTTPS certificate (
cert_path).
The first node generates a cluster certificate on first start if you omit cluster.tls. You can instead supply your own pair (DNS SAN required):
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 \
-nodes -keyout cluster.key -out cluster.crt -subj "/CN=notary-cluster" \
-addext "subjectAltName=DNS:localhost,DNS:notary-cluster,IP:10.0.0.1,IP:10.0.0.2"
1. Start the first node¶
Use an empty data directory. Set cluster.name (like LXD’s server name). Do not pass --join. cluster.tls is optional on this node.
key_path: "/etc/notary/config/key.pem"
cert_path: "/etc/notary/config/cert.pem"
db_path: "/var/lib/notary/database"
cluster:
name: "node1"
address: "10.0.0.1:9000"
port: 3000
encryption_backend:
type: "none"
notary start --config /etc/notary/config/config.yaml
Notary writes cluster.crt and cluster.key into db_path. Later starts reload them from that directory.
If this data directory was created before cluster TLS (a one-node store with no cluster.crt), resume stays plaintext and notary cluster add fails until you set cluster.tls in the YAML and restart. That restart writes the files into db_path.
2. Add a member and join¶
On a machine that is already in the cluster (daemon running), create a join token. This is the same idea as lxc cluster add:
notary cluster add node2 --config /etc/notary/config/config.yaml
The command prints a one-time token (valid for three hours). Until it is redeemed or expires, it is a bearer credential: anyone who presents it to an existing member’s HTTPS API receives the cluster private key. After a successful join it is spent and cannot hand out the key again.
On the second machine, use a new empty data directory and the name from cluster add. Do not copy cluster TLS files. Point HTTPS certs at this node’s files:
key_path: "/etc/notary/config/key.pem"
cert_path: "/etc/notary/config/cert.pem"
db_path: "/var/lib/notary/database"
cluster:
name: "node2"
address: "10.0.0.2:9000"
port: 3000
encryption_backend:
type: "none"
notary start --config /etc/notary/config/config.yaml --join '<token>'
You can also set cluster.join_token in the YAML instead of --join. The token is used only on first start. After info.yaml exists in db_path, the node resumes without it.
If you set cluster.tls on the joiner, it must match the cluster certificate returned after redeeming the token. Joining with cluster.join addresses and no token still requires cluster.tls files.
Set external_hostname (host or host:port) when joiners should redeem against a public API address. Required when cluster.address is a wildcard bind (0.0.0.0 or ::). The default localhost is not enough: join tokens must not tell another machine to dial loopback.
3. List members¶
With the daemon running:
notary cluster list --config /etc/notary/config/config.yaml
Or, as an admin, GET /api/v1/cluster or GET /api/v1/cluster/members. You should see both names and one leader.
A two-node cluster typically shows the joiner as a spare, not a second voter. dqlite needs three voters for availability if one node fails. Add a third member the same way (cluster add / --join) when you want that quorum.
4. Remove a member¶
Like lxc cluster remove:
notary cluster remove node2 --config /etc/notary/config/config.yaml
Then stop Notary on the machine you removed. You cannot remove the last remaining member.
If a join dies after dqlite has already added the node (for example notary start --join times out waiting for the cluster), cluster list may show a member with no name. Remove it by address:
notary cluster remove 10.0.0.2:9000 --config /etc/notary/config/config.yaml
5. Stop a node¶
Stop the process (Ctrl+C, or your systemd/snap stop). Notary hands cluster roles to another node when one is available, then closes dqlite.
After a clean stop, start again with the same db_path, cluster.name, and cluster.address. You do not need --join again.