New to KubeDB? Please start here.
Reconfigure Etcd Cluster
This guide will show you how to use the KubeDB Ops-manager operator to reconfigure a running Etcd
cluster with an EtcdOpsRequest.
Before You Begin
At first, you need to have a Kubernetes cluster, and the
kubectlcommand-line tool must be configured to communicate with your cluster.Install
KubeDBProvisioner and Ops-manager operator in your cluster following the steps here. Etcd support is behind an alpha feature gate, so make sure both operators are installed withfeatureGates.Etcd=true.You should be familiar with the following
KubeDBconcepts:
To keep everything isolated, we are going to use a separate namespace called demo throughout this
tutorial.
$ kubectl create ns demo
namespace/demo created
Note: YAML files used in this tutorial are stored in docs/examples/etcd folder in GitHub repository kubedb/docs.
Deploy Etcd
In this section we deploy a 3 member Etcd cluster that already carries a few tuning knobs, so
that we can watch them change. Below is the YAML of the Etcd CR we are going to create:
apiVersion: kubedb.com/v1alpha2
kind: Etcd
metadata:
name: etcd-quickstart
namespace: demo
spec:
version: "3.6.4"
replicas: 3
storageType: Durable
storage:
storageClassName: "standard"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
configuration:
tuning:
quotaBackendBytes: 2147483648
autoCompactionMode: periodic
autoCompactionRetention: "1h"
snapshotCount: 10000
deletionPolicy: WipeOut
Here, the backend quota is 2 GiB and etcd compacts the keyspace history every hour.
Let’s create the Etcd CR we have shown above,
$ kubectl create -f https://github.com/kubedb/docs/raw/v2026.7.10/docs/examples/etcd/reconfigure/etcd.yaml
etcd.kubedb.com/etcd-quickstart created
Now, wait until etcd-quickstart has status Ready. i.e,
$ kubectl get etcd -n demo
NAME VERSION STATUS AGE
etcd-quickstart 3.6.4 Ready 3m
Check the current configuration
The tuning knobs are rendered onto the etcd command line, so the authoritative place to look is the container args of a member pod:
$ kubectl get pod -n demo etcd-quickstart-0 -o jsonpath='{.spec.containers[?(@.name=="etcd")].args}' | jq .
[
"--name=$(POD_NAME)",
"--data-dir=/var/lib/etcd/data",
"--initial-advertise-peer-urls=$(ETCD_MEMBER_PEER_URL)",
"--listen-peer-urls=http://0.0.0.0:2380",
"--listen-client-urls=http://0.0.0.0:2379",
"--advertise-client-urls=$(ETCD_MEMBER_CLIENT_URL)",
"--listen-metrics-urls=http://0.0.0.0:2381",
"--quota-backend-bytes=2147483648",
"--auto-compaction-mode=periodic",
"--auto-compaction-retention=1h",
"--snapshot-count=10000"
]
The per-member flags (--name, the peer/client URLs) are resolved from the downward API inside the
pod, which is why one PodSpec can serve every ordinal. The last four entries are the tuning knobs
from spec.configuration.tuning.
You can also confirm that the cluster itself is healthy before touching anything. Grab the credentials from the auth Secret first:
$ export ETCD_PASSWORD=$(kubectl get secret -n demo etcd-quickstart-auth -o jsonpath='{.data.password}' | base64 -d)
$ kubectl exec -it -n demo etcd-quickstart-0 -c etcd -- etcdctl \
--endpoints=http://127.0.0.1:2379 --user=root:$ETCD_PASSWORD endpoint status -w table
+------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| http://127.0.0.1:2379 | 8e9e05c52164694d | 3.6.4 | 20 kB | false | false | 2 | 14 | 14 | |
+------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
Note:
etcdctl endpoint statusreports runtime state (version, backend size, Raft term, leadership) — it does not echo the process flags back. To verify a tuning change, read the container args as shown above, or theEtcdobject’sspec.configuration.tuning.
Reconfigure using the tuning knobs
Now we will reconfigure this cluster to raise the backend quota to 8 GiB and switch auto compaction from time based to revision based, keeping the last 1000 revisions.
Note that autoCompactionRetention is interpreted differently depending on the mode: it is a
duration (1h) in periodic mode and a revision count (1000) in revision mode. When you change
the mode, change the retention value along with it.
Below is the YAML of the EtcdOpsRequest CR that we are going to create:
apiVersion: ops.kubedb.com/v1alpha1
kind: EtcdOpsRequest
metadata:
name: etcd-reconfigure
namespace: demo
spec:
type: Reconfigure
databaseRef:
name: etcd-quickstart
configuration:
tuning:
quotaBackendBytes: 8589934592
autoCompactionMode: revision
autoCompactionRetention: "1000"
timeout: 5m
apply: IfReady
Here,
spec.databaseRef.namespecifies that we are reconfiguring theetcd-quickstartcluster.spec.typespecifies that we are performing aReconfigureoperation.spec.configuration.tuningcarries the knobs to apply. Only the knobs named here are touched —snapshotCountis not in the request, so it keeps its current value of10000.
Note:
spec.configuration.applyConfigis not supported for etcd — an ops request that uses it is rejected at admission and told to usespec.configuration.tuninginstead. See the overview for why.
Let’s create the EtcdOpsRequest CR we have shown above,
$ kubectl apply -f https://github.com/kubedb/docs/raw/v2026.7.10/docs/examples/etcd/reconfigure/etcdops-reconfigure.yaml
etcdopsrequest.ops.kubedb.com/etcd-reconfigure created
This ops request restarts the members
Some KubeDB databases can apply a new configuration to a running server and only restart when the
changed settings demand it. Etcd cannot. The tuning knobs are etcd process command line flags,
and etcd has no live-reload path for them, so a Reconfigure on etcd is a rolling restart by
default: after re-rendering the PetSet, the operator rolls the member pods using the same leader-aware
sequence as the Restart ops request — followers first, one
at a time, quorum verified between each, the Raft leader last and only after its leadership has been
transferred away.
That is why you will normally see a RestartEtcdPods condition on a successful etcd Reconfigure.
Setting
spec.configuration.restart: "false"does skip the rolling restart, but it does not give you a live reconfiguration: the running members keep their old flags until something else recreates them. Only the desired state on theEtcdobject and thePetSettemplate change. Use it only if you intend to schedule the restart yourself later.
Verify the new configuration
Let’s wait for the EtcdOpsRequest to be Successful. Run the following command to watch it,
$ watch kubectl get etcdopsrequest -n demo
Every 2.0s: kubectl get etcdopsrequest -n demo
NAME TYPE STATUS AGE
etcd-reconfigure Reconfigure Successful 3m
We can see from the above output that the EtcdOpsRequest has succeeded. If we describe it, we get
an overview of the steps that were followed:
$ kubectl describe etcdopsrequest -n demo etcd-reconfigure
Name: etcd-reconfigure
Namespace: demo
Labels: <none>
Annotations: <none>
API Version: ops.kubedb.com/v1alpha1
Kind: EtcdOpsRequest
Metadata:
Creation Timestamp: 2026-02-10T08:27:00Z
Generation: 1
Resource Version: 1548116
UID: 4f3daa11-c41b-4079-a8d8-1040931284ef
Spec:
Apply: IfReady
Configuration:
Tuning:
Auto Compaction Mode: revision
Auto Compaction Retention: 1000
Quota Backend Bytes: 8589934592
Database Ref:
Name: etcd-quickstart
Timeout: 5m
Type: Reconfigure
Status:
Conditions:
Last Transition Time: 2026-02-10T08:27:00Z
Message: Reconfigure is in progress
Observed Generation: 1
Reason: Running
Status: True
Type: Running
Last Transition Time: 2026-02-10T08:27:06Z
Message: Successfully updated the Etcd configuration
Observed Generation: 1
Reason: UpdateDatabase
Status: True
Type: UpdateDatabase
Last Transition Time: 2026-02-10T08:27:08Z
Message: Successfully re-rendered the petset with the new configuration
Observed Generation: 1
Reason: UpdateEtcdPetSet
Status: True
Type: UpdateEtcdPetSet
Last Transition Time: 2026-02-10T08:27:45Z
Message: check pod ready; ConditionStatus:True; PodName:etcd-quickstart-0
Observed Generation: 1
Status: True
Type: CheckPodReady--etcd-quickstart-0
Last Transition Time: 2026-02-10T08:27:50Z
Message: etcd cluster healthy; ConditionStatus:True; PodName:etcd-quickstart-0
Observed Generation: 1
Status: True
Type: EtcdClusterHealthy--etcd-quickstart-0
Last Transition Time: 2026-02-10T08:28:25Z
Message: check pod ready; ConditionStatus:True; PodName:etcd-quickstart-2
Observed Generation: 1
Status: True
Type: CheckPodReady--etcd-quickstart-2
Last Transition Time: 2026-02-10T08:28:35Z
Message: move leader; ConditionStatus:True; PodName:etcd-quickstart-1
Observed Generation: 1
Status: True
Type: MoveLeader--etcd-quickstart-1
Last Transition Time: 2026-02-10T08:29:10Z
Message: check pod ready; ConditionStatus:True; PodName:etcd-quickstart-1
Observed Generation: 1
Status: True
Type: CheckPodReady--etcd-quickstart-1
Last Transition Time: 2026-02-10T08:29:16Z
Message: Successfully restarted the etcd members with the new configuration
Observed Generation: 1
Reason: RestartEtcdPods
Status: True
Type: RestartEtcdPods
Last Transition Time: 2026-02-10T08:29:18Z
Message: Successfully reconfigured the etcd cluster
Observed Generation: 1
Reason: Successful
Status: True
Type: Successful
Observed Generation: 1
Phase: Successful
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal PauseDatabase 3m KubeDB Ops-manager Operator Pausing Etcd demo/etcd-quickstart
Normal UpdateDatabase 2m54s KubeDB Ops-manager Operator Successfully updated the Etcd configuration
Normal UpdateEtcdPetSet 2m52s KubeDB Ops-manager Operator Successfully re-rendered the petset with the new configuration
Normal RestartEtcdPods 44s KubeDB Ops-manager Operator Successfully restarted the etcd members with the new configuration
Normal ResumeDatabase 42s KubeDB Ops-manager Operator Resuming Etcd demo/etcd-quickstart
Normal Successful 42s KubeDB Ops-manager Operator Successfully reconfigured the etcd cluster
The three phases of the request are visible in the conditions: UpdateDatabase (the Etcd object’s
spec.configuration.tuning is patched), UpdateEtcdPetSet (the PetSet template is re-rendered with
the new flags) and RestartEtcdPods (the members are rolled, leader last).
Now, wait until etcd-quickstart is Ready again. i.e,
$ kubectl get etcd -n demo
NAME VERSION STATUS AGE
etcd-quickstart 3.6.4 Ready 12m
First, check the desired state on the Etcd object:
$ kubectl get etcd -n demo etcd-quickstart -o jsonpath='{.spec.configuration.tuning}' | jq .
{
"autoCompactionMode": "revision",
"autoCompactionRetention": "1000",
"quotaBackendBytes": 8589934592,
"snapshotCount": 10000
}
Note that snapshotCount is still 10000 — the ops request did not name it, so it was left alone.
Then check that the running members actually carry the new flags:
$ kubectl get pod -n demo etcd-quickstart-0 -o jsonpath='{.spec.containers[?(@.name=="etcd")].args}' | jq .
[
"--name=$(POD_NAME)",
"--data-dir=/var/lib/etcd/data",
"--initial-advertise-peer-urls=$(ETCD_MEMBER_PEER_URL)",
"--listen-peer-urls=http://0.0.0.0:2380",
"--listen-client-urls=http://0.0.0.0:2379",
"--advertise-client-urls=$(ETCD_MEMBER_CLIENT_URL)",
"--listen-metrics-urls=http://0.0.0.0:2381",
"--quota-backend-bytes=8589934592",
"--auto-compaction-mode=revision",
"--auto-compaction-retention=1000",
"--snapshot-count=10000"
]
--quota-backend-bytes has been raised from 2147483648 to 8589934592 and the auto compaction
has switched from periodic/1h to revision/1000, so the reconfiguration is complete.
Finally, confirm that the cluster is still healthy and every member came back:
$ kubectl exec -it -n demo etcd-quickstart-0 -c etcd -- etcdctl \
--endpoints=http://127.0.0.1:2379 --user=root:$ETCD_PASSWORD endpoint health --cluster -w table
+---------------------------------------------------------------+--------+------------+-------+
| ENDPOINT | HEALTH | TOOK | ERROR |
+---------------------------------------------------------------+--------+------------+-------+
| http://etcd-quickstart-0.etcd-quickstart-pods.demo.svc:2379 | true | 3.1ms | |
| http://etcd-quickstart-1.etcd-quickstart-pods.demo.svc:2379 | true | 3.4ms | |
| http://etcd-quickstart-2.etcd-quickstart-pods.demo.svc:2379 | true | 2.9ms | |
+---------------------------------------------------------------+--------+------------+-------+
Cleaning Up
To clean up the Kubernetes resources created by this tutorial, run:
kubectl delete etcdopsrequest -n demo etcd-reconfigure
kubectl delete etcd -n demo etcd-quickstart
kubectl delete ns demo
Next Steps
- Detail concepts of Etcd object.
- Detail concepts of EtcdOpsRequest object.
- Restart the cluster without changing anything with Restart.
- Rotate the etcd credentials with Rotate Authentication.
- Want to hack on KubeDB? Check our contribution guidelines.
































