5.1.2.2. Certificates
Certificates are digital documents that confirm the authenticity and reliability of participants in a system interaction. In Kubernetes, certificates are used to establish secure connections between cluster components, nodes, and clients. They are based on Public Key Infrastructure (PKI) and provide authentication, authorization, and data encryption. Each certificate is associated with a private key and contains information about its owner, validity period, and the certificate authority that issued the certificate.
- master-1
- master-2
- master-3
export HOST_NAME=master-1
export HOST_NAME=master-2
export HOST_NAME=master-3
5.1.2.2.1. Etcd client > Etcd
Purpose: Client certificate for etcd healthcheck probes (liveness probe). Used for connecting to the etcd client API when checking cluster availability. Signed by etcd-ca.
- HardWay
- Kubeadm
Working directory
mkdir -p /etc/kubernetes/pki/etcd
mkdir -p /etc/kubernetes/openssl/csr
Configuration
cat <<EOF > /etc/kubernetes/openssl/healthcheck-client.conf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[ dn ]
CN = kube-etcd-healthcheck-client
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=clientAuth
EOF
Private key generation
openssl genrsa \
-out /etc/kubernetes/pki/etcd/healthcheck-client.key 2048
CSR generation
openssl req \
-new \
-key /etc/kubernetes/pki/etcd/healthcheck-client.key \
-out /etc/kubernetes/openssl/csr/etcd-client.csr \
-config /etc/kubernetes/openssl/healthcheck-client.conf
CSR signing
openssl x509 \
-req \
-days 365 \
-sha256 \
-CA /etc/kubernetes/pki/etcd/ca.crt \
-CAkey /etc/kubernetes/pki/etcd/ca.key \
-CAcreateserial \
-in /etc/kubernetes/openssl/csr/etcd-client.csr \
-out /etc/kubernetes/pki/etcd/healthcheck-client.crt \
-extensions v3_ext \
-extfile /etc/kubernetes/openssl/healthcheck-client.conf
Certificate readiness check
/etc/kubernetes/openssl/cert-report.sh /etc/kubernetes/pki/etcd/healthcheck-client.crt
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
etcd-healthcheck-client Oct 22, 2025 22:06 UTC 364d etcd-ca no
Certificate generation
kubeadm init phase certs etcd-healthcheck-client \
--config=/var/run/kubeadm/kubeadm.yaml
After running the command, we get the following output.
#### Certificate generation
[certs] Generating "etcd/healthcheck-client" certificate and key
Certificate readiness check
kubeadm certs check-expiration
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
etcd-healthcheck-client Oct 22, 2025 22:06 UTC 364d etcd-ca no
5.1.2.2.2. Etcd server
Purpose: Server certificate for etcd serving client connections on port 2379. Presented during TLS connection from kube-apiserver and other etcd clients. Signed by etcd-ca.
- HardWay
- Kubeadm
Environment variables
export CLUSTER_NAME=my-first-cluster
export BASE_DOMAIN=example.com
export FULL_HOST_NAME=${HOST_NAME}.${CLUSTER_NAME}.${BASE_DOMAIN}
export MACHINE_LOCAL_ADDRESS=$(ip -4 addr show scope global | awk '/inet/ {print $2; exit}' | cut -d/ -f1)
Working directory
mkdir -p /etc/kubernetes/pki
mkdir -p /etc/kubernetes/openssl/csr
Configuration
cat <<EOF > /etc/kubernetes/openssl/etcd-server.conf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = localhost
DNS.2 = ${HOST_NAME}
DNS.3 = ${FULL_HOST_NAME}
IP.1 = 127.0.0.1
IP.2 = 0:0:0:0:0:0:0:1
IP.3 = ${MACHINE_LOCAL_ADDRESS}
[ dn ]
CN = ${FULL_HOST_NAME}
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
EOF
Private key generation
openssl genrsa \
-out /etc/kubernetes/pki/etcd/server.key 2048
CSR generation
openssl req \
-new \
-key /etc/kubernetes/pki/etcd/server.key \
-out /etc/kubernetes/openssl/csr/etcd-server.csr \
-config /etc/kubernetes/openssl/etcd-server.conf
CSR signing
openssl x509 \
-req \
-days 365 \
-sha256 \
-CA /etc/kubernetes/pki/etcd/ca.crt \
-CAkey /etc/kubernetes/pki/etcd/ca.key \
-CAcreateserial \
-in /etc/kubernetes/openssl/csr/etcd-server.csr \
-out /etc/kubernetes/pki/etcd/server.crt \
-extensions v3_ext \
-extfile /etc/kubernetes/openssl/etcd-server.conf
Certificate readiness check
/etc/kubernetes/openssl/cert-report.sh /etc/kubernetes/pki/etcd/server.crt
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
etcd-server Oct 22, 2025 22:06 UTC 364d etcd-ca no
Certificate generation
kubeadm init phase certs etcd-server \
--config=/var/run/kubeadm/kubeadm.yaml
After running the command, we get the following output.
#### Certificate generation
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost master-1.my-first-cluster.example.com] and IPs [192.168.10.27 127.0.0.1 ::1]
Certificate readiness check
kubeadm certs check-expiration
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
etcd-server Oct 22, 2025 22:06 UTC 364d etcd-ca no
5.1.2.2.3. Etcd peer > Etcd
Purpose: Certificate for mutual authentication (mutual TLS) between etcd cluster nodes on port 2380. Each cluster member uses the peer certificate for both the server and client side of the connection. Signed by etcd-ca.
- HardWay
- Kubeadm
Environment variables
export CLUSTER_NAME=my-first-cluster
export FULL_HOST_NAME=${HOST_NAME}.${CLUSTER_NAME}.${BASE_DOMAIN}
export MACHINE_LOCAL_ADDRESS=$(ip -4 addr show scope global | awk '/inet/ {print $2; exit}' | cut -d/ -f1)
Working directory
mkdir -p /etc/kubernetes/pki
mkdir -p /etc/kubernetes/openssl/csr
Configuration
cat <<EOF > /etc/kubernetes/openssl/etcd-peer.conf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = localhost
DNS.2 = ${HOST_NAME}
DNS.3 = ${FULL_HOST_NAME}
IP.1 = 127.0.0.1
IP.2 = 0:0:0:0:0:0:0:1
IP.3 = ${MACHINE_LOCAL_ADDRESS}
[ dn ]
CN = ${FULL_HOST_NAME}
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
EOF
Private key generation
openssl genrsa \
-out /etc/kubernetes/pki/etcd/peer.key 2048
CSR generation
openssl req \
-new \
-key /etc/kubernetes/pki/etcd/peer.key \
-out /etc/kubernetes/openssl/csr/etcd-peer.csr \
-config /etc/kubernetes/openssl/etcd-peer.conf
CSR signing
openssl x509 \
-req \
-days 365 \
-sha256 \
-CA /etc/kubernetes/pki/etcd/ca.crt \
-CAkey /etc/kubernetes/pki/etcd/ca.key \
-CAcreateserial \
-in /etc/kubernetes/openssl/csr/etcd-peer.csr \
-out /etc/kubernetes/pki/etcd/peer.crt \
-extensions v3_ext \
-extfile /etc/kubernetes/openssl/etcd-peer.conf
Certificate readiness check
/etc/kubernetes/openssl/cert-report.sh /etc/kubernetes/pki/etcd/peer.crt
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
etcd-peer Oct 22, 2025 22:06 UTC 364d etcd-ca no
Certificate generation
kubeadm init phase certs etcd-peer \
--config=/var/run/kubeadm/kubeadm.yaml
After running the command, we get the following output.
#### Certificate generation
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost master-1.my-first-cluster.example.com] and IPs [192.168.10.27 127.0.0.1 ::1]
Certificate readiness check
kubeadm certs check-expiration
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
etcd-peer Oct 22, 2025 22:06 UTC 364d etcd-ca no