Last updated: 2026-05-14
etcd TLS Configuration
etcd has two independent TLS surfaces: client (etcdctl, Kubernetes API server → etcd) and peer (etcd node → etcd node in a cluster). Both must be secured: an etcd cluster with client auth disabled but peer auth enabled is still fully exposed to any process that can reach port 2379.
Certificate Setup
A minimal etcd PKI:
- One CA certificate (separate client and peer CAs are also valid)
- A server certificate per node, with each node's IP addresses and hostname in the SAN
- A peer certificate per node (can be the same as the server cert if the SANs cover both roles)
- A client certificate for each consumer (API server, etcdctl, backup tools)
The peer certificate SAN must include every member's peer URL; etcd validates these during cluster join. Missing IP SANs are the most common reason peer TLS fails to initialize.
Server Configuration
Settings can be passed as flags or as a YAML config file (/etc/etcd/etcd.conf.yaml). The YAML keys use hyphens, matching the flag names with -- stripped.
# Client TLS
cert-file: /etc/etcd/ssl/server.crt
key-file: /etc/etcd/ssl/server.key
trusted-ca-file: /etc/etcd/ssl/ca.crt
client-cert-auth: true
# Peer TLS
peer-cert-file: /etc/etcd/ssl/peer.crt
peer-key-file: /etc/etcd/ssl/peer.key
peer-trusted-ca-file: /etc/etcd/ssl/ca.crt
peer-client-cert-auth: true
Key settings:
client-cert-auth: true: requires clients to present a certificate signed bytrusted-ca-file. Without it, any process that can reach port 2379 has full access to the cluster.peer-client-cert-auth: true: same enforcement for peer connections. Without it, a rogue process can present itself as an etcd member.auto-tls/peer-auto-tls: generates self-signed certificates automatically. Fine for testing, not for production (no CA validation).
Client Connections
etcdctl
etcdctl \
--endpoints=https://etcd1.internal:2379 \
--cacert=/etc/etcd/ssl/ca.crt \
--cert=/etc/etcd/ssl/client.crt \
--key=/etc/etcd/ssl/client.key \
endpoint health
These repeat on every command, so export them as environment variables:
export ETCDCTL_ENDPOINTS=https://etcd1.internal:2379
export ETCDCTL_CACERT=/etc/etcd/ssl/ca.crt
export ETCDCTL_CERT=/etc/etcd/ssl/client.crt
export ETCDCTL_KEY=/etc/etcd/ssl/client.key
Kubernetes API server
The API server connects to etcd as a client. The relevant kube-apiserver flags:
--etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
--etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
--etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
kubeadm generates and sets these automatically. When managing etcd externally, verify the API server's client certificate is signed by the etcd CA and that its CN is accepted by etcd's auth policy.
Verification
Check cluster health over TLS:
etcdctl endpoint health --cluster
Confirm member list and peer URLs:
etcdctl member list -w table
Test the TLS handshake on both ports:
openssl s_client -connect etcd1.internal:2379 -CAfile /etc/etcd/ssl/ca.crt
openssl s_client -connect etcd1.internal:2380 -CAfile /etc/etcd/ssl/ca.crt
Port 2379 is the client port; 2380 is the peer port. Both should complete a valid handshake with peer auth enabled.