1etcd基础介绍
Posted huageyiyangdewo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1etcd基础介绍相关的知识,希望对你有一定的参考价值。
互联网技术发展真的快,层出不穷的新技术。最近项目使用到了
etcd
,自己之前在部署k8s集群的时候玩过,但是并没有系统的学习。正好趁这个机会,系统性的学习下。文章中的内容有些是来自官方文档,有些是来自网上的资料,有些是自己的思考。如果有不错的地方,请不吝赐教,大家有好的教程,也欢迎评论区留言,学习学习。感谢感谢!
这一系列文章是etcd的入门教程,并不是深入的教程,适合像我这种对 etcd 了解不深入或者完全不了解的同学,大牛请绕道。
1、什么是etcd
对于 etcd 的定义,我们来看一看官方是如何描述的。描述如下:A distributed, reliable key-value store for the most critical data of a distributed system
。翻译过来就是:一个分布式、可靠的键值存储系统,用于存储分布式系统中最关键的数据。
对于上面这句话,我们可以提取出来几个关键词,分布式、可靠的、键值存储系统、最关键的数据。对于在互联网行业待过一段时间的同学,应该对前面三个词比较熟悉,最后一个最关键的数据
如何理解呢?我说说自己的理解。
etcd 中存储的是这个分布式系统中最重要的数据,例如配置信息、元数据等,这些数据对于整个分布式系统而言是至关重要的,一旦出现问题,就可能导致系统出现故障或者问题。
通过上面,我们知道了 etcd 是分布式系统中的基础设施,为分布式系统提供了可靠的数据存储和管理能力。它是由CoreOS开发的,k8s 中的信息就是存储在 etcd 中,是 k8s 集群管理工具的核心组件之一。
etcd采用 Raft
一致性算法来保证数据的一致性和可靠性,支持多节点部署,可以容忍节点故障和网络分区等故障情况。etcd的使用非常广泛,除了作为 k8s 的核心组件之一,还可以用于服务发现、配置管理、分布式锁
等场景。etcd提供了简单易用的API,支持多种语言的客户端,可以方便地集成到各种应用中。
2、etcd的应用场景
通过上面的了解,感觉 etcd 还是挺牛逼的,那 etcd的应用场景一般在那些地方呢?
-
服务发现:etcd可以存储服务的地址和端口信息,例如Web服务、数据库服务等。客户端可以通过etcd API查询服务的地址和端口信息,从而实现服务发现和负载均衡。
-
分布式锁:etcd可以实现分布式锁,多个进程可以通过etcd API竞争锁资源,从而实现分布式同步和协调。
-
集群管理:etcd可以存储集群的状态信息,例如节点状态、领导者选举结果等。应用程序可以通过etcd API查询集群状态信息,从而实现集群管理和监控。
-
分布式任务调度:etcd可以存储任务的状态信息,例如任务的执行状态、执行结果等。应用程序可以通过etcd API查询任务状态信息,从而实现分布式任务调度和监控。
-
配置管理:etcd可以存储应用程序的配置信息,例如数据库连接信息、日志级别、缓存大小等。应用程序可以通过etcd API读取这些配置信息,从而实现动态配置管理。
-
容器编排:k8s中集群管理的核心组件之一就是etcd。
上面是 etcd 的一些常用的场景,等大家熟悉 etcd 后,可以根据自己的实际需求,来选择是否需要使用到 etcd 这个组件。
3、为什么使用etcd
下面再来说说 etcd 的优点,这样跟同事吹牛的时候或者面试的时候,可以吹一吹,哈哈!
- 可靠性:etcd采用
Raft算法
实现分布式一致性,保证数据的可靠性和一致性。 - 高可用性:etcd支持多节点部署,节点之间通过
Raft协议
进行数据同步和选举,保证系统的高可用性。 - 灵活性:etcd提供了RESTful API和gRPC API,可以方便地与各种编程语言进行交互。
- 安全性:etcd支持TLS加密和访问控制,可以保证数据的安全性。
- 可扩展性:etcd支持水平扩展,可以通过添加更多的节点来提高系统的性能和容量。
4、etcd架构图
上图是 etcd 基础架构图,按照分层模型,etcd可分为Client层、API网络层、Raft算法层、逻辑层和存储层
。这些层的功能如下:
-
Client层:Client层包括client v2 和v3两个大版本API客户端,提供了简介易用的API,同时支持负载均衡、节点间故障自动转移,可极大降低业务使用etcd复杂度,提升开发效率、增强服务的可用性。
-
API网络层:
API网络层主要包括client访问server和server节点之间的通信协议
。一方面,client访问etcd server 的API分为V2和V3两大版本。V2 API使用http/1.x协议,v3 API使用gRPC协议。同时v3通过etcd grpc-gateway 组件也支持 http/1.x 协议,便于各种语言的服务调用。另一方面,server之间通信协议,是指节点间通过Raft算法实现数据复制和Leader选举等功能时使用的HTTP协议。 -
Raft算法层:
Raft算法层实现了Leader选举、日志复制、ReadIndex等核心算法特性,用于保障etcd多个节点间的数据一致性,提升服务可用性等
,是etcd的基石。 -
逻辑层:etcd核心特性实现层,如典型的KVserver模块、MVCC模块、Auth鉴权模块、Lease租约模块、Compactor压缩模块等,其中MVCC模块主要由treeIndex模块和boltdb模块组成。
-
存储层:存储层包含预习日志(WAL)模块、快照(Snapshot)模块、boltdb模块。其中WAL可保障etcd crash后数据不丢失,boltdb则保存了集群元数据和用户写入数据。
参考资料:
彻底搞懂 etcd 系列文章:etcd 安全
0 专辑概述
etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件。
《彻底搞懂 etcd 系列文章》将会从 etcd 的基本功能实践、API 接口、实现原理、源码分析,以及实现中的踩坑经验等几方面具体展开介绍 etcd。预计会有 20 篇左右的文章,笔者将会每周持续更新,欢迎关注。
1 etcd 安全
在上一篇文章介绍了 etcd 集群的运维部署之后,本文将会重点讲解 etcd 的安全通信实践。 etcd 支持通过 TLS 协议进行的加密通信。TLS 通道可用于对等体之间的加密内部群集通信以及加密的客户端流量。本文提供了使用对等和客户端 TLS 设置群集的示例。
2 TLS 与 SSL
互联网的通信安全,建立在 SSL/TLS 协议之上。不使用 SSL/TLS 的 HTTP 通信,就是不加密的通信。所有信息明文传播,带来了三大风险:
- 窃听风险(eavesdropping):第三方可以获知通信内容。
- 篡改风险(tampering):第三方可以修改通信内容。
- 冒充风险(pretending):第三方可以冒充他人身份参与通信。
SSL/TLS 协议是为了解决这三大风险而设计的,希望达到:
- 所有信息都是加密传播,第三方无法窃听。
- 具有校验机制,一旦被篡改,通信双方会立刻发现。
- 配备身份证书,防止身份被冒充。
下面具体介绍下 SSL 与 TLS 的相关概念:
- SSL (Secure Socket Layer):为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取。目前一般通用之规格为40 bit之安全标准,美国则已推出128 bit之更高安全标准,但限制出境。只要3.0版本以上之I.E.或Netscape浏览器即可支持SSL。
- 安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。
想要实现数据 HTTPS 加密协议访问,保障数据的安全,就需要 SSL 证书,TLS 是 SSL 与 HTTPS 安全传输层协议名称。
3 进行 TLS 加密实践
为了进行实践,我们将会安装一些实用的命令行工具,其中包括 cfssl、cfssljson。
cfssl 是 CloudFlare 的 PKI/TLS 利器。 它既是命令行工具,又可以用于签名,验证和捆绑 TLS 证书的 HTTP API 服务器,环境构建方面需要 Go 1.12+。
cfssljson 程序,从 cfssl 获取 JSON 输出,并将证书、密钥、CSR和 bundle 写入指定位置。
环境配置
HostName | ip | 客户端交互端口 | peer 通信端口
:-: | :-: | :-: | :-:
infra0 | 192.168.202.128 | 2379 | 2380 |
infra1 | 192.168.202.129 | 2379 | 2380 |
infra2 | 192.168.202.130| 2379 | 2380 |
3.1 安装 cfssl
$ ls ~/Downloads/cfssl
cfssl-certinfo_1.4.1_linux_amd64 cfssl_1.4.1_linux_amd64 cfssljson_1.4.1_linux_amd64
chmod +x cfssl_1.4.1_linux_amd64 cfssljson_1.4.1_linux_amd64 cfssl-certinfo_1.4.1_linux_amd64
mv cfssl_1.4.1_linux_amd64 /usr/local/bin/cfssl
mv cfssljson_1.4.1_linux_amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_1.4.1_linux_amd64 /usr/bin/cfssl-certinfo
安装完成之后,查看版本信息的结果:
$ cfssl version
Version: 1.4.1
Runtime: go1.12.12
3.2 配置 CA 并创建 TLS 证书
我们将使用 CloudFlare‘s PKI 工具 cfssl 来配置 PKI Infrastructure,然后使用它去创建 Certificate Authority(CA), 并为 etcd 创建 TLS 证书。
首先创建 ssl 配置目录:
mkdir /opt/etcd/{bin,cfg,ssl} -p
cd /opt/etcd/ssl/
etcd ca 配置:
cat << EOF | tee ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"etcd": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
etcd ca证书:
cat << EOF | tee ca-csr.json
{
"CN": "etcd CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Shanghai",
"ST": "Shanghai"
}
]
}
EOF
生成 CA 凭证和私钥:
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
2020/04/30 20:36:58 [INFO] generating a new CA key and certificate from CSR
2020/04/30 20:36:58 [INFO] generate received request
2020/04/30 20:36:58 [INFO] received CSR
2020/04/30 20:36:58 [INFO] generating key: rsa-2048
2020/04/30 20:36:58 [INFO] encoded CSR
2020/04/30 20:36:58 [INFO] signed certificate with serial number 252821789025044258332210471232130931231440888312
$ ls
ca-config.json ca-csr.json ca-key.pem ca.csr ca.pem
etcd server证书:
cat << EOF | tee server-csr.json
{
"CN": "etcd",
"hosts": [
"192.168.202.128",
"192.168.202.129",
"192.168.202.130"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
EOF
生成 server 证书:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd server-csr.json | cfssljson -bare server
2020/04/30 20:44:37 [INFO] generate received request
2020/04/30 20:44:37 [INFO] received CSR
2020/04/30 20:44:37 [INFO] generating key: rsa-2048
2020/04/30 20:44:37 [INFO] encoded CSR
2020/04/30 20:44:37 [INFO] signed certificate with serial number 73061688633166283265484923779818839258466531108
ls
ca-config.json ca-csr.json ca-key.pem ca.csr ca.pem server-csr.json server-key.pem server.csr server.pem
启动 etcd 集群,配置如下:
#etcd1 启动
$ /opt/etcd/bin/etcd --name etcd1 --initial-advertise-peer-urls https://192.168.202.128:2380
--listen-peer-urls https://192.168.202.128:2380
--listen-client-urls https://192.168.202.128:2379,https://127.0.0.1:2379
--advertise-client-urls https://192.168.202.128:2379
--initial-cluster-token etcd-cluster-1
--initial-cluster etcd1=https://192.168.202.128:2380, etcd2=https://192.168.202.129:2380, etcd3=https://192.168.202.130:2380
--initial-cluster-state new
--client-cert-auth --trusted-ca-file=/opt/etcd/ssl/ca.pem
--cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem
--peer-client-cert-auth --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem
--peer-cert-file=/opt/etcd/ssl/server.pem --peer-key-file=/opt/etcd/ssl/server-key.pem
#etcd2 启动
/opt/etcd/bin/etcd --name etcd2 --initial-advertise-peer-urls https://192.168.202.129:2380
--listen-peer-urls https://192.168.202.129:2380
--listen-client-urls https://192.168.202.129:2379,https://127.0.0.1:2379
--advertise-client-urls https://192.168.202.129:2379
--initial-cluster-token etcd-cluster-1
--initial-cluster etcd1=https://192.168.202.128:2380, etcd2=https://192.168.202.129:2380, etcd3=https://192.168.202.130:2380
--initial-cluster-state new
--client-cert-auth --trusted-ca-file=/opt/etcd/ssl/ca.pem
--cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem
--peer-client-cert-auth --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem
--peer-cert-file=/opt/etcd/ssl/server.pem --peer-key-file=/opt/etcd/ssl/server-key.pem
#etcd3 启动
/opt/etcd/bin/etcd --name etcd3 --initial-advertise-peer-urls https://192.168.202.130:2380
--listen-peer-urls https://192.168.202.130:2380
--listen-client-urls https://192.168.202.130:2379,https://127.0.0.1:2379
--advertise-client-urls https://192.168.202.130:2379
--initial-cluster-token etcd-cluster-1
--initial-cluster etcd1=https://192.168.202.128:2380, etcd2=https://192.168.202.129:2380, etcd3=https://192.168.202.130:2380
--initial-cluster-state new
--client-cert-auth --trusted-ca-file=/opt/etcd/ssl/ca.pem
--cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem
--peer-client-cert-auth --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem
--peer-cert-file=/opt/etcd/ssl/server.pem --peer-key-file=/opt/etcd/ssl/server-key.pem
通过三台服务器的控制台可以知道,集群已经成功建立,我们进行验证:
$ /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.202.128:2379,https://192.168.202.129:2379,https://192.168.202.130:2379" endpoint health
# 输出如下:
https://192.168.202.129:2379 is healthy: successfully committed proposal: took = 9.492956ms
https://192.168.202.130:2379 is healthy: successfully committed proposal: took = 12.805109ms
https://192.168.202.128:2379 is healthy: successfully committed proposal: took = 13.036091ms
查看三个节点的健康状况,endpoint health
,输出的结果符合我们的预期。其次,查看集群的成员列表:
$ /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.202.128:2379,https://192.168.202.129:2379,https://192.168.202.130:2379" member list
# 输出如下:
48e15f7612b3de1, started, etcd2, https://192.168.202.129:2380, https://192.168.202.129:2379, false
6b57a3c3b8a54873, started, etcd3, https://192.168.202.130:2380, https://192.168.202.130:2379, false
c1ba2629c5bc62ac, started, etcd1, https://192.168.202.128:2380, https://192.168.202.128:2379, false
输出三个成员,完全符合我们的预期。经过 TLS 加密的 etcd 集群,在进行操作时,需要加上认证相关的信息,我们尝试先写再读的操作:
$ /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.202.128:2379,https://192.168.202.129:2379,https://192.168.202.130:2379" put hello world
OK
$ /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.202.128:2379,https://192.168.202.129:2379,https://192.168.202.130:2379" get hello
hello
world
写入 hello->wold 的键值对,读取的时候,控制台正常输出了键值。至此,我们成功将 etcd 的通信加密。
3.3 自动证书
如果集群需要加密的通信但不需要经过身份验证的连接,则可以将 etcd 配置为自动生成其密钥。 在初始化时,每个成员都基于其通告的 IP 地址和主机创建自己的密钥集。
在每台机器上,etcd 将使用以下标志启动:
$ etcd --name etcd1 --initial-advertise-peer-urls https://192.168.202.128:2380
--listen-peer-urls https://192.168.202.128:2380
--listen-client-urls https://192.168.202.128:2379,https://127.0.0.1:2379
--advertise-client-urls https://10.0.1.10:2379
--initial-cluster-token etcd-cluster-1
--initial-cluster infra0=https://192.168.202.128:2380,infra1=https://192.168.202.129:2380,infra2=https://192.168.202.130:2380
--initial-cluster-state new
--auto-tls
--peer-auto-tls
注意,由于自动签发证书并不认证身份,因此直接 curl 会返回错误。需要使用 curl 的 -k
命令屏蔽对证书链的校验。
4 小结
本文重点讲解了 etcd 集群的 TLS 安全认证配置,数据通信明文传播存在篡改、窃听、冒充等风险。互联网的通信安全,建立在 SSL/TLS 协议之上。基于 cfssl 工具,验证并且捆绑 TLS 证书,为 etcd 集群成员之间的通信保驾护航。
订阅最新文章,欢迎关注我的公众号
推荐阅读
- etcd 与 Zookeeper、Consul 等其它 k-v 组件的对比
- 彻底搞懂 etcd 系列文章(一):初识 etcd
- 彻底搞懂 etcd 系列文章(二):etcd 的多种安装姿势
- 彻底搞懂 etcd 系列文章(三):etcd 集群运维部署
参考
以上是关于1etcd基础介绍的主要内容,如果未能解决你的问题,请参考以下文章