云原生监控系统Prometheus——服务发现(基于 Consul 的服务发现)

服务发现(基于 Consul 的服务发现)

  基于 Consul 的服务发现是一种使用网络的服务发现机制和配置工具,是使用 Go 语言开发的,部署安装较为简单,具有分布式、高可用性和极高的可扩展性。它提供了以下几个关键功能。

    • 服务发现:Consul 通过 HTTP API 和 DNS 进行服务注册和服务发现。对于外部服务(如 SaaS 提供者)也可以注册。
    • 健康检查:Consul 支持对各类服务运行状态的健康检查工作,能够迅速向管理员告警集群中的任何问题,可以防止将流量路由到问题或故障主机,可动态监视服务运行状况并适当更新服务注册表。
    • 键/值存储:键/值存储可以灵活地进行存储动态配置、功能标记、协调和领导者选举等。简单的 HTTP API 使其易于在任何地方使用。
    • 多数据中心:Consul 支持单一数据中心,可扩展以支持多个数据中心,并且无须复杂的配置。
    • 服务分割:通过自动 TLS 加密和基于身份的授权实现安全的服务间通信。

  官方提供的 Consul 架构图如下所示:

  首先 Consul 支持多数据中心,在上图中有两 DataCenter,他们通过 Internet 互联,同时请注意为了提高通信效率,只有 Server 节点才加入跨数据中心的通信。

  在单个数据中心中,Consul 分为 Client 和 Server 两种节点(所有的节点也被称为 Agent ),Server 节点保存数据,Client 负责健康检查及转发数据请求到 Server;Server 节点有一个 Leader 和多个 Follower ,Leader 节点会将数据同步到 Follower, Server 的数量推荐是 3 个或者 5 个,在 Leader 挂掉的时候会启动选举机制产生一个新的 Leader。

 

  Server(即服务器)端模式是具有一组扩展功能的代理,包括参与 Raft 选举、集群状态维护和响应 RPC 查询。Server 端与其他数据中心交互 WAN Gossip,并将查询转发给 Server Leader 或远程数据中心。它可以持久化所数据信息到本地,这样就算出现故障,信息也得以保存。Server Leader 负责 Server 间注册信息的同步和各个节点的监控检查工作。

  集群内的 Consul 节点通过 gossip 协议(流言协议)维护成员关系,也就是说某个节点了解集群内现在还有哪些节点,这些节点是 Client 还是 Server。单个数据中心的流言协议同时使用 TCP 和 UDP 通信,并且都使用 8301 端口。跨数据中心的流言协议也同时使用 TCP 和 UDP 通信,端口使用 8302。

  在每个数据中心中,所有的节点都要加入 Gossip 协议。这样的设计有以下目的:

    • 第一,不需要为客户端配置服务器地址,发现是自动完成的;
    • 第二,检测节点故障的工作不是放在服务器上,而是分布式的;
    • 第三,可以被用作消息传递层,比如 Leader 选举事件。

  集群内数据的读写请求既可以直接发到 Server,也可以通过 Client 使用 RPC 转发到 Server,请求最终会到达 Leader 节点,在允许数据轻微陈旧的情况下,读请求也可以在普通的 Server 节点完成,集群内数据的读写和复制都是通过 TCP 的 8300 端口完成。

一、部署 Consul

  Documentation: https://docs.consulproject.org/docs/

  官网:http://consulproject.org、https://www.consul.io/

  consul 在 Github 下载页面地址 https://github.com/consul/consul/releases,也可以直接使用 git 进行 clone 操作 git clone https://github.com/consul/consul.git。

  • 1.1)安装依赖:

install git, Ruby 2.7.6, CMake, pkg-config, shared-mime-info, Node.js and PostgreSQL (>=9.5).

  • 1.2)安装步骤:

    git clone https://github.com/consul/consul.git
    cd consul
    bundle install
    cp config/database.yml.example config/database.yml
    cp config/secrets.yml.example config/secrets.yml
    bin/rake db:create
    bin/rake db:migrate
    bin/rake db:dev_seed
    RAILS_ENV=test rake db:setup
    

      或 

    Installing Consul on Kubernetes 

    1、添加 HashiCorp Helm 存储库:
    $ helm repo add hashicorp https://helm.releases.hashicorp.com
    2、验证您是否有权访问 helm chart 权限 $ helm search repo hashicorp/consul NAME CHART VERSION APP VERSION DESCRIPTION hashicorp/consul 0.39.0 1.11.1 Official HashiCorp Consul Chart
    3、使用 Helm 在 Kubernetes 上安装 Consul。Helm chart 做了一切来设置推荐的 Consul-on-Kubernetes 部署。安装完成后,会形成一个 Consul 集群,选举出 leader,每个节点都会有一个运行的 Consul agent。 3.1)要在 Kubernetes 上安装最新版本的 Consul,请发出以下命令以使用 Helm 使用默认配置安装 Consul。-n 您还可以通过修改 Helm 安装的标志值来将 Consul 安装在您选择的专用命名空间上。 $ helm install consul hashicorp/consul --set global.name=consul --create-namespace --namespace consul 3.2)要在 Kubernetes 上安装特定版本的 Consul,请发出以下带有--version标志的命令,以使用 Helm 使用默认配置安装指定版本。 $ export VERSION=0.43.0 $ helm install consul hashicorp/consul --set global.name=consul --version ${VERSION} --create-namespace --namespace consul
  • 1.3)运行程序:

    ./consul agent -dev -config-dir=/etc/consul/consul.d
  • 1.4)查看当前集群中的所有节点信息

    ./consul member

 二、服务注册发现

  Consul 服务注册提供了两种注册方法:

    • 一种是定义配置文件服务注册方法,即在配置文中定义服务来进行注册;
    • 一种是 HTTP API 服务注册方法,即在启动后由服务自身通过调用 API 进行自我注册。
  • 首先介绍 JSON 格式的配置文件(例子:https://www.consul.io/docs/discovery/services)
    mkdir -pv /etc/consul/consul.d
    cd /etc/consul/consul.d
    vim node_exporter.json
    {
      service {
          name = "redis"
          id   = "redis"
          port = 80
          tags = ["primary"]
        
          meta = {
            custom_meta_key = "custom_meta_value"
          }
        
          tagged_addresses = {
            lan = {
              address = "192.168.0.55"
              port    = 8000
            }
        
            wan = {
              address = "198.18.0.23"
              port    = 80
            }
          }
        
          port                = 8000
          socket_path         = "/tmp/redis.sock"
          enable_tag_override = false
        
          checks = [
            {
              args     = ["/usr/local/bin/check_redis.py"]
              interval = "10s"
            }
          ]
        
          kind              = "connect-proxy"
          proxy_destination = "redis"
        
          proxy = {
            destination_service_name  = "redis"
            destination_service_id    = "redis1"
            local_service_address     = "127.0.0.1"
            local_service_port        = 9090
            local_service_socket_path = "/tmp/redis.sock"
            mode                      = "transparent"
        
            transparent_proxy {
              outbound_listener_port = 22500
            }
        
            mesh_gateway = {
              mode = "local"
            }
        
            expose = {
              checks = true
        
              paths = [
                {
                  path            = "/healthz"
                  local_path_port = 8080
                  listener_port   = 21500
                  protocol        = "http2"
                }
              ]
            }
          }
        
          connect = {
            native = false
          }
        
          weights = {
            passing = 5
            warning = 1
          }
        
          token     = "233b604b-b92e-48c8-a253-5f11514e4b50"
          namespace = "foo"
      }
    }
  • 配置文件内容说明(例子:https://www.consul.io/docs/discovery/services):

    service 服务参数配置说明
    参数 说明 默认值 Required
    id 指定服务 ID 的字符串值。如果未指定,name 将使用该字段的值。每个节点的服务必须有唯一的 ID,因此如果默认值name会与其他服务冲突,您应该指定唯一值。 可选提供项,弱提供,则将其设置为 name 一致 可选
    name 指定服务的名称,必须提供项。如果未指定 ID 参数,则使用此参数的值作为 ID。为了与外部 DNS 兼容,我们建议使用有效的 DNS 标签作为服务定义名称。 None 必选
    tags
    可用于添加服务级标签的字符串值列表。例如,可以定义区分主节点和辅助节点或服务版本的标记。为了与外部 DNS 兼容,我们建议使用有效的 DNS 标签作为服务定义 ID。标记值对于参数是不透明的。 None 可选
    address 

    指定特定于服务的IP地址或主机名的字符串值。如果未指定任何值,则默认情况下使用代理节点的IP地址。此参数没有服务端验证。

    代理节点的 IP 地址 可选
    meta

    定义最多 64 个键/值对的映射的对象。元对象与节点定义中的节点元对象具有相同的限制。可以按服务的单个实例检索元数据。给定服务的所有实例都有自己的元数据副本。

    Node 可选
    tagged_addresses 标记地址是可以为节点或服务定义的附加地址。 None 可选
    port 可以简单的理解为服务注册到 Consul 使用的端口,服务发现也是发现 address 对应的端口。 None 可选
    socket_path

    指定服务套接字路径的字符串值。如果服务侦听Unix域套接字,请指定此参数以向网格公开服务。

    None 可选
    enable_tag_override 布尔值,确定是否启用了服务的反熵特性。如果设置为 true,则外部代理可以在目录中更新此服务并修改标记。此代理随后的本地同步操作将忽略更新的标记。此参数仅应用于本地注册的服务。如果多个节点注册了相同的服务,那么 able _ tag _ overage 配置和所有其他服务配置项将独立运行。更新一个节点上注册的服务的标记独立于另一个节点上注册的相同服务(按名称)。有关更多信息,请参见反熵同步。 None 可选
     checks

    定义服务健康检查的对象数组。

    None 可选
    kind 将服务标识为 Connect 代理的字符串值。 None
    可选
    proxy_destination 字符串值,指定当前配置的服务代理到的目标服务的名称。 此参数已弃用。请改用 proxy.destination_service。  None
    可选
    proxy 定义当前配置的服务代理到目标服务的对象。 None 可选
    connect
    该对象配置 ConsulConnect 服务网格连接。 None

    如果启用 ACL,则为必需 

    token 字符串值,指定用于注册服务的 ACL 令牌(如果启用了 ACL 系统)。服务与服务目录交互需要令牌。 None 可选
     namespace 字符串值,指定应在其中注册服务的 Consul 命名空间。    

 三、与 Prometheus 集成

  Consul 完成了服务的发现和注册后,维护着整个应用环境中的所有服务信息。此时通过 Prometheus 与 consul 的交互便可取得上面已经注册的 node_exporter 的信息。我们需要对 Prometheus 的配置定义  prometheus.yml 进行编辑,添加如下基于 Consul 的服务发现内容:

vim prometheus.yml
scrape_configs:
  - job_name: 'consul_sd_node_exporter'
    scheme: http
    consul_sd_configs:
      - server: 127.0.0.1:8500  #指定 consul 服务地址。
	    service: ['node_exporter','mysqld_exporter']  #如果不填写,则默认获取 Consul 上注册的所有服务。

四、常见 API

  当被监控服务节点故障失效或回收下线,需要删除被发现的服务,否则 Prometheus 的 targets 列表中仍然会显示该服务。需要用一下 api 来进行删除操作:

curl  --request PUT http://127.0.0.1:8500/v1/agent/service/deregister/node_exporter

  被监控的服务节点故障恢复后,可以使用 "reload" 重新加载生效。

./consul reload

  如果想彻底关闭这个 job,有没有办法呢?有的,编辑 prometheus.yml 文件,删除或者注释掉原来添加的内容,并重新启动 Prometheus 服务。

posted @ 2022-07-17 18:48  左扬  阅读(726)  评论(3编辑  收藏  举报
levels of contents