作者介绍:简历上没有一个精通的运维工程师,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

数据库是一个系统(应用)最重要的资产之一,所以我们的数据库将从以下几个数据库来进行介绍。
MySQL
PostgreSQL
Redis
Etcd(本章节)
我们今天采用的是使用自己手动生成证书来部署Etcd集群,如果是Kubernetes可以使用kubeadmin来自动生成证书,但是我们如果我们是需要把Etcd集群额外部署或者其他用途则可以使用此方案。
环境规划
现场可根据自己需要调整这里的名字和IP地址。
角色 | IP |
|---|---|
etcd-1 | 192.168.31.100 |
etcd-2 | 192.168.31.101 |
etcd-2 | 192.168.31.102 |
证书工具准备
在以前早期的Kubernetes,我们也使用这个方法来生成证书,目前还能在网上搜索到类似的文章,所以我们这里也使用它来下载证书工具。
# 安装cfssl(证书生成工具)
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssl_1.6.4_linux_amd64 -o /usr/local/bin/cfssl
curl -L https://github.com/cloudflare/cfssl/releases/download/v1.6.4/cfssljson_1.6.4_linux_amd64 -o /usr/local/bin/cfssljson
chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson
# 创建对应的数据目录,为了避免默认这里目录生成了一个新的
mkdir -p /etc/etcd/certs /var/lib/etcdnew生成证书
一个完整的证书链至少包括CA证书及由CA证书签发出来的证书,然后验证的时候也需要使用CA证书的公钥来验证证书的可靠性。
mkdir -p /etc/etcd/certs && cd /etc/etcd/certs
# 1. 重新创建ca-config.json(此文件无地域信息,无需修改)
cat > ca-config.json << 'EOF'
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"etcd": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "87600h"
}
}
}
}
EOF
# 2. 重新创建ca-csr.json(ST和L字段替换为Chengdu)
cat > ca-csr.json << 'EOF'
{
"CN": "etcd-ca",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Chengdu",
"L": "Chengdu",
"O": "etcd",
"OU": "etcd-cluster"
}
]
}
EOF
# 3. 重新创建etcd-csr.json(纯IP版,ST和L字段替换为Chengdu)
cat > etcd-csr.json << 'EOF'
{
"CN": "etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Chengdu",
"L": "Chengdu",
"O": "etcd",
"OU": "etcd-cluster"
}
],
"hosts": [
"127.0.0.1",
"192.168.31.100",
"192.168.31.101",
"192.168.31.102"
]
}
EOF
# 生成证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd etcd-csr.json | cfssljson -bare etcd -
chmod 600 /etc/etcd/certs/*-key.pem
# 同步证书到其他节点
scp /etc/etcd/certs/* root@192.168.31.101:/etc/etcd/certs/
scp /etc/etcd/certs/* root@192.168.31.102:/etc/etcd/certs/
文件名 | 文件类型 | 核心用途 |
|---|---|---|
ca-config.json | JSON 配置文件 | CA 证书的签发规则配置(如有效期、证书用途),是生成证书的 “规则文件” |
ca-csr.json | JSON 请求文件 | CA 根证书的签名请求文件,定义 CA 证书的基本信息(如地域、密钥算法) |
ca.pem | CA 根证书(公钥) | 集群的根证书,用于验证所有 etcd 节点证书的合法性(核心信任凭证) |
ca-key.pem | CA 根私钥 | 生成 CA 证书的私钥,用于签发 etcd 节点证书,极其敏感,需严格保密 |
ca.csr | CA 证书签名请求 | 生成 CA 证书过程中产生的临时文件,包含证书请求的原始信息,生成后可删除 |
etcd-csr.json | JSON 请求文件 | etcd 节点证书的签名请求文件,定义节点证书的 IP、地域等信息 |
etcd.pem | etcd 节点证书 | etcd 节点的服务端 / 客户端证书,用于节点间通信加密和客户端身份认证 |
etcd-key.pem | etcd 节点私钥 | 与 etcd.pem 配对的私钥,用于解密通信数据,需严格保密 |
etcd.csr | etcd 证书请求 | 生成 etcd 节点证书的临时文件,包含节点证书的请求信息,生成后可删除 |
节点 1(192.168.31.100)
我们这里采用的生成脚本,方便启动调试,但是启动方式还是采用的前台方式,启动的时候直接执行脚本即可。
cat > /usr/local/bin/start-etcd.sh << 'EOF'
#!/bin/bash
etcd \
--name=etcd-1 \
--data-dir=/var/lib/etcdnew \
--listen-client-urls=https://192.168.31.100:2379 \
--advertise-client-urls=https://192.168.31.100:2379 \
--listen-peer-urls=https://192.168.31.100:2380 \
--initial-advertise-peer-urls=https://192.168.31.100:2380 \
--initial-cluster=etcd-1=https://192.168.31.100:2380,etcd-2=https://192.168.31.101:2380,etcd-3=https://192.168.31.102:2380 \
--initial-cluster-token=etcd-cluster-token \
--initial-cluster-state=new \
--cert-file=/etc/etcd/certs/etcd.pem \
--key-file=/etc/etcd/certs/etcd-key.pem \
--peer-cert-file=/etc/etcd/certs/etcd.pem \
--peer-key-file=/etc/etcd/certs/etcd-key.pem \
--trusted-ca-file=/etc/etcd/certs/ca.pem \
--peer-trusted-ca-file=/etc/etcd/certs/ca.pem \
--client-cert-auth \
--peer-client-cert-auth
EOF
# 添加执行权限
chmod +x /usr/local/bin/start-etcd.sh节点 2(192.168.31.101)
cat > /usr/local/bin/start-etcd.sh << 'EOF'
#!/bin/bash
etcd \
--name=etcd-2 \
--data-dir=/var/lib/etcdnew \
--listen-client-urls=https://192.168.31.101:2379 \
--advertise-client-urls=https://192.168.31.101:2379 \
--listen-peer-urls=https://192.168.31.101:2380 \
--initial-advertise-peer-urls=https://192.168.31.101:2380 \
--initial-cluster=etcd-1=https://192.168.31.100:2380,etcd-2=https://192.168.31.101:2380,etcd-3=https://192.168.31.102:2380 \
--initial-cluster-token=etcd-cluster-token \
--initial-cluster-state=new \
--cert-file=/etc/etcd/certs/etcd.pem \
--key-file=/etc/etcd/certs/etcd-key.pem \
--peer-cert-file=/etc/etcd/certs/etcd.pem \
--peer-key-file=/etc/etcd/certs/etcd-key.pem \
--trusted-ca-file=/etc/etcd/certs/ca.pem \
--peer-trusted-ca-file=/etc/etcd/certs/ca.pem \
--client-cert-auth \
--peer-client-cert-auth
EOF
# 添加执行权限
chmod +x /usr/local/bin/start-etcd.sh节点 3(192.168.31.102)
cat > /usr/local/bin/start-etcd.sh << 'EOF'
#!/bin/bash
etcd \
--name=etcd-3 \
--data-dir=/var/lib/etcdnew \
--listen-client-urls=https://192.168.31.102:2379 \
--advertise-client-urls=https://192.168.31.102:2379 \
--listen-peer-urls=https://192.168.31.102:2380 \
--initial-advertise-peer-urls=https://192.168.31.102:2380 \
--initial-cluster=etcd-1=https://192.168.31.100:2380,etcd-2=https://192.168.31.101:2380,etcd-3=https://192.168.31.102:2380 \
--initial-cluster-token=etcd-cluster-token \
--initial-cluster-state=new \
--cert-file=/etc/etcd/certs/etcd.pem \
--key-file=/etc/etcd/certs/etcd-key.pem \
--peer-cert-file=/etc/etcd/certs/etcd.pem \
--peer-key-file=/etc/etcd/certs/etcd-key.pem \
--trusted-ca-file=/etc/etcd/certs/ca.pem \
--peer-trusted-ca-file=/etc/etcd/certs/ca.pem \
--client-cert-auth \
--peer-client-cert-auth
EOF
# 添加执行权限
chmod +x /usr/local/bin/start-etcd.sh当3个节点都启动成功的时候,并且可以从前台看到日志是否出错。
验证集群
这里我们必须提前定义使用的证书,否则无法链接成功。
# 设置环境变量
export ETCDCTL_API=3
export ETCDCTL_CACERT=/etc/etcd/certs/ca.pem
export ETCDCTL_CERT=/etc/etcd/certs/etcd.pem
export ETCDCTL_KEY=/etc/etcd/certs/etcd-key.pem
# 检查集群健康状态(仅用IP)
etcdctl --endpoints=https://192.168.31.100:2379,https://192.168.31.101:2379,https://192.168.31.102:2379 endpoint health
# 测试数据读写
etcdctl --endpoints=https://192.168.31.100:2379 put testkey "hello etcd (only IP)"
etcdctl --endpoints=https://192.168.31.100:2379 get testkey
如果我们使用http方式去请求etcd,也必须使用证书,通过请求也可以看到服务器返回给我们关于我们前面生成的证书信息。
[root@localhost ~]# curl -v \
> --cacert /etc/etcd/certs/ca.pem \
> --cert /etc/etcd/certs/etcd.pem \
> --key /etc/etcd/certs/etcd-key.pem \
> https://192.168.31.102:2379/version
* About to connect() to 192.168.31.102 port 2379 (#0)
* Trying 192.168.31.102...
* Connected to 192.168.31.102 (192.168.31.102) port 2379 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: /etc/etcd/certs/ca.pem
CApath: none
* NSS: client certificate from file
* subject: CN=etcd,OU=etcd-cluster,O=etcd,L=Chengdu,ST=Chengdu,C=CN
* start date: Feb 08 15:01:00 2026 GMT
* expire date: Feb 06 15:01:00 2036 GMT
* common name: etcd
* issuer: CN=etcd-ca,OU=etcd-cluster,O=etcd,L=Chengdu,ST=Chengdu,C=CN
* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate:
* subject: CN=etcd,OU=etcd-cluster,O=etcd,L=Chengdu,ST=Chengdu,C=CN
* start date: Feb 08 15:01:00 2026 GMT
* expire date: Feb 06 15:01:00 2036 GMT
* common name: etcd
* issuer: CN=etcd-ca,OU=etcd-cluster,O=etcd,L=Chengdu,ST=Chengdu,C=CN
> GET /version HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.31.102:2379
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Sun, 08 Feb 2026 15:25:15 GMT
< Content-Length: 45
<
* Connection #0 to host 192.168.31.102 left intact到这里我们的带证书的集群配置部署就算完成,客户端请求也必须带上证书才能连接成功。