0. 前言
[技术源于艺术, 艺术源于生活]
1) 这是我第一次发布程序相关的技术文章, 10年前发表过很多关于3dsmax和maya的技术文章
2) 有人无端转载我的文章, 所以这里留一个我的联系方式, 欢迎讨论
邮箱: kekuer@gmail.com qq: 5513219
1. 背景
自发现服务基础需要一个高可用键值存储系统, 很容易联想到redis, memcached等KV内存数据库, 但是我最后选择了etcd, 主要是因为他天生就是为集群化而设计的, 并且生来就是用作conf的节点数据同步.
1) etcd为coreos的一个基础部件, 也是用于保存配置信息, 在这里我们主要讨论非coreos系统的etcd部署及使用
2) 目前etcd最新版本为: v2.3.6, 测试版为: v3.x, 我们基于v2版本进行演练
2. 注意
我的所有docker镜像都是基于alpine 3.x版本进行构建, 如果需要其他版本请自行修改
3. 准备
1) etcd官方地址
https://github.com/coreos/etcd
2) Linux最新版本下载地址
https://github.com/coreos/etcd/releases/download/v2.3.6/etcd-v2.3.6-linux-amd64.tar.gz
3) 构建基于alpine的etcd docker镜像
FROM alpine:3.3
MAINTAINER Etcd Maintainers "kekuer@gmail.com"
RUN ETCD_VER=2.3.6 && \
echo "http://127.0.0.1:8098/main" > /etc/apk/repositories && \
apk --update add curl && \
mkdir src && \
cd src && \
curl -O http://127.0.0.1:8080/etcd-v${ETCD_VER}-linux-amd64.tar.gz && \
tar xzvf etcd-v${ETCD_VER}-linux-amd64.tar.gz && \
cd etcd-v${ETCD_VER}-linux-amd64 && \
cp etcd etcdctl /usr/bin/ && \
apk --update del curl && \
rm -rf /var/cache/apk/* /src
ENTRYPOINT ["/usr/bin/etcd"]
注意:
根据自己的alpine 镜像地址修改repository地址, 构建自己的alpine本地镜像, 请参考我的另外一篇文章: Alpine Linux Repository本地镜像制作我在这里做了一个文件池, 放在一台服务器上, 如果你们相应的文件池服务器, 修改etcd下载地址为: https://github.com/coreos/etcd/releases/download/v${ETCD_VER}/etcd-v${ETCD_VER}-linux-amd64.tar.gz
4. 概念
1) 静态配置和自发现
a) 静态配置: 通过initial-cluster启动参量来启动etcd服务, 用于已经预知集群地址
-initial-cluster infra0=http://172.0.1.10:2380,http://172.0.1.11:2380,infra2=http://172.0.1.12:2380 \
-initial-cluster-state new
或者使用环境变量
ETCD_INITIAL_CLUSTER="infra0=http://172.0.1.10:2380,infra1=http://172.0.1.11:2380,infra2=http://172.0.1.12:2380"
ETCD_INITIAL_CLUSTER_STATE=new
b) 自发现模式: 通过指定discovery发现服务token地址来自动配置集群服务
可以使用官方地址: https://discovery.etcd.io/new?size=3, 当然在国内最好还是自己构建一个etcd-discovery服务, 使用之前构建的etcd镜像, 跑一个docker container, 并放开discovery端口, 我这里使用的是80端口, container内部端口是2379
docker run --name etcd-discovery -d --restart=always --log-opt max-size=100m -p 80:2379 -v /docker/mount/etcd-discovery/:/etcd funwun.io/etcd:1.4 \
-data-dir /etcd \
-snapshot-count=100 \
-listen-client-urls http://0.0.0.0:2379 \
-advertise-client-urls http://0.0.0.0:2379
注意:
recover etcd数据是一件比较繁琐的事情, 所以尽量把data挂载到host上, 如果是EC2的话, 最好是重新挂载一个EBS来作为所有docker的挂载盘 (我的习惯, 你们也可以提出自己的意见和建议)snapshot-count的改小, 是因为我的机器都是1G内存的轻量host, 所以我要保证内存的使用情况
2) etcd节点
由于etcd采用Raft算法, 因此在做决策时需要多数节点的投票, 所以一般部署为奇数节点: 3, 5, 7
3) etcd四个主要概念
a) listen-peer-urls
用于节点与节点之间数据交换, 因此需要监听在其他节点可以访问的IP地址上
默认端口为: 2380 & 7001 (7001不推荐使用, 已基本废弃, 主要用于兼容老服务)
b) listen-client-urls
用户客户机访问etcd数据, 一般监听在本地, 如果需要集中管理, 可以监听在管理服务器可以访问的IP地址上
默认端口为: 2379 & 4001 (4001不推荐使用, 已基本废弃, 主要用于兼容老服务)
c) initial-advertise-peer-urls
该参数表示节点监听其他节点同步信号的地址
默认端口为: 2380 & 7001 (7001不推荐使用, 已基本废弃, 主要用于兼容老服务)
d) advertise-client-urls
在加入proxy节点后, 会使用该广播地址, 因此需要监听在一个proxy节点可以访问的IP地址上
默认端口为: 2379 & 4001 (4001不推荐使用, 已基本废弃, 主要用于兼容老服务)
5. 使用
1) 创建一个discovery服务配置信息
TOKEN=test-1
curl -X PUT http://127.0.0.1/v2/keys/discovery/${TOKEN}/_config/size -d value=3
在这里, 我们使用的是test-1作为token, 你可以UUID一个来作为token
注意:
生产环境请注意该名称, 我不建议使用UUID来做token, 因为语义不明, 最好起一个自己能记住的名称, 方便以后辨识
2) 在3个节点服务器上分别启动etcd服务
a) 获取本地IP (此为举例, 我使用EC2, 因此以下shell已经足够, 如果网络配置较复杂的服务器上, 根据自行条件获取对应的对外IP)
IP=$(hostname --all-ip-addresses | awk '{print $1}') && echo $IP
b) 在3个服务器上启动etcd节点
docker run --name etcd -d --log-opt max-size=100m -p 2379:2379 -p 2380:2380 -v /docker/mount/etcd:/etcd funwun.io/etcd:1.4 \
-name ${IP} \
-data-dir /etcd \
-snapshot-count=1000 \
-listen-client-urls http://0.0.0.0:2379 \
-advertise-client-urls http://${IP}:2379 \
-listen-peer-urls http://0.0.0.0:2380 \
-initial-advertise-peer-urls http://${IP}:2380 \
-discovery http://172.0.0.1/v2/keys/discovery/test-1
c) 在集群初始化为3个节点的话, 必须凑齐3个节点, 服务才能正常运行, 超出部分将启动为proxy节点, 因此在第4个服务器上, 我们应该将节点启动为proxy
docker run --name etcd -d --log-opt max-size=100m --net=host -v /docker/mount/etcd:/etcd funwun.io/etcd:1.4 \
-name ${IP} \
-data-dir /etcd \
-snapshot-count=1000 \
--proxy on \
-listen-client-urls http://0.0.0.0:2379 \
-discovery http://172.31.16.100/v2/keys/discovery/test-1
注意:
name必须是唯一的, etcd是用这个来确定节点的, 如果使用--initial-cluster, 我们还会使用该名称作为集群的节点名称 (一般使用节点IP来作为名称, 你也可以使用hostname)discovery地址修改为你的discovery服务地址
6. 结语
这里主要讲解了etcd的一个集群的简单使用, 基本满足作为自发现键值对存储服务
推荐阅读InfoQ上的该文章: