Administer etcd
An etcd cluster serves as the shared store backend for Itential Gateway when running distributed execution or active-standby high availability. Gateway requires etcd v3.5, the version these procedures target. Examples assume a three-node cluster, the smallest topology that tolerates a single-node failure while preserving write quorum.
Procedures that modify state, restart processes, or alter on-disk data are marked with a warning.
Before you begin
The commands here assume the following environment variables are set:
If TLS isn’t enabled in your deployment, set ETCDCTL_TLS="" and use http:// URLs in ETCD_ENDPOINTS. A non-TLS etcd deployment isn’t recommended for any environment that isn’t air-gapped.
ETCDCTL_TLS above assumes transport TLS only, on both the client and peer planes: etcd nodes present certificates but don’t require clients or peers to present client certificates back. In etcd terms, --cert-file / --key-file and --peer-cert-file / --peer-key-file are set, but neither --client-cert-auth nor --peer-client-cert-auth is enabled.
If your deployment uses full mTLS (--client-cert-auth=true), add --cert and --key flags to ETCDCTL_TLS, pointing at a client certificate and key trusted by the cluster’s CA. Reference: etcd v3.5 transport security. TLS private keys must never be stored in version control or distributed outside your secrets management process.
In a 3-node etcd cluster, two members must remain healthy for the cluster to accept writes. Never restart, stop, or otherwise take offline more than one node at a time. A second failure during a planned outage breaks quorum and makes the cluster read-only or unavailable until a member returns.
Deployment types
RPM/DEB and container deployments differ mainly in how the process is controlled. The underlying etcdctl and etcdutl commands are identical either way.
Confirm the actual paths against your deployment before running any command. etcd’s documented data directory default is ${name}.etcd relative to the working directory. /var/lib/etcd is a package convention, not an etcd default.
Check cluster health and status
etcd is a Raft-based consensus system. As long as a majority of members are healthy and reachable, the cluster accepts writes. Regular health checks confirm every member is reachable, the leader is stable, and no follower is lagging far enough behind to compromise availability if the leader fails.
Check cluster-wide health
etcdctl endpoint health contacts every endpoint, measures round-trip time, and reports whether each member would accept a write:
Every endpoint should report true under HEALTH with low TOOK latency. In v3.5, etcd also exposes HTTP /health, /livez, and /readyz endpoints at the address set by --listen-metrics-urls, useful for external monitoring. This guide uses etcdctl endpoint health for operator-facing checks. Reference: etcd v3.5 monitoring.
Check per-endpoint status
etcdctl endpoint status reveals which member holds the leader role, each member’s Raft term and index, and database size on disk:
The default --quota-backend-bytes is 0, which etcd interprets as a low space quota. Confirm the configured value before relying on absolute numbers; a DB SIZE approaching the quota is the most common cause of cluster read-only events.
List cluster members and the current leader
Each member-list row shows the member ID, name, peer URL, client URL, and whether it’s a learner (a non-voting replica being added). No member should be a learner in a steady-state cluster. Resolve the leader at runtime before any operation that will restart a node, so you can plan to handle it last.
Verify read and write availability
This exercises the full Raft commit path. Health-check keys accumulate, so clean them up periodically.
Manage the etcd service
In a 3-node cluster, restarting a follower is low-risk; quorum holds and the cluster keeps serving. Restarting the leader briefly pauses writes during the election that follows. Restarting two members at once breaks quorum.
Check status on all nodes
An etcd process that’s crashed but hasn’t been restarted reduces the cluster to two members without raising an alarm at the application layer until the next Gateway read fails.
Restart on a single node
Restarting the leader triggers an election that pauses writes for under a second. If you must restart the leader, prefer to step leadership down first (see Shut down etcd safely) so the restart targets a follower instead.
Verify the node rejoined and cluster-wide health, then confirm the rejoined member caught up to the leader’s Raft index before touching another member:
The RAFT INDEX of the rejoined member should be within a few hundred of the leader’s; a persistent gap warrants investigation in the etcd logs.
Start and stop on a single node
Enable etcd to start on boot (RPM/DEB)
Enable any node that returns disabled:
A single offline member in a 3-node cluster leaves zero redundancy; the loss of any other member breaks quorum. For container deployments, configure the runtime’s restart policy (restart: always in Compose, or --restart=always for docker run) to achieve the same effect.
Review the configuration
etcd has no canonical default config-file path.
Inspect what the running process actually sees:
References: etcd v3.5 configuration, clustering.
Shut down etcd safely
etcd has no documented way to quiesce a member before stopping it. A safe shutdown is a sequencing exercise: keep the rest of the cluster healthy and, optionally, move leadership off the target node first to avoid a brief election pause.
Move the leader off the target node, if applicable
Stopping the leader triggers an automatic election. Transferring leadership explicitly beforehand lets you control when the election happens and ensures the new leader is a member you’ve already verified is healthy. Skip this step if the target node isn’t the leader.
If it is, transfer leadership to a healthy follower:
Confirm leadership moved with endpoint status --write-out=table.
Verify cluster quorum before the shutdown
Every member must report healthy. If the cluster is already running with one member unhealthy, taking a second offline breaks quorum; repair the unhealthy member first.
Back up and restore etcd
etcd is the source of truth for Gateway cluster coordination state. A corrupted data directory, a lost majority of members, or an inadvertent destructive operation against the keyspace can require restoring from a snapshot. With a current snapshot, recovery is typically a single multi-node procedure; without one, the recovery path is rebuilding Gateway cluster state from scratch.
References: etcd v3.5 disaster recovery, maintenance.
What to back up
A snapshot alone isn’t sufficient if a host is also lost; without the TLS material, a restored cluster can’t be reached by clients still configured against the old CA. Back up /etc/etcd/ (or the equivalent host-mounted volume) alongside each snapshot.
Take and verify a snapshot
etcdctl snapshot save produces a consistent snapshot without blocking writes. Target a single endpoint, not a comma-separated list; any healthy member works, though targeting the leader produces the most up-to-date snapshot.
For container deployments, prefix the snapshot command with docker exec <etcd-container> and write the file inside the container’s volume so it lands on the host filesystem.
A snapshot that’s corrupt or truncated fails at restore time, so verify immediately after creation, while the healthy cluster is still available to compare against. Snapshot inspection lives in etcdutl, the offline data-management binary shipped alongside etcdctl:
A non-zero hash and key count confirm the snapshot is intact. Compare its revision against the live cluster’s revision (from endpoint status) to confirm it captured recent state.
Copy the snapshot off the host and schedule regular runs
A snapshot stored only on the host that produced it doesn’t protect against host loss:
Schedule a daily snapshot, verify it, copy it off-host, and prune local copies older than your retention window:
The wrapper script should run snapshot save, run snapshot status and exit non-zero on a zero hash or key count, copy the snapshot offsite and verify the copy, delete local snapshots past the retention window, and log success or failure. Pair the cron job with monitoring that alerts when the most recent successful snapshot exceeds your recovery point objective; a silently broken cron job is not a data protection strategy.
Restore from a snapshot
Restoring overwrites the data directory of every member and starts a new cluster from the snapshot contents. All keyspace history written after the snapshot is lost. Only restore when the running cluster is unrecoverable.
A restore is a four-phase process: stop etcd everywhere, restore the data directory on each member, start etcd, and verify the new cluster.
Stop etcd on all members
Because the live cluster is unrecoverable in a restore scenario, the one-node-at-a-time quorum constraint doesn’t apply here.
Move the existing data directories aside
etcdutl snapshot restore refuses to overwrite an existing data directory. Rename it rather than deleting it, so the original is recoverable if the restore fails.
Restore on each member
Copy the snapshot to each member, then run etcdutl snapshot restore on each. --initial-cluster and --initial-advertise-peer-urls must reflect your actual topology and match across all three restore commands.
The --initial-cluster-token value is arbitrary but must match on all three members. Use a fresh value on every restore so the restored cluster doesn’t collide with any pre-existing peer state.
Compact and defragment the keyspace
etcd retains every revision of every key by default. For a Gateway store backend, that history is unused (Gateway reads current values, never historical ones), so accumulating revisions only grows disk usage. Without compaction, the database eventually hits --quota-backend-bytes and refuses writes. Compaction marks old revisions as free; defragmentation reclaims the freed space on disk. Both are needed.
Reference: etcd v3.5 maintenance.
Configure auto-compaction
Configure etcd to compact continuously, retaining one hour of revision history, a comfortable safety window for incident triage without letting the database bloat:
Or in YAML:
Restart each member one at a time (see Manage the etcd service) to pick up the change, then confirm the configured value loaded:
Run manual compaction
If auto-compaction isn’t configured yet, or the database grew faster than the auto-compaction interval can keep up with:
Schedule periodic defragmentation
Compaction frees revisions inside the bbolt backend file but doesn’t shrink it; defragmentation rewrites the backend in place to reclaim physical disk space. It pauses requests on the targeted member while it runs, so target one member at a time, preferring followers before the leader.
Schedule a weekly defrag during a low-activity window:
Confirm DB SIZE decreased on each member with endpoint status --write-out=table afterward.
Recover from a quota alarm
If etcd has already filled and refused writes, recovery is required even with auto-compaction configured: compact, defrag every member, then disarm the alarm.
Manage logs
The etcd log records leader elections, member additions and removals, slow disk warnings, and any error that prevents a write from committing, the first place to look when the cluster behaves unexpectedly.
Reference: etcd v3.5 configuration logging flags.
Log destinations
etcd v3.5 supports two log destinations, controlled by --log-outputs:
stdout and stderr are also valid --log-outputs values, typical in container deployments where the runtime captures the stream. Confirm the configured destination before relying on a specific path:
View and search logs
Search across all nodes for the events most worth flagging:
Configure log rotation
journald (default): rotation is controlled in /etc/systemd/journald.conf:
Apply with sudo systemctl restart systemd-journald, and confirm with journalctl --disk-usage.
File output: etcd v3.5 has built-in rotation when enabled:
Restart each member one at a time to pick up the change. If your deployment can’t enable --enable-log-rotation (for example, a locked-down vendor wrapper), fall back to external logrotate with copytruncate, since etcd holds the file open:
Save as /etc/logrotate.d/etcd on each node. This is the third-best option; prefer journald or --enable-log-rotation when possible.
Rotate TLS certificates
TLS certificates come in two planes:
This guide assumes transport TLS only on both planes. If your deployment uses full mTLS, the same rotation steps apply to the client and peer cert files plus their CA trust bundles.
Since v3.2, etcd reloads client-plane certificates on every new client connection: replacing cert-file and key-file on a member takes effect for the next client connection without a restart. The peer plane, where connections are long-lived between members, isn’t documented as hot-reloadable; treat peer-cert changes as requiring a rolling restart. When the CA changes, deploy a bundled CA file (old and new concatenated) so every member trusts either cert during the rollout; this is an operator pattern, not an etcd-documented one, but it’s the standard way to roll a CA without a window of mutual rejection.
Reference: etcd v3.5 transport security.
Inspect current certificate configuration
For container deployments, inspect the container args/env instead of the systemd unit.
Check current expiry
Plan the rotation at least two weeks before the earliest expiry.
A faster wire-side check confirms what each member is actually serving:
Take a snapshot before rotating
If the peer-plane rotation later requires a rolling restart and something goes wrong, a fresh snapshot eliminates the worst-case outcome (cluster fragmentation requiring restore). See Take and verify a snapshot.
Verify new certificates locally before deploying
The peer certificate’s SANs must include every peer URL hostname and IP other members use to reach this one; a missing SAN causes those members to reject the connection. Don’t proceed if openssl verify errors or a modulus pair doesn’t match.
Distribute new certificate files
Copy the new files to all nodes before any member starts using them. If the CA changed, deploy the bundled CA file described above; once every member holds new server/peer certs, replace it with a new-CA-only file in a follow-up rotation.
For container deployments, write the new files into the host-mounted PKI directory instead.
Pick up the new certificates
Client-plane only, no CA change: no restart required. Open a fresh connection to force the reload and confirm:
Peer-plane changed, or CA changed: a rolling restart is required. For each member in sequence: move the leader off it if applicable, verify quorum, restart, then confirm it rejoined and is presenting the new certificate before moving to the next member.
Rollback
If the cluster fully fragmented because rotation was attempted on multiple nodes simultaneously, restore from the snapshot taken before the rotation using Restore from a snapshot.