确认证书SAN内容,需要用CA证书还是自签证书

前置条件

  1. 要确定自签证书,内部通信节点有哪些IP
  2. 访问的客户端ip段是什么
  3. 上层用到的SLB 地址或域名是什么
  4. 本机务必添加上(127.0.0.1 、localhost)
  5. 证书是什么类型(服务端、客户端、服务端+客户端)
  6. 生产必须CA证书,不能自签证书
1.需要确认的 IP 地址(注意不能是网段,不支持签发网段)
  1. etcd 节点自己的 IP
# 当前节点所有网络接口的 IP
- 物理网卡 IP: 例如 100.112.0.222
- 虚拟网卡 IP: 例如 100.112.6.78 (可能是容器或虚拟化网络)
- 回环地址: 127.0.0.1
  1. Kubernetes 控制平面 VIP/负载均衡器 IP
- API Server 负载均衡器 IP: 如果有外部负载均衡器
- Keepalived 虚拟 IP: 如果使用 VIP
  1. Service Cluster IP 范围
# etcd 在 K8s 内部的 Service IP
- 通常是 K8s Service CIDR 中的某个 IP
- 例如: 10.96.0.0/12 范围内的某个 IP
2.需要确认的域名/DNS
  1. 本地主机名
- localhost
- $(hostname)  # 当前节点的主机名
  1. Kubernetes 内部 DNS 名称(最常用)
# etcd StatefulSet 的标准 DNS 名称
etcd-0.etcd-headless.default.svc.cluster.local
etcd-0.etcd-headless.kube-system.svc.cluster.local

# Headless Service 名称
etcd-headless.default.svc.cluster.local

# 单节点常用
etcd.default.svc.cluster.local
etcd.kube-system.svc.cluster.local
  1. 外部访问域名(如果有)
- etcd.example.com
- etcd.production.company.com
3. 证书是什么类型

服务端、客户端、服务端+客户端

忘记添加 Service DNS 名称 → kube-apiserver 通过 Service 访问 etcd 时会失败
缺少节点 IP → 本地访问 etcd 失败
大小写错误 → DNS 名称必须全部小写
IPv6 与 IPv4 混用 → 保持一致
证书过期时间 → 36500 天(100年)虽然可以,但有些安全扫描会报警

4. CA证书和自签证书的区别

自签名证书:自己给自己发身份证(我是我自己的公安局)
内部 CA 签发:公司公安局给员工发工牌(统一的信任体系)
实际建议:
玩一玩、快速测试 → 自签名
生产环境、K8s 集群 → 内部 CA
对外服务 → 公共 CA

总结:

# 自签名:我是我自己的权威
# 优点:简单、一步到位
# 缺点:无法形成信任网、难以管理
# 内部 CA:建立自己的信任王国
# 优点:集中管理、易扩展、可吊销
# 缺点:需要额外维护 CA
  1. 信任机制的区别
    自签名证书:点对点信任
节点A的证书 ──┬── 节点B手动信任
              ├── 节点C手动信任
              └── 节点D手动信任

每个节点都要单独配置信任关系

CA 签发:层次化信任

              ┌── 节点A证书 (CA签发)
    ┌─────────┼── 节点B证书 (CA签发)
CA证书 ───────┼── 节点C证书 (CA签发)
    └─────────└── 节点D证书 (CA签发)

所有节点只需信任同一个 CA
  1. 实际操作对比
    自签名证书(一步完成)
# 直接生成证书,不需要 CA
openssl req -x509 -new -nodes -days 365 \
  -key server.key \
  -subj "/CN=etcd-server" \
  -addext "subjectAltName=IP:192.168.1.10" \
  -out server.crt

# 客户端配置:必须明确信任这个证书
etcdctl --cacert server.crt \  # ← 直接信任证书本身
        --endpoints https://192.168.1.10:2379 \
        get /key

CA 签发(需要 CA)

# 1. 创建 CA(只做一次)
openssl req -x509 -new -nodes -days 3650 \
  -key ca.key -subj "/CN=My Company CA" \
  -out ca.crt

# 2. 为每个服务生成证书(需要 CA 签名)
openssl req -new -key server.key -out server.csr
openssl x509 -req -in server.csr \
  -CA ca.crt -CAkey ca.key \  # ← CA 签名
  -out server.crt

# 3. 客户端配置:只需信任 CA
etcdctl --cacert ca.crt \     # ← 信任 CA 即可
        --endpoints https://192.168.1.10:2379 \
        get /key
  1. 实际场景问题
    场景 1:Kubernetes 集群有 3 个 etcd 节点
    自签名方案:
# etcd 配置
etcd:
  cert-file: /etc/etcd/server-1.crt  # 节点1的证书
  key-file: /etc/etcd/server-1.key
  
# kube-apiserver 配置(要信任3个不同证书)
--etcd-cafile=/etc/kubernetes/certs/server-1.crt  # 证书1
--etcd-cafile=/etc/kubernetes/certs/server-2.crt  # 证书2  ← 无法配置多个
--etcd-cafile=/etc/kubernetes/certs/server-3.crt  # 证书3  ← 参数只能指定一个!

问题:–etcd-cafile 只能指定一个文件,无法同时信任多个自签名证书。
CA 方案:

# kube-apiserver 只需信任 CA
--etcd-cafile=/etc/kubernetes/certs/ca.crt  # 一个 CA 信任所有节点

场景 2:证书过期

自签名:

# 每个节点单独处理
ssh node1 "openssl req -x509 -new ... -out server.crt"
ssh node2 "openssl req -x509 -new ... -out server.crt"
ssh node3 "openssl req -x509 -new ... -out server.crt"

# 每个客户端都要重新配置信任
# 痛苦!要更新所有配置文件

CA 签发:

# 集中签发新证书
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -out server-new.crt

# 分发给各节点
scp server-new.crt node1:/etc/etcd/
scp server-new.crt node2:/etc/etcd/
scp server-new.crt node3:/etc/etcd/

# 客户端无需任何改动(仍然信任同一个 CA)

场景 3:节点扩容

自签名:

# 新节点生成自签名证书
# 所有客户端都要添加对这个新证书的信任
# 在 K8s 中几乎不可行

CA 签发:

# 为新节点生成证书(CA 签名)
openssl req -new -key node4.key -out node4.csr
openssl x509 -req -in node4.csr -CA ca.crt -CAkey ca.key -out node4.crt
# 客户端无需任何配置,自动信任(因为 CA 没变)

在这里插入图片描述

多san 简化命令(这个就是自签证书签发非CA证书签发)

CN 是证书主体的主要标识字段,用于指定该证书要保护的主域名

openssl req -x509 -new -nodes -sha512 -days 36500 \
  -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Htzh/CN=*.htwisdom.cn" \
  -addext "subjectAltName = DNS:harborai.htwisdom.cn,DNS:htwisdom.cn,DNS:htwisdom.io,DNS:htwisdom.local,DNS:*.htwisdom.io,DNS:*.htwisdom.local,DNS:htwisdom.com,DNS:*.htwisdom.com, DNS:*.htwisdom.cn,DNS:*.htwisdom.local, DNS:localhost, IP:100.112.0.222, IP:100.112.6.78, IP:127.0.0.1" \
  -addext "keyUsage = digitalSignature, keyEncipherment" \
  -addext "extendedKeyUsage = serverAuth, clientAuth" \
  -key server.key \
  -out server.crt

验证证书

openssl x509 -in server.crt -text -noout | grep -A1 "Subject Alternative Name"
openssl x509 -in server.crt -text -noout | grep "Subject:"

使用 CA 签名的三层结构,这是k8s官方和所有生产环境的做法

etcd 需要:
独立的 CA 证书
CA 签发的服务器证书
CA 签发的客户端证书

优化前的脚本
cat etcd-gencrt-old.sh(不具备keyUsage,extendedKeyUsage功能,权限较大 )

# 1. 生成 CA 证书(根证书)
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -sha256 -days 36500 \
  -key ca.key \
  -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Htzh/CN=etcd-ca" \
  -out ca.crt

# 2. 生成服务器私钥和证书请求
openssl genrsa -out server.key 2048
openssl req -new -sha256 \
  -key server.key \
  -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Htzh/CN=etcd-server" \
  -out server.csr

# 3. 用 CA 签发服务器证书(带 SAN)

openssl x509 -req -sha256 -days 36500 \
  -in server.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt \
  -addext "subjectAltName = DNS:localhost,DNS:etcd,DNS:etcd.default.svc,DNS:etcd.default.svc.cluster.local,IP:127.0.0.1,IP:100.112.0.222,IP:100.112.6.78"

或者
openssl x509 -req -sha256 -days 36500 \
  -in server.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt \
  -extfile <(printf "subjectAltName=DNS:localhost,DNS:etcd,DNS:etcd.default.svc,DNS:etcd.default.svc.cluster.local,IP:127.0.0.1,IP:100.112.0.222,IP:100.112.6.78")



# 4. 生成客户端证书(kube-apiserver 使用)
openssl genrsa -out client.key 2048
openssl req -new -sha256 \
  -key client.key \
  -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Htzh/CN=etcd-client" \
  -out client.csr

# 5. 用 CA 签发客户端证书
openssl x509 -req -sha256 -days 36500 \
  -in client.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out client.crt
优化前的脚本

CSR = 证书签名请求文件,相当于一张"证书申请表"。

cat etcd-gencrt-new.sh

#!/bin/bash
# 设置变量
DAYS=36500
COUNTRY="CN"
STATE="SiChuan"
CITY="ChengDu"
ORG="Htzh"

# 生成 CA
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -sha256 -days ${DAYS} \
  -key ca.key \
  -subj "/C=${COUNTRY}/ST=${STATE}/L=${CITY}/O=${ORG}/CN=etcd-ca" \
  -addext "keyUsage = critical, keyCertSign, cRLSign" \
  -addext "basicConstraints = critical, CA:TRUE" \
  -out ca.crt

# 生成服务器证书
openssl genrsa -out server.key 2048
openssl req -new -sha256 \
  -key server.key \
  -subj "/C=${COUNTRY}/ST=${STATE}/L=${CITY}/O=${ORG}/CN=etcd-server" \
  -out server.csr

openssl x509 -req -sha256 -days ${DAYS} \
  -in server.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt \
  -addext "subjectAltName = DNS:localhost,DNS:etcd,DNS:etcd.default.svc,DNS:etcd.default.svc.cluster.local,IP:127.0.0.1,IP:100.112.0.222,IP:100.112.6.78" \
  -addext "keyUsage = critical, digitalSignature, keyEncipherment" \
  -addext "extendedKeyUsage = serverAuth"

# 生成客户端证书
openssl genrsa -out client.key 2048
openssl req -new -sha256 \
  -key client.key \
  -subj "/C=${COUNTRY}/ST=${STATE}/L=${CITY}/O=${ORG}/CN=etcd-client" \
  -out client.csr

openssl x509 -req -sha256 -days ${DAYS} \
  -in client.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out client.crt \
  -addext "keyUsage = critical, digitalSignature, keyEncipherment" \
  -addext "extendedKeyUsage = clientAuth"

echo "证书生成完成!"
ls -lh *.crt *.key
最后优化后的脚本 (前两个第一个没有keyUsage,和extendedKeyUsage ,第二个openssl x509 -req 不支持-addext)CA 不变 → 新证书可被信任,TLS 验证没问题,新加IP 一定要注释掉CA生成部分

cat gen-etcd-cert.sh

# 创建扩展配置文件 如果有新的IP 就需要从新生成,建议使用负载均衡的VIP
cat > server-ext.cnf <<'EOF'
subjectAltName = DNS:localhost,DNS:etcd,DNS:etcd.default.svc,DNS:etcd.default.svc.cluster.local,DNS:*.etcd.cluster.local,IP:127.0.0.1,IP:100.112.5.70
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
EOF

cat > client-ext.cnf <<'EOF'
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
EOF

cat > peer-ext.cnf <<EOF
subjectAltName = DNS:localhost,DNS:etcd-0,DNS:etcd-1,DNS:etcd-2,IP:127.0.0.1,IP:100.112.5.70
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
EOF

# 1. 生成 CA,如果有新IP加入就一定要注释掉这个CA生成部分
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -sha256 -days 36500 \
  -key ca.key \
  -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Htzh/CN=etcd-ca" \
  -addext "keyUsage=critical,keyCertSign,cRLSign" \
  -addext "basicConstraints=critical,CA:TRUE" \
  -out ca.crt

# 2. 生成服务器证书
openssl genrsa -out server.key 2048
openssl req -new -sha256 \
  -key server.key \
  -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Htzh/CN=etcd-server" \
  -out server.csr

openssl x509 -req -sha256 -days 36500 \
  -in server.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt \
  -extfile server-ext.cnf

# 3. 生成客户端证书
openssl genrsa -out client.key 2048
openssl req -new -sha256 \
  -key client.key \
  -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Htzh/CN=etcd-client" \
  -out client.csr

openssl x509 -req -sha256 -days 36500 \
  -in client.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out client.crt \
  -extfile client-ext.cnf

# 4. 生成对等证书
openssl genrsa -out peer.key 2048
openssl req -new -sha256 \
  -key peer.key \
  -subj "/C=CN/ST=SiChuan/L=ChengDu/O=Htzh/CN=etcd-peer" \
  -out peer.csr

openssl x509 -req -sha256 -days 36500 \
  -in peer.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out peer.crt \
  -extfile peer-ext.cnf

# 5. 验证结果
echo "=== 生成的文件 ==="
ls -lh *.crt *.key

echo ""
echo "=== 验证服务器证书 ==="
openssl x509 -in server.crt -text -noout | grep -E "(Subject:|X509v3 Extended Key Usage|X509v3 Subject Alternative Name)" -A 1

echo ""
echo "✅ 证书生成完成!"

echo "生成 k8s api 客户端连接证书"
cp client.key apiserver-etcd-client.key
cp client.crt apiserver-etcd-client.crt

echo "✅ k8s api 客户端证书生成完成!"

三种证书的用途对比

在这里插入图片描述


证书类型	keyUsage	extendedKeyUsage	使用场景
CA 证书	keyCertSign, cRLSign	无	签发其他证书
服务器证书	digitalSignature, keyEncipherment	serverAuth	etcd 服务端
客户端证书	digitalSignature, keyEncipherment	clientAuth	API Server 访问 etcd
对等证书	digitalSignature, keyEncipherment	serverAuth, clientAuth	etcd 集群内部通信
1. 服务器证书 (serverAuth):
etcd 启动时使用 --cert-file 参数
证明自己是合法的 etcd 服务器
2. 客户端证书 (clientAuth):
kube-apiserver 使用 --etcd-certfile 参数
证明自己有权限访问 etcd
3. 对等证书 (serverAuth + clientAuth):
etcd 集群节点间互相验证
既要验证对方身份(clientAuth),又要证明自己身份(serverAuth)

证书类型 keyUsage与extendedKeyUsage

keyUsage(基础密钥用途)
控制证书的私钥可以执行哪些加密操作。

常用值详解
值	含义	实际场景	类比
digitalSignature	数字签名,证明数据未被篡改	TLS 握手时的签名验证	在合同上签字
keyEncipherment	加密对称密钥	HTTPS 中传输会话密钥	用信封封装秘密文件
keyCertSign	签发下级证书	CA 证书给其他证书签名	公安局签发身份证
cRLSign	签发证书吊销列表	CA 发布黑名单	法院发布通缉令
dataEncipherment	直接加密数据(少用)	某些特殊加密场景	用密码锁锁日记本

extendedKeyUsage(扩展用途)
指定证书在 TLS/SSL 协议层的具体使用场景。

常用值详解
值	含义	谁使用	验证方向
serverAuth	作为 TLS 服务器	Nginx, etcd, API Server	客户端验证服务器
clientAuth	作为 TLS 客户端	curl, kubectl, kubelet	服务器验证客户端
codeSigning	签名代码/软件	软件开发商	用户验证软件来源
emailProtection	加密/签名邮件	Outlook, Thunderbird	邮件客户端验证

关键理解
serverAuth ≠ 服务器证书,而是"这个证书可以用于服务器身份验证"。

# etcd 服务端证书
extendedKeyUsage = serverAuth    # 证明自己是 etcd 服务器

# kube-apiserver 客户端证书  
extendedKeyUsage = clientAuth    # 证明自己有权限访问 etcd

# etcd 集群内部通信(既是客户端又是服务器)
extendedKeyUsage = serverAuth, clientAuth
etcd 场景的具体应用
  1. CA 证书(根证书)
keyUsage = keyCertSign, cRLSign          # 只能签发证书
# 没有 extendedKeyUsage(CA 不直接参与 TLS)

作用:像个"公安局",只负责签发身份证,自己不上街执勤。

  1. etcd 服务器证书
keyUsage = digitalSignature, keyEncipherment   # 能签名和加密
extendedKeyUsage = serverAuth                  # 只能做服务器

作用:像"警官证",证明自己是警察(服务器身份)。
3. 客户端证书(kube-apiserver 用)

keyUsage = digitalSignature, keyEncipherment   # 能签名和加密
extendedKeyUsage = clientAuth                  # 只能做客户端

作用:像"通行证",证明自己有权限进入。

  1. 对等证书(多节点集群)
keyUsage = digitalSignature, keyEncipherment   # 能签名和加密
extendedKeyUsage = serverAuth, clientAuth      # 既能当服务器又能当客户端

作用:像"外交护照",既能在本国用,也能在他国用。

对比

在这里插入图片描述
openssl req -x509 完全支持 -addext 自签证书没有信任连 但openssl x509 -req 不支持-addext CA签发有完整的信任链

一些说明及直接用kubeadm 生成etcd证书,etcd 需要专门为 Kubernetes 添加额外信息,用脚本扩展不方便

etcd 需要专门为 Kubernetes 添加额外信息吗?
不需要。etcd 本身不关心证书中是否包含 kubernetes 相关字段。只要:

客户端证书被 etcd 信任(由同一个 CA 签发)

客户端证书的 extendedKeyUsage 包含 clientAuth

服务端证书的 SAN 匹配连接地址

就可以正常工作。Kubernetes 也没有特殊要求,apiserver-etcd-client 证书的 CN、O 等字段可以是任意值(通常用 etcd-client 即可)。

  • apiserver-etcd-client 证书:当前 client.crt/key 配置完全正确,可直接使用。

  • 服务端证书:请根据实际 etcd 部署的网络地址补全 SAN,否则可能导致 TLS 握手失败。

  • 集群模式:必须额外生成 peer 证书,并配置双向认证。

  • 无需为 Kubernetes 添加特殊字段,标准证书扩展即可。

上面gen-etcd-cert.sh 脚本如果后面我有新的etcd IP加入集群,这个扩展性一点不好

方案一:使用外部负载均衡器(推荐)

原理:所有 etcd 客户端(如 kube-apiserver)只通过一个固定的负载均衡器 VIP/DNS 访问 etcd 集群。服务端证书的 SAN 中只需包含这个 VIP 或 DNS 名称,无需包含每个 etcd 节点的真实 IP。

优点:

证书 SAN 列表固定,新增 etcd 节点不需要重新签发证书

客户端配置无需改变

负载均衡器自动处理后端 etcd 节点的健康检查和故障转移

缺点:

需要额外部署负载均衡器(如 HAProxy、Nginx、云厂商的 LB)

etcd 集群本身仍需配置 peer 证书,但 peer 证书的 SAN 可以包含所有节点(因为 peer 之间直接通信,不过 peer 证书也可以通过负载均衡器吗?不,peer 间需直接互联,但 peer 证书的 SAN 仍会面临扩展性问题。见下个方案解决 peer 证书问题)

注意:对于 etcd 集群内部 peer 通信,负载均衡器方案不适用(peer 需要直接点对点连接)。但 peer 证书的扩展性可以通过“提前预留 SAN”或“使用 DNS 通配符”解决。

方案二:使用 DNS 通配符 + 有状态命名规则

原理:为 etcd 集群规划一个统一的 DNS 子域,例如 *.etcd.cluster.local,并为每个节点分配固定主机名:etcd-0.etcd.cluster.local、etcd-1.etcd.cluster.local……。服务端证书和 peer 证书的 SAN 中只需包含 *.etcd.cluster.local 和 etcd.cluster.local(通配符证书)。
etcd-0.etcd.cluster.local、'etcd-1.etcd.cl

优点:

新增节点时无需重新生成证书(只要节点主机名匹配通配符模式)

通配符证书可以同时用于服务端和 peer(需同时包含 serverAuth 和 clientAuth)

缺点:

通配符证书的安全性稍低(一旦泄露,所有子域均受影响)

某些环境可能不支持通配符 SAN(但 openssl 和 etcd 都支持)

需要内部 DNS 服务支持解析这些主机名
生成通配符证书示例(server-ext.cnf):

subjectAltName = DNS:etcd.cluster.local,DNS:*.etcd.cluster.local,IP:127.0.0.1
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth   # 同时用于服务端和 peer
方案三:使用 API 动态签发证书(最灵活)

原理:部署一个内部 CA 服务(如 cfssl、Vault、cert-manager + Jetstack etcd-operator),当新 etcd 节点加入时,自动向该 CA 请求新证书,并且证书的 SAN 只包含该节点自己的 IP/DNS。集群内所有节点信任同一个 CA。

优点:

完全动态,无需人工干预

每个节点有自己的专用证书,安全性高

适合大规模动态集群(如 Kubernetes 中的 etcd-operator)

缺点:

需要额外部署和维护 CA 服务

相对复杂,适合云原生环境

示例:使用 cert-manager 和 etcd-operator 可以自动管理 etcd 集群证书。

方案四:提前预留 SAN(简单但不完美)

如果节点数量有限且可预测,可以在初始证书中预留多个额外的 IP 和 DNS(例如 IP:10.0.0.10-10.0.0.20,但 openssl 不支持 IP 范围,需要逐个列出)。或者预留足够多的占位符,未来加入新节点时,将其 IP 映射到预留的 SAN 条目上(但这通常很难操作)。

不推荐,仅适用于节点数量固定且很少变化的小型集群

Kubernetes 环境中的特殊说明

如果您使用的是 kubeadm 初始化的集群(etcd 作为静态 Pod 运行在 master 节点上):

kubeadm 在 init 时会生成 etcd 证书,其中 SAN 包含了当时所有 master 节点的 IP 和主机名。

当您后续通过 kubeadm join --control-plane 添加新的 master 节点时,kubeadm 会自动重新生成 etcd 证书,包含新节点的 IP。也就是说,kubeadm 已经帮你解决了扩展性问题(但要求新节点加入时使用 --control-plane 并上传证书密钥)。

如果您手动管理证书(如您自己用 openssl 生成),则失去了 kubeadm 的自动更新能力,需要手动处理。

因此,如果您使用 kubeadm 管理集群,建议直接使用 kubeadm 的证书管理机制,不要手动替换 apiserver-etcd-client 等证书,否则会破坏 kubeadm 的自动轮转和扩展能力。

最终建议:如果您在用 kubeadm,不要自己手动生成 etcd 证书,而是使用 kubeadm init --upload-certs 和 kubeadm join --control-plane 自动处理。如果必须手动管理,优先考虑负载均衡器 + 通配符证书的组合。

etcd 需要以下两类证书:
证书类型 用途 需要的 Extended Key Usage 需要的 扩展密钥使用
服务端证书(server.crt) 接收客户端连接(如 apiserver 连接 etcd) serverAuth 服务器认证
客户端证书(client.crt) 作为客户端连接其他 etcd 节点或 apiserver clientAuth
对等证书(peer.crt) etcd 集群内部节点间通信 同时包含 serverAuth 和 clientAuth

利用kubeadm 直接生成证书(很方便,但需要先安装kubeadm,再部署etcd)

cat kubeadm-gen-etcd-cert-config.yaml

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: v1.34.5   # 替换为实际使用的版本
#controlPlaneEndpoint: "k8s-lb.example.com:6443"   # 负载均衡器地址(HA集群必需)
#controlPlaneEndpoint: "100.112.5.70:6443"   # 负载均衡器地址(HA集群必需)
#imageRepository: harborai.htwisdom.local
certificatesDir: /etc/kubernetes/pki

# etcd 配置段(本地静态Pod方式)
etcd:
  local:
    # 数据目录(建议使用独立磁盘或高性能路径)
    #dataDir: /var/lib/etcd
    # 服务器证书的额外 SAN(API Server 及其他客户端可能使用的地址)
    serverCertSANs:
      #- "k8s-lb.example.com"           # 负载均衡器 DNS
      #- "192.168.10.100"               # 负载均衡器 IP
      #- "etcd-0.example.com"           # 单个 etcd 节点主机名(可选)
      #- "etcd-1.example.com"
      #- "etcd-2.example.com"
      #- "10.96.0.10"                   # Kubernetes 集群中 etcd 的 Service IP(如果有)
      - "127.0.0.1"                    # 本地回环
      - "localhost"
      - "100.112.5.70"
      - "100.200.194.4"
    # 对等证书的额外 SAN(etcd 集群内部节点通信地址)
    peerCertSANs:
      #- "etcd-0.example.com"
      #- "etcd-1.example.com"
      #- "etcd-2.example.com"
      #- "192.168.10.11"                # etcd-0 的真实 IP
      #- "192.168.10.12"                # etcd-1 的真实 IP
      #- "192.168.10.13"                # etcd-2 的真实 IP
      - "127.0.0.1"
      - "localhost"
      - "100.112.5.70"
      - "100.200.194.4"

## 其他常用生产配置(可选,但建议保留)
#networking:
#  serviceSubnet: "10.96.0.0/12"
#  podSubnet: "10.244.0.0/16"
#  dnsDomain: "cluster.local"
#  

cat gen-etcd-cert.sh

### 后面的放到脚本中执行
# 生成 etcd 服务器证书
kubeadm init phase certs etcd-server --config=kubeadm-gen-etcd-cert-config.yaml
# 生成 etcd 对等证书
kubeadm init phase certs etcd-peer --config=kubeadm-gen-etcd-cert-config.yaml
# 生成健康检查客户端证书
kubeadm init phase certs etcd-healthcheck-client --config=kubeadm-gen-etcd-cert-config.yaml
# 生成 API Server 连接 etcd 的客户端证书
kubeadm init phase certs apiserver-etcd-client --config=kubeadm-gen-etcd-cert-config.yaml
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐