etcd集群部署
-
部署形态
-
单点
-
集群
-
http通信集群
-
https通信集群
-
单证书部署(集群节点证书相同)
-
多证书部署(集群节点证书不同)
-
-
-
上面几种,单点和http集群没啥好说的,单证书部署的操作请参考我全手动部署kubernetes (h2c.tech) ,本文主要说的是多证书的情形。
下载etcd
访问 Releases · etcd-io/etcd (github.com) 下载etcd
下载cfssl
访问 Releases · cloudflare/cfssl (github.com) 下载cfssl,别问我为啥不直接用openssl,问就是懒。下载下面这三个:
-
cfssl
-
cfssl-certinfo
-
cfssljson
生成证书
$ mkdir {ca,cfssl_conf,node_cert}
$ cat > cfssl-conf/ca-config.json<<EOF
{
"signing": {
"default": {
"expiry": "168h"
},
"profiles": {
"server": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"client": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"peer": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
$ cat > cfssl-conf/ca-csr.json<<EOF
{
"CN": "etcd CA",
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan"
}
]
}
EOF
$ node0=172.15.110.84;node1=172.15.110.85;node2=172.15.110.86;node3=172.15.110.87;
for i in {0..3};do
cat > cfssl-conf/infra$i-csr.json<<EOF
{
"CN": "infra$i",
"hosts": [
"$(eval echo \$node$i)"
],
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "h2c.tech",
"CN": "infra$i.h2c.tech"
}
]
}
EOF
done
$ cfssl gencert -initca cfssl-conf/ca-csr.json | cfssljson -bare ca/ca -
$ for i in `seq 0 4`;do
cfssl gencert \
-ca=cfssl-conf/ca.pem \
-ca-key=cfssl-conf/ca-key.pem \
-config=ca-config.json \
-profile=peer \
infra$i-csr.json | cfssljson -bare node_cert/infra$i;
done
上面用到了一个小技巧,用$(eval echo \$node$i)来 Evaluation 获取变量值,避免直接展开成字符串,如果你直接写$(node$i)那就会获取不到。
解析:cfssl gencert -initca cfssl-conf/ca-csr.json | cfssljson -bare ca/ca -
cfssl gencert -initca cfssl-conf/ca-csr.json这部分是生成自签名的根CA证书和私钥。它使用-initca标志表示这是一个CA根证书,并从cfssl-conf/ca-csr.json文件读取证书签名请求配置。|管道符用于将前一个命令的输出作为后一个命令的输入。cfssljson -bare ca/ca这个部分将从管道输入解析出证书和私钥,并以ca为前缀输出到ca/下。即会生成ca/ca.pem证书文件和ca/ca-key.pem私钥文件。-符号表示输出到标准输出,也就是终端屏幕。
另外一个类似,只有一个区别就是它指定了profile使用peer这个。
生成完成以后分发到各个节点,指定一个固定的路径给它存放,我是放到了/etc/etcd/etcd-cert/node-cert/
etcdctl证书
我还习惯单独给客户端发一个证书:
$ cat > cfssl-conf/client-csr.json<<EOF
{
"CN": "client",
"hosts": [
"0.0.0.0"
],
"names": [
{
"C": "CN",
"ST": "Hubei",
"L": "Wuhan",
"O": "h2c.tech",
"CN": "client.h2c.tech"
}
]
}
$ cfssl gencert \
-ca=cfssl-conf/ca.pem \
-ca-key=cfssl-conf/ca-key.pem \
-config=ca-config.json \
-profile=peer \
client-csr.json | cfssljson -bare node_cert/client;
配置etcd
官方示例:
# 本示例来自官方项目示例,个人做了中文翻译(不保证准确) # etcd节点的人类可读名称 name: 'default' # 数据目录的路径 data-dir: # 专用WAL目录的路径 wal-dir: # 触发将快照写入磁盘的已提交事务数 snapshot-count: 10000 # 心跳间隔时间(毫秒) heartbeat-interval: 100 # 选举超时时间(毫秒) election-timeout: 1000 # 当后端大小超过给定配额时发出警报。0表示使用默认配额 quota-backend-bytes: 0 # 用于对等流量的监听URL列表,用逗号分隔 listen-peer-urls: http://localhost:2380 # 用于客户端流量的监听 URL 列表,用逗号分隔 listen-client-urls: http://localhost:2379 # 要保留的最大快照文件数(0 为无限制) max-snapshots: 5 # 要保留的最大 WAL 文件数(0 为无限制) max-wals: 5 # 逗号分隔的CORS(跨域资源共享)的域白名单 cors: # 此成员的对等URL列表,用于向集群其余部分通告 initial-advertise-peer-urls: http://localhost:2380 # 此成员的客户端 URL 列表,用于向公众通告 advertise-client-urls: http://localhost:2379 # 用于引导集群的发现 URL discovery: # 有效值为“exit”、“proxy” discovery-fallback: 'proxy' # 用于访问发现服务的流量的 HTTP 代理 discovery-proxy: # 引导初始集群的使用的 DNS 域 discovery-srv: # 引导初始集群配置的字符串 # 例如: "infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11:2380,infra2=http://10.0.1.12:2380" initial-cluster: # etcd 集群引导过程中的初始集群令牌 initial-cluster-token: 'etcd-cluster' # 初始集群状态(“新建”或“现有”) initial-cluster-state: 'new' # 拒绝会导致法定人数丢失的重新配置请求 strict-reconfig-check: false # 通过 HTTP 服务器启用运行时性能分析数据 enable-pprof: true # 有效值为 “开启”、“只读”、“关闭” proxy: 'off' # 端点将持续失败状态的时间(毫秒) proxy-failure-wait: 5000 # 端点刷新间隔的时间(毫秒) proxy-refresh-interval: 30000 # 拨号超时的时间(毫秒) proxy-dial-timeout: 1000 # 写入超时的时间(毫秒) proxy-write-timeout: 5000 # 读取超时的时间(毫秒) proxy-read-timeout: 0 # 客户端传输安全配置 client-transport-security: # 客户端服务器 TLS 证书文件的路径 cert-file: # 客户端服务器 TLS 密钥文件的路径 key-file: # 启用客户端证书验证 client-cert-auth: false # 客户端服务器 TLS 受信任 CA 证书文件的路径 trusted-ca-file: # 使用生成的证书的客户端 TLS auto-tls: false # 对等服务器传输安全配置 peer-transport-security: # 对等服务器 TLS 证书文件的路径 cert-file: # 对等服务器 TLS 密钥文件的路径 key-file: # 启用对等客户端证书验证 client-cert-auth: false # 对等服务器 TLS 受信任的 CA 证书文件的路径 trusted-ca-file: # 使用生成的证书的对等 TLS auto-tls: false # 自签名证书的有效期,单位为年 self-signed-cert-validity: 1 # 为 etcd 启用调试级别的日志记录 log-level: debug # 指定“stdout”或“stderr”可跳过 journald 日志记录,即使在 systemd 下运行也是如此。 log-outputs: [stderr] # 强制创建一个新的单成员集群 force-new-cluster: false # 自动压缩模式 auto-compaction-mode: periodic # 自动压缩保留期 auto-compaction-retention: "1" # 将 etcd 限制在一组特定的 TLS 加密套件中 cipher-suites: [ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ] # 将 etcd 限制在特定的 TLS 协议版本 tls-min-version: 'TLS1.2' tls-max-version: 'TLS1.3'
测试环境示例配置文件:
# etcd节点的人类可读名称 name: infra0 # 数据目录的路径 data-dir: /var/lib/etcd/default.etcd # 专用WAL目录的路径 wal-dir: /var/lib/etcd/default.etcd.wal # 触发将快照写入磁盘的已提交事务数 snapshot-count: 10000 # 心跳间隔时间(毫秒) heartbeat-interval: 100 # 选举超时时间(毫秒) election-timeout: 1000 # 当后端大小超过给定配额时发出警报。0表示使用默认配额 quota-backend-bytes: 0 # 用于对等流量的监听URL列表,用逗号分隔 listen-peer-urls: https://172.15.110.84:2380 # 用于客户端流量的监听 URL 列表,用逗号分隔 listen-client-urls: https://localhost:2379,https://172.15.110.84:2379 # 要保留的最大快照文件数(0 为无限制) max-snapshots: 5 # 要保留的最大 WAL 文件数(0 为无限制) # max-wals: 5 # 逗号分隔的CORS(跨域资源共享)的域白名单 # cors: # 此成员的对等URL列表,用于向集群其余部分通告 initial-advertise-peer-urls: https://172.15.110.84:2380 # 此成员的客户端 URL 列表,用于向公众通告 advertise-client-urls: https://172.15.110.84:2379 # 用于引导集群的发现 URL discovery: # 有效值为“exit”、“proxy” discovery-fallback: 'proxy' # 用于访问发现服务的流量的 HTTP 代理 discovery-proxy: # 引导初始集群的使用的 DNS 域 discovery-srv: # 引导初始集群配置的字符串 # 例如: "infra0=http://10.0.1.10:2380,infra1=http://10.0.1.11iiinfra0,infra2=http://10.0.1.12:2380" initial-cluster: "infra0=https://172.15.110.84:2380,infra1=https://172.15.110.85:2380,infra2=https://172.15.110.86:2380,infra3=https://172.15.110.87:2380" # etcd 集群引导过程中的初始集群令牌 initial-cluster-token: 'etcd-cluster-k8s' # 初始集群状态(“新建”或“现有”) initial-cluster-state: 'new' # 拒绝会导致法定人数丢失的重新配置请求 strict-reconfig-check: false # 通过 HTTP 服务器启用运行时性能分析数据 enable-pprof: true # 有效值为 “开启”、“只读”、“关闭” proxy: 'off' # 端点将持续失败状态的时间(毫秒) proxy-failure-wait: 5000 # 端点刷新间隔的时间(毫秒) proxy-refresh-interval: 30000 # 拨号超时的时间(毫秒) proxy-dial-timeout: 1000 # 写入超时的时间(毫秒) proxy-write-timeout: 5000 # 读取超时的时间(毫秒) proxy-read-timeout: 0 # 客户端传输安全配置 client-transport-security: # 客户端服务器 TLS 证书文件的路径 cert-file: '/etc/etcd/etcd-cert/node-cert/infra0.pem' # 客户端服务器 TLS 密钥文件的路径 key-file: '/etc/etcd/etcd-cert/node-cert/infra0-key.pem' # 启用客户端证书验证 client-cert-auth: true # 客户端服务器 TLS 受信任 CA 证书文件的路径 trusted-ca-file: '/etc/etcd/etcd-cert/ca/ca.pem' # 使用生成的证书的客户端 TLS auto-tls: true # 对等服务器传输安全配置 peer-transport-security: # 对等服务器 TLS 证书文件的路径 cert-file: '/etc/etcd/etcd-cert/node-cert/infra0.pem' # 对等服务器 TLS 密钥文件的路径 key-file: '/etc/etcd/etcd-cert/node-cert/infra0-key.pem' # 启用对等客户端证书验证 client-cert-auth: true # 对等服务器 TLS 受信任的 CA 证书文件的路径 trusted-ca-file: '/etc/etcd/etcd-cert/ca/ca.pem' # 使用生成的证书的对等 TLS auto-tls: true # 自签名证书的有效期,单位为年 self-signed-cert-validity: 1 # 为 etcd 启用调试级别的日志记录 log-level: debug # 指定“stdout”或“stderr”可跳过 journald 日志记录,即使在 systemd 下运行也是如此。 log-outputs: [stderr] # 强制创建一个新的单成员集群 force-new-cluster: false # 自动压缩模式 auto-compaction-mode: periodic # 自动压缩保留期 auto-compaction-retention: "1" # 将 etcd 限制在一组特定的 TLS 加密套件中 #cipher-suites: [ # TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, # TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 #] # 将 etcd 限制在特定的 TLS 协议版本 #tls-min-version: 'TLS1.2' #tls-max-version: 'TLS1.3'
上面的配置文件用户主要需要关注的是:
-
name
-
data-dir
-
wal-dir
-
listen-peer-urls
-
listen-client-urls
-
initial-advertise-peer-urls
-
advertise-client-urls
-
initial-cluster
-
client-transport-security.cert-file
-
client-transport-security.key-file
-
client-transport-security.trusted-ca-file
-
peer-transport-security.cert-file
-
peer-transport-security.key-file
-
peer-transport-security.trusted-ca-file
其他节点与上面节点不同,需要修改的内容为:
-
name: infra0:infra0改成对应的节点名 -
listen-peer-urls: https://172.15.110.84:2380:172.15.110.84 改成对应机器的IP或者域名 -
advertise-client-urls: https://172.15.110.84:2379:172.15.110.84 改成对应机器的IP或者域名 -
cert-file: '/etc/etcd/etcd-cert/node-cert/infra0.pem':节点公钥修改成自己对应节点的公钥 -
key-file: '/etc/etcd/etcd-cert/node-cert/infra0-key.pem':节点私钥修改成自己对应节点的私钥
配置systemd
[Unit] Description=etcd service Documentation=https://coreos.com/etcd/docs/latest/ After=network.target [Service] Type=notify ExecStart=/usr/local/bin/etcd --config-file=/etc/etcd/etcd.conf Restart=on-failure RestartSec=10 LimitNOFILE=65536 [Install] WantedBy=multi-user.target Alias=etcd3.service
配置完成以后重载:
$ systemctl daemon-reload $ systemctl start etcd
验证
$ export ETCDCTL_API=3 \
HOST_1=172.15.110.84 \
HOST_2=172.15.110.85 \
HOST_3=172.15.110.86 \
HOST_4=172.15.110.87 \
ENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379,$HOST_4:2379
$ etcdctl --endpoints=$ENDPOINTS \
--cacert="/etc/etcd/etcd-cert/ca/ca.pem" \
--cert="/etc/etcd/etcd-cert/node-cert/client.pem" \
--key="/etc/etcd/etcd-cert/node-cert/client-key.pem" \
member list --write-out=table
$ etcdctl --endpoints=$ENDPOINTS \
--cacert="/etc/etcd/etcd-cert/ca/ca.pem" \
--cert="/etc/etcd/etcd-cert/node-cert/client.pem" \
--key="/etc/etcd/etcd-cert/node-cert/client-key.pem" \
endpoint status --write-out=table
+--------------------+------------------+-------------+---------+----------------+-------------------+---------------------+--------------------+-------------------------------------+---------------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS | +--------------------+------------------+-------------+---------+----------------+-------------------+---------------------+--------------------+-------------------------------------+---------------+ | 172.15.110.84:2379 | 667eeb25771855b7 | 3.5.11 | 20 kB | false | false | 3 | 21 | 21 | | | 172.15.110.85:2379 | 2b8e9ab68dcdd2d5 | 3.5.11 | 20 kB | true | false | 3 | 21 | 21 | | | 172.15.110.86:2379 | b7487f18e8d35925 | 3.5.11 | 20 kB | false | false | 3 | 21 | 21 | | | 172.15.110.87:2379 | 29a6b7b89a53ff4 | 3.5.11 | 20 kB | false | false | 3 | 21 | 21 | | +--------------------+------------------+-------------+---------+----------------+-------------------+---------------------+--------------------+-------------------------------------+---------------+
浙公网安备 33010602011771号