服务注册,内置健康检查,DNS和HTTP接口,让服务发现变得更加简单。
在动态的世界中,服务负载变得不再高效,负载均衡经常被用在服务的上层,然后提供一个静态的IP给客户端调用。它增加成本和延时,引入了单点故障,并且必须随着服务扩缩容而更新。
动态架构下的服务发现
动态架构下,服务发现是取代负载均衡的最佳选择。注册中心来维护一个实时的服务列表,包括服务地址和服务的健康状况。客户端通过注册中心查询服务端的地址,然后直接跟服务端通信。这就达到了脱离负载均衡也能弹性括缩容和优雅容错的目的。
Consul 提供了一个注册中心,我们可以看到所有的运行节点和服务还有它们的健康状况。通过它的 HTTP 接口,运维人员可以了解环境,了解那些与动态架构交互的应用程序和自动化运维工具。
Consul 使用内置的 DNS 服务器来实现服务发现。因为几乎所有的应用都支持使用 DNS 来做 IP 解析,这就让现有的应用很容易集成。使用 DNS 代替静态 IP 地址,可以让服务弹性扩缩容和绕过故障节点变得更加简单。
- $ dig web-frontend.service.consul. ANY
- ; «» DiG 9.8.3-P1 «» web-frontend.service.consul. ANY
- ;; global options: +cmd
- ;; Got answer:
- ;; -»HEADER«- opcode: QUERY, status: NOERROR, id: 29981
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
- ;; QUESTION SECTION: ;web-frontend.service.consul. IN ANY
- ;; ANSWER SECTION: web-frontend.service.consul. 0 IN A 10.0.3.83 web-frontend.service.consul. 0 IN A 10.0.1.109
Consul 提供了 HTTP 接口,供用户从注册中心查询节点,服务及其健康信息。该接口还支持阻塞查询或者对更改进行轮询。它允许自动化工具对正在注册或者健康状态发生变化的服务实时地修改配置或者重新路由。
- $ curl http://localhost:8500/v1/health/service/web?index=11&wait=30s
- {
- ...
- "Node": "10-0-1-109",
- "CheckID": "service:web",
- "Name": "Service 'web' check",
- "Status": "critical",
- "ServiceID": "web",
- "ServiceName": "web",
- "CreateIndex": 10,
- "ModifyIndex": 20
- ...
- }
Consul 支持开箱即用的多数据中心,而且不需要复杂的配置。在另一个数据中心查询服务,跟查询本地服务一样。预查询(Prepared Queries)等高级功能可以自动将失败查询转移到其他数据中心。
- $ curl http://localhost:8500/v1/catalog/datacenters
- ["dc1", "dc2"]$ curl http://localhost:8500/v1/catalog/nodes?dc=dc2
- [
- {
- "ID": "7081dcdf-fdc0-0432-f2e8-a357d36084e1",
- "Node": "10-0-1-109",
- "Address": "10.0.1.109",
- "Datacenter": "dc2",
- "TaggedAddresses": {
- "lan": "10.0.1.109",
- "wan": "10.0.1.109"
- },
- "CreateIndex": 112,
- "ModifyIndex": 125
- },
- ...
-
将服务发现和健康检查结合,就可以防止请求被路由到不健康的主机,继而轻松实现断路器功能。
自动TLS加密和身份认证让服务间访问变得更加安全
防火墙模式在动态配置下伸缩性不强。
服务间防火墙基于 IP 访问限制来保护入网和出网流量。但是在动态的世界里,服务随时会创建和销毁,防火墙的扩展性很低,因为它带来的是复杂的网络拓扑和随时变换的防火墙规则。
基于服务隔离的动态服务鉴权。
服务隔离是让服务自己管理访问限制,而不是依赖网络。Consul 使用服务策略规定哪些服务有权限访问。这些策略摆脱了IP规则和网络架构的束缚,可以在数据中心和大集群之间任意扩展。
定义和强制服务间的访问使用 Intentions 配置。基于服务的规则比基于 IP 的规则更容易管理变来变去的动态架构。
新旧平台之间的安全通信。Sidecar 可以让你在不改代码的情况下将它集成进应用程序,4层协议兼容所有的常见协议。
使用 TLS 鉴别服务和加密通讯。SPIFFE 格式的证书可以更好地跟其他平台协作。Consul 可以作为一个授权中心来简化开发,或者与 Vault 这样的外部认证中心整合。
所有的服务间通信都经过 TLS 加密和鉴权。TLS 保证服务能正确识别,并对通信数据进行加密。 了解更多(link:https://bishion.github.io/2018/07/28/consul-tutorial/#docs-connect-ca)
- $ consul connect proxy -service web \
- -service-addr 127.0.0.1:8000
- -listen 10.0.1.109:7200
- ==> Consul Connect proxy starting...
- Configuration mode: Flags
- Service: web
- Public listener: 10.0.1.109:7200 => 127.0.0.1:8000
- ...
- $ tshark -V \
- -Y "ssl.handshake.certificate" \
- -O "ssl" \
- -f "dst port 7200"
- Frame 39: 899 bytes on wire (7192 bits), 899 bytes captured (7192 bits) on interface 0
- Internet Protocol Version 4, Src: 10.0.1.110, Dst: 10.0.1.109
- Transmission Control Protocol, Src Port: 61918, Dst Port: 7200, Seq: 136, Ack: 916, Len: 843
- Secure Sockets Layer
- TLSv1.2 Record Layer: Handshake Protocol: Certificate
- Version: TLS 1.2 (0x0303)
- Handshake Protocol: Certificate
- RDNSequence item: 1 item (id-at-commonName=Consul CA 7)
- RelativeDistinguishedName item (id-at-commonName=Consul CA 7)
- Id: 2.5.4.3 (id-at-commonName)
- DirectoryString: printableString (1)
- printableString: Consul CA 7
-
支持富配置中心
运行时的配置管理在大规模集群下性能不高。
服务总会有一些运行时修改的配置,比如状态标识或者开关等,需要实时生效。使用配置系统分发这些配置或者重启服务一般都需要几分钟甚至数小时。在推送过程中,框架一致性很难保证,服务配置也可能出错。
分布式应用的实时配置中心
Consul 支持上千节点的配置数据实时更新。配置存储在树状的 Key/Value 结构中,高效的边界触发器可以将更新快速地推送出去。
开关,状态等动态服务配置信息采用富 Key/Value 存储结构。
Key/Value 支持读或者写事务,它允许多个 key 原子地读写。服务配置的修改可以原子操作,从而避免一致性问题。
- $ curl http://localhost:8500/v1/txn \
- --request PUT \
- --data \
- '[
- {
- "KV": {
- "Verb": "set",
- "Key": "lock",
- "Value": "MQ=="
- }
- },
- {
- "KV": {
- "Verb": "cas",
- "Index": 10,
- "Key": "configuration",
- "Value": "c29tZS1jb25maWc="
- }
- }
- ]'
-
Consul API 支持阻塞查询,允许边界触发更新。客户端通过这种方式可以在数据更新时收到通知。Consul-Template 或者类似工具允许配置文件在被修改时重新初始化。
- $ curl http://localhost:8500/v1/kv/web/config/rate_limit?wait=1m&index=229
- [
- {
- "LockIndex": 0,
- "Key": "web/config/rate_limit",
- "Flags": 0,
- "Value": "NjAw",
- "CreateIndex": 229,
- "ModifyIndex": 234
- }
- ]
-
监控组件使用阻塞查询来管理配置信息和健康状态的更新,在更新发生时去执行用户事先定义好的特定脚本。这给建造一个响应式架构带来了很大便利。
- $ consul watch \
- -type=key \
- -key=web/config/rate_limit \
- /usr/local/bin/record-rate-limit.sh
-
Key/Value 存储支持分布式锁和信号量。应用可以使用这个功能做 leader 选举或者控制共享资源的访问。