关于etcd的集群模式部署

284 阅读4分钟

本文已参与 \lceil新人创作礼\rfloor 活动,一起开启掘金创作之路

最近在看k8s相关内容,里面有用到一个数据库叫etcd,主要用来存储pod、service等服务的一些配置信息,今天尝试了etcd的一个集群模式部署,下面分享下。

1. 简述

etcd是coreos团队于2013年6月发起的开源项目。是一个高可用的分布式键值数据库,基于go语言实现。

2. 特点

  • 简单:支持REST风格的HTTP+JSON API

  • 安全:支持https方式的访问

  • 快速:支持并发每秒一千次的写操作

  • 可靠:支持分布式结构,基于Raft算法实现一致性

3. 集群部署

etcd支持两种模式来构建集群:静态配置、动态配置

3.1 静态配置

3.1.1 配置hosts


# vim /etc/hosts

192.168.60.100 node1

192.168.60.101 node2

192.168.60.102 node3

3.1.2 生成key


# wget <https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64>

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

# wget <https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64>

# chmod +x *

# 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

# vim generate_key.sh

#!/bin/bash

# cat ca-config.json

cat > ca-config.json <<EOF

{

  "signing": {

    "default": {

      "expiry": "87600h"

    },

    "profiles": {

      "www": {

         "expiry": "87600h",

         "usages": [

            "signing",

            "key encipherment",

            "server auth",

            "client auth"

        ]

      }

    }

  }

}

EOF

 

# cat ca-csr.json

cat > ca-csr.json <<EOF

{

    "CN": "etcd CA",

    "key": {

        "algo": "rsa",

        "size": 2048

    },

    "names": [

        {

            "C": "CN",

            "L": "WuXi",

            "ST": "WuXi"

        }

    ]

}

EOF

 

# cat server-csr.json

cat > server-csr.json <<EOF

{

    "CN": "etcd",

    "hosts": [

    "192.168.60.100",

    "192.168.60.101",

    "192.168.60.102"

    ],

    "key": {

        "algo": "rsa",

        "size": 2048

    },

    "names": [

        {

            "C": "CN",

            "L": "WuXi",

            "ST": "WuXi"

        }

    ]

}

EOF

# bash generate_key.sh

# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr. json | cfssljson -bare server

# ls *.pem

image.png

3.1.3 下载二进制etcd并生成配置文件


# mkdir -p /opt/etcd/{bin,cfg,ssl,data}

# cp *.pem /opt/etcd/ssl/

# tar -zxvf etcd-v3.4.0-linux-amd64.tar.gz

# cp etcd-v3.4.0-linux-amd64/etcd*  /opt/etcd/bin/

# vim  /opt/etcd/cfg/etcd.yml

# 3台机器 ETCD_NAME 名字不一样  本机IP不一样

name: etcd01

data-dir: /opt/etcd/data

initial-advertise-peer-urls: http://192.168.60.100:2380

listen-peer-urls: http://192.168.60.100:2380

listen-client-urls: http://192.168.60.100:2379,http://127.0.0.1:2379

advertise-client-urls: http://192.168.60.100:2379

initial-cluster-token: etcd-cluster-token

initial-cluster: etcd01=http://node1:2380,etcd02=http://node2:2380,etcd03=http://node3:2380

initial-cluster-state: new

cert-file: /opt/etcd/ssl/server.pem

key-file: /opt/etcd/ssl/server-key.pem

peer-cert-file: /opt/etcd/ssl/server.pem

peer-key-file: /opt/etcd/ssl/server-key.pem

trusted-ca-file: /opt/etcd/ssl/ca.pem

peer-trusted-ca-file: /opt/etcd/ssl/ca.pem

  参数说明:

name 节点名称

data-dir 数据目录

listen-peer-urls 集群通信监听地址

listen-client-urls 客户端访问监听地址

initial-advertise-peer-urls 集群通告地址

advertise-client-urls 客户端通告地址

initial-cluster 集群节点地址

initial-cluster-token 集群Token

initial-cluster-state 加入集群的当前状态,new是新集群,existing表示加入已有集群


# scp -r /opt/etcd root@node2:/opt/

# scp -r /opt/etcd root@node3:/opt/

### []()2.1.4 **配置成系统服务******

# 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

ExecStart=/opt/etcd/bin/etcd --config-file /opt/etcd/cfg/etcd.yml

Restart=on-failure

LimitNOFILE=65536

 

[Install]

WantedBy=multi-user.target

# scp etcd.service root@node2:/usr/lib/systemd/system/

# scp etcd.service root@node3:/usr/lib/systemd/system/

### []()2.1.5 **启动******

# systemctl daemon-reload

# systemctl enable etcd.service

# systemctl start etcd.service

注意:启动第一个member的时候,会等待其它member初始化完毕,处于watting状态,此时紧接着启动第二个就行了。initial-cluster-state的值在刚开始创建集群的时候应该为new,如果是长时间以后添加node,需要改为existing

 

然后可以在任一节点查看集群节点和状态:

# etcdctl member list

# ./etcdctl endpoint health

image.png

3.1.6 测试

在node1设置值

# etcdctl set /test/key "xxx"

在node2节点获取值:

# etcdctl get /test/key\

3.2 动态配置

3.2.1 使用公开的etcd发现服务

CoreOS提供了一个公开的etcd发现服务,地址:discovery.etcd.io

1、为集群申请一个独一无二的uuid

# curl discovery.etcd.io/new?size=3  //size=3是指集群中节点的个数

discovery.etcd.io/dda998739f7…

2、启动集群

节点1:


etcd --name node1 \

--initial-cluster-token cluster1 \

--initial-cluster-state new \

--listen-client-urls <http://192.168.60.100:2379,http://localhost:2379> \

--listen-peer-urls <http://192.168.60.100:2380> \

--advertise-client-urls <http://192.168.60.100:2379> \

--initial-advertise-peer-urls <http://192.168.60.100:2380> \

--discovery <https://discovery.etcd.io/dda998739f702db412b4929de580c6c9>

 

节点2:


etcd --name node2 \

--initial-cluster-token cluster1 \

--initial-cluster-state new \

--listen-client-urls <http://192.168.60.101:2379,http://localhost:2379> \

--listen-peer-urls <http://192.168.60.101:2380> \

--advertise-client-urls <http://192.168.60.101:2379> \

--initial-advertise-peer-urls <http://192.168.60.101:2380> \

--discovery <https://discovery.etcd.io/dda998739f702db412b4929de580c6c9>

 

节点3:


# etcd --name node3 \

--initial-cluster-token cluster1 \

--initial-cluster-state new \

--listen-client-urls <http://192.168.60.102:2379,http://localhost:2379> \

--listen-peer-urls <http://192.168.60.102:2380> \

--advertise-client-urls <http://192.168.60.102:2379> \

--initial-advertise-peer-urls <http://192.168.60.102:2380> \

--discovery <https://discovery.etcd.io/dda998739f702db412b4929de580c6c9>

3.2.2 通过域名发现自动注册

另外一种实现动态发现的机制是通过DNS域名,为每一个节点指定同一个子域的域名,然后通过域名发现来自动给注册。

1、为三个节点配置hosts


# vim /etc/hosts

n1.mycluster.com

n2.mycluster.com

n3.mycluster.com

2、启动三节点

启动参数中的集群节点列表信息替换为:--discovery-srv mycluster.com

# ./etcd --name node1 --initial-cluster-token cluster1 --initial-cluster-state new --listen-client-urls http://192.168.60.100:2379,http://localhost:2379 --listen-peer-urls http://192.168.60.100:2380 --advertise-client-urls http://192.168.60.100:2379 --initial-advertise-peer-urls http://192.168.60.100:2380 --discovery-srv mycluster.com


# ./etcd --name node2 --initial-cluster-token cluster1 --initial-cluster-state new --listen-client-urls http://192.168.60.101:2379,http://localhost:2379 --listen-peer-urls http://192.168.60.101:2380 --advertise-client-urls http://192.168.60.101:2379 --initial-advertise-peer-urls http://192.168.60.101:2380 --discovery-srv mycluster.com


# ./etcd --name node3 --initial-cluster-token cluster1 --initial-cluster-state new --listen-client-urls http://192.168.60.102:2379,http://localhost:2379 --listen-peer-urls http://192.168.60.102:2380 --advertise-client-urls http://192.168.60.102:2379 --initial-advertise-peer-urls http://192.168.60.102:2380 --discovery-srv mycluster.com

# ./etcdctl member list

4. 关于集群参数配置

4.1 时钟同步

对于分布式集群来说,各个节点上的同步时钟十分重要。etcd集群需要各个节点时钟差不超过1s,否则可能会导致raft协议异常。所以集群节点最好配置定时始时钟同步。


# yum install ntpdate

# ntpdate ntp1.aliyun.com

或者通过chrony服务来配置同步的时钟服务器

4.2 心跳时间间隔和选举时间间隔

选举时间间隔要大于心跳时间间隔,一般建议设置为心跳时间间隔的5倍以上,默认情况下心跳时间间隔为100ms,选举时间间隔为1s,这个配置在本地局域网环境下比较合适的。

指定心跳时间按间隔参数:-heartbeat-interval

指定选举时间间隔参数:-election-timeout

跨数据中心的集群配置可以配置为:

-heartbeat-interval=200  -election-timeout=2000

对于跨地域的网络(例如中美之间的数据中心RTT往往数百ms),还可以适当延长

4.3 snapshot频率

ectd会定期地将数据的修改存储为snapshot,默认情况下每10000次修改才会存储一个snapshot。可以适当将这个值调小一点,例如每2000个修改就做一次snapshot


# etcd -snapshot-count=2000

4.4 修改节点

无论是添加、删除还是迁移节点,都要一个一个地进行。步骤如下:

将节点从集群中移除----》等集群状态重新稳定----》添加新的节点

4.5 节点恢复

删除问题节点(etcdctl member rm [member])----》清空数据目录----》作为新节点加入集群

etcd提供了-strict-reconfig-check,确保当集群不稳定(例如启动节点数还不够达到quorum)的时候拒绝对配置状态的修改。

4.6 重启集群

极端情况下,集群大部分节点都出现问题,需要重启整个集群。保险的做法:

找到一个数据记录完整且比较新的节点,以它为唯一节点创建新的集群,然后将其他节点一个一个地添加进来。

好了,这次的分享就到这里了,希望对大家有所帮助,我们下期再见~~