找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3710

积分

1

好友

502

主题
发表于 2026-2-12 08:23:00 | 查看: 29| 回复: 0

在构建高可用的分布式系统时,Etcd 作为可靠的键值存储,其安全性至关重要。相比于集成在 Kubernetes 中由 kubeadm 自动管理证书的场景,当你需要独立部署 Etcd 集群用于其他服务(如服务发现、配置存储)时,手动管理证书是必须掌握的技能。本文将详细演示如何从零开始,使用 CFSSL 工具生成 TLS 证书,并部署一个带双向认证的三节点 Etcd 集群。

环境规划

部署前,需要规划好集群节点。以下是示例规划,你可以根据实际网络环境调整主机名和 IP 地址。

角色 IP
etcd-1 192.168.31.100
etcd-2 192.168.31.101
etcd-3 192.168.31.102

证书工具准备

我们将使用 Cloudflare 开源的 PKI/TLS 工具 cfssl 来生成证书。这个方法在早期 Kubernetes 手动部署中也被广泛使用,非常成熟可靠。

在任一节点(如 etcd-1)上执行以下命令安装工具并创建必要的目录:

# 安装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

生成证书

一个完整的 TLS 认证体系至少包含 CA(证书颁发机构)根证书以及由它签发的服务端/客户端证书。验证时,需要使用 CA 证书的公钥来验证下级证书的合法性。

所有证书生成操作在 etcd-1 节点上进行:

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/

执行完成后,使用 ls -l 命令检查证书目录,应看到如下文件:
Etcd证书目录列表

为了方便理解,下表列出了生成的所有文件及其用途:

文件名 文件类型 核心用途
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 节点证书的临时文件,包含节点证书的请求信息,生成后可删除

配置并启动 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

依次在三个节点上执行 start-etcd.sh 脚本启动服务。观察前台日志,确认所有节点都启动成功且无报错。

验证集群

集群启动后,需要进行健康检查和基本读写测试。必须提前设置好证书环境变量,否则 etcdctl 无法通过 TLS 认证连接到集群。

在任意已安装 etcdctl 的节点上执行:

# 设置环境变量
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

Etcd集群健康状态与读写测试结果

如果看到所有端点均为 healthy,并且能正常写入和读取数据,说明基于 TLS 的 集群部署 成功。

我们也可以使用 curl 命令通过 HTTPS 接口访问 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

从输出中可以看到,服务器返回的证书信息正是我们前面所生成的。至此,一个带 TLS 双向认证的 Etcd 集群就部署完成了。任何客户端(包括 etcdctl、应用程序)在连接此集群时,都必须提供有效的证书才能通过认证,这为你的 分布式系统 提供了坚实的安全基础。

对于更复杂的运维场景,例如监控、自动化部署等,可以深入探索相关的工具链与实践。如果你想查看更多关于 数据库中间件 部署与优化的实战内容,欢迎访问 云栈社区运维 & 测试 板块进行交流学习。




上一篇:用Claude/Cursor Skill封装业务流程:告别AI Agent碎片化,开启“入职手册”时代
下一篇:前GitHub CEO押注AI开发平台:Agent推理过程可追溯,让Git记住“为什么”
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-23 12:58 , Processed in 0.633568 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表