{"id":6235,"date":"2026-03-24T02:47:03","date_gmt":"2026-03-23T23:47:03","guid":{"rendered":"https:\/\/computingforgeeks.com\/?p=6235"},"modified":"2026-03-24T15:15:21","modified_gmt":"2026-03-24T12:15:21","slug":"install-etcd-ubuntu","status":"publish","type":"post","link":"https:\/\/computingforgeeks.com\/install-etcd-ubuntu\/","title":{"rendered":"Install etcd on Ubuntu 24.04 \/ 22.04"},"content":{"rendered":"\n<p>etcd is a distributed, reliable key-value store designed for the most critical data in distributed systems. It powers <a href=\"https:\/\/computingforgeeks.com\/install-kubernetes-cluster-on-ubuntu-using-kubeadm\/\">Kubernetes<\/a> as the backend data store for all cluster state, but it works just as well as a standalone service for configuration management, service discovery, and leader election. etcd uses the Raft consensus algorithm to guarantee strong consistency across nodes, even during network partitions or node failures.<\/p>\n\n\n\n<p>This guide covers two installation methods on Ubuntu 24.04 and 22.04: the Ubuntu repository (quick, stable) and the official GitHub binary (latest version). Both methods produce a working single-node etcd instance, but the binary method gives you the latest version (v3.5.28 at the time of writing).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before you start, make sure you have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An Ubuntu 24.04 or 22.04 server with at least 2 GB RAM<\/li>\n\n\n\n<li>A user with sudo privileges or root access<\/li>\n\n\n\n<li>Ports 2379 (client) and 2380 (peer) available<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Method 1: Install etcd from Ubuntu Repositories<\/h2>\n\n\n\n<p>Ubuntu ships etcd in its default repositories. This is the fastest way to get running, though the packaged version may lag behind the latest upstream release.<\/p>\n\n\n\n<p>Update your package index and install both the server and client packages:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update\nsudo apt install -y etcd-server etcd-client<\/code><\/pre>\n\n\n\n<p>Verify the installed version with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcd --version<\/code><\/pre>\n\n\n\n<p>On Ubuntu 24.04, you should see etcd version 3.4.x or 3.5.x depending on the repository version. Ubuntu 22.04 ships with etcd 3.3.x, which is quite old. If you need a newer version, skip to Method 2.<\/p>\n\n\n\n<p>The package automatically creates a systemd unit and the <code>etcd<\/code> user. Start and enable the service:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl enable --now etcd<\/code><\/pre>\n\n\n\n<p>Check that etcd is running:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl status etcd<\/code><\/pre>\n\n\n\n<p>The service should show active (running). If you installed from the repository and everything looks good, skip ahead to the <strong>Basic etcdctl Operations<\/strong> section. Otherwise, continue with Method 2 for the latest binary.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Method 2: Install etcd from GitHub Binary Releases<\/h2>\n\n\n\n<p>For production use and access to the latest features and security patches, install etcd directly from the official GitHub releases. The current stable release is v3.5.28 (released March 2026). There is also a newer v3.6.x series available if you want the cutting edge, but 3.5.x remains the most widely deployed in production.<\/p>\n\n\n\n<p>Set the version variable and download the release tarball:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ETCD_VER=v3.5.28\nDOWNLOAD_URL=https:\/\/github.com\/etcd-io\/etcd\/releases\/download\n\ncurl -fsSL ${DOWNLOAD_URL}\/${ETCD_VER}\/etcd-${ETCD_VER}-linux-amd64.tar.gz -o \/tmp\/etcd-${ETCD_VER}-linux-amd64.tar.gz<\/code><\/pre>\n\n\n\n<p>Extract the archive and move the binaries into your system path:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>tar xzf \/tmp\/etcd-${ETCD_VER}-linux-amd64.tar.gz -C \/tmp\/\nsudo mv \/tmp\/etcd-${ETCD_VER}-linux-amd64\/etcd \/usr\/local\/bin\/\nsudo mv \/tmp\/etcd-${ETCD_VER}-linux-amd64\/etcdctl \/usr\/local\/bin\/\nsudo mv \/tmp\/etcd-${ETCD_VER}-linux-amd64\/etcdutl \/usr\/local\/bin\/<\/code><\/pre>\n\n\n\n<p>Confirm the binaries are in place:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcd --version\netcdctl version<\/code><\/pre>\n\n\n\n<p>You should see version 3.5.28 confirmed for both binaries.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Create a Dedicated etcd User and Directories<\/h3>\n\n\n\n<p>Running etcd as root is a bad idea. Create a dedicated system user and set up the data and configuration directories:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo groupadd --system etcd\nsudo useradd -s \/sbin\/nologin --system -g etcd etcd\nsudo mkdir -p \/var\/lib\/etcd\nsudo mkdir -p \/etc\/etcd\nsudo chown -R etcd:etcd \/var\/lib\/etcd<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Configure etcd<\/h3>\n\n\n\n<p>Create the etcd configuration file. This example configures a single-node setup listening on all interfaces. For a multi-node cluster, you would add the initial cluster peer URLs here.<\/p>\n\n\n\n<p>Open the configuration file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo vi \/etc\/etcd\/etcd.conf.yml<\/code><\/pre>\n\n\n\n<p>Add the following configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>name: 'default'\ndata-dir: '\/var\/lib\/etcd'\nwal-dir: '\/var\/lib\/etcd\/wal'\nlisten-peer-urls: 'http:\/\/0.0.0.0:2380'\nlisten-client-urls: 'http:\/\/0.0.0.0:2379'\ninitial-advertise-peer-urls: 'http:\/\/127.0.0.1:2380'\nadvertise-client-urls: 'http:\/\/127.0.0.1:2379'\ninitial-cluster: 'default=http:\/\/127.0.0.1:2380'\ninitial-cluster-token: 'etcd-cluster-1'\ninitial-cluster-state: 'new'\nlogger: 'zap'\nlog-level: 'info'<\/code><\/pre>\n\n\n\n<p>If you plan to expose etcd to other hosts on your network, replace <code>127.0.0.1<\/code> in the advertise URLs with your server&#8217;s actual IP address (for example, <code>192.168.1.10<\/code>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Create a systemd Service Unit<\/h3>\n\n\n\n<p>Create the systemd unit file to manage etcd as a service:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo vi \/etc\/systemd\/system\/etcd.service<\/code><\/pre>\n\n\n\n<p>Add the following service definition:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[Unit]\nDescription=etcd key-value store\nDocumentation=https:\/\/etcd.io\/docs\/\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nUser=etcd\nGroup=etcd\nType=notify\nExecStart=\/usr\/local\/bin\/etcd --config-file \/etc\/etcd\/etcd.conf.yml\nRestart=always\nRestartSec=10s\nLimitNOFILE=40000\n\n[Install]\nWantedBy=multi-user.target<\/code><\/pre>\n\n\n\n<p>Reload systemd and start etcd:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl daemon-reload\nsudo systemctl enable --now etcd<\/code><\/pre>\n\n\n\n<p>Verify the service is running properly:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl status etcd<\/code><\/pre>\n\n\n\n<p>The output should show the service as active (running) with no errors in the log lines.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Basic etcdctl Operations<\/h2>\n\n\n\n<p>etcdctl is the command-line client for interacting with etcd. Starting with etcd 3.4+, the v3 API is the default, so you do not need to set <code>ETCDCTL_API=3<\/code> unless you are running a very old version.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Put and Get Key-Value Pairs<\/h3>\n\n\n\n<p>Store a key-value pair in etcd:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl put greeting \"Hello from etcd\"<\/code><\/pre>\n\n\n\n<p>etcd responds with OK to confirm the write succeeded. Retrieve the value:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl get greeting<\/code><\/pre>\n\n\n\n<p>This returns both the key and its value on separate lines. To get only the value without the key name, use the <code>--print-value-only<\/code> flag:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl get greeting --print-value-only<\/code><\/pre>\n\n\n\n<p>You can also retrieve all keys with a common prefix. This is useful for organizing configuration under namespaces:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl put \/config\/db\/host \"10.0.1.50\"\netcdctl put \/config\/db\/port \"5432\"\netcdctl put \/config\/db\/name \"appdb\"\netcdctl get \/config\/db\/ --prefix<\/code><\/pre>\n\n\n\n<p>All three keys under the <code>\/config\/db\/<\/code> prefix are returned.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Delete Keys<\/h3>\n\n\n\n<p>Remove a single key:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl del greeting<\/code><\/pre>\n\n\n\n<p>etcd returns the number of keys deleted (1 in this case). You can delete multiple keys by prefix as well:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl del \/config\/db\/ --prefix<\/code><\/pre>\n\n\n\n<p>This removes all keys that start with <code>\/config\/db\/<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Watch for Changes<\/h3>\n\n\n\n<p>etcd supports watching keys for real-time change notifications. This is how Kubernetes controllers detect configuration changes. Open a watch on a key:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl watch \/config\/db\/host<\/code><\/pre>\n\n\n\n<p>This command blocks and waits. In another terminal, update the key:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl put \/config\/db\/host \"10.0.1.100\"<\/code><\/pre>\n\n\n\n<p>The watch terminal immediately shows the PUT event with the new value. Press Ctrl+C to stop watching.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Check Cluster Health and Member List<\/h2>\n\n\n\n<p>Even on a single-node setup, you should know how to check the health of your etcd instance. Run the endpoint health check:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl endpoint health<\/code><\/pre>\n\n\n\n<p>A healthy node returns something like <code>127.0.0.1:2379 is healthy: successfully committed proposal<\/code> with a latency measurement.<\/p>\n\n\n\n<p>For more detail, check the endpoint status in table format:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl endpoint status --write-out=table<\/code><\/pre>\n\n\n\n<p>This shows the endpoint, member ID, revision, Raft term, leader status, and database size, all critical information for troubleshooting cluster issues.<\/p>\n\n\n\n<p>List all members of the cluster:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl member list --write-out=table<\/code><\/pre>\n\n\n\n<p>On a single-node setup, you see one member. In a production <a href=\"https:\/\/computingforgeeks.com\/install-kubernetes-cluster-on-ubuntu-using-kubeadm\/\">Kubernetes cluster<\/a>, you would typically see three or five etcd members for high availability.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configure UFW Firewall for etcd<\/h2>\n\n\n\n<p>etcd uses two ports that need to be open if you are running a multi-node cluster or accepting connections from remote clients:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>2379\/tcp<\/strong> &#8211; client communication (etcdctl, application requests)<\/li>\n\n\n\n<li><strong>2380\/tcp<\/strong> &#8211; peer communication (cluster member replication)<\/li>\n<\/ul>\n\n\n\n<p>If <a href=\"https:\/\/computingforgeeks.com\/common-ufw-firewall-commands-with-examples\/\">UFW is enabled<\/a> on your Ubuntu server, allow these ports:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ufw allow 2379\/tcp comment 'etcd client'\nsudo ufw allow 2380\/tcp comment 'etcd peer'\nsudo ufw reload<\/code><\/pre>\n\n\n\n<p>Verify the rules are active:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ufw status verbose<\/code><\/pre>\n\n\n\n<p>You should see both ports listed as ALLOW. For single-node setups where etcd only listens on localhost, these firewall rules are not strictly required.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Backup and Restore etcd Data<\/h2>\n\n\n\n<p>Regular backups are critical, especially if etcd is storing your Kubernetes cluster state. A corrupted or lost etcd database means losing your entire cluster configuration. etcdctl has built-in snapshot support that makes this straightforward.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Create a Snapshot Backup<\/h3>\n\n\n\n<p>Take a snapshot of the current etcd data:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl snapshot save \/tmp\/etcd-backup.db<\/code><\/pre>\n\n\n\n<p>etcd confirms the snapshot was saved along with the number of keys captured. Verify the snapshot is valid:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl snapshot status \/tmp\/etcd-backup.db --write-out=table<\/code><\/pre>\n\n\n\n<p>The output shows the snapshot hash, revision, total keys, and database size. In production, automate this with a cron job and store backups off-server:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo vi \/etc\/cron.d\/etcd-backup<\/code><\/pre>\n\n\n\n<p>Add the following cron entry to take a daily backup at 2 AM:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>0 2 * * * etcd \/usr\/local\/bin\/etcdctl snapshot save \/var\/lib\/etcd\/backups\/etcd-$(date +\\%Y\\%m\\%d).db<\/code><\/pre>\n\n\n\n<p>Make sure the backup directory exists and is owned by the etcd user:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mkdir -p \/var\/lib\/etcd\/backups\nsudo chown etcd:etcd \/var\/lib\/etcd\/backups<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Restore from a Snapshot<\/h3>\n\n\n\n<p>Restoring from a snapshot creates a new data directory. Stop etcd first, then run the restore:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl stop etcd<\/code><\/pre>\n\n\n\n<p>Run the snapshot restore command, specifying a new data directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdutl snapshot restore \/tmp\/etcd-backup.db \\\n  --data-dir \/var\/lib\/etcd-restored \\\n  --name default \\\n  --initial-cluster default=http:\/\/127.0.0.1:2380 \\\n  --initial-advertise-peer-urls http:\/\/127.0.0.1:2380<\/code><\/pre>\n\n\n\n<p>Move the restored data into place and fix ownership:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo mv \/var\/lib\/etcd \/var\/lib\/etcd-old\nsudo mv \/var\/lib\/etcd-restored \/var\/lib\/etcd\nsudo chown -R etcd:etcd \/var\/lib\/etcd<\/code><\/pre>\n\n\n\n<p>Start etcd again and verify it is healthy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl start etcd\netcdctl endpoint health<\/code><\/pre>\n\n\n\n<p>The restored instance should come up healthy with all the data from the snapshot intact.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting Common Issues<\/h2>\n\n\n\n<p>Here are some problems you might run into and how to fix them.<\/p>\n\n\n\n<p><strong>etcd fails to start with &#8220;member has already been bootstrapped&#8221;<\/strong> &#8211; This happens when you change the configuration but the old data directory still exists. Either remove the data directory (<code>sudo rm -rf \/var\/lib\/etcd\/*<\/code>) for a fresh start, or change <code>initial-cluster-state<\/code> from <code>new<\/code> to <code>existing<\/code>.<\/p>\n\n\n\n<p><strong>etcdctl reports &#8220;context deadline exceeded&#8221;<\/strong> &#8211; Usually means etcd is not running or not listening on the expected address. Check with <code>ss -tlnp | grep 2379<\/code> to confirm etcd is listening, then verify your <code>ETCDCTL_ENDPOINTS<\/code> environment variable matches.<\/p>\n\n\n\n<p><strong>High latency warnings in logs<\/strong> &#8211; etcd is sensitive to disk I\/O latency. If you see &#8220;apply request took too long&#8221; warnings, move the data directory to an SSD. On cloud instances, use provisioned IOPS volumes. The WAL (write-ahead log) is especially latency-sensitive.<\/p>\n\n\n\n<p><strong>Database size keeps growing<\/strong> &#8211; etcd keeps a history of all key revisions. Run compaction and defragmentation periodically:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>etcdctl compact $(etcdctl endpoint status --write-out=json | python3 -c \"import sys,json; print(json.load(sys.stdin)[0]['Status']['header']['revision'])\")\netcdctl defrag<\/code><\/pre>\n\n\n\n<p>This reclaims storage by removing old revisions and defragmenting the database file.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Uninstall etcd<\/h2>\n\n\n\n<p>If you installed from the Ubuntu repository:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt remove --purge -y etcd-server etcd-client\nsudo rm -rf \/var\/lib\/etcd<\/code><\/pre>\n\n\n\n<p>If you installed from the binary release:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl stop etcd\nsudo systemctl disable etcd\nsudo rm \/etc\/systemd\/system\/etcd.service\nsudo rm \/usr\/local\/bin\/etcd \/usr\/local\/bin\/etcdctl \/usr\/local\/bin\/etcdutl\nsudo rm -rf \/var\/lib\/etcd \/etc\/etcd\nsudo userdel etcd\nsudo groupdel etcd\nsudo systemctl daemon-reload<\/code><\/pre>\n\n\n\n<p>This cleanly removes all etcd components from your system.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>You now have a working etcd installation on Ubuntu with the knowledge to perform key-value operations, health checks, and disaster recovery through snapshots. For production deployments, run at least three etcd nodes behind a load balancer and set up automated backups with off-site storage. The <a href=\"https:\/\/etcd.io\/docs\/v3.5\/\" rel=\"noopener\" target=\"_blank\" rel=\"noreferrer noopener\">official etcd documentation<\/a> covers multi-node clustering, TLS authentication, and role-based access control when you are ready to harden your setup.<\/p>\n\n\n<!--\nSEO META\nTitle: How to Install and Configure etcd on Ubuntu 24.04 \/ 22.04\nDescription: Install etcd distributed key-value store on Ubuntu 24.04 and 22.04 from apt or GitHub binary. Configure, manage with etcdctl, backup and restore snapshots.\nFocus Keyword: install etcd on ubuntu\nKeywords: etcd ubuntu, etcd install, etcdctl, etcd backup restore, etcd key value store, etcd ubuntu 24.04\nCategories (--by=id): 299, 50, 81\nSlug: how-to-install-etcd-on-ubuntu-linux\n-->\n\n","protected":false},"excerpt":{"rendered":"<p>etcd is a distributed, reliable key-value store designed for the most critical data in distributed systems. It powers Kubernetes as the backend data store for all cluster state, but it works just as well as a standalone service for configuration management, service discovery, and leader election. etcd uses the Raft consensus algorithm to guarantee strong &#8230; <a title=\"Install etcd on Ubuntu 24.04 \/ 22.04\" class=\"read-more\" href=\"https:\/\/computingforgeeks.com\/install-etcd-ubuntu\/\" aria-label=\"Read more about Install etcd on Ubuntu 24.04 \/ 22.04\">Read more<\/a><\/p>\n","protected":false},"author":3,"featured_media":6289,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[299,50,81],"tags":[819,36811],"class_list":["post-6235","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-how-to","category-linux-tutorials","category-ubuntu","tag-etcd","tag-install-etcd-on-ubuntu"],"_links":{"self":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/6235","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/comments?post=6235"}],"version-history":[{"count":3,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/6235\/revisions"}],"predecessor-version":[{"id":164159,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/6235\/revisions\/164159"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media\/6289"}],"wp:attachment":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media?parent=6235"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/categories?post=6235"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/tags?post=6235"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}