ETCD(基于TLS部署)外部集群
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
利用CFSSL生成需要的证书
创建CA签名配置文件
cat > ca-config.json << EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
#给服务端用的
"etcdserver": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
},
#给etcdctl查询信息用的
"etcdclient": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
#给member用的
"etcdpeer": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
ca-config.json:可以定义多个profiles,分别指定不同的过期时间、使用场景等参数。后续在签名证书时使用定义的某个profile
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcdserver server-csr.json | cfssljson -bare server
signing:表示该证书可用于签名其它证书
key encipherment:密钥加密
server auth:表示client可以用该CA对server提供的证书进行验证
client auth:表示server可以用该CA对client提供的证书进行验证
创建签名请求文件
cat > ca-csr.json <<EOF
{
"CN": "Etcd CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
EOF
CN(Common Name):kubernetes的apiserver从证书中提取该字段作为请求的用户名 (User Name),浏览器使用该字段验证网站是否合法。对于 SSL 证书,一般为网站域名,而对于代码签名证书则为申请单位名称,而对于客户端证书则为证书申请者的姓名。
O(Organization):kubernetes的apiserver从证书中提取该字段作为请求用户所属的组 (Group)。对于客户端单位证书则为证书申请者所在单位名称。
C(Country):所在国家
L(Locality):所在城市
ST(State/Provice):所在省(没记错应该有叫S的,可选)这东西都是国外的所以国外把省好像叫州个人猜测
单向认证双向认证
SSL/TLS单向认证,双向认证?
单向认证指的是只有单一一侧对象校验对端的证书合法性。
多数都是client来校验服务端的合法性。那么client需要一个ca.crt,服务器需要server.crt,server.key
双向认证指的是相互校验,你看我我也看你(互相伤害)。
server 需要 server.key 、server.crt 、ca.crt(CA证书)
client 需要 client.key 、client.crt 、ca.crt
生成根证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
会生成多出几个文件:
ca-key.pem
ca.csr
ca.pem
查看证书的信息的话用openssl吧,cfssl的信息太简陋了。命令如下
cfssl certinfo -cert=ca.pem
openssl x509 -noout -text -in ca.pem
创建服务端的签名请求配置文件(提供给客户端进行校验)
cat > server-csr.json << EOF
{
"CN": "etcd server",
"hosts": [
"172.21.130.169",
"172.21.130.168",
"172.28.17.85"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
生成server证书与私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcdserver server-csr.json | cfssljson -bare server
可以在生成一个member-csr.json给etcd成员之间使用,client就给etcdctl使用也可以(server-csr.json copy member-csr.json修改一下名字即可)
生成etcdctl客户端使用的证书
配置签名请求文件
cat > client.json <<EOF
{
"CN": "etcdclient",
"hosts": [
"172.21.130.169",
"172.21.130.168",
"172.28.17.85"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcdclient client.json | cfssljson -bare client
开始部署ETCD服务
1、规划的etcd应用家目录在/var/local/etcd下
ETCD所有文件都在/var/local/etcd/下。分别是ssl(证书)、cfg(配置文件)、data(数据文件)数据可以在细分为wal与data
2、所以每个节点创建ETCD家目录
mkdir /var/local/etcd
3、在etcd1上把所有文件都cp过去
scp /usr/lib/systemd/system/etcd.service root@172.21.130.168:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service root@172.28.17.85:/usr/lib/systemd/system/
scp -r /var/local/etcd/ root@172.21.130.168:/var/local/etcd/
scp -r /var/local/etcd/ root@172.28.17.85:/var/local/etcd/
scp -r /usr/local/bin/{etcd,etcdctl} root@172.21.130.168:/usr/local/bin
scp -r /usr/local/bin/{etcd,etcdctl} root@172.28.17.85:/usr/local/bin
4、修改每个节点配置文件
#节点1 [root@master etcd_ssl]# cat /var/local/etcd/cfg/etcd.conf #[Member]
#冲突就失败,而且报错不明显,默认是default也就是http://localhost:2380 ETCD_NAME="etcd-1" ETCD_DATA_DIR="/var/local/etcd/data/default.etcd"
#监听集群内部其他member发过来的请求通过这个设置的ip:port
ETCD_LISTEN_PEER_URLS="https://172.21.130.169:2380"
#监听客户端发过来的请求通过这个设置的ip:port
ETCD_LISTEN_CLIENT_URLS="https://172.21.130.169:2379" #[Clustering]
#通过这个参数告诉member如果联系我请通过这个ip:port
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.21.130.169:2380"
#通过这个参数告诉客户端如果联系我请通过这个ip:port
ETCD_ADVERTISE_CLIENT_URLS="https://172.21.130.169:2379"
#这个是静态的配置方式还有动态发现的不过依赖于已有etcd集群才可以,启动会通过这个参数配置找对应的机器
ETCD_INITIAL_CLUSTER="etcd-1=https://172.21.130.169:2380,etcd-2=https://172.21.130.168:2380,etcd-3=https://172.28.17.85:2380"
ETCD_INITIAL_CLUSTER_TOKEN="my-etcd-cluster"
#有两个值new和existing。如果填为existing,则该member启动时会尝试与其他member交互。
集群初次建立时,要填为new,通过测试发现最后一个节点填existing也正常(因为属于后加入,不能同时启动进程,existing要落后前两个节点一丢丢时间启动),其他节点不能填为existing。
集群运行过程中,一个member故障后恢复时填为existing,如果是new的话需要集群没有业务数据。
概括如下:
new适用于无数据集群加入(就是所有节点都没有业务数据)
existing适用于有数据的集群加入(有两个节点有数据,新节点没有数据)
ETCD_INITIAL_CLUSTER_STATE="new"
#[security]
ETCD_CERT_FILE="/var/local/etcd/ssl/server.pem"
ETCD_KEY_FILE="/var/local/etcd/ssl/server-key.pem"
#受信任的CA证书
ETCD_TRUSTED_CA_FILE="/var/local/etcd/ssl/ca.pem"
ETCD_PEER_CERT_FILE="/var/local/etcd/ssl/member.pem"
ETCD_PEER_KEY_FILE="/var/local/etcd/ssl/member-key.pem"
#受信任的CA证书
ETCD_PEER_TRUSTED_CA_FILE="/var/local/etcd/ssl/ca.pem"
#将为受信任CA签名的证书的客户端,检查所有的传入的HTTPS请求,不能提供有效客户端证书的请求会失败
ETCD_CLIENT_CERT_AUTH="true"
#将为受信任CA签名的证书的客户端,检查所有传入的对等请求
ETCD_PEER_CLIENT_CERT_AUTH="true"
#为客户端的TLS链接,使用自动生成的自签名证书
ETCD_AUTO_TLS="true"
#为对等体之间的TLS链接使用自动生成的自签名证书
ETCD_PEER_AUTO_TLS="true"
#节点2
#[Member]
ETCD_NAME="etcd-2"
ETCD_DATA_DIR="/var/local/etcd/data/default.etcd"
ETCD_LISTEN_PEER_URLS="https://172.21.130.168:2380"
ETCD_LISTEN_CLIENT_URLS="https://172.21.130.168:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.21.130.168:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://172.21.130.168:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://172.21.130.169:2380,etcd-2=https://172.21.130.168:2380,etcd-3=https://172.28.17.85:2380"
ETCD_INITIAL_CLUSTER_TOKEN="my-etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
#[security]
ETCD_CERT_FILE="/var/local/etcd/ssl/server.pem"
ETCD_KEY_FILE="/var/local/etcd/ssl/server-key.pem"
ETCD_TRUSTED_CA_FILE="/var/local/etcd/ssl/ca.pem"
ETCD_PEER_CERT_FILE="/var/local/etcd/ssl/member.pem"
ETCD_PEER_KEY_FILE="/var/local/etcd/ssl/member-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/var/local/etcd/ssl/ca.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_AUTO_TLS="true"
ETCD_PEER_AUTO_TLS="true"
#节点3
#[Member]
ETCD_NAME="etcd-3"
ETCD_DATA_DIR="/var/local/etcd/data/default.etcd"
ETCD_LISTEN_PEER_URLS="https://172.28.17.85:2380"
ETCD_LISTEN_CLIENT_URLS="https://172.28.17.85:2379,http://172.28.17.85:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.28.17.85:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://172.28.17.85:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://172.21.130.169:2380,etcd-2=https://172.21.130.168:2380,etcd-3=https://172.28.17.85:2380"
ETCD_INITIAL_CLUSTER_TOKEN="my-etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
#[security]
ETCD_CERT_FILE="/var/local/etcd/ssl/server.pem"
ETCD_KEY_FILE="/var/local/etcd/ssl/server-key.pem"
ETCD_TRUSTED_CA_FILE="/var/local/etcd/ssl/ca.pem"
ETCD_PEER_CERT_FILE="/var/local/etcd/ssl/member.pem"
ETCD_PEER_KEY_FILE="/var/local/etcd/ssl/member-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/var/local/etcd/ssl/ca.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_AUTO_TLS="true"
ETCD_PEER_AUTO_TLS="true"
5、启动
[root@master etcd_ssl]# cat /usr/lib/systemd/system/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/var/local/etcd/cfg/etcd.conf
ExecStart=/usr/local/bin/etcd --logger=zap
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
启动
systemctl start etcd
6、检查集群状态
ETCDCTL_API=3 /var/local/etcd/bin/etcdctl --cacert=/var/local/etcd/ssl/ca.pem --cert=/var/local/etcd/ssl/client.pem --key=/var/local/etcd/ssl/client-key.pem --endpoints="https://172.21.130.169:2379,https://172.21.130.168:2379,https://172.28.17.85:2379" endpoint health --write-out=table
如果嫌太长麻烦,把相关证书设置成环境变量即可。而且endpoints可以写一个,目的实际就是想写的那个节点发送查询请求。
导致下面的原因:
conflicting environment variable "ETCD_CERT_FILE" is shadowed by corresponding command-line flag (either unset environment variable or disable flag)
下面的参数如果在配置文件中配置了,就不要在unit启动文件中再次配置了,会因为冲突导致启动失败因为会自动加载配置文件中的参数,然后在加载下面的参数导致上面的结果
WorkingDirectory 这是个奇葩如果在unit中配置了一定要确保指定的目录存在,不存在会报错。日志没有相关明确点出该错误。
[Unit]
Description=Etcd Server
After=network.target
[Service]
Type=notify
WorkingDirectory=/var/local/etcd/
EnvironmentFile=/var/local/etcd/cfg/etcd.conf
ExecStart=/usr/local/bin/etcd \
--name=${ETCD_NAME} \
--data-dir=${ETCD_DATA_DIR} \
--listen-peer-urls=${ETCD_LISTEN_PEER_URLS} \
--listen-client-urls=${ETCD_LISTEN_CLIENT_URLS} \
--advertise-client-urls=${ETCD_ADVERTISE_CLIENT_URLS} \
--initial-advertise-peer-urls=${ETCD_INITIAL_ADVERTISE_PEER_URLS} \
--initial-cluster=${ETCD_INITIAL_CLUSTER} \
--initial-cluster-token=${ETCD_INITIAL_CLUSTER_TOKEN} \
--initial-cluster-state=${ETCD_INITIAL_CLUSTER_STATE} \
--cert-file=${ETCD_CERT_FILE} \
--key-file=${ETCD_KEY_FILE} \
--trusted-ca-file=${ETCD_TRUSTED_CA_FILE} \
--peer-cert-file=${ETCD_PEER_CERT_FILE} \
--peer-key-file=${ETCD_PEER_KEY_FILE} \
--peer-trusted-ca-file=${ETCD_PEER_TRUSTED_CA_FILE}
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
浙公网安备 33010602011771号