1. etcd 简介
coreos 开发的分布式服务系统,内部采用 raft 协议作为一致性算法。作为服务发现系统,有以下的特点:
- 简单:安装配置简单,而且提供了 HTTP API 进行交互,使用也很简单
- 安全:支持 SSL 证书验证
- 快速:根据官方提供的 benchmark 数据,单实例支持每秒 2k+ 读操作
- 可靠:采用 raft 算法,实现分布式系统数据的可用性和一致性
在这篇文章编写的时候,etcd 已经发布了 3.4.13 版本,被被用在 CoreOS、kubernetes、Cloud Foundry 等项目中。
etcd 目前默认使用 2379
端口提供 HTTP API 服务,2380
端口和 peer 通信(这两个端口已经被 IANA 官方预留给 etcd);在之前的版本中,可能会分别使用 4001
和 7001
,在使用的过程中需要注意这个区别。
虽然 etcd 也支持单点部署,但是在生产环境中推荐集群方式部署,一般 etcd 节点数会选择 3、5、7。etcd 会保证所有的节点都会保存数据,并保证数据的一致性和正确性。
2. etcd 主要功能
基本的 key-value 存储
监听机制
key 的过期及续约机制,用于监控和服务发现
原子 CAS 和 CAD,用于分布式锁和 leader 选举
3. etcd 环境准备
操作系统 | ip |
CentOS7.x-86_x64 | 192.268.248.202 |
CentOS7.x-86_x64 | 192.268.248.220 |
CentOS7.x-86_x64 | 192.268.248.224 |
3. etcd 部署
3.1 安装必要的软件cfssl(仅192.268.248.202安装即可)
首先下载安装包
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*
重命名
for x in cfssl*; do mv $x ${x%*_linux-amd64}; done
移动文件到目录 (/usr/bin)
mv cfssl* /usr/bin
3.2 配置 CA 并创建 TLS 证书
我们将使用 CloudFlare's PKI 工具 cfssl 来配置 PKI Infrastructure,然后使用它去创建 Certificate Authority(CA), 并为 etcd创建 TLS 证书。
创建目录
mkdir /opt/etcd/{bin,cfg,ssl} -p
cd /opt/etcd/ssl/
etcd ca配置
cat << EOF | tee ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"etcd": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
etcd ca证书
cat << EOF | tee ca-csr.json
{
"CN": "etcd CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
EOF
生成 CA 凭证和私钥:
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
结果将生成以下两个文件:
ca-key.pem ca.pem
etcd server证书
cat << EOF | tee server-csr.json
{
"CN": "etcd",
"hosts": [
"192.168.248.202",
"192.168.248.220",
"192.168.248.224"
],
"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=etcd server-csr.json | cfssljson -bare server
结果将生成以下两个文件:
server-key.pem server.pem
cfssl安装参考:
3.3 etcd安装
下载并解压缩
ETCD_VER=v3.4.13
# choose either URL
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}
curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /opt/etcd-${ETCD_VER}-linux-amd64.tar.gz
cd /opt && tar -zxvf etcd-v3.4.13-linux-amd64.tar.gz && cd etcd-v3.4.13-linux-amd64 && cp etcd etcdctl /opt/etcd/bin/
配置etcd主文件
vim /opt/etcd/cfg/etcd.conf
#[Member]
ETCD_NAME="etcd01"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.248.202:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.248.202:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.248.202:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.248.202:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.248.202:2380,etcd02=https://192.168.248.220:2380,etcd03=https://192.168.248.224:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_ENABLE_V2="true"
#[Security]
ETCD_CERT_FILE="/opt/etcd/ssl/server.pem"
ETCD_KEY_FILE="/opt/etcd/ssl/server-key.pem"
ETCD_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_PEER_CERT_FILE="/opt/etcd/ssl/server.pem"
ETCD_PEER_KEY_FILE="/opt/etcd/ssl/server-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
注意:ETCD3.4版本ETCDCTL_API=3 etcdctl 和 etcd --enable-v2=false 成为了默认配置,如要使用v2版本,执行etcdctl时候需要设置ETCDCTL_API环境变量,例如:ETCDCTL_API=2 etcdctl,flannel操作etcd使用的是v2的API,而kubernetes操作etcd使用的v3的API,为了兼容flannel,将默认开启v2版本,故配置文件中设置 ETCD_ENABLE_V2="true"
配置etcd启动文件
vim /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=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
注意:ETCD3.4版本会自动读取环境变量的参数,所以EnvironmentFile文件中有的参数,不需要再次在ExecStart启动参数中添加,二选一,如同时配置,会触发以下类似报错“etcd: conflicting environment variable "ETCD_NAME" is shadowed by corresponding command-line flag (either unset environment variable or disable flag)”
分发并修改文件到集群另外两个节点(192.168.248.220、192.168.248.224)
scp -r /opt/etcd/ 192.168.248.220:/opt/
scp -r /opt/etcd/ 192.168.248.224:/opt/
scp /usr/lib/systemd/system/etcd.service 192.168.248.220:/usr/lib/systemd/system/etcd.service
scp /usr/lib/systemd/system/etcd.service 192.168.248.224:/usr/lib/systemd/system/etcd.service
192.168.248.220 /opt/etcd/cfg/etcd.conf
#[Member]
ETCD_NAME="etcd02"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.248.220:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.248.220:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.248.220:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.248.220:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.248.202:2380,etcd02=https://192.168.248.220:2380,etcd03=https://192.168.248.224:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_ENABLE_V2="true"
#[Security]
ETCD_CERT_FILE="/opt/etcd/ssl/server.pem"
ETCD_KEY_FILE="/opt/etcd/ssl/server-key.pem"
ETCD_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_PEER_CERT_FILE="/opt/etcd/ssl/server.pem"
ETCD_PEER_KEY_FILE="/opt/etcd/ssl/server-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
192.168.248.224 /opt/etcd/cfg/etcd.conf
#[Member]
ETCD_NAME="etcd03"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.248.224:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.248.224:2379,http://127.0.0.1:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.248.224:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.248.224:2379"
ETCD_INITIAL_CLUSTER="etcd01=https://192.168.248.202:2380,etcd02=https://192.168.248.220:2380,etcd03=https://192.168.248.224:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_ENABLE_V2="true"
#[Security]
ETCD_CERT_FILE="/opt/etcd/ssl/server.pem"
ETCD_KEY_FILE="/opt/etcd/ssl/server-key.pem"
ETCD_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_PEER_CERT_FILE="/opt/etcd/ssl/server.pem"
ETCD_PEER_KEY_FILE="/opt/etcd/ssl/server-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/opt/etcd/ssl/ca.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
启动
systemctl daemon-reload
systemctl enable etcd
systemctl restart etcd
3.4 etcd查看集群状态
/opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.248.202:2379,https://192.168.248.220:2379,https://192.168.248.224:2379" endpoint status --write-out=table
/opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.248.202:2379,https://192.168.248.220:2379,https://192.168.248.224:2379" endpoint health
/opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.248.202:2379,https://192.168.248.220:2379,https://192.168.248.224:2379" member list
etcd 3.4注意事项:
ETCD3.4版本ETCDCTL_API=3 etcdctl 和 etcd --enable-v2=false 成为了默认配置,如要使用v2版本,执行etcdctl时候需要设置ETCDCTL_API环境变量,例如:ETCDCTL_API=2 etcdctl
ETCD3.4版本会自动读取环境变量的参数,所以EnvironmentFile文件中有的参数,不需要再次在ExecStart启动参数中添加,二选一,如同时配置,会触发以下类似报错“etcd: conflicting environment variable “ETCD_NAME” is shadowed by corresponding command-line flag (either unset environment variable or disable flag)”
flannel操作etcd使用的是v2的API,而kubernetes操作etcd使用的v3的API
注意:flannel操作etcd使用的是v2的API,而kubernetes操作etcd使用的v3的API,为了兼容flannel,将默认开启v2版本,故需要配置文件/opt/soft/etcd/etcd.conf中设置 ETCD_ENABLE_V2=“true”