wmenjoy / awesome-knowleges

汇总有用的知识
38 stars 7 forks source link

Consul 学习 #8

Open wmenjoy opened 4 years ago

wmenjoy commented 4 years ago

Consul 概念

什么是consul

Consul官网描述如下:

Consul is a service mesh solution providing a full featured control plane with service discovery, configuration, and segmentation functionality. Each of these features can be used individually as needed, or they can be used together to build a full service mesh. Consul requires a data plane and supports both a proxy and native integration model. Consul ships with a simple built-in proxy so that everything works out of the box, but also supports 3rd party proxy integrations such as Envoy.

Consul 基本定位服务发现,服务配置,并且提供Service Mesh的控制面板功能,提供如下功能: 1. 服务发现: Consul 客户端可以注册一个服务,比如 api 接口或者 mysql 服务,其他的客户端可以通过 Consul 来发现这些服务的提供方。通过 DNS 或者 HTTP,引用可以很方便地找到它所依赖的服务。 2. 健康检查: Consul 客户端可以提供任意数量的健康检查,无论是特定服务(服务是否返回200状态)还是本地节点(比如内存使用率是否大于90%)。运维人员可以通过这些信息管理集群的健康情况,服务发现组件也可以使用这些信息过滤掉不健康节点。 3. KV 存储: 应用可以使用 Consul 的树状 key/value 存储做很多事情,比如动态配置,开关,协作,leader 选举等等。KV 存储使用的是 HTTP 接口,非常简单易用。 4. 服务通信加密: Consul 可以生成并分发 TLS 证书给服务,从而保证服务之间使用 TLS 通信。我们可以使用 intentions 组件来自定义允许哪些服务访问。使用 intentions 可以实时地操作服务隔离,这比使用复杂的网络拓扑和静态防火墙规则要简单很多。 5. 多数据中心: Consul 支持开箱即用的多数据中心功能。这意味着当工作区域扩展至多个的时候,用户不需要费心去创建额外的抽象层来满足多中心需求。 Consul 设计时就考虑到了对 DevOps 社区和应用开发者友好,这让它非常适合新兴的弹性架构。

工作原理图

consul_client

Consul 支持多中心,就如上图,有两个DataCenter, 通过互联网互联,只有Server 节点才能够跨数据中心通信, Server之间通过哦WAN GOSSIIP协议来沟通哦那个,内部存在Server和Agent节点,之间通过gossiip来维护关系, 数据的读写请求,既可以直接发送到Server,也可以通过Client使用RPC发送到Server。

Agent

Consul 系统的每个节点都是一些Agent, Agent 可以使Server或者Client模式

Client

负责转发所有的 RPC 到 server 节点,本身无状态且轻量级,因此可以部署大量的 client 节点

Server

负责的数据存储和数据的复制集,一般 Consul server 由 3-5 个结点组成来达到高可用,server 之间能够进行相互选举。一个 datacenter 推荐至少有一个 Consul server 的集群。

Consul 和其他软件的对比

和其他注册中心的简单比对

  consul zookeeper Eureka
APi 网关集成 1、可以借助于DNS2、可以单独集成API 1、需要单独集成API 1、需要单独集成API
CAP CP CP AP
KV 存储 支持 支持 不支持
spring-cloud集成 支持 支持 支持
一致性算法 Raft Zab -
分布式任务调度 没有现成的框架,需要做开发 elastic-job 没有
可靠性对机器数量的需求 5 3 3
多数据中心 支持 不支持 不支持
对外服务 Http和DNS 客户端 HTTP
开发语言 go java java

其他功能的对比

参看here

参考资料

  1. Consul 文档翻译
  2. Consul and Other Software
wmenjoy commented 4 years ago

Consul的安装和配置

手动步骤

1、下载 自己到consul下载页,根据操作系统的版本下载 如果需要从源代码编译,参考Compile From Source 2、解压缩 如果是二进制安装需要解压缩,

   unzip consul*.zip

3、添加到path路径

4、验证安装

$ consul
usage: consul [--version] [--help] <command> [<args>]

Available commands are:
    agent          Runs a Consul agent
    event          Fire a new event

参考

  1. Consul 安装和基本使用
  2. manual: install
wmenjoy commented 4 years ago

Consul服务注册和使用

为什么使用服务发现

防止硬编码、容灾、水平扩缩容、提高运维效率等等,只要你想使用服务发现总能找到合适的理由。

一般的说法是因为使用微服务架构。传统的单体架构不够灵活不能很好的适应变化,从而向微服务架构进行转换,而伴随着大量服务的出现,管理运维十分不便,于是开始搞一些自动化的策略,服务发现应运而生。所以如果需要使用服务发现,你应该有一些对服务治理的痛点。

但是引入服务发现就可能引入一些技术栈,增加系统总体的复杂度,如果你只有很少的几个服务,比如10个以下,并且业务不怎么变化,吞吐量预计也很稳定,可能就没有必要使用服务发现

服务发现原理

consul-service-discovery-principle 首先需要有一个正常的Consul集群,有Server,有Leader。这里在服务器Server1、Server2、Server3上分别部署了Consul Server,假设他们选举了Server2上的Consul Server节点为Leader。这些服务器上最好只部署Consul程序,以尽量维护Consul Server的稳定。

然后在服务器Server4和Server5上通过Consul Client分别注册Service A、B、C,这里每个Service分别部署在了两个服务器上,这样可以避免Service的单点问题。服务注册到Consul可以通过HTTP API(8500端口)的方式,也可以通过Consul配置文件的方式。Consul Client可以认为是无状态的,它将注册信息通过RPC转发到Consul Server,服务信息保存在Server的各个节点中,并且通过Raft实现了强一致性。

最后在服务器Server6中Program D需要访问Service B,这时候Program D首先访问本机Consul Client提供的HTTP API,本机Client会将请求转发到Consul Server,Consul Server查询到Service B当前的信息返回,最终Program D拿到了Service B的所有部署的IP和端口,然后就可以选择Service B的其中一个部署并向其发起请求了。如果服务发现采用的是DNS方式,则Program D中直接使用Service B的服务发现域名,域名解析请求首先到达本机DNS代理,然后转发到本机Consul Client,本机Client会将请求转发到Consul Server,Consul Server查询到Service B当前的信息返回,最终Program D拿到了Service B的某个部署的IP和端口。

参考

  1. Consul 服务注册和查询
  2. 使用Consul做服务发现的若干姿势
wmenjoy commented 4 years ago

Consul 做DNS Server 使用

Consul 相比于服务发现的软件的优势在于完美支持DNS 。这样可以使程序不需要高度集成Consul, 便可以使用服务发现的功能。尤其是Http的功能, 只需要把原先的域名,或者主机地址,替换为consul对应的dns name即可。下面我们来实际操作一下consul实现,集成DNS到系统中

集成方案

  1. Consul 默认监听8600端口,DNS Server默认是53端口,可以通过-dns-port来修改
  2. 我们有多种方法来集成DNS到现有系统,一种是通过DNS resolver library 指向到Consul, 另一种是使用Consul提供的recursors配置来完成非Consul查询的转发,最后一种是我们将我们的DNS Server服务,把Consul domain的请求转发到Consul Agent上来。接下来重点关注第二种,和第三种。

在调试的时候,我们可以使用 dig命令,来进行DNS实验 具体参考here

为了解析名称,Consul依赖于特定的查询格式,目前consul支持两种查询Node和service 查询,

Node 查询

node 查询只的是查询一个命名Node的IP地址 Node的格式如下

<node>.node[.datacenter].<domain>

其中datacenter 可选,如果没有值,使用agent的datacenter值,简单查询如下

### 查询Node
[root@fs03-192-168-xxx-xx ~]# ./consul catalog nodes
Node       ID        Address         DC
agent-one  774efd26  192.168.126.18  dc1

[root@fs03-192-168-xx-xx~]# dig @127.0.0.1 -p53 agent-one.node.consul

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> @127.0.0.1 -p53 agent-one.node.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4010
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;agent-one.node.consul.     IN  A

;; ANSWER SECTION:
agent-one.node.consul.  0   IN  A   192.168.126.18

;; ADDITIONAL SECTION:
agent-one.node.consul.  0   IN  TXT "consul-network-segment="

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: 四 1月 16 14:54:43 CST 2020
;; MSG SIZE  rcvd: 102

3 Service 查询

Service查询用于查询服务的提供者,Service查询支持两种查询 standard 和strict [RFC 2782](https://tools.ietf.org/html/rfc2782).


; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> @127.0.0.1 -p53 web.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3174
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;web.service.consul.        IN  A

;; ANSWER SECTION:
web.service.consul. 0   IN  A   192.168.126.18

;; ADDITIONAL SECTION:
web.service.consul. 0   IN  TXT "consul-network-segment="

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: 四 1月 16 15:06:45 CST 2020
;; MSG SIZE  rcvd: 99

RFC 2782 查询

_<service>._<protocol>[.service][.datacenter][.domain]

根据DNS标准,服务查询必须使用_作为service和protocol的前缀,用来阻止DNS命名冲突, protocol可以是service定义的各种标签,如果没有标签,请使用tcp来代替。

[root@fs03-192-168-xxx-xx ~]# dig @127.0.0.1 -p53 _web._tcp.service.consul

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-9.P2.el7 <<>> @127.0.0.1 -p53 _web._tcp.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15972
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;_web._tcp.service.consul.  IN  A

;; ANSWER SECTION:
_web._tcp.service.consul. 0 IN  A   192.168.126.18

;; ADDITIONAL SECTION:
_web._tcp.service.consul. 0 IN  TXT "consul-network-segment="

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: 四 1月 16 15:13:25 CST 2020
;; MSG SIZE  rcvd: 105

其他高级特性Prepared Query Lookups和 Connect_Capable Service Lookups参考官方文档即可

下面我们来处理在服务器上使用consul作为默认的DNS

使用recursors 实现

  1. 启动的时候,指定recursor参数, 如果喜欢默认端口,可以通过-dns-port来指定
    ./consul agent -server -bootstrap-expect=1 -data-dir=/tmp/consul -node=agent-one -bind=192.168.xxx.xx -enable-script-checks=true -config-dir=./consul.d -client 0.0.0.0 -ui -dns-port=53  -recursor=8.8.8.8&
  2. 修改 vim /etc/resolv.conf 替换原来的nameserver为
    nameserver 127.0.0.1
  3. 好了现在就可以通过注册服务来尝试Consul作为默认的DNS了
[root@fs03-192-168-xxx-xx ~]# mkdir consul.d
[root@fs03-192-168-xxx-xx ~]# echo '{"service": {"name": "web", "tags": ["rails"], "port": 80}}'  | sudo tee ./web.json
[root@fs03-192-168-xxx-xx ~]# ./consul agent -server -bootstrap-expect=1 -data-dir=/tmp/consul -node=agent-one -bind=192.168.xxx.xx -enable-script-checks=true -config-dir=./consul.d -client 0.0.0.0 -ui -dns-port=53  -recursor=8.8.8.8&
[root@fs03-192-168-xxx-xx ~]# dig @127.0.0.1 -p53 _web._tcp.service.consul

使用DNS 转发到Consul

这个参考Forward DNS

开启DNS Cache

默认的配置,需要每次都去查询DNS服务器,这样在QPS高的情况下,DNS解析会对性能有很大影响,如果能够容忍短暂的因DNS未同步缓存导致的问题,可以考虑使用DNS cache

{
  "dns_config": {
    "service_ttl": {
      "*": "10s"
    },
    "node_ttl": "10s"
  }
}

当然还有许多调优的参数,具体参考DNS Caching

参考

  1. DNS Interface
  2. Using Consul DNS Interface
wmenjoy commented 4 years ago
  1. Consul的反熵
  2. 使用Consul做leader选举的方案
wmenjoy commented 4 years ago

Consul Agent 参数

Usage: consul agent [options]

  Starts the Consul agent and runs until an interrupt is received. The
  agent represents a single node in a cluster.

HTTP API Options

  -datacenter=<value>
     Datacenter of the agent.

Command Options

  -advertise=<value>
     Sets the advertise address to use.

  -advertise-wan=<value>
     Sets address to advertise on WAN instead of -advertise address.

  -allow-write-http-from=<value>
     Only allow write endpoint calls from given network. CIDR format,
     can be specified multiple times.

  -alt-domain=<value>
     Alternate domain to use for DNS interface.

  -bind=<value>
     Sets the bind address for cluster communication.

  -bootstrap
     Sets server to bootstrap mode.

  -bootstrap-expect=<value>
     Sets server to expect bootstrap mode.

  -check_output_max_size=<value>
     Sets the maximum output size for checks on this agent

  -client=<value>
     Sets the address to bind for client access. This includes RPC, DNS,
     HTTP, HTTPS and gRPC (if configured).

  -config-dir=<value>
     Path to a directory to read configuration files from. This
     will read every file ending in '.json' as configuration in this
     directory in alphabetical order. Can be specified multiple times.

  -config-file=<value>
     Path to a file in JSON or HCL format with a matching file
     extension. Can be specified multiple times.

  -config-format=<value>
     Config files are in this format irrespective of their extension.
     Must be 'hcl' or 'json'

  -data-dir=<value>
     Path to a data directory to store agent state.

  -dev
     Starts the agent in development mode.

  -disable-host-node-id
     Setting this to true will prevent Consul from using information
     from the host to generate a node ID, and will cause Consul to
     generate a random node ID instead.

  -disable-keyring-file
     Disables the backing up of the keyring to a file.

  -dns-port=<value>
     DNS port to use.

  -domain=<value>
     Domain to use for DNS interface.

  -enable-local-script-checks
     Enables health check scripts from configuration file.

  -enable-script-checks
     Enables health check scripts.

  -encrypt=<value>
     Provides the gossip encryption key.

  -grpc-port=<value>
     Sets the gRPC API port to listen on (currently needed for Envoy xDS
     only).

  -hcl=<value>
     hcl config fragment. Can be specified multiple times.

  -http-port=<value>
     Sets the HTTP API port to listen on.

  -join=<value>
     Address of an agent to join at start time. Can be specified
     multiple times.

  -join-wan=<value>
     Address of an agent to join -wan at start time. Can be specified
     multiple times.

  -log-file=<value>
     Path to the file the logs get written to

  -log-level=<value>
     Log level of the agent.

  -log-rotate-bytes=<value>
     Maximum number of bytes that should be written to a log file

  -log-rotate-duration=<value>
     Time after which log rotation needs to be performed

  -log-rotate-max-files=<value>
     Maximum number of log file archives to keep

  -node=<value>
     Name of this node. Must be unique in the cluster.

  -node-id=<value>
     A unique ID for this node across space and time. Defaults to a
     randomly-generated ID that persists in the data-dir.

  -node-meta=<key:value>
     An arbitrary metadata key/value pair for this node, of the format
     `key:value`. Can be specified multiple times.

  -non-voting-server
     (Enterprise-only) This flag is used to make the server not
     participate in the Raft quorum, and have it only receive the data
     replication stream. This can be used to add read scalability to
     a cluster in cases where a high volume of reads to servers are
     needed.

  -pid-file=<value>
     Path to file to store agent PID.

  -protocol=<value>
     Sets the protocol version. Defaults to latest.

  -raft-protocol=<value>
     Sets the Raft protocol version. Defaults to latest.

  -recursor=<value>
     Address of an upstream DNS server. Can be specified multiple times.

  -rejoin
     Ignores a previous leave and attempts to rejoin the cluster.

  -retry-interval=<value>
     Time to wait between join attempts.

  -retry-interval-wan=<value>
     Time to wait between join -wan attempts.

  -retry-join=<value>
     Address of an agent to join at start time with retries enabled. Can
     be specified multiple times.

  -retry-join-wan=<value>
     Address of an agent to join -wan at start time with retries
     enabled. Can be specified multiple times.

  -retry-max=<value>
     Maximum number of join attempts. Defaults to 0, which will retry
     indefinitely.

  -retry-max-wan=<value>
     Maximum number of join -wan attempts. Defaults to 0, which will
     retry indefinitely.

  -segment=<value>
     (Enterprise-only) Sets the network segment to join.

  -serf-lan-bind=<value>
     Address to bind Serf LAN listeners to.

  -serf-lan-port=<value>
     Sets the Serf LAN port to listen on.

  -serf-wan-bind=<value>
     Address to bind Serf WAN listeners to.

  -serf-wan-port=<value>
     Sets the Serf WAN port to listen on.

  -server
     Switches agent to server mode.

  -server-port=<value>
     Sets the server port to listen on.

  -syslog
     Enables logging to syslog.

  -ui
     Enables the built-in static web UI server.

  -ui-content-path=<value>
     Sets the external UI path to a string. Defaults to: /ui/

  -ui-dir=<value>
     Path to directory containing the web UI resources.
wmenjoy commented 4 years ago

服务发现工具对比

Feature Consul zookeeper etcd euerka
服务健康检查 服务状态内存,硬盘等 (弱)长连接,keepalive 连接心跳 可配支持
多数据中心 支持
kv存储服务 支持 支持 支持
一致性 raft paxos raft
cap ca cp cp ap
使用接口(多语言能力) 支持http和dns 客户端 http/grpc http(sidecar)
watch支持 全量/支持long polling 支持 支持 long polling 支持 long polling/大部分增量
自身监控 metrics metrics metrics
安全 acl /https acl https支持(弱)
spring cloud集成 已支持 已支持 已支持 已支持

1.ETCD、Consul、Zookeeper、Etcd、Eureka对比

wmenjoy commented 4 years ago

consul-template

参考

  1. consul 0.25.0 · helm/hashicorp
  2. hashicorp/consul-template: Template rendering, notifier, and supervisor for @HashiCorp Consul and Vault data.
  3. stakater/dockerfile-nginx-with-consul-template: dockerfile of nginx with consul template