Overview
etcd is a distributed, strongly consistent key-value store for the most critical data of a distributed system: leader election, distributed locks, service discovery and shared configuration. This template deploys an etcd cluster as one stateful workload whose replicas form a single Raft quorum in one location, each member on its own persistent volume, with auto-compaction configured so the backend does not grow without bound. It is also the consensus store that Postgres Highly Available and TimescaleDB Highly Available bundle for Patroni.This template deploys into an existing GVC you already have; it does not create one. Each member builds its peer list from its own location, so the cluster is meant for a GVC with a single location — for a cluster that spans locations use the etcd Multi-Location template instead.
What Gets Created
The template creates no credential secret: etcd here runs without TLS or authentication, and access is governed by the internal firewall (see Internal Access).
Prerequisites
None for a default install. There are no secrets to create and no cloud account to connect.Installation
A default install needs only a release name and the GVC to deploy into:UI
Browse, install, and manage templates visually
CLI
Manage templates from your terminal
Terraform
Declare templates in your Terraform configurations
Pulumi
Declare templates in your Pulumi programs
Configuration
Each subsection below shows the shipped default for one area ofvalues.yaml. Override only what you need with --set or a values file.
Replicas
replicas— Number of etcd members in the cluster. Must be at least 3 and odd; an even count adds no fault tolerance and risks split votes. Install-time validation rejects anything else. Choose the count when you install — see Scaling and Availability.
Image
image— The etcd container image. The shipped tag carries etcd3.6.5together withetcdctlandetcdutl.
Resources
resources.cpu/resources.memory— CPU and memory limit for each member. These can be lowered for lighter workloads; see the etcd hardware recommendations for sizing guidance.
Multi-Zone
multiZone— Whentrue, distributes the members across the availability zones of the location.
Not all locations support multi-zone deployments. Confirm that your target location supports multi-zone before enabling this option.
Compaction and Backend Growth
etcd never discards a superseded revision on its own. Every write creates a new revision and the old one is kept until a compaction removes it, so the backend grows with time alone whenever a client writes on a timer — Patroni, for example, renews its leader lease every few seconds, producing new revisions whether or not any application data changes. Left uncompacted, an otherwise idle cluster reaches etcd’s default 2 GiB backend quota in a matter of months. When the quota is reached, etcd raises a cluster-wideNOSPACE alarm and every member goes read-only until an operator intervenes. Auto-compaction is what prevents that, and this template configures it by default:
tuning.autoCompactionMode— HowautoCompactionRetentionis read.periodictreats it as a time window;revisiontreats it as a number of revisions to keep. There is no “off” — an unrecognized mode is rejected at render time.tuning.autoCompactionRetention— How much history is kept before old revisions are discarded. The default1hkeeps the backend flat. Raising it to24hor more buys a longer history window at the cost of a larger backend.tuning.quotaBackendBytes— Backend size ceiling in bytes.0(the default) means the flag is not passed at all and etcd applies its own 2 GiB limit. Leave it at0unless the keyspace genuinely outgrows that; 8 GiB (8589934592) is etcd’s own suggested maximum, above which it warns at startup.
0, an unrecognized mode and a negative quota (which etcd reads as “no quota at all”) are each rejected at render time, because each one produces a chart that installs cleanly and fails weeks later.
Compaction frees pages for reuse inside the backend file; it does not shrink the file. The reported
DB SIZE therefore plateaus rather than dropping, while DB SIZE IN USE falls back to the size of the live keyspace. That is expected and is sufficient to stay under the quota, because reclaimed pages are reused for new writes. Only etcdctl defrag returns space to the filesystem, and this template does not automate it — defragmentation blocks the member it runs on.Storage
volumeset.capacity— Size in GiB of the persistent volume each member gets for/var/lib/etcd(minimum 10). The volume set keeps snapshots for 7 days and takes a final snapshot when the release is uninstalled.
Internal Access
internal_access.type— Controls which workloads can reach the client API on port2379:
internal_access.workloads— The workload links allowed in whentypeisworkload-list.
Connecting
The cluster has no public endpoint: external inbound traffic is closed and no load balancer is created. Clients connect from inside the GVC, or from your machine through a port-forward.
Always use the fully qualified hostname; the bare workload name is not reliably resolvable.
Verify the cluster from inside one of its members.
etcdctl is in the image and talks to the local member by default:
RAFT TERM and exactly one IS LEADER: true. From another workload in the GVC, point etcdctl at the service address:
etcdctl against http://127.0.0.1:2379:
Operations
Backing Up
Two independent layers protect the data:-
Volume set snapshots. The volume set
RELEASE_NAME-etcd-vskeeps snapshots for 7 days and takes a final snapshot when the release is uninstalled; this is configured by the template and needs no action. To take one on demand: -
An etcd snapshot file.
etcdctl snapshot savewrites a consistent, hash-protected copy of the whole keyspace from one member. The image shipsetcdctlandbase64, so the file can be pulled out throughcpln workload exec. Pass it throughbase64on both sides — the exec stream is text-only and corrupts raw binary:Then confirm the file is intact on your machine withetcdutl, which is part of every etcd release:
The snapshot command above was checked against the shipped image’s contents and the upstream
etcdctl documentation, but has not been exercised against a live install of this template. Run it once on a test release and confirm etcdutl snapshot status reports the hash before you rely on it.Restoring a Backup
Restoring is not a procedure this template performs or has verified. The upstream path —etcdutl snapshot restore — rebuilds a data directory for every member with a new cluster ID and requires each member to be stopped and started from the rebuilt directory. This template manages the data directory through the startup script and gives you no supported way to stop a member and replace /var/lib/etcd on its volume. Restoring a volume set snapshot in place is likewise unverified for this template.
If you must recover a keyspace, follow the etcd disaster recovery guide against a new release and rehearse it on a throwaway release first. Where etcd came bundled with a database template as its Patroni consensus store, consult that parent template’s page before attempting any etcd-level recovery.
Upgrading From a Version Before 1.4.2
Auto-compaction is configured from template version1.4.2 onward. Earlier versions passed no compaction flags at all, so a cluster installed from one of them retains every revision it has ever written and grows until it hits the backend quota.
- Upgrading is a normal
cpln helm upgrade; thetuningkeys are new and their defaults apply if you set nothing. - Upgrading turns compaction on but cannot rescue a cluster that has already filled its backend — see If the Backend Quota Is Already Full and check that first.
- If etcd came bundled with Postgres Highly Available or TimescaleDB Highly Available, the etcd version is pinned by that parent chart. Upgrade the parent; do not install this template alongside it.
If the Backend Quota Is Already Full
The symptom usually surfaces in the client rather than in etcd. A Patroni replica that cannot renew its lease exits cleanly, so it restart-loops withexitCode: 0 and reason: Completed and a climbing restart count — which reads as healthy and gets misdiagnosed as a database fault. Check etcd first.
Both inspection commands are read-only and safe to run on a live cluster:
DB SIZE close to 2.1 GB on every member, plus NOSPACE in the alarm list, confirms it. A healthy cluster prints nothing at all for alarm list. Recovery from there — compacting to a revision, defragmenting each member, then disarming the alarm — is an operator procedure this template deliberately does not perform, because each step is disruptive and the order matters. Follow etcd’s maintenance guide and plan it as a maintenance window.
Scaling and Availability
- Fault tolerance follows the member count. A cluster of
Nmembers keeps serving while a majority is up: 3 members tolerate 1 failure, 5 tolerate 2. Even counts add nothing, which is why the template requires an odd number. - Choose
replicasat install time. Each member derives its peer list from the replica count when it boots, and the template performs noetcdctl member addormember remove. Changingreplicason a running release is therefore not a supported operation; to change the size, install a new release and move clients over. - Spread across zones with
multiZone: truewhen the location supports it, so a single-zone failure cannot take a majority down. - A restart of the whole workload (a
cpln helm upgradethat changes the workload, or a forced redeployment) restarts the members; each rejoins from its own volume with--initial-cluster-state existing, so the keyspace is preserved. Expect writes to pause while a leader is re-elected.
Troubleshooting
Install fails: .Values.replicas must be an odd number / must be at least 3
Install fails: .Values.replicas must be an odd number / must be at least 3
Cause: The template validates
replicas at render time. An even number or anything below 3 is rejected before any resource is created.Fix: Set replicas to 3, 5 or 7.Install fails: tuning.autoCompactionRetention must carry an explicit unit
Install fails: tuning.autoCompactionRetention must carry an explicit unit
Cause: In
periodic mode etcd reads a bare number as hours, so the template refuses an unsuffixed retention rather than letting a 30 become thirty hours.Fix: Add a unit — 30m, 1h, 24h. In revision mode supply a plain revision count instead, such as 10000.Writes fail with etcdserver: mvcc: database space exceeded
Writes fail with etcdserver: mvcc: database space exceeded
Cause: The backend quota is full and etcd has raised a cluster-wide
NOSPACE alarm. Every member is read-only until the alarm is cleared. This is the expected end state of a cluster installed from a version before 1.4.2 that was never compacted.Fix: Confirm with etcdctl alarm list, then follow If the Backend Quota Is Already Full. Upgrading the template alone does not clear it.Reads fail with etcdserver: mvcc: required revision has been compacted
Reads fail with etcdserver: mvcc: required revision has been compacted
Cause: A client asked for a revision older than the retention window — a
get --rev or a watch resuming from a revision that auto-compaction has already discarded. With the default autoCompactionRetention: 1h only the last hour of history is readable.Fix: Read the current revision instead, or restart the watch from the current revision. If your application genuinely needs a longer history, raise tuning.autoCompactionRetention (for example 24h) and accept the larger backend.etcdctl hangs, then reports context deadline exceeded
etcdctl hangs, then reports context deadline exceeded
Cause: Fewer than a majority of members are reachable, so the cluster cannot commit writes; etcd waits for quorum rather than failing fast. Linearizable reads wait as well.Fix: Check which members are healthy and whether any replica is restarting:Once a majority is back, pending operations complete on their own. Always give clients a
--command-timeout so an outage surfaces as an error instead of a hang.Patroni replicas restart-loop with exitCode 0 and reason Completed
Patroni replicas restart-loop with exitCode 0 and reason Completed
Cause: The Postgres cluster’s consensus store cannot accept writes — most often because this etcd cluster’s backend quota is full — so Patroni cannot renew its leader lease and exits cleanly. The restarts look healthy because the exit code is zero.Fix: Run the two read-only commands in If the Backend Quota Is Already Full before touching the database.
Important Notes
replicasmust be odd and at least 3, and is chosen at install time. The template does not resize a running cluster.- Deploy into a single-location GVC. Members only discover peers in their own location; use the etcd Multi-Location template for a cluster that spans locations.
- No TLS, no authentication. Scope
internal_accesswithworkload-listwhenever the GVC holds workloads that should not read or write the keyspace. - Compaction is required and cannot be switched off. A full backend quota puts the cluster into a read-only
NOSPACEalarm that survives restarts and must be cleared explicitly after compacting and defragmenting. - Uninstalling deletes the volume sets, and with them the entire keyspace. The volume set takes a final snapshot first.
External References
etcd Documentation
Official etcd documentation
Maintenance and Compaction
Compaction, defragmentation, and clearing a NOSPACE alarm
Disaster Recovery
Snapshotting and restoring a cluster with etcdctl and etcdutl
Hardware Recommendations
etcd hardware and resource sizing guidelines
etcd Template
View the source files, default values, and chart definition