【导读】新年快乐!本文介绍了etcd集群的工作原理和高可用技术细节。

etcd 简介

coreos 开发的分布式服务系统etcd集群,内部采用 raft 协议作为一致性算法。作为服务发现系统,有以下的特点:

etcd 目前默认使用 2379 端口提供 HTTP API 服务,2380 端口和 peers(集群内其他节点)通信

虽然 etcd 也支持单点部署,但是在生产环境中推荐集群方式部署,一般 etcd 节点数会选择 3、5、7。etcd 会保证所有的节点都会保存数据,并保证数据的一致性和正确性。

工作原理

每个 etcd cluster 都是有若干个 member 组成的,每个 member 是一个独立运行的 etcd 实例,单台机器上可以运行多个 member。

在正常运行的状态下,集群中会有一个 leader,其余的 member 都是 followers。leader 向 followers 同步日志,保证数据在各个 member 都有副本。leader 还会定时向所有的 member 发送心跳报文,如果在规定的时间里 follower 没有收到心跳,就会重新进行选举。

客户端所有的请求都会先发送给 leader,leader 向所有的 followers 同步日志,等收到超过半数的确认后就把该日志存储到磁盘,并返回响应客户端。

每个 etcd 服务有三大主要部分组成:raft 实现、WAL 日志存储、数据的存储和索引。WAL 会在本地磁盘(就是之前提到的 –data-dir)上存储日志内容(wal file)和快照(snapshot)。

集群规划

nameIPHOSTNAME

etcd01

192.168.255.131

master1

etcd02

192.168.255.132

master2

etcd03

192.168.255.133

master3

安装

在安装和启动 etcd 服务的时候,各个节点需要知道集群中其他节点的信息(一般是 ip 和 port 信息)。根据你是否可以提前知道每个节点的 ip,有几种不同的启动方案:

一般生产环境都是使用静态配置etcd集群,我们这里也采用这种方法。并配置 SSL来保证通信安全。

1、安装cfssl

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64

chmod +x cfssl_linux-amd64 cfssljson_linux-amd64

mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson

2、创建ca证书,客户端,服务端,节点之间的证书

Etcd属于server ,etcdctl 属于client,二者之间通过http协议进行通信。

1) 创建目录

mkdir -p /etc/etcd/pki
cd /etc/etcd/pki
cfssl print-defaults config > ca-config.json
cfssl print-defaults csr > ca-csr.json

2) 创建ca证书

修改ca-config.json

server auth表示client可以用该ca对server提供的证书进行验证

client auth表示server可以用该ca对client提供的证书进行验证

{
    "signing": {
        "default": {
            "expiry""43800h"
        },
        "profiles": {
            "server": {
                "expiry""43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            },
            "client": {
                "expiry""43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            },
            "peer": {
                "expiry""43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}

创建证书签名请求ca-csr.json

{
    "CN""etcd",
    "key": {
        "algo""rsa",
        "size": 2048
    }
}

生成CA证书和私钥

# cfssl gencert -initca ca-csr.json | cfssljson -bare ca
# ls ca*
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem

3) 生成客户端证书

vim client.json

{
    "CN""client",
    "key": {
        "algo""ecdsa",
        "size": 256
    }
}

生成

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json  | cfssljson -bare client -
# ls ca*
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem client-key.pem client.pem

4) 生成server,peer证书

vim etcd.json

{
    "CN""etcd",
    "hosts": [
        "127.0.0.1",
        "192.168.255.131",
        "192.168.255.132",
        "192.168.255.133"
    ],
    "key": {
        "algo""ecdsa",
        "size": 256
    },
    "names": [
        {
            "C""CN",
            "L""SH",
            "ST""SH"
        }
    ]
}

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server etcd.json | cfssljson -bare server

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer etcd.json | cfssljson -bare peer

3、安装etcd二进制文件

wget https://github.com/coreos/etcd/releases/download/v3.1.5/etcd-v3.1.5-linux-amd64.tar.gz
tar -xvf etcd-v3.1.5-linux-amd64.tar.gz
mv etcd-v3.1.5-linux-amd64/etcd* /usr/local/bin

4、service配置文件

vim /usr/lib/systemd/system/etcd.service, 三台机器配置不一样,需要替换为相应的IP和name。

[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://github.com/coreos

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd
ExecStart=/usr/local/bin/etcd 
--data-dir=/var/lib/etcd 
--name=master1 
--cert-file=/etc/etcd/pki/server.pem 
--key-file=/etc/etcd/pki/server-key.pem 
--trusted-ca-file=/etc/etcd/pki/ca.pem 
--peer-cert-file=/etc/etcd/pki/peer.pem 
--peer-key-file=/etc/etcd/pki/peer-key.pem 
--peer-trusted-ca-file=/etc/etcd/pki/ca.pem 
--listen-peer-urls=https://192.168.255.131:2380 
--initial-advertise-peer-urls=https://192.168.255.131:2380 
--listen-client-urls=https://192.168.255.131:2379,http://127.0.0.1:2379 
--advertise-client-urls=https://192.168.255.131:2379 
--initial-cluster-token=etcd-cluster-0 
--initial-cluster=master1=https://192.168.255.131:2380,master2=https://192.168.255.132:2380,master3=https://192.168.255.133:2380 
--initial-cluster-state=new 
--heartbeat-interval=250 
--election-timeout=2000
Restart=on-failure
RestartSec=5
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

配置参数的含义

--name:方便理解的节点名称,默认为 default,在集群中应该保持唯一,可以使用 hostname
--data-dir:服务运行数据保存的路径,默认为 ${name}.etcd

--snapshot-count:指定有多少事务(transaction)被提交时,触发截取快照保存到磁盘
--heartbeat-interval:leader 多久发送一次心跳到 followers。默认值是 100ms
--eletion-timeout:重新投票的超时时间,如果 follow 在该时间间隔没有收到心跳包,会触发重新投票,默认为 1000 ms

--listen-peer-urls:和集群内其他节点通信的地址, http://ip:2380,如果有多个,使用逗号分隔。需要所有节点都能够访问,所以不要使用 localhost!
--listen-client-urls:节点与客户端通信的地址,比如 http://ip:2379,http://127.0.0.1:2379,客户端会连接到这里和 etcd 交互
--advertise-client-urls:对外通告的该节点客户端监听地址,http://ip:2379,这个值会通知集群中其他节点

--initial-advertise-peer-urls:节点与其他节点通信的地址,会通告给集群的其他成员。这个地址用来传输集群数据。因此这个地址必须是可以被集群中所有的成员访问http://ip:2380

--initial-cluster:集群中所有节点的信息,格式为 node1=http://ip1:2380,node2=http://ip2:2380,…。注意:这里的 node1 是节点的 --name 指定的名字;后面的 ip1:2380 是 --initial-advertise-peer-urls 指定的值
--initial-cluster-state:新建集群的时候,这个值为 new;假如已经存在的集群,这个值为 existing
--initial-cluster-token:创建集群的 token,这个值每个集群保持唯一。这样的话,如果你要重新创建集群,即使配置和之前一样,也会再次生成新的集群和节点 uuid;否则会导致多个集群之间的冲突,造成未知的错误

所有以--initial 开头的配置都是在 bootstrap(引导) 集群的时候才会用到,后续节点重启时会被忽略。

5、创建存放etcd数据的目录,启动 etcd

mkdir /var/lib/etcd

systemctl daemon-reload && systemctl enable etcd && systemctl start etcd && systemctl status etcd

6、验证是否成功

在任意一台机器(无论是不是集群节点,前提是需要有etcdctl工具和ca证书,server证书)上执行如下命令:

[root@master1] /etc/etcd/pki$ etcdctl --ca-file=/etc/etcd/pki/ca.pem --cert-file=/etc/etcd/pki/server.pem --key-file=/etc/etcd/pki/server-key.pem --endpoints=https://192.168.255.131:2379 cluster-health
2019-01-27 20:41:26.909601 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
2019-01-27 20:41:26.910165 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
member 5d7a44f5c39446c1 is healthy: got healthy result from https://192.168.255.132:2379
member e281e4e43dceb752 is healthy: got healthy result from https://192.168.255.133:2379
member ea5e4f12ed162d4b is healthy: got healthy result from https://192.168.255.131:2379
cluster is healthy

如果你没有指定证书,会报如下错误

client: etcd cluster is unavailable or misconfigured; error #0: x509: certificate signed by unknown authority

查看集群成员

[root@master1] /etc/etcd/pki$ etcdctl --ca-file=/etc/etcd/pki/ca.pem --cert-file=/etc/etcd/pki/server.pem --key-file=/etc/etcd/pki/server-key.pem --endpoints=https://192.168.255.131:2379 member list
2019-01-27 22:58:46.914338 I | warning: ignoring ServerName for user-provided CA for backwards compatibility is deprecated
5d7a44f5c39446c1: name=master2 peerURLs=https://192.168.255.132:2380 clientURLs=https://192.168.255.132:2379 isLeader=false
e281e4e43dceb752: name=master3 peerURLs=https://192.168.255.133:2380 clientURLs=https://192.168.255.133:2379 isLeader=false
ea5e4f12ed162d4b: name=master1 peerURLs=https://192.168.255.131:2380 clientURLs=https://192.168.255.131:2379 isLeader=true

etcd的使用

限时特惠:本站每日持续更新海量展厅资源,一年会员只需29.9元,全站资源免费下载
站长微信:zhanting688