为什么是Consul?

Consul 解决了各种规模组织在微服务架构中遇到的挑战。这范围从在各种分布式环境和地理位置中运行,到满足保护所有应用程序流量的需要。世界正在迅速变化和发展,计算网络层也是如此。
当今的网络必须快速适应并确保始终加密通信。Consul 使组织能够在扩大规模的同时采用零信任模型。Consul 可以实现这一切,同时通过关键网络任务的自动化减轻运营商和开发人员的负担。

什么是Consul?

Consul 是一个服务网格解决方案,提供具有服务发现、配置和分段功能的全功能控制平面。这些功能中的每一个都可以根据需要单独使用,也可以一起使用来构建完整的服务网格。Consul 需要数据平面并支持代理和原生集成模型。Consul 附带一个简单的内置代理,因此一切都可以开箱即用,而且还支持 Envoy 等 3rd 方代理集成。

Consul的主要特点

服务发现

Consul 的客户端可以注册服务,例如 apior mysql,其他客户端可以使用 Consul 发现给定服务的提供者。使用 DNS 或 HTTP,应用程序可以轻松找到它们所依赖的服务。

健康检查

Consul 客户端可以提供任意数量的健康检查,或者与给定服务相关联(“网络服务器是否返回 200 OK”),或者与本地节点相关联(“内存利用率是否低于 90%”)。操作员可以使用此信息来监控集群的健康状况,服务发现组件使用它来将流量从不健康的主机中路由出去。

KV存储

应用程序可以将 Consul 的分层键(key)/值(value)存储用于任意数量的目的,包括动态配置、特征标记、协调、领导者选举等。简单的 HTTP API 使其易于使用。

安全服务通信

Consul 可以为服务生成和分发 TLS 证书以建立相互 TLS 连接。 Intentions可用于定义允许通信的服务。可以通过可以实时更改的Intentions轻松管理服务分段,而不是使用复杂的网络拓扑和静态防火墙规则。

多数据中心

Consul 支持开箱即用的多个数据中心。这意味着 Consul 的用户不必担心构建额外的抽象层以扩展到多个区域。

Consul 旨在对 DevOps 社区和应用程序开发人员都友好,使其非常适合现代、弹性的基础设施。

Consul的基本架构

Consul 是一个分布式的、高可用的系统。本节将介绍基础知识,故意省略一些不必要的细节,以便您快速了解 Consul 的工作原理。有关更多详细信息,请参阅 深入的架构概述
每个为 Consul 提供服务的节点都运行一个Consul 代理。发现其他服务或获取、设置key/value数据不需要运行代理。代理负责节点上的服务以及节点本身的健康检查。
Consul代理与一台或多台Consul 服务器连接通信。Consul 服务器是存储和复制数据的地方。服务器自己选举领导者。虽然 Consul 可以在一台服务器运行,但建议使用 3 到 5 台,以避免服务器故障导致数据丢失的场景。建议为每个数据中心使用一组 Consul 服务器。
服务器维护一个目录,该目录是通过聚合代理提交的信息形成的。该目录维护集群的高级视图,包括哪些服务可用、哪些节点运行这些服务、健康信息等等。可以在 此处找到代理和目录如何交互。
需要发现其他服务或节点的基础架构组件可以查询任何 Consul 服务器或任何 Consul 代理。代理会自动将查询转发到服务器。
每个数据中心运行一个 Consul 服务器集群。当提出跨数据中心的服务发现或配置请求时,本地 Consul 服务器将请求转发到远程数据中心并返回结果。
image.png
首先,我们可以看到有两个数据中心,分别标记为“DATACENTER1”和“DATACENTER2”。Consul 对多个数据中心提供一流的支持。
在每个数据中心内,我们混合了客户端和服务器。预计将有三到五台服务器。这在故障情况下的可用性和性能之间取得了平衡,因为随着更多机器的添加,consensus(共识)变得越来越慢。但是,客户端的数量没有限制,它们可以轻松扩展到数千或数万。

推荐架构

下图显示了部署具有最大弹性的单个 Consul 集群的推荐架构:
image.png
我们建议在 Consul 集群中部署 5 个节点,分布在三个可用区之间,因为这种架构可以承受集群内两个节点的丢失或整个可用区的丢失。这些服务器一起运行 Raft 驱动的一致状态存储,用于更新目录、会话、准备好的查询、ACL 和 KV 状态。
如果无法部署到三个可用区,则可以在一个或两个可用区使用相同的架构,但在可用区中断的情况下会产生重大的可靠性风险。有关各种集群大小的仲裁大小和容错性的更多信息,请参阅Consul 部署表
对于 Consul Enterprise 客户,通过实施多集群架构可以实现额外的弹性,该架构允许额外的性能和灾难恢复选项。有关更多信息,请参阅使用 WAN Gossip Learn 联合多个数据中心教程。此外,有关可能影响推荐架构的企业功能,请参阅下面的扩展注意事项部分。

使用Consul注意事项

系统要求

小型集群适用于大多数初始生产部署或开发和测试环境。
大型集群是具有持续高工作负载的生产环境。

集群规模 CPU 内存(Memory) 磁盘容量 磁盘 IO 磁盘吞吐量
2-4核 8-16 GB 内存 100+ GB 3000+ IOPS 75+ MB/秒
8-16核 32-64 GB 内存 200+ GB 7500+ IOPS 250+ MB/秒

缩放注意事项

单个数据中心的建议最大大小为 5,000 个 Consul 客户端代理。此建议不仅基于可扩展性,还考虑了整个数据中心发生故障时的影响和恢复时间。对于读/写繁重的数据中心,您可能需要进一步减少最大代理数,具体取决于 KV 对的数量和大小以及 watch 的数量。当您添加更多客户端代理时,gossip需要更多时间才能融合。类似地,当新的服务器代理加入具有大型 KV 存储的现有多千节点数据中心时,将存储复制到新服务器的日志可能需要更多时间,并且更新率可能会增加。

什么是服务网格(Service Mesh)?

服务网格是一个专用网络层,可在基础架构内和跨基础架构(包括本地和云环境)提供安全的服务到服务通信。服务网格通常与微服务架构模式一起使用,但可以在涉及复杂网络的任何场景中提供价值。

服务网格的优点

服务网格的一些好处包括:

  • 服务发现(service discovery)
  • 应用程序健康监控(application health monitoring)
  • 负载均衡(load balancing)
  • 自动容灾处理(故障转移)(automatic failover)
  • 服务网格通常由控制平面和数据平面组成。控制平面维护一个中央注册表,用于跟踪所有服务及其各自的 IP 地址。此活动称为服务发现。只要应用程序在控制平面上注册,控制平面就能够与网格的其他成员共享如何与应用程序通信,并强制执行谁可以相互通信的规则。

控制平面负责保护网格、促进服务发现、健康检查、策略实施和其他类似的操作问题。
数据平面处理服务之间的通信。许多服务网格解决方案使用 sidecar 代理来处理数据平面通信,因此限制了服务对网络环境所需的感知水平。

  • (交通)管理(traffic management)
  • 加密(encryption)
  • 可观察性和可追溯性(observability and traceability)
  • 身份验证和授权(authentication and authorization),
  • 网络自动化(network automation)

利用服务网格的一个常见用例是实现零信任模型。在零信任模型中,应用程序需要基于身份的访问,以确保服务网格内的所有通信都使用 TLS 证书进行身份验证并在传输过程中加密。
在传统的安全策略中,保护主要集中在网络的外围。在云环境中,网络访问的表面积比传统的本地网络要宽得多。此外,传统的安全实践忽略了许多不良行为者可能来自网络墙内的事实。零信任模型解决了这些问题,同时允许组织根据需要进行扩展。

服务网格如何工作?

服务网格通常由控制平面和数据平面组成。控制平面维护一个中央注册表,用于跟踪所有服务及其各自的 IP 地址。此活动称为服务发现。只要应用程序在控制平面上注册,控制平面就能够与网格的其他成员共享如何与应用程序通信,并强制执行谁可以相互通信的规则。
控制平面负责保护网格、促进服务发现、健康检查、策略实施和其他类似的操作问题。
数据平面处理服务之间的通信。许多服务网格解决方案使用 sidecar 代理来处理数据平面通信,因此限制了服务对网络环境所需的感知水平。
image.png

开始使用Consul

安装Consul

安装Consul教程
安装 Consul 很简单。有三种安装 Consul 的方法:

  1. 使用预编译的二进制文件
  2. 从源安装
  3. 在 Kubernetes 上安装

下载预编译的二进制文件是最简单的,我们通过 TLS 提供下载以及 SHA256 和来验证二进制文件。我们还分发带有可以验证的 SHA256 和的 PGP 签名。
入门指南提供了在本地计算机上安装和使用 Consul的快速演练。

运行Consul Agent

在生产中,您可以在服务器或客户端模式下运行每个 Consul 代理。每个 Consul 数据中心必须至少有一台服务器,负责维护 Consul 的状态。这包括有关其他 Consul 服务器和客户端的信息,哪些服务可用于发现,以及哪些服务可以与哪些其他服务通信。

警告:我们强烈反对单服务器生产部署。

为了确保即使服务器发生故障也能保留 Consul 的状态,您应该始终在生产环境中运行三到五台服务器。奇数个服务器(不超过五个)在性能和容错之间取得平衡。

启动代理

在开发模式下启动 Consul 代理:

  1. consul agent -dev

警告:-dev永远不要在生产模式下运行 Consul 。

启动输出日志:

  1. ==> Starting Consul agent...
  2. Version: '1.12.2'
  3. Node ID: 'd1e9c4a7-d109-19e7-1947-1a4761e7ef0b'
  4. Node name: 'VM-4-4-centos'
  5. Datacenter: 'dc1' (Segment: '<all>')
  6. Server: true (Bootstrap: false)
  7. Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
  8. Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
  9. Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false
  10. ==> Log data will now stream in as it occurs:
  11. 2022-07-05T14:06:59.592+0800 [INFO] agent.server.raft: initial configuration: index=1 servers="[{Suffrage:Voter ID:d1e9c4a7-d109-19e7-1947-1a4761e7ef0b Address:127.0.0.1:8300}]"
  12. 2022-07-05T14:06:59.592+0800 [INFO] agent.server.raft: entering follower state: follower="Node at 127.0.0.1:8300 [Follower]" leader=
  13. 2022-07-05T14:06:59.593+0800 [INFO] agent.server.serf.wan: serf: EventMemberJoin: VM-4-4-centos.dc1 127.0.0.1
  14. 2022-07-05T14:06:59.593+0800 [INFO] agent.server.serf.lan: serf: EventMemberJoin: VM-4-4-centos 127.0.0.1
  15. 2022-07-05T14:06:59.593+0800 [INFO] agent.router: Initializing LAN area manager
  16. 2022-07-05T14:06:59.593+0800 [INFO] agent.server: Adding LAN server: server="VM-4-4-centos (Addr: tcp/127.0.0.1:8300) (DC: dc1)"
  17. 2022-07-05T14:06:59.593+0800 [INFO] agent.server.autopilot: reconciliation now disabled
  18. 2022-07-05T14:06:59.593+0800 [INFO] agent.server: Handled event for server in area: event=member-join server=VM-4-4-centos.dc1 area=wan
  19. 2022-07-05T14:06:59.593+0800 [WARN] agent: [core]grpc: addrConn.createTransport failed to connect to {dc1-127.0.0.1:8300 VM-4-4-centos <nil> 0 <nil>}. Err: connection error: desc = "transport: Error while dialing dial tcp 127.0.0.1:0->127.0.0.1:8300: operation was canceled". Reconnecting...
  20. 2022-07-05T14:06:59.594+0800 [INFO] agent: Started DNS server: address=127.0.0.1:8600 network=udp
  21. 2022-07-05T14:06:59.594+0800 [DEBUG] agent.server.autopilot: autopilot is now running
  22. 2022-07-05T14:06:59.594+0800 [DEBUG] agent.server.autopilot: state update routine is now running
  23. 2022-07-05T14:06:59.594+0800 [INFO] agent: Started DNS server: address=127.0.0.1:8600 network=tcp
  24. 2022-07-05T14:06:59.594+0800 [INFO] agent: Starting server: address=127.0.0.1:8500 network=tcp protocol=http
  25. 2022-07-05T14:06:59.595+0800 [INFO] agent: Started gRPC server: address=127.0.0.1:8502 network=tcp
  26. 2022-07-05T14:06:59.595+0800 [INFO] agent: started state syncer
  27. 2022-07-05T14:06:59.595+0800 [INFO] agent: Consul agent running!
  28. 2022-07-05T14:06:59.651+0800 [WARN] agent.server.raft: heartbeat timeout reached, starting election: last-leader=
  29. 2022-07-05T14:06:59.651+0800 [INFO] agent.server.raft: entering candidate state: node="Node at 127.0.0.1:8300 [Candidate]" term=2
  30. 2022-07-05T14:06:59.651+0800 [DEBUG] agent.server.raft: votes: needed=1
  31. 2022-07-05T14:06:59.651+0800 [DEBUG] agent.server.raft: vote granted: from=d1e9c4a7-d109-19e7-1947-1a4761e7ef0b term=2 tally=1
  32. 2022-07-05T14:06:59.651+0800 [INFO] agent.server.raft: election won: tally=1
  33. 2022-07-05T14:06:59.651+0800 [INFO] agent.server.raft: entering leader state: leader="Node at 127.0.0.1:8300 [Leader]"
  34. 2022-07-05T14:06:59.651+0800 [INFO] agent.server: cluster leadership acquired
  35. 2022-07-05T14:06:59.652+0800 [INFO] agent.server: New leader elected: payload=VM-4-4-centos
  36. 2022-07-05T14:06:59.652+0800 [INFO] agent.server.autopilot: reconciliation now enabled
  37. 2022-07-05T14:06:59.652+0800 [INFO] agent.leader: started routine: routine="federation state anti-entropy"
  38. 2022-07-05T14:06:59.652+0800 [INFO] agent.leader: started routine: routine="federation state pruning"
  39. 2022-07-05T14:06:59.652+0800 [DEBUG] connect.ca.consul: consul CA provider configured: id=fb:50:9b:45:1a:65:15:c1:68:57:73:5f:da:cd:b8:0d:0f:e2:26:eb:68:66:43:11:85:9d:67:a9:7a:56:9c:b9 is_primary=true
  40. 2022-07-05T14:06:59.653+0800 [INFO] connect.ca: initialized primary datacenter CA with provider: provider=consul
  41. 2022-07-05T14:06:59.653+0800 [INFO] agent.leader: started routine: routine="intermediate cert renew watch"
  42. 2022-07-05T14:06:59.653+0800 [INFO] agent.leader: started routine: routine="CA root pruning"
  43. 2022-07-05T14:06:59.653+0800 [INFO] agent.leader: started routine: routine="CA root expiration metric"
  44. 2022-07-05T14:06:59.653+0800 [INFO] agent.leader: started routine: routine="CA signing expiration metric"
  45. 2022-07-05T14:06:59.653+0800 [INFO] agent.leader: started routine: routine="virtual IP version check"
  46. 2022-07-05T14:06:59.653+0800 [DEBUG] agent.server: successfully established leadership: duration=1.694662ms
  47. 2022-07-05T14:06:59.653+0800 [INFO] agent.server: member joined, marking health alive: member=VM-4-4-centos partition=default
  48. 2022-07-05T14:06:59.654+0800 [INFO] agent.leader: stopping routine: routine="virtual IP version check"
  49. 2022-07-05T14:06:59.654+0800 [INFO] agent.leader: stopped routine: routine="virtual IP version check"
  50. 2022-07-05T14:06:59.662+0800 [INFO] agent.server: federation state anti-entropy synced
  51. 2022-07-05T14:06:59.781+0800 [DEBUG] agent: Skipping remote check since it is managed automatically: check=serfHealth
  52. 2022-07-05T14:06:59.782+0800 [INFO] agent: Synced node info
  53. 2022-07-05T14:07:00.256+0800 [DEBUG] agent: Skipping remote check since it is managed automatically: check=serfHealth
  54. 2022-07-05T14:07:00.256+0800 [DEBUG] agent: Node info in sync
  55. 2022-07-05T14:07:00.256+0800 [DEBUG] agent: Node info in sync
  56. 2022-07-05T14:08:04.906+0800 [DEBUG] agent: Skipping remote check since it is managed automatically: check=serfHealth
  57. 2022-07-05T14:08:04.906+0800 [DEBUG] agent: Node info in sync

发现数据中心成员(Discover datacenter members)

consul members通过在新的终端窗口中运行命令来检查 Consul 数据中心的成员资格。输出列出了数据中心中的代理。

  1. consul members
  1. Node Address Status Type Build Protocol DC Partition Segment
  2. VM-4-4-centos 127.0.0.1:8301 alive server 1.12.2 2 dc1 default <all>

输出显示consul的代理、它的 IP 地址、它的健康状态、它在数据中心的角色以及一些版本信息。您可以通过提供-detailed标志来发现其他元数据。
该members命令针对 Consul 客户端运行,该客户端通过gossip 协议获取其信息。客户端拥有的信息最终是一致的,但在任何时候它的世界视图都可能与服务器上的状态不完全匹配。要获得高度一致的世界观,请查询HTTP API,它将请求转发到 Consul 服务器。

  1. curl localhost:8500/v1/catalog/nodes
  1. [
  2. {
  3. "ID": "d1e9c4a7-d109-19e7-1947-1a4761e7ef0b",
  4. "Node": "VM-4-4-centos",
  5. "Address": "127.0.0.1",
  6. "Datacenter": "dc1",
  7. "TaggedAddresses": {
  8. "lan": "127.0.0.1",
  9. "lan_ipv4": "127.0.0.1",
  10. "wan": "127.0.0.1",
  11. "wan_ipv4": "127.0.0.1"
  12. },
  13. "Meta": {
  14. "consul-network-segment": ""
  15. },
  16. "CreateIndex": 13,
  17. "ModifyIndex": 15
  18. }
  19. ]

除了 HTTP API,您还可以使用 DNS 接口来发现节点。除非您启用了缓存,否则 DNS 接口会将您的查询发送到 Consul 服务器。要执行 DNS 查找,您必须指向 Consul 代理的 DNS 服务器,该服务器8600默认在端口上运行。

  1. dig @127.0.0.1 -p 8600 VM-4-4-centos.node.consul
  1. ; <<>> DiG 9.11.26-RedHat-9.11.26-4.el8_4 <<>> @127.0.0.1 -p 8600 VM-4-4-centos.node.consul
  2. ; (1 server found)
  3. ;; global options: +cmd
  4. ;; Got answer:
  5. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28021
  6. ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2
  7. ;; WARNING: recursion requested but not available
  8. ;; OPT PSEUDOSECTION:
  9. ; EDNS: version: 0, flags:; udp: 4096
  10. ;; QUESTION SECTION:
  11. ;VM-4-4-centos.node.consul. IN A
  12. ;; ANSWER SECTION:
  13. VM-4-4-centos.node.consul. 0 IN A 127.0.0.1
  14. ;; ADDITIONAL SECTION:
  15. VM-4-4-centos.node.consul. 0 IN TXT "consul-network-segment="
  16. ;; Query time: 0 msec
  17. ;; SERVER: 127.0.0.1#8600(127.0.0.1)
  18. ;; WHEN: 7 05 14:24:05 CST 2022
  19. ;; MSG SIZE rcvd: 106

停止代理

使用consul leave命令停止 Consul 代理。这将优雅地停止代理,使其离开 Consul 数据中心并关闭。

  1. consul leave

当您发出leave命令时,Consul 会通知其他成员该代理已离开数据中心。当代理离开时,其在同一节点上运行的本地服务及其检查将从目录中删除,并且 Consul 不会再次尝试联系该节点。
强制终止代理进程向 Consul 数据中心中的其他代理指示节点失败而不是离开。当一个节点发生故障时,它的运行状况被标记为关键,但它不会从目录中删除。Consul 将自动尝试重新连接到失败的节点,假设它可能由于网络分区而不可用,并且它可能会回来。
如果代理作为服务器运行,优雅的离开对于避免导致影响共识协议的潜在可用性中断很重要。 有关如何安全地添加和删除服务器的详细信息,请查看添加和删除服务器教程。

使用Consul服务发现注册服务

在本节教程中,您将通过注册服务和健康检查来开始使用 Consul。
Consul 的主要用例之一是服务发现。Consul 提供了一个 DNS 接口,下游服务可以使用它来查找其上游依赖项的 IP 地址。
Consul 知道这些服务的位置,因为每个服务都向其本地 Consul 客户端注册。运营商可以手动注册服务,配置管理工具可以在部署时注册服务,或者容器编排平台可以通过集成自动注册服务。
您将通过向 Consul 提供配置文件来手动注册服务和健康检查,并使用 Consul 通过 DNS 接口和 HTTP API 发现其位置。手动注册服务将帮助您了解自动化工具最终需要提供给 Consul 以利用服务发现的信息。

定义服务

您可以通过提供服务定义(这是注册服务的最常用方式)或调用 HTTP API 来注册服务。
首先,为 Consul 配置创建一个目录。Consul 加载配置目录中的所有配置文件,因此 Unix 系统上的一个常见约定是将目录命名为类似/etc/consul.d.d后缀表示“此目录包含一组配置文件”)。
/root/consul.d目录下,添加服务,例如batman-video-player.json

  1. {
  2. "sercice": {
  3. "name": "batman-video-player", // 服务名称
  4. "tags": ["video", "player"], // 标签:可用于定位该服务
  5. "port": 8001 // 服务运行端口
  6. }
  7. }

现在,重新启动代理,使用命令行标志指定配置目录并在代理上启用脚本检查。

安全警告:在某些配置中启用脚本检查可能会引入已知被恶意软件攻击的远程执行漏洞。在生产中,我们强烈建议添加-enable-local-script-checks

  1. # 先停止代理
  2. consul leave
  3. # 重置代理,并设置配置文件路径
  4. consul agent -dev -enable-local-script-checks -config-dir=/root/consul.d
  1. ==> Starting Consul agent...
  2. Version: '1.12.2'
  3. Node ID: '1f014511-1ab8-5207-1d69-228ec48e8880'
  4. Node name: 'VM-4-4-centos'
  5. Datacenter: 'dc1' (Segment: '<all>')
  6. Server: true (Bootstrap: false)
  7. Client Addr: [127.0.0.1] (HTTP: 8500, HTTPS: -1, gRPC: 8502, DNS: 8600)
  8. Cluster Addr: 127.0.0.1 (LAN: 8301, WAN: 8302)
  9. Encrypt: Gossip: false, TLS-Outgoing: false, TLS-Incoming: false, Auto-Encrypt-TLS: false
  10. ==> Log data will now stream in as it occurs:
  11. 2022-07-05T16:24:16.970+0800 [INFO] agent.server.raft: initial configuration: index=1 servers="[{Suffrage:Voter ID:1f014511-1ab8-5207-1d69-228ec48e8880 Address:127.0.0.1:8300}]"
  12. 2022-07-05T16:24:16.970+0800 [INFO] agent.server.raft: entering follower state: follower="Node at 127.0.0.1:8300 [Follower]" leader=
  13. 2022-07-05T16:24:16.970+0800 [INFO] agent.server.serf.wan: serf: EventMemberJoin: VM-4-4-centos.dc1 127.0.0.1
  14. 2022-07-05T16:24:16.970+0800 [INFO] agent.server.serf.lan: serf: EventMemberJoin: VM-4-4-centos 127.0.0.1
  15. 2022-07-05T16:24:16.970+0800 [INFO] agent.router: Initializing LAN area manager
  16. 2022-07-05T16:24:16.971+0800 [INFO] agent.server: Adding LAN server: server="VM-4-4-centos (Addr: tcp/127.0.0.1:8300) (DC: dc1)"
  17. 2022-07-05T16:24:16.971+0800 [INFO] agent.server.autopilot: reconciliation now disabled
  18. 2022-07-05T16:24:16.971+0800 [WARN] agent: [core]grpc: addrConn.createTransport failed to connect to {dc1-127.0.0.1:8300 VM-4-4-centos <nil> 0 <nil>}. Err: connection error: desc = "transport: Error while dialing dial tcp 127.0.0.1:0->127.0.0.1:8300: operation was canceled". Reconnecting...
  19. 2022-07-05T16:24:16.971+0800 [INFO] agent.server: Handled event for server in area: event=member-join server=VM-4-4-centos.dc1 area=wan
  20. 2022-07-05T16:24:16.971+0800 [WARN] agent: [core]grpc: addrConn.createTransport failed to connect to {dc1-127.0.0.1:8300 VM-4-4-centos <nil> 0 <nil>}. Err: connection error: desc = "transport: Error while dialing dial tcp 127.0.0.1:0->127.0.0.1:8300: operation was canceled". Reconnecting...
  21. 2022-07-05T16:24:16.972+0800 [DEBUG] agent.server.autopilot: autopilot is now running
  22. 2022-07-05T16:24:16.972+0800 [INFO] agent: Started DNS server: address=127.0.0.1:8600 network=udp
  23. 2022-07-05T16:24:16.972+0800 [DEBUG] agent.server.autopilot: state update routine is now running
  24. 2022-07-05T16:24:16.972+0800 [INFO] agent: Started DNS server: address=127.0.0.1:8600 network=tcp
  25. 2022-07-05T16:24:16.972+0800 [INFO] agent: Starting server: address=127.0.0.1:8500 network=tcp protocol=http
  26. 2022-07-05T16:24:16.972+0800 [INFO] agent: Started gRPC server: address=127.0.0.1:8502 network=tcp
  27. 2022-07-05T16:24:16.972+0800 [INFO] agent: started state syncer
  28. 2022-07-05T16:24:16.972+0800 [INFO] agent: Consul agent running!
  29. 2022-07-05T16:24:17.021+0800 [WARN] agent.server.raft: heartbeat timeout reached, starting election: last-leader=
  30. 2022-07-05T16:24:17.021+0800 [INFO] agent.server.raft: entering candidate state: node="Node at 127.0.0.1:8300 [Candidate]" term=2
  31. 2022-07-05T16:24:17.021+0800 [DEBUG] agent.server.raft: votes: needed=1
  32. 2022-07-05T16:24:17.021+0800 [DEBUG] agent.server.raft: vote granted: from=1f014511-1ab8-5207-1d69-228ec48e8880 term=2 tally=1
  33. 2022-07-05T16:24:17.021+0800 [INFO] agent.server.raft: election won: tally=1
  34. 2022-07-05T16:24:17.021+0800 [INFO] agent.server.raft: entering leader state: leader="Node at 127.0.0.1:8300 [Leader]"
  35. 2022-07-05T16:24:17.021+0800 [INFO] agent.server: cluster leadership acquired
  36. 2022-07-05T16:24:17.022+0800 [INFO] agent.server: New leader elected: payload=VM-4-4-centos
  37. 2022-07-05T16:24:17.022+0800 [INFO] agent.server.autopilot: reconciliation now enabled
  38. 2022-07-05T16:24:17.022+0800 [INFO] agent.leader: started routine: routine="federation state anti-entropy"
  39. 2022-07-05T16:24:17.022+0800 [INFO] agent.leader: started routine: routine="federation state pruning"
  40. 2022-07-05T16:24:17.022+0800 [DEBUG] connect.ca.consul: consul CA provider configured: id=fb:50:9b:45:1a:65:15:c1:68:57:73:5f:da:cd:b8:0d:0f:e2:26:eb:68:66:43:11:85:9d:67:a9:7a:56:9c:b9 is_primary=true
  41. 2022-07-05T16:24:17.023+0800 [INFO] connect.ca: initialized primary datacenter CA with provider: provider=consul
  42. 2022-07-05T16:24:17.023+0800 [INFO] agent.leader: started routine: routine="intermediate cert renew watch"
  43. 2022-07-05T16:24:17.023+0800 [INFO] agent.leader: started routine: routine="CA root pruning"
  44. 2022-07-05T16:24:17.023+0800 [INFO] agent.leader: started routine: routine="CA root expiration metric"
  45. 2022-07-05T16:24:17.023+0800 [INFO] agent.leader: started routine: routine="CA signing expiration metric"
  46. 2022-07-05T16:24:17.023+0800 [INFO] agent.leader: started routine: routine="virtual IP version check"
  47. 2022-07-05T16:24:17.023+0800 [DEBUG] agent.server: successfully established leadership: duration=1.699051ms
  48. 2022-07-05T16:24:17.023+0800 [INFO] agent.server: member joined, marking health alive: member=VM-4-4-centos partition=default
  49. 2022-07-05T16:24:17.024+0800 [INFO] agent.leader: stopping routine: routine="virtual IP version check"
  50. 2022-07-05T16:24:17.024+0800 [INFO] agent.leader: stopped routine: routine="virtual IP version check"
  51. 2022-07-05T16:24:17.171+0800 [DEBUG] agent: Skipping remote check since it is managed automatically: check=serfHealth
  52. 2022-07-05T16:24:17.171+0800 [INFO] agent: Synced node info
  53. 2022-07-05T16:24:17.171+0800 [INFO] agent: Synced service: service=batman-video-player
  54. 2022-07-05T16:24:17.272+0800 [INFO] agent.server: federation state anti-entropy synced
  55. 2022-07-05T16:24:17.734+0800 [DEBUG] agent: Skipping remote check since it is managed automatically: check=serfHealth
  56. 2022-07-05T16:24:17.734+0800 [DEBUG] agent: Node info in sync
  57. 2022-07-05T16:24:17.734+0800 [DEBUG] agent: Service in sync: service=batman-video-player
  58. 2022-07-05T16:24:17.734+0800 [DEBUG] agent: Node info in sync
  59. 2022-07-05T16:24:17.734+0800 [DEBUG] agent: Service in sync: service=batman-video-player

您会在输出中注意到 Consul “同步”了 batman-video-player服务。这意味着代理从配置文件中加载了服务定义,并已成功将其注册到服务目录中。

注意:Consul 可以注册尚未运行的服务。它根据服务的端口将每个正在运行的服务与其注册相关联。

在多代理 Consul 数据中心中,每个服务都会向其本地 Consul 客户端注册,客户端会将注册转发到维护服务目录的 Consul 服务器。
如果要注册多个服务,可以在 Consul 配置目录中创建多个服务定义文件。

查询服务

一旦代理将服务添加到 Consul 的服务目录中,您就可以使用 DNS 接口或 HTTP API 来查询它。

DNS接口

首先使用 Consul 的 DNS 接口查询 服务。在 Consul 注册的服务的 DNS 名称是NAME.service.consul,其中NAME是您用于注册服务的名称(在本例中为batman-video-player)。默认情况下,所有 DNS 名称都在consul命名空间中,尽管 这是可配置的

  1. dig @127.0.0.1 -p 8600 batman-video-player.service.consul
  1. ; <<>> DiG 9.11.26-RedHat-9.11.26-4.el8_4 <<>> @127.0.0.1 -p 8600 batman-video-player.service.consul
  2. ; (1 server found)
  3. ;; global options: +cmd
  4. ;; Got answer:
  5. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26639
  6. ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
  7. ;; WARNING: recursion requested but not available
  8. ;; OPT PSEUDOSECTION:
  9. ; EDNS: version: 0, flags:; udp: 4096
  10. ;; QUESTION SECTION:
  11. ;batman-video-player.service.consul. IN A
  12. ;; ANSWER SECTION:
  13. batman-video-player.service.consul. 0 IN A 127.0.0.1
  14. ;; Query time: 0 msec
  15. ;; SERVER: 127.0.0.1#8600(127.0.0.1)
  16. ;; WHEN: 7 05 16:39:08 CST 2022
  17. ;; MSG SIZE rcvd: 79

Tip: 由于我们从consul最小配置开始,A 记录将返回本地主机 ( 127.0.0.1)。如果您想通告对数据中心中的其他节点有意义的 IP 地址,请设置 Consul 代理-advertise参数或在定义服务中的设置address字段。

您还可以使用 DNS 接口检索整个地址/端口对作为 SRV记录。

  1. dig @127.0.0.1 -p 8600 batman-video-player.service.consul SRV
  1. ; <<>> DiG 9.11.26-RedHat-9.11.26-4.el8_4 <<>> @127.0.0.1 -p 8600 batman-video-player.service.consul SRV
  2. ; (1 server found)
  3. ;; global options: +cmd
  4. ;; Got answer:
  5. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13174
  6. ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 3
  7. ;; WARNING: recursion requested but not available
  8. ;; OPT PSEUDOSECTION:
  9. ; EDNS: version: 0, flags:; udp: 4096
  10. ;; QUESTION SECTION:
  11. ;batman-video-player.service.consul. IN SRV
  12. ;; ANSWER SECTION:
  13. batman-video-player.service.consul. 0 IN SRV 1 1 8001 VM-4-4-centos.node.dc1.consul.
  14. ;; ADDITIONAL SECTION:
  15. VM-4-4-centos.node.dc1.consul. 0 IN A 127.0.0.1
  16. VM-4-4-centos.node.dc1.consul. 0 IN TXT "consul-network-segment="
  17. ;; Query time: 0 msec
  18. ;; SERVER: 127.0.0.1#8600(127.0.0.1)
  19. ;; WHEN: 7 05 16:54:11 CST 2022
  20. ;; MSG SIZE rcvd: 164

SRV记录可查看到 batman-video-player 服务在端口 8001 上运行,并且存在于节点上VM-4-4-centos.node.dc1.consul.。DNS 会返回一个附加部分,其中包含A该节点的记录。
最后,您还可以使用 DNS 接口按标签过滤服务。基于标签的服务查询的格式是TAG.NAME.service.consul。 在下面的示例中,您将向 Consul 询问所有带有“video”标签的 batman-video-player 服务。由于您使用该标签注册了 batman-video-player 服务,因此您将获得成功的响应。

  1. dig @127.0.0.1 -p 8600 video.batman-video-player.service.consul
  1. ; <<>> DiG 9.11.26-RedHat-9.11.26-4.el8_4 <<>> @127.0.0.1 -p 8600 video.batman-video-player.service.consul
  2. ; (1 server found)
  3. ;; global options: +cmd
  4. ;; Got answer:
  5. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15692
  6. ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
  7. ;; WARNING: recursion requested but not available
  8. ;; OPT PSEUDOSECTION:
  9. ; EDNS: version: 0, flags:; udp: 4096
  10. ;; QUESTION SECTION:
  11. ;video.batman-video-player.service.consul. IN A
  12. ;; ANSWER SECTION:
  13. video.batman-video-player.service.consul. 0 IN A 127.0.0.1
  14. ;; Query time: 0 msec
  15. ;; SERVER: 127.0.0.1#8600(127.0.0.1)
  16. ;; WHEN: 7 05 17:09:02 CST 2022
  17. ;; MSG SIZE rcvd: 85

HTTP API

除了 DNS 接口,您还可以使用 HTTP API 查询batman-video-player服务。

  1. curl http://localhost:8500/v1/catalog/service/batman-video-player
  1. [
  2. {
  3. "ID": "1f014511-1ab8-5207-1d69-228ec48e8880",
  4. "Node": "VM-4-4-centos",
  5. "Address": "127.0.0.1",
  6. "Datacenter": "dc1",
  7. "TaggedAddresses": {
  8. "lan": "127.0.0.1",
  9. "lan_ipv4": "127.0.0.1",
  10. "wan": "127.0.0.1",
  11. "wan_ipv4": "127.0.0.1"
  12. },
  13. "NodeMeta": {
  14. "consul-network-segment": ""
  15. },
  16. "ServiceKind": "",
  17. "ServiceID": "batman-video-player",
  18. "ServiceName": "batman-video-player",
  19. "ServiceTags": [
  20. "video",
  21. "player"
  22. ],
  23. "ServiceAddress": "",
  24. "ServiceWeights": {
  25. "Passing": 1,
  26. "Warning": 1
  27. },
  28. "ServiceMeta": {},
  29. "ServicePort": 8001,
  30. "ServiceSocketPath": "",
  31. "ServiceEnableTagOverride": false,
  32. "ServiceProxy": {
  33. "Mode": "",
  34. "MeshGateway": {},
  35. "Expose": {}
  36. },
  37. "ServiceConnect": {},
  38. "CreateIndex": 15,
  39. "ModifyIndex": 15
  40. }
  41. ]

HTTP API 列出了托管给定服务的所有节点。正如您稍后将在我们讨论运行状况检查时确认的那样,您通常希望仅过滤运行状况良好的服务实例的查询,DNS 会在后台自动执行此操作。过滤您的 HTTP API 查询以仅查找健康的实例。

  1. # HTTP API 过滤查询健康的实例
  2. curl http://localhost:8500/v1/catalog/service/batman-video-player?passing

更新服务

接下来,您将通过为其注册运行状况检查来更新 Web 服务。
您可以通过更改服务定义文件并将 a 发送SIGHUP到代理或运行来更新服务定义而无需任何停机时间consul reload。或者,您可以使用 HTTP API 动态添加、删除和修改服务。在此示例中,您将更新注册文件。

  1. {
  2. "service": {
  3. "name": "batman-video-player",
  4. "tags": ["video", "player"],
  5. "port": 8001,
  6. "check": {
  7. "args": [
  8. "curl",
  9. "localhost"
  10. ],
  11. "interval": "10s"
  12. }
  13. }
  14. }

此服务定义的check添加了一个基于脚本的运行状况检查,它每 10 秒尝试通过 curl 连接到 batman-video-player 服务。基于脚本的健康检查以启动 Consul 进程的同一用户身份运行。
现在重新加载 Consul 的配置,让它知道新的健康检查。

  1. consul reload
  2. 返回结果:
  3. Configuration reload triggered

使用 Consul Service Mesh 和 Envoy 保护服务通信

https://learn.hashicorp.com/tutorials/consul/service-mesh-with-envoy-proxy
Consul 服务网格通过授权和加密来保护服务到服务的通信。应用程序可以在服务网格配置中使用 sidecar 代理来自动为入站和出站连接建立 TLS 连接,而无需了解网络配置和拓扑。除了保护您的服务之外,Consul 服务网格还可以拦截有关服务到服务通信的数据并将其呈现给监控工具。
在本章教程中,您将在 Consul 目录中注册两个服务及其sidecar代理。然后,您将启动服务和 sidecar 代理。最后,将通过intention停止流量来证明服务到服务的通信正在通过代理。
image.png
虽然本教程使用了不适合生产环境的元素——Consul 开发代理和模拟服务——但它将教你使用 Consul 服务网格部署自己的服务的通用过程。在本教程的最后,我们还提供了有关使该过程适应更多类似生产环境的其他信息。

先决条件

  • 启用了 Consul 服务网格的正在运行的 Consul 服务器。对于本教程,您将使用本地开发代理,它默认启用 Consul 服务网格。
  • 安装在 Consul 代理上的Envoy二进制文件。Consul 包括一个用于测试和开发的内置第 4 层 (L4) 代理,但也为 Envoy 作为 sidecar 代理提供一流的支持。本教程提供了两者的命令,推荐使用 Envoy 代理。
  • 需要安全通信的两个服务应用程序。对于本教程,您将使用两个示例服务应用程序,一个计数器服务和一个仪表板。下载并解压缩可执行文件以进行后续操作。