etcd 简介
etcd:键值存储,具有zookeeper的功能,使用raft进行分布式协调,它相对于zookeeper来说,性能更好,可以支持持久watch,开放接口相对于zk来说多很多(zk只支持java和c接口),是coreos公司使用go语言编写。当前etcd有v1,v2,v3三个版本,v1接触的不多;v2使用http 1.1 的rest api进行通讯;v3使用gRPC进行通讯,也可以使用rest进行通讯 协议使用http 2.0。
github https://github.com/etcd-io/etcd/releases
officalwebsite https://coreos.com/etcd/
测试环境部署带有tls的etcd集群
环境设定
主机:
IP地址 | 系统版本 | etcd版本 |
---|---|---|
172.16.0.208 | centos7.2 | 3.3.12 |
172.16.0.191 | centos7.2 | 3.3.12 |
172.16.0.204 | centos7.2 | 3.3.12 |
一、使用源码部署
软件包:
etcd-v3.3.12-linux-amd64.tar.gz github地址
使用ansible批量部署etcd
ansible 'test_k8s_etcd' -u root -m copy -a 'src=etcd-v3.3.12-linux-amd64.tar.gz dest=/root/etcd-v3.3.12-linux-amd64.tar.gz'
ansible 'test_k8s_etcd' -u root -m shell -a 'mkdir -p /app/ 2>/dev/null && tar -xf /root/etcd-v3.3.12-linux-amd64.tar.gz -c /app/ && mv /app/etcd-v3.3.12-linux-amd64 /app/etcd && mkdir -p /data/etcd_data 2>/dev/null'
配置etcd证书参数,(可参考官网连接)
生成自签证书
cfssl是ETCD官方推荐的CA生产工具,我使用这个工具来生成证书。
下载工具
cd /root/
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
mv cfssl_linux-amd64 /usr/bin/cfssl
mv cfssljson_linux-amd64 /usr/bin/cfssljson
chmod +x /usr/bin/{cfssl,cfssljson}
生成自签CA
mkdir -p /etc/pki/etcd
cd /etc/pki/etcd
#创建两个json文件,如下
vim ca-config.json
{
"signing": {
"default": {
"expiry": "100000h"
},
"profiles": {
"server": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "100000h"
},
"client": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "8760h"
}
}
}
}
vim ca-csr.json
{
"CN": "Etcd",
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "CN",
"L": "Beijing",
"O": "ETCD",
"OU": "K8S",
"ST": "Beijing"
}
]
}
#执行如下命令生成证书文件
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
生成三个文件:
ca-key.pem - CA 私钥key
ca.pem - CA证书
ca.csr - CA证书签名请求文件
在安装中出现的问题 Segmentation fault
[root@k8s01 ssl]# cfssl print-defaults config > config.json
Segmentation fault
可能是写载文件出现了问题,重新下载相应的文件。
生成服务器间通信证书等文件
#创建如下json文件
vim server-csr.json
{
"CN": "etcd-server",
"hosts": [
"localhost",
"0.0.0.0",
"127.0.0.1",
"172.16.0.208",
"172.16.0.191",
"172.16.0.204",
"etcd1.lianhang.jetair",
"etcd2.lianhang.jetair",
"etcd3.lianhang.jetair"
],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "CN",
"L": "Beijing",
"O": "ETCD",
"OU": "k8s",
"ST": "Beijing"
}
]
}
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server-csr.json | cfssljson -bare server
生成三个文件:server.pem, server-key.pem和server.csr
生成客户端访问证书文件
vim client-csr.json
{
"CN": "etcd-client",
"hosts": [
"localhost",
"127.0.0.1",
"kmaster1.lianhang.jetair",
"kmaster2.lianhang.jetair",
"kmaster3.lianhang.jetair",
"etcd1.lianhang.jetair",
"etcd2.lianhang.jetair",
"etcd3.lianhang.jetair"
],
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "ETCD",
"OU": "k8s"
}
]
}
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client-csr.json | cfssljson -bare client
生成三个文件:client.pem, client-key.pem和client.csr
将client.pem, client-key.pem,client.csr,server.pem, server-key.pem,server.csr,ca-key.pem,ca.pem,ca.csr这些生成的文件拷贝到3个etcd节点的“/data/etcd_ssl/”目录下
scp client* server* ca* root@172.16.0.208:data/etcd_ssl/
scp client* server* ca* root@172.16.0.191:data/etcd_ssl/
scp client* server* ca* root@172.16.0.204:data/etcd_ssl/
配置etcd启动参数
静态启动模式(测试环境使用的这种方式部署的)
因为etcd还不是特别复杂,所以不太喜欢用配置文件和借助systemd来启动etcd,直接用脚本
208上配置:
vim /app/etcd/start.sh
nohup /app/etcd/etcd \
--name etcd1 \
--data-dir /data/etcd_data/data \
--advertise-client-urls https://172.16.0.208:2379,https://127.0.0.1:4001 \
--listen-client-urls https://172.16.0.208:2379,https://127.0.0.1:4001 \
--listen-peer-urls https://172.16.0.208:2380 \
--cert-file /data/etcd_ssl/server.pem \
--key-file /data/etcd_sslserver-key.pem \
--trusted-ca-file /data/etcd_ssl/ca.pem \
--peer-cert-file /data/etcd_ssl/server.pem \
--peer-key-file /data/etcd_ssl/server-key.pem \
--peer-trusted-ca-file /data/etcd_ssl/ca.pem \
--initial-advertise-peer-urls https://172.16.0.208:2380 \
--initial-cluster etcd1=https://172.16.0.208:2380,etcd2=https://172.16.0.191:2380,etcd3=https://172.16.0.204:2380 \
--initial-cluster-token etcd_k8s \
--initial-cluster-state new &
191上的配置:
vim /app/etcd/start.sh
nohup /app/etcd/etcd \
--name etcd2 \
--data-dir /data/etcd_data/data \
--advertise-client-urls https://172.16.0.191:2379,https://127.0.0.1:4001 \
--listen-client-urls https://172.16.0.191:2379,https://127.0.0.1:4001 \
--listen-peer-urls https://172.16.0.191:2380 \
--cert-file /data/etcd_ssl/server.pem \
--key-file /data/etcd_ssl/server-key.pem \
--trusted-ca-file /data/etcd_ssl/ca.pem \
--peer-cert-file /data/etcd_ssl/server.pem \
--peer-key-file /data/etcd_ssl/server-key.pem \
--peer-trusted-ca-file /data/etcd_ssl/ca.pem \
--initial-advertise-peer-urls https://172.16.0.191:2380 \
--initial-cluster etcd1=https://172.16.0.208:2380,etcd2=https://172.16.0.191:2380,etcd3=https://172.16.0.204:2380 \
--initial-cluster-token etcd_k8s \
--initial-cluster-state new &
208上的配置:
vim /app/etcd/start.sh
nohup /app/etcd/etcd \
--name etcd3 \
--data-dir /data/etcd_data/data \
--advertise-client-urls https://172.16.0.204:2379,https://127.0.0.1:4001 \
--listen-client-urls https://172.16.0.204:2379,https://127.0.0.1:4001 \
--listen-peer-urls https://172.16.0.204:2380 \
--cert-file /data/etcd_ssl/server.pem \
--key-file /data/etcd_ssl/server-key.pem \
--trusted-ca-file /data/etcd_ssl/ca.pem \
--peer-cert-file /data/etcd_ssl/server.pem \
--peer-key-file /data/etcd_ssl/server-key.pem \
--peer-trusted-ca-file /data/etcd_ssl/ca.pem \
--initial-advertise-peer-urls https://172.16.0.204:2380 \
--initial-cluster etcd1=https://172.16.0.208:2380,etcd2=https://172.16.0.191:2380,etcd3=https://172.16.0.204:2380 \
--initial-cluster-token etcd_k8s \
--initial-cluster-state new &
启动etcd
sh /app/etcd/start.sh
使用etcd自动发现模式配置集群
很多场景,我们无法预支急群众各个成员的地址,比如我们通过云提供商动态的创建节点或者使用DHCP网络时是不知道集群成员地址的。这时候就不能使用上面的静态配置方式了,而是需要所谓的“服务自发现”。简单说,etcd服务自发现即为使用一个现有的etcd集群来启动另一个新的etcd集群。富足自发现包含两种模式
- etcd自发现模式
- dns自发现模式
下面将逐一说明:
etcd自发现模式
如果已经有了一个etcd集群,那么我们可以执行如下命令设定集群的大小,假设要将集群大小设置为3,则相关代码如下:
curl -X PUT https://myetcd_cluster/v2/keys/discovery/xxxxxxxxxxdirectory/_config/size -d value=3
自动发现的URL则为“https://myetcd_cluster/v2/keys/discovery/xxxxxxxxxxdirectory” ,现在我们需要做的只是在之前静态配置中删除“—initial-advertise-peer-urls”和”—initial-cluster-state new“ 并添加 “—discovery https://myetcd_cluster/v2/keys/discovery/xxxxxxxxxxdirectory/ “ 项,即可
注意:集群设置配置的3,当有超过3个集群的节点前去注册,只有前三个可以加入集群。
官方提供了一个免费的etcd自发现服务,我们可以通过如下操作来使用官方提供的自发现服务,就不需要再去额外搭建一个etcd集群了。
curl https://discovery.etcd.io/new?size=3
#返回值
https://discovery.etcd.io/xxxxxxxxdirectory
dns自发现模式
DNS的SRV记录可以用于服务自发现,因此etcd还支持使用DNS SRV记录进行启动。我们要在DNS服务器上进行相应的配置才能够实现etcd给予DNS的自发现模式。
配置dns添加SRV记录如下
dig +noall _answer SRV _etcd-server._tcp.lianhang.jetair
_answer SRV _etcd-server._tcp.lianhang.jetair. 300 IN SRV 0 0 2380 etcd1.lianhang.jetair.
_answer SRV _etcd-server._tcp.lianhang.jetair. 300 IN SRV 0 0 2380 etcd2.lianhang.jetair.
_answer SRV _etcd-server._tcp.lianhang.jetair. 300 IN SRV 0 0 2380 etcd3.lianhang.jetair.
_etcd-server:service,所需服务器的符号。
_tcp:proto,所需服务的传输协议,通常是 TCP 或 UDP。
lianhang.jetair:name,此记录有效的域名,以 . 结束。
300:TTL,标准 DNS TTL 字段。
IN:class,标准 DNS class 字段,如:IN。
第一个0:priority,目标主机的优先级,值低的优先。
第二个0:weight,具有相同优先级的记录的相对权重,值高的优先。
2380:port,该服务的 TCP 或 UDP 端口。
etcd3.lianhang.jetair:target,提供服务的机器的规范主机名,以 . 结束。
配置etcd 使用dns自发现启动参数
现在我们需要做的是在之前静态配置中删除“—initial-advertise-peer-urls”并添加 “—discovery-srv lianhang.jetair”,并将所有ip地址换成域名
启动参数有关tls选项可参见官方文档:https://coreos.com/etcd/docs/latest/op-guide/security.html
配置kubenetes连接etcd集群
复制CA文件到/etc/kubernetes/ssl
/etc/kubernetes/config添加配置:
–etcd-cafile=/etc/kubernetes/ssl/ca.pem
–etcd-certfile=/etc/kubernetes/ssl/client.pem
–etcd-keyfile=/etc/kubernetes/ssl/client-key.pem
或者初始化集群时直接使用以上3个证书文件
部署遇到的坑
1.启动参数不能使用 0.0.0.0 作为本地监听的地址,会导致集群通信无法加入到同一个集群,然后一直报rafthttp: request sent was ignored (cluster ID mismatch
错误
验证集群是否OK
cd /app/etcd
./etcdctl --cert-file=/data/etcd_ssl/client.pem --key-file=/data/etcd_ssl/client-key.pem --ca-file=/data/etcd_ssl/ca.pem --endpoints=https://172.16.0.208:2379 cluster-health
member 887e1fb7af1d37e6 is healthy: got healthy result from https://127.0.0.1:4001
member d9023dd59de6c46e is healthy: got healthy result from https://127.0.0.1:4001
member f8fb1571b560f556 is healthy: got healthy result from https://127.0.0.1:4001
cluster is healthy
二、使用yum安装etcd
- 使用
yum install etcd
安装etcd(etcd版本要>=3.0.0) - 创建etcd需要的目录
mkdir -p /data/etcd_data
mkdir -p /data/etcd_ssl
mkdit -p /etc/etcd
- 生成自签名证书,方式同源码安装的生成方式
- 在3个etcd节点上创建etcd的配置文件并存放在”/etc/etcd/etcd.conf”内
节点1配置文件(注意修改ip地址,其他两个配置问价你也需要修改)
节点2配置文件ETCD_DATA_DIR="/data/etcd_data"
ETCD_LISTEN_PEER_URLS="https://172.16.0.185:2380"
ETCD_LISTEN_CLIENT_URLS="https://172.16.0.185:2379"
ETCD_MAX_SNAPSHOTS="5"
ETCD_MAX_WALS="5"
ETCD_NAME="etcd1"
ETCD_SNAPSHOT_COUNT="100000"
ETCD_HEARTBEAT_INTERVAL="100"
ETCD_ELECTION_TIMEOUT="1000"
ETCD_QUOTA_BACKEND_BYTES="0"
ETCD_MAX_REQUEST_BYTES="1572864"
ETCD_GRPC_KEEPALIVE_MIN_TIME="5s"
ETCD_GRPC_KEEPALIVE_INTERVAL="2h0m0s"
ETCD_GRPC_KEEPALIVE_TIMEOUT="20s"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.16.0.185:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://172.16.0.185:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://172.16.0.185:2380,etcd2=https://172.16.0.186:2380,etcd3=https://172.16.0.187:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_CERT_FILE="/data/etcd_ssl/server.pem"
ETCD_KEY_FILE="/data/etcd_ssl/server-key.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_TRUSTED_CA_FILE="/data/etcd_ssl/ca.pem"
ETCD_AUTO_TLS="true"
ETCD_PEER_CERT_FILE="/data/etcd_ssl/server.pem"
ETCD_PEER_KEY_FILE="/data/etcd_ssl/server-key.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_PEER_TRUSTED_CA_FILE="/data/etcd_ssl/ca.pem"
ETCD_PEER_AUTO_TLS="true"
节点3配置文件ETCD_DATA_DIR="/data/etcd_data"
ETCD_LISTEN_PEER_URLS="https://172.16.0.186:2380"
ETCD_LISTEN_CLIENT_URLS="https://172.16.0.186:2379"
ETCD_MAX_SNAPSHOTS="5"
ETCD_MAX_WALS="5"
ETCD_NAME="etcd2"
ETCD_SNAPSHOT_COUNT="100000"
ETCD_HEARTBEAT_INTERVAL="100"
ETCD_ELECTION_TIMEOUT="1000"
ETCD_QUOTA_BACKEND_BYTES="0"
ETCD_MAX_REQUEST_BYTES="1572864"
ETCD_GRPC_KEEPALIVE_MIN_TIME="5s"
ETCD_GRPC_KEEPALIVE_INTERVAL="2h0m0s"
ETCD_GRPC_KEEPALIVE_TIMEOUT="20s"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.16.0.186:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://172.16.0.186:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://172.16.0.185:2380,etcd2=https://172.16.0.186:2380,etcd3=https://172.16.0.187:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_CERT_FILE="/data/etcd_ssl/server.pem"
ETCD_KEY_FILE="/data/etcd_ssl/server-key.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_TRUSTED_CA_FILE="/data/etcd_ssl/ca.pem"
ETCD_AUTO_TLS="true"
ETCD_PEER_CERT_FILE="/data/etcd_ssl/server.pem"
ETCD_PEER_KEY_FILE="/data/etcd_ssl/server-key.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_PEER_TRUSTED_CA_FILE="/data/etcd_ssl/ca.pem"
ETCD_PEER_AUTO_TLS="true"
ETCD_DATA_DIR="/data/etcd_data"
ETCD_LISTEN_PEER_URLS="https://172.16.0.187:2380"
ETCD_LISTEN_CLIENT_URLS="https://172.16.0.187:2379"
ETCD_MAX_SNAPSHOTS="5"
ETCD_MAX_WALS="5"
ETCD_NAME="etcd3"
ETCD_SNAPSHOT_COUNT="100000"
ETCD_HEARTBEAT_INTERVAL="100"
ETCD_ELECTION_TIMEOUT="1000"
ETCD_QUOTA_BACKEND_BYTES="0"
ETCD_MAX_REQUEST_BYTES="1572864"
ETCD_GRPC_KEEPALIVE_MIN_TIME="5s"
ETCD_GRPC_KEEPALIVE_INTERVAL="2h0m0s"
ETCD_GRPC_KEEPALIVE_TIMEOUT="20s"
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.16.0.187:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://172.16.0.187:2379"
ETCD_INITIAL_CLUSTER="etcd1=https://172.16.0.185:2380,etcd2=https://172.16.0.186:2380,etcd3=https://172.16.0.187:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_CERT_FILE="/data/etcd_ssl/server.pem"
ETCD_KEY_FILE="/data/etcd_ssl/server-key.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_TRUSTED_CA_FILE="/data/etcd_ssl/ca.pem"
ETCD_AUTO_TLS="true"
ETCD_PEER_CERT_FILE="/data/etcd_ssl/server.pem"
ETCD_PEER_KEY_FILE="/data/etcd_ssl/server-key.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
ETCD_PEER_TRUSTED_CA_FILE="/data/etcd_ssl/ca.pem"
ETCD_PEER_AUTO_TLS="true"
- 启动etcd
systemctl start etcd