Consul

2022-05-24  本文已影响0人  想成为大师的学徒小纪

一、简介

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

consul主要特点:

二、Consul基础架构

生产部署可以参照下面多数据中心架构图进行:

每个为Consul提供服务的节点都运行一个Consul agent。发现其他服务或获取/设置键值数据不需要运行agent。agent负责对节点上的服务以及节点本身进行健康检查。

agent与一个或多个Consul server通信。Consul server是数据存储和复制的地方。这些server自己选出一个leader。虽然Consul可以在一台server上运行,但建议3到5台,以避免导致数据丢失的故障情况。建议每个数据中心有一个Consul server集群。

Consul的服务发现由服务目录(catalog)支持,该目录(catalog)是由agent提交的信息汇总而成的。目录维护集群的高层视图,包括哪些服务是可用的,哪些节点运行这些服务,健康信息等等。该目录用于通过Consul提供的各种接口暴露这些信息,包括DNS和HTTP。与agent相比,目录上下文中的服务和检查的字段更为有限。这是因为目录只负责记录和返回有关服务、节点和健康的信息。目录只由server节点维护。这是因为目录是通过Raft日志复制的,以提供集群的统一和一致的视图。

需要发现其他服务或节点的基础架构组件,可以查询任何Consul server或任何Consul agent。agent会自动将查询转发给server。

每个数据中心运行一个Consul server集群。当一个跨数据中心的服务发现或配置请求被提出时,本地Consul server将请求转发到远程数据中心并返回结果。

一个数据中心中的所有agent都参与了gossip协议。有一个特定的gossip池,包含了一个数据中心的所有agent。这样有几个效果:1、不需要为client配置server的地址;发现是自动完成的。2、检测agent故障的工作不是放在server上,而是分布式的,这使得故障检测比简单的心跳方案更具可扩展性。它还为节点提供了故障检测,如果无法访问agent,则节点可能已发生故障。3、还能用作信息传递层,在发生leader选举等重要事件时进行通知。

每个数据中心的server都是单个Raft对等集的一部分,它们一起工作来选举一个leader。一个被选中的server拥有额外的职责,leader负责处理所有查询和事务。作为consensus协议的一部分,还必须将事务复制到所有对等体,由于这一要求,当非leader的server收到一个RPC请求时,它会转发给集群leader。

server agents也作为WAN gossip池的一部分运行,它与LAN池不同,因为它针对互联网的高延迟进行了优化,预计只包含其他Consul server agents。这个池子的目的是允许数据中心以低接触的方式相互发现。将一个新的数据中心加入集群,只需将它加入现有的WAN gossip池,由于server都在这个池里运行,还可以实现跨数据中心的请求。当一个server收到对不同数据中心的请求时,它会将其转发到正确的数据中心中的一个随机server。然后,该server可以转发到本地leader。

一般来说,数据不会在不同的Consul数据中心之间进行复制。当对另一个数据中心的资源发出请求时,本地Consul server会将RPC请求转发给远程Consul server并返回结果。如果远程数据中心不可用,那么这些资源也将不可用,但这不会影响本地数据中心。

三、Service Mesh(服务网格)

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

1、优点

从安全性到提高应用程序弹性,服务网络能带来以下好处:

  • 服务发现

  • 应用程序健康监控

  • 负载均衡

  • 自动故障转移

  • 流量管理

  • 加密

  • 可观察性和可追溯性

  • 认证和授权

  • 网络自动化

2、工作原理

Consul Connect 是Consul附带的组件,用于启用服务网格功能。

服务网格通常由控制平面和数据平面组成。控制平面维护一个中央注册表,用于跟踪所有服务及其各自的 IP 地址,这称为服务发现。只要应用程序在控制平面上注册,控制平面就能够与网格的其他成员共享如何与应用程序通信,并强制执行谁可以相互通信的规则。

控制平面负责保护网格、促进服务发现、健康检查、策略实施和其他类似的操作问题。

数据平面处理服务之间的通信。许多服务网格解决方案使用sidecar代理来处理数据平面通信,因此限制了服务对网络环境所需的感知水平。

四、端口详解

Consul需要多达6个不同的端口才能正常工作,其中一些在TCP、UDP或两种协议上。

名称 默认端口 source dest 说明
DNS 8600 client & server client & server DNS接口用于解析DNS查询。(TCP和UDP)
HTTP 8500 client & server client & server HTTP API客户端端口。(TCP)
HTTPS 8501 client & server client & server 默认关闭,HTTPS API客户端端口
gRPC 8502 Envoy proxy 管理 sidecar agent服务注册的client或server 目前gRPC仅用于向Envoy代理公开xDS API,默认关闭。
Serf LAN 8301 client & server client & server 用于LAN gossip通信端口。(TCP和UDP)
Serf WAN 8302 server server server使用该端口通过WAN向server进行gossip通信。(TCP和UDP)
RPC 8300 client & server server server使用该端口处理来自其他agent的传入请求。(TCP)
Sidecar Proxy 21000 client & server 管理 sidecar agent服务注册的client或server 用于自动分配的sidecar服务注册的最小端口号。
Sidecar Proxy 21255 client & server 管理 sidecar agent服务注册的client或server 用于自动分配的sidecar服务注册的最大端口号。

五、安装部署

1、Server端部署

环境准备:

节点名称 IP
consul-server01 10.81.0.101
consul-server02 10.81.0.102
consul-server03 10.81.0.103

<!== 二进制安装 ==>

2、Client端部署

步骤与server端相同,此处列举不同处

3、加密通信

加密通信主要分为两类:gossip加密和TLS。TLS用于保护agent之间的RPC调用,因agent之间的goosip是通过UDP完成的,所以gossip通信用对称密钥来保护。

六、动态应用配置

Consul KV是Consul的一个核心功能,与Consul agent一起安装。Consul KV允许用户存储索引对象,尽管其主要用途是存储配置参数和元数据。它只是一个简单的KV存储,并不是一个全功能的数据存储。可以使用它来动态配置应用程序、协调服务、管理leader选举或用作 Vault的数据后端,以及其他用途。

Consul KV数据存储位于server上,但可以由任何agent(client或server)访问。原生集成的RPC功能允许client向server转发请求,包括键/值的读取和写入。Consul允许数据在所有server上自动复制。为了确保在完全中断的情况下不会丢失数据,请使用consul snapshot功能来备份数据。

七、服务发现

服务发现的主要目标之一是提供可用服务的目录。为此,agent提供了一种简单的服务定义格式,以声明服务的可用性,并可能将其与健康检查联系起来。与服务相关联的健康检查被认为是应用程序级的检查。在配置文件中定义服务或在运行时使用HTTP接口添加服务。

1、注册服务

服务定义文件要存放在-config-dir目录下以.json或.hcl结尾命名,使用consul reload命令更新注册服务。或者通过HTTP API动态注册。还可以Python、Java、.Net Core等的SDK进行注册。

以下是官方服务定义模板:

{
  "service": {
    //每个节点的服务必须具有唯一的ID,如果未指定,则该值将使用name字段。
    "id": "redis",
    //必须指定的服务名称
    "name": "redis",
    //添加服务标签
    "tags": ["primary"],
    //指定服务的IP地址或主机名,默认为agent节点的IP
    "address": "",
    //定义服务元数据,最多64个键值对的映射的对象,默认none
    "meta": {
      "meta": "for my service"
    },
    //标签地址是可以为节点或服务定义的额外地址。标签地址可以被远程agent和服务用作与给定节点或服务进行通信的替代地址,默认none
    "tagged_addresses": {
      //LAN标签地址
      "lan": {
        "address": "192.168.0.55",
        "port": 8000,
      },
      //WAN标签地址
      "wan": {
        "address": "198.18.0.23",
        "port": 80
      }
    },
    //指定服务特定端口号
    "port": 8000,
    //指定服务Unix域套接字路径,默认none
    "socket_path": "/tmp/redis.sock",
    //如果设置为 true,则外部agent可以更新目录中的此服务并修改标签。默认false
    "enable_tag_override": false,
    //定义服务健康检查,默认none
    "checks": [
      {
        "args": ["/usr/local/bin/check_redis.py"],
        "interval": "10s"
      }
    ],
    //用于标识服务是一个Connect代理。默认none
    "kind": "connect-proxy",
    //用于指定当前正在配置的服务所代理的目标服务的名称。默认none
    "proxy_destination_service": "redis",
    //服务定义允许一个可选的代理注册,默认none
    "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
      },
      "config": {},
      "upstreams": [],
      "mesh_gateway": {
        "mode": "local"
      },
      "expose": {
        "checks": true,
        "paths": [
          {
            "path": "/healthz",
            "local_path_port": 8080,
            "listener_port": 21500,
            "protocol": "http2"
          }
       ]
      }
    },
    //Consul Connect服务网格连接的对象,默认none
    "connect": {
      "native": false,
      "sidecar_service": {}
      "proxy": {  // Deprecated
        "command": [],
        "config": {}
      }
    },
    //根据其DNS服务(SRV)响应配置服务的权重。默认none
    "weights": {
      "passing": 5,
      "warning": 1
    },
    //指定用于注册服务的ACL令牌,默认none
    "token": "233b604b-b92e-48c8-a253-5f11514e4b50",
    //指定注册服务的Consul命名空间。默认none
    "namespace": "foo"
  }
}

使用Spring Cloud Consul进行服务注册:

  1. 添加consul发现客户端相应版本依赖

  2. 修改代码,application文件添加consul注册配置

    #连接consul agent节点地址
    spring.cloud.consul.host = localhost
    #连接consul agent节点端口
    spring.cloud.consul.port = 8500
    #是否启用spring cloud consul
    spring.cloud.consul.enabled = true
    #是否启用consul发现客户端
    spring.cloud.consul.discovery.enable = true
    #是否启用服务注册
    spring.cloud.consul.discovery.register = true
    #注册服务时使用的标签
    spring.cloud.consul.discovery.tags = live,prometheus
    #定义在服务列表中查询的标签
    spring.cloud.consul.discovery.default-query-tag = live
    #是否在consul中禁用自动注销服务。
    spring.cloud.consul.discovery.deregister = true
    #HTTP健康检查路径
    spring.cloud.consul.discovery.health-check-path = /actuator/health
    #执行HTTP健康检查的频率
    spring.cloud.consul.discovery.health-check-interval = 10s
    #HTTP健康检查超时时间
    spring.cloud.consul.discovery.health-check-timeout = 10s
    #HTTP健康检查失败多长时间后,会取消注册服务
    spring.cloud.consul.discovery.health-check-critical-timeout = 30m
    #是否启用TTL心跳检测,默认false
    spring.cloud.consul.discovery.heartbeat.enabled = false
    #心跳检测失败时重新注册服务
    spring.cloud.consul.discovery.heartbeat.reregister-service-on-failure = false
    #ttl存活时间
    spring.cloud.consul.discovery.heartbeat.ttl = 30s
    #是否注册时使用ip地址而不是主机名。
    spring.cloud.consul.discovery.prefer-ip-address = true
    #访问服务时使用的IP地址
    spring.cloud.consul.discovery.ip-address = ${spring.cloud.client.ipaddress}
    #唯一的服务实例ID
    spring.cloud.consul.discovery.instance-id = ${spring.application.name}:${spring.cloud.client.ipaddress}:${spring.application.instance_id:${server.port}}
    #注册服务的端口,默认为监听端口
    spring.cloud.consul.discovery.port = ${server.port}
    #初始重试时间间隔,以毫秒为单位
    spring.cloud.consul.retry.initial-interval = 10000
    

2、健康检查

agent的主要角色之一是管理系统级和应用程序级健康检查。如果健康检查与服务相关联,则它被认为是应用程序级别的。如果未与服务关联,则检查会监控整个节点的运行状况。

可以在你的服务定义中添加健康检查。健康检查执行若干安全功能,例如允许WEB均衡器优雅地移除故障节点,允许数据库替换故障的二级数据库。健康检查功能也被强烈地集成到DNS界面中。如果一个服务的健康检查失败或一个节点有任何失败的系统级检查,则DNS接口将从任何服务查询中忽略该节点。

健康检查名称会自动生成为service:<service-id>。如果注册了多个服务检查,ID将被生成为service:<service-id>:<num>,其中是一个从1开始的递增数字。

以上是常用的健康检查类型,更多类型请参考官网checks

3、查找服务

八、负载均衡集成

NGINX将通过CONSUL TEMPLATE从Consul服务发现中获得一个健康的服务器列表,并根据自己的配置均衡互联网流量到这些服务器。

Consul Template是一个简单而又强大的工具。启动时,它会读取一个或多个模板文件,并查询Consul以获取渲染它们所需的所有数据。通常,可以把consul-template作为一个守护程序运行,它将获取初始值,然后继续观察更新,每当数据中心发生相关更改时,就重新渲染模板。你也可以使用-once标志来获取并渲染一次模板,这对测试和设置脚本很有用。最后,模板还可以在更新过程完成后运行任意命令。例如,它可以在配置更改后向负载均衡器服务发送HUP信号。

部署流程如下:

  1. 将对应服务注册到consul中

  2. 在nginx节点上安装consul client及nginx

  3. 在nginx节点安装consul template

    wget https://releases.hashicorp.com/consul-template/0.29.0/consul-template_0.29.0_linux_amd64.zip
    unzip consul-template_0.29.0_linux_amd64.zip -d /usr/bin/
    
  4. 创建consul template配置文件

    可参考官方配置文件详解

    mkdir /etc/consul-template
    mkdir -p /data/logs/consul-template
    cat > /etc/consul-template/config.json <<'EOF'
    {
      "log_level": "info",
      "wait": {
        "min": "1s",
        "max": "3s"
      },
      "syslog": {
        "enabled": false
      },
      "template_error_fatal": false,
      "log_file": {
        "path": "/data/logs/consul-template/info.log",
        "log_rotate_bytes": 1024000000,
        "log_rotate_duration": "24h",
        "log_rotate_max_files": 7
      },
      "consul": {
        "address": "127.0.0.1:8500",
        "retry": {
          "enabled": true,
          "attempts": 12,
          "backoff": "250ms"
        },
        "transport": {
          "disable_keep_alives": false,
          "dial_keep_alive": "30s",
          "max_idle_conns_per_host": 256
        },
        "ssl": {
          "enabled": false,
        }
      },
      "template": {
        "source": "/usr/local/nginx-1.16.1/conf/vhosts/fps-task-worker.conf.ctmpl",
        "destination": "/usr/local/nginx-1.16.1/conf/vhosts/fps-task-worker.conf",
        "create_dest_dirs": true,
        "perms": "0644",
        "command": "/usr/local/nginx-1.16.1/sbin/nginx -s reload"
      }
    }
    EOF
    
  5. 创建模板文件

    <!== /usr/local/nginx-1.16.1/conf/vhosts/fps-task-worker.conf.ctmpl ==>

    upstream fpstaskworker {
    {{- range service "fps-task-worker" }}
      server {{ .Address }}:{{ .Port }};
    {{- end }}
    }
    server {
      listen          9102;
      server_name    localhost;
      charset utf-8;
      client_max_body_size    10m;
      client_body_buffer_size 128k;  
      location / {
        proxy_pass http://fpstaskworker;
        proxy_connect_timeout  600;
        proxy_send_timeout     600;
        proxy_read_timeout     600;
        proxy_buffer_size      4k;
        proxy_buffers          4 32k;
        proxy_busy_buffers_size 64k;
        proxy_temp_file_write_size 64k;
      }
    }
    
  6. 设置systemd管理consul-template

    cat >/etc/systemd/system/consul-template.service <<'EOF'
    [Unit]
    Description=consul-template
    Requires=network-online.target
    After=network-online.target consul.service vault.service
    
    [Service]
    EnvironmentFile=-/etc/consul-template
    User=root
    Group=root
    ExecStart=/usr/bin/consul-template $OPTIONS -config=/etc/consul-template/config.json
    Restart=on-failure
    KillSignal=SIGINT
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    systemctl daemon-reload
    systemctl start consul-template
    systemctl enable consul-template
    
上一篇下一篇

猜你喜欢

热点阅读