手把手教你用ETCD
一句话概括的话:ETCD 是一个基于 RAFT 的分布式 KV 存储系统。一个 ETCD 集群通常是由 3、5、7 之类奇数个节点组成的,为什么不选择偶数个节点?在集群系统中为了选出 LEADER 节点,至少要有半数以上的节点达成共识,举例说明:
如何搭建一个 ETCD 集群呢?比如在本地部署一个 3 个节点的集群,参考文档操作:集群运行起来后,可以通过如下命令来确认状态是否正常:虽然在本地部署 ETCD 集群很简单,但是在 K8S 上部署 ETCD 集群的话,往往会复杂很多,网上能找到一些别人共享的部署脚本,估计大家看了会疯掉。难点主要在于当我们在 K8S 上部署 ETCD 集群的时候,出于可伸缩性的考虑,一般不会采用固定 IP 的做法,也就是说节点的 IP 是无法事先确定的,而启动 ETCD 集群的时候又需要确定各个接入的节点(initial-cluster),于是产生了矛盾。好在作为一个有状态服务(StatefulSet),可以使用 Headless service 为每一个 POD 提供一个稳定的并且唯一的网络标识,也就是内网域名:「$(statefulset)-$(ordinal).$(service).$(namespace).svc.cluster.local」,当交互双方在同一个 namespace 下的话,甚至可以简写成「$(statefulset)-$(ordinal).$(service)」:
友情提示:如上脚本非完整代码,此外,其中有几个需要留意的配置,分别是:
最后,再安利一下 etcd web ui 方面比较出色的工具:etcdkeeper,收工。
原文地址:https://huoding.com/2020/08/19/839
- 当集群有 3 个节点的时候,至少要有 2 个节点达成共识,最多容灾 1 个节点。当集群有 4 个节点的时候,至少要有 3 个节点达成共识,最多容灾 1 个节点。当集群有 5 个节点的时候,至少要有 3 个节点达成共识,最多容灾 2 个节点。
如何搭建一个 ETCD 集群呢?比如在本地部署一个 3 个节点的集群,参考文档操作:
- CLUSTER="etcd-0=http://127.0.0.1:2380,etcd-1=http://127.0.0.1:3380,etcd-2=http://127.0.0.1:4380"
- /usr/local/bin/etcd \
- --name etcd-0 \
- --data-dir etcd-0.etcd \
- --listen-client-urls http://127.0.0.1:2379 \
- --listen-peer-urls http://127.0.0.1:2380 \
- --advertise-client-urls http://127.0.0.1:2379 \
- --initial-advertise-peer-urls http://127.0.0.1:2380 \
- --initial-cluster ${CLUSTER} &
- /usr/local/bin/etcd \
- --name etcd-1 \
- --data-dir etcd-1.etcd \
- --listen-client-urls http://127.0.0.1:3379 \
- --listen-peer-urls http://127.0.0.1:3380 \
- --advertise-client-urls http://127.0.0.1:3379 \
- --initial-advertise-peer-urls http://127.0.0.1:3380 \
- --initial-cluster ${CLUSTER} &
- /usr/local/bin/etcd \
- --name etcd-2 \
- --data-dir etcd-2.etcd \
- --listen-client-urls http://127.0.0.1:4379 \
- --listen-peer-urls http://127.0.0.1:4380 \
- --advertise-client-urls http://127.0.0.1:4379 \
- --initial-advertise-peer-urls http://127.0.0.1:4380 \
- --initial-cluster ${CLUSTER} &
- shell> etcdctl member list -w table
- +------------------+---------+--------+-----------------------+-----------------------+------------+
- | ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
- +------------------+---------+--------+-----------------------+-----------------------+------------+
- | b71f75320dc06a6c | started | etcd-0 | http://127.0.0.1:2380 | http://127.0.0.1:2379 | false |
- | d07d5325fff892c1 | started | etcd-1 | http://127.0.0.1:3380 | http://127.0.0.1:3379 | false |
- | b7bacd4212cc9323 | started | etcd-2 | http://127.0.0.1:4380 | http://127.0.0.1:4379 | false |
- +------------------+---------+--------+-----------------------+-----------------------+------------+
- shell> etcdctl endpoint status --cluster -w table
- +-----------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
- | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
- +-----------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
- | http://127.0.0.1:2379 | b71f75320dc06a6c | 3.4.10 | 25 kB | false | false | 2 | 8 | 8 | |
- | http://127.0.0.1:3379 | d07d5325fff892c1 | 3.4.10 | 25 kB | true | false | 2 | 8 | 8 | |
- | http://127.0.0.1:4379 | b7bacd4212cc9323 | 3.4.10 | 25 kB | false | false | 2 | 8 | 8 | |
- +-----------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
- $(statefulset) 是 StatefulSet 的名字。$(ordinal) 是 Pod 的序号,从 0 到 N-1。$(service) 是 Service 的名字。$(namespace) 是服务所在的 namespace。
- apiVersion: v1
- kind: Service
- metadata:
- name: etcd
- namespace: default
- spec:
- clusterIP: None
- publishNotReadyAddresses: true
- ---
- apiVersion: apps/v1
- kind: StatefulSet
- metadata:
- name: etcd
- namespace: default
- spec:
- serviceName: etcd
- replicas: 3
- template:
- spec:
- dnsPolicy: ClusterFirst
- containers:
- - name: etcd
- command:
- - sh
- - -c
- - |
- CLUSTER=""
- for i in $(seq 0 3); do
- CLUSTER=${CLUSTER}${CLUSTER:+,}etcd-${i}=http://etcd-${i}.etcd:2380
- done
- exec /usr/local/bin/etcd \
- --name ${HOSTNAME} \
- --data-dir /var/run/etcd/default.etcd \
- --listen-client-urls http://0.0.0.0:2379 \
- --listen-peer-urls http://0.0.0.0:2380 \
- --advertise-client-urls http://${HOSTNAME}.etcd:2379 \
- --initial-advertise-peer-urls http://${HOSTNAME}.etcd:2380 \
- --initial-cluster ${CLUSTER}
- clusterIP: None:表示是一个 Headless service。publishNotReadyAddresses: true:不管 POD 是否准备就绪,都发布内网域名。dnsPolicy: ClusterFirst:请求会优先在集群所在域查询,如此内网域名才会生效。
最后,再安利一下 etcd web ui 方面比较出色的工具:etcdkeeper,收工。
原文地址:https://huoding.com/2020/08/19/839