consul是使用go语言开发的服务发现、配置管理中心服务。内置了服务注册与发现框 架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。服务部署简单,只有一个可运行的二进制的包。每个节点都需要运行agent,他有两种运行模式server和client。每个数据中心官方建议需要3或5个server节点以保证数据安全,同时保证server-leader的选举能够正确的进行。
产品具有以下特点:
服务发现
Consul 的客户端可以注册一个服务,例如 api 或 mysql,其他客户端可以使用 Consul 来发现给定服务的提供者。
健康检查
Consul 可以根据给定的信息,对服务的状态进行检查,并获取服务的健康状态。
Key/Value存储
通过HTTP API的方式实现Key/Value存储,可用于动态配置、功能标记、协商等多种场景。
多数据中心支持
支持多数据中心的分布式架构。
Consul角色
-
client: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群.
-
server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其他数据中心通讯. 每个数据中心的 server 数量推荐为 3 个或是 5 个.
2、consul二进制安装
wget https://releases.hashicorp.com/consul/1.14.1/consul_1.14.1_linux_amd64.zip unzip consul_1.14.1_linux_amd64.zip mv consul /usr/local
2.2 启动Consul
./consul agent -server -bootstrap -bind=192.168.100.221 -client=192.168.100.221 -data-dir=data -ui -node=192.168.100.221 &
2.3 consul启动参数介绍
-server :定义agent运行在server模式 -bootstrap-expect :在一个datacenter中期望提供的server节点数目,当该值提供的时候,consul一直等到达到指定sever数目的时候才会引导整个集群,该标记不能和bootstrap共用 -data-dir:提供一个目录用来存放agent的状态,所有的agent允许都需要该目录,该目录必须是稳定的,系统重启后都继续存在 -node:节点在集群中的名称,在一个集群中必须是唯一的,默认是该节点的主机名 -bind:该地址用来在集群内部的通讯,集群内的所有节点到地址都必须是可达的,默认是0.0.0.0 -ui:启动web界面 -config-dir:配置文件目录,里面所有以.json结尾的文件都会被加载 -rejoin:使consul忽略先前的离开,在再次启动后仍旧尝试加入集群中。 -client:consul服务侦听地址,这个地址提供HTTP、DNS、RPC等服务,默认是127.0.0.1所以不对外提供服务,如果你要对外提供服务改成0.0.0.0
通过system启动consul
vim /etc/consul/consul.json { "datacenter": "Consul", "data_dir": "/opt/consul/data", "log_level": "INFO", "enable_debug": false, "bind_addr": "0.0.0.0", "client_addr": "0.0.0.0", "server": true, "bootstrap_expect": 1, "ui_config": { "enabled": true } }
vim /etc/systemd/system/consul.service [Unit] Description=Consul Service Discovery Agent Documentation=https://www.consul.io/ After=network-online.target Wants=network-online.target [Service] Type=simple User=root Group=root ExecStart=/usr/local/bin/consul agent -server -ui -config-dir /etc/consul ExecReload=/bin/kill -s SIGHUP $MAINPID ExecStop=/bin/kill -INT $MAINPID ExecReload=/bin/kill -HUP KillSignal=SIGINT TimeoutStopSec=5 Restart=on-failure SyslogIdentifier=consul [Install] WantedBy=multi-user.target systemctl daemon-reload && systemctl restart consul
通过配置文件的方式注册 node-exporter 服务到 Consul
#多个node-exporter写在一个文件中 { "services": [ { "name": "node_exporter_20", "tags": ["node20"], "address": "10.10.0.20", "port": 9100, "check": [ { "http": "http://10.10.0.20:9100/metrics", "interval": "10s" } ] }, { "name": "node_exporter_21", "tags": ["node21"], "address": "10.10.0.21", "port": 9100, "check": [ { "http": "http://10.10.0.21:9100/metrics", "interval": "10s" } ] } ] }
一个node-exporter写一个json文件
{ "service": { "name": "node_exporter66", "tags": ["node66"], "address": "10.10.0.66", "port": 9100, "check": { "http": "http://10.10.0.66:9100/metrics", "interval": "10s" } } }
Docker 安装 使用 Docker 启动 Consul 单节点服务,直接获取最新版官方镜像 consul:latest 命令如下:
docker run --name consul -d -p 8500:8500 consul
2.3 访问
打开浏览器,访问http://<cousul_ip>:8500,可看到Consul已经正常启动,目前只有默认的consul服务。
Consul API 注册 node-exporter 服务到 Consul
通过 API 注册node-exporter 服务信息到 Consul 中,服务地址及端口为 node-exporter 默认提供指标数据的地址。注意:服务注册到Consul的id不能相同。
Consul API注册"id=node-exporter"服务 #用curl的方式注册到Consul中
curl -X PUT -d '{"id": "node-exporter","name": "node-exporter-192.168.100.221","address": "192.168.100.221","port": 9100,"tags": ["node-exporter"],"Meta":{"app": "linux-node","project": "yewu"},"checks": [{"http": "http://192.168.100.221:9100/metrics", "interval": "5s"}]}' http://192.168.100.221:8500/v1/agent/service/register
Consul Web 控制台 查看注册服务
Consul API 注销"id=node-exporter" 服务
curl -X PUT http://192.168.100.221:8500/v1/agent/service/deregister/node-exporter
Prometheus 实现自动服务发现
vim /usr/local/prometheus/prometheus.yml
- job_name: 'consul-node-exporter' consul_sd_configs: - server: '192.168.100.221:8500' services: [] relabel_configs: - source_labels: [__meta_consul_tags] regex: .*node* action: keep - source_labels: ['__meta_consul_service'] regex: '(.*)' target_label: 'job' replacement: '$1' - source_labels: ['__meta_consul_service_address'] regex: '(.*)' target_label: 'instance' replacement: '$1' - source_labels: ['__meta_consul_service_metadata_project'] regex: '(.*)' target_label: 'project' replacement: '$1'
高级配置 把标签全部打印出来:
- job_name: 'consul61' metrics_path: /metrics scheme: http consul_sd_configs: - server: "10.10.0.61:8500" services: [] relabel_configs: - source_labels: [__meta_consul_tags] action: keep regex: .*node.* - source_labels: ['__meta_consul_service'] regex: '(.*)' target_label: 'job' replacement: '$1' - source_labels: ['__meta_consul_service_address'] regex: '(.*)' target_label: 'instance' replacement: '$1' #标签全部打印出来配置 - source_labels: ['__meta_consul_service_metadata'] regex: __meta_consul_service_metadata_(.+) action: labelmap
注释 :consul_sd_configs 配置使用 Consul 服务发现类型
server 指定Consul 的服务地址
relabel_configs 用来实现自定义标签及分类
Prometheus的restful接口热加载配置
curl -X POST http://127.0.0.1:9090/-/reload
#######################################上面配置意图如下
1.会发现 Prometheus 同时加载出来了默认服务 consul,这个是不需要的。 2.默认只显示 job 及 instance 两个标签,其他标签都默认属于 before relabeling 下,有些必要的服务信息,也想要在标签中展示,该如何操作呢? 3.如果需要自定义一些标签,例如 team、group、project 等关键分组信息,方便后边 alertmanager 进行告警规则匹配,该如何处理呢? 4.所有 Consul 中注册的 Service 都会默认加载到 Prometheus 下配置的 consul_prometheus 组,如果有多种类型的 exporter,如何在 Prometheus 中配置分配给指定类型的组,方便直观的区别它们?
以上问题,我们可以通过 Prometheus 配置中的 relabel_configs
参数来解决
6、配置 relabel_configs 实现自定义标签及分类
我们先来普及一下 relabel_configs 的功能, Prometheus 允许用户在采集任务设置中,通过 relabel_configs 来添加自定义的 Relabeling 的额过程,来对标签进行指定规则的重写。 Prometheus 加载 Targets 后,这些 Targets 会自动包含一些默认的标签,Target 以 __ 作为前置的标签是在系统内部使用的,这些标签不会被写入到样本数据中。眼尖的会发现,每次增加 Target 时会自动增加一个 instance 标签,而 instance 标签的内容刚好对应 Target 实例的 address 值,这是因为实际上 Prometheus 内部做了一次标签重写处理,默认 address 标签设置为 : 地址,经过标签重写后,默认会自动将该值设置为 instance 标签,所以我们能够在页面看到该标签。
详细 relabel_configs
配置及说明可以参考 relabel_config 官网说明,这里我简单列举一下里面每个 relabel_action
的作用,方便下边演示。
1.replace: 根据 regex 的配置匹配 source_labels标签的值(注意:多个 source_label的值会按照 separator 进行拼接),并且将匹配到的值写入到 target_label当中,如果有多个匹配组,则可以使用 ${1}, ${2} 确定写入的内容。如果没匹配到任何内容则不对 target_label进行重新, 默认为 replace。
2.keep: 丢弃 source_labels 的值中没有匹配到 regex 正则表达式内容的 Target 实例 3.drop: 丢弃 source_labels 的值中匹配到 regex 正则表达式内容的 Target 实例 4.hashmod: 将 target_label 设置为关联的 source_label的哈希模块 5.labelmap: 根据 regex 去匹配 Target 实例所有标签的名称(注意是名称),并且将捕获到的内容作为为新的标签名称,regex 匹配到标签的的值作为新标签的值 6.labeldrop: 对 Target 标签进行过滤,会移除匹配过滤条件的所有标签 7.labelkeep: 对 Target 标签进行过滤,会移除不匹配过滤条件的所有标签
接下来,我们来挨个处理上述问题。
问题一,我们可以配置 relabel_configs 来实现标签过滤,只加载符合规则的服务。以上边为例,可以通过过滤 __meta_consul_tags 标签为 test 的服务,relabel_config 向 Consul 注册服务的时候,只加载匹配 regex 表达式的标签的服务到自己的配置文件。修改 prometheus.yml 配置如下:
... - job_name: 'consul-prometheus' consul_sd_configs: - server: '172.30.12.167:8500' services: [] relabel_configs: - source_labels: [__meta_consul_tags] regex: .*test.* action: keep
解释下,这里的 relabel_configs 配置作用为丢弃源标签中 meta_consul_tags 不包含 test 标签的服务,meta_consul_tags 对应到 Consul 服务中的值为 “tags”: [“test”],默认 consul 服务是不带该标签的,从而实现过滤。重启 Prometheus 可以看到现在只获取了 node-exporter-172.30.12.167 这个服务了。
问题二和问题三可以归为一类,就是将系统默认标签或者用户自定义标签转换成可视化标签,方便查看及后续 Alertmanager 进行告警规则匹配分组。不过要实现给服务添加自定义标签,我们还得做一下修改,就是在注册服务时,将自定义标签信息添加到 Meta Data 数据中,具体可以参考 这里 官网说明,下边来演示一下如何操作。
对于自定义标签的添加,可通过json文件的方式进行操作。
新建 node1.json
如下:
$ vim node1.json { "ID": "node-exporter", "Name": "node-exporter-172.30.12.167", "Tags": [ "test" ], "Address": "172.30.12.167", "Port": 9100, "Meta": { "app": "spring-boot", "team": "appgroup", "project": "bigdata" }, "EnableTagOverride": false, "Check": { "HTTP": "http://172.30.12.167:9100/metrics", "Interval": "10s" } }
注释:ID 指定实例的唯一ID名称;Name 指定服务名,可以多个实例共用服务名;Tags 指定服务的标签列表//可写可不写,这些标签可用于过滤服务,并通过API进行公开;Address 指定服务的实例地址;Port 指定实例的端口号;Meta 指定服务的元数据,格式为key:value,此处用于保存我们的标签信息;EnableTagOverride 此处禁用服务标签的反熵功能;Check 服务的检查列表,Consul会根据配置信息定时发起检查,确定服务是否正常;
通过json文件注册服务
curl --request PUT --data @node1.json http://192.168.75.160:8500/v1/agent/service/register
示例:
{ "services": [ { "id": "stfp-test-206", "name": "测试sftp", "address": "10.75.43.206", "port": 9100, "meta": { "project": "SFTP", "env": "test", "service": "sftp", "user": "刘汉宝", "phone": "15721586305" }, "checks": [ { "tcp": "10.75.13.10:9100", "interval": "10s" } ] }, { "id": "prod-java-node-11", "name": "收银平台", "address": "10.75.13.11", "port": 9100, "meta": { "project": "收银平台", "env": "prod", "service": "核心区", "user": "钟佳林", "phone": "xxx" }, "checks": [ { "tcp": "10.75.13.11:9100", "interval": "10s" } ] } ] }
5.3 查看Consul
查看Consul,可看到实例的元数据中已包含标签信息
5.4 查看Prometheus
元数据在Prometheus自动发现的过程中,会变成以_meta_consul_service_metadata开头的标签,如下图所示。
我们可以通过前面介绍的Relabeling(标签重写)功能,将其转换为我们需要的标签。
将job进行如下修改:
- job_name: 'consul-prom' consul_sd_configs: - server: '192.168.75.160:8500' services: ['node_exporter'] relabel_configs: - regex: __meta_consul_service_metadata_(.+) action: labelmap
5.5 重新加载配置
重新加载配置后,可看到标签已经生成。
#生成环境配置 - job_name: consul服务发现 consul_sd_configs: - server: "10.75.41.115:8500" refresh_interval: 10s relabel_configs: - regex: __meta_consul_service_metadata_(.*) replacement: $1
Consul 集群部署
Consul角色
-
client: 客户端, 无状态, 将 HTTP 和 DNS 接口请求转发给局域网内的服务端集群.
-
server: 服务端, 保存配置信息, 高可用集群, 在局域网内与本地客户端通讯, 通过广域网与其他数据中心通讯. 每个数据中心的 server 数量推荐为 3 个或是 5 个.
此处采用的是 3Server + 1Client 的集群架构
1、安装 Consul 配置主机名,命令示例:(以下操作在所有节点配置)
hostnamectl set-hostname consul-01 hostnamectl set-hostname consul-02 hostnamectl set-hostname consul-03 hostnamectl set-hostname consul-client
下载consul二进制文件
export VER="1.12.3" wget https://releases.hashicorp.com/consul/${VER}/consul_${VER}_linux_amd64.zip
解压安装
apt install -y unzip unzip consul_${VER}_linux_amd64.zip -d /usr/local/bin/
查看版本
consul version 1
创建consul用户和组
sudo groupadd --system consul sudo useradd -s /sbin/nologin --system -g consul consul
创建consul安装目录
mkdir -p /data/consul/{config,data,logs} chown -R consul:consul /data/consul chmod -R 775 /data/consul
设置 DNS 或编辑/etc/hosts 文件以配置所有服务器的主机名,替换example.com为您的实际域名。
cat >/etc/hosts<<EOF 192.168.94.10 consul-01.example.com consul-01 192.168.94.11 consul-02.example.com consul-02 192.168.94.12 consul-03.example.com consul-03 192.168.94.13 consul-client.example.com consul-client EOF
2、Server 节点配置
生成Consul secret
consul keygen
为server节点创建json配置文件,其他节点配置修改IP地址及节点名称即可
consul-01节点
cat >/data/consul/config/consul.json<<EOF { "advertise_addr": "192.168.94.10", "bind_addr": "192.168.94.10", "bootstrap_expect": 3, "client_addr": "0.0.0.0", "datacenter": "DC1", "node_name": "consul-01", "data_dir": "/data/consul/data", "domain": "consul", "enable_script_checks": true, "dns_config": { "enable_truncate": true, "only_passing": true }, "enable_syslog": true, "encrypt": "F0VSq05Die32sMUimbZ2LAzUIc5Ry4jCL2ouwz/Gu8Q=", "leave_on_terminate": true, "log_level": "INFO", "rejoin_after_leave": true, "retry_join": [ "consul-01", "consul-02", "consul-03" ], "server": true, "start_join": [ "consul-01", "consul-02", "consul-03" ], "ui": true } EOF
配置参数说明:
datacenter:此标志控制运行代理的数据中心。如果未提供,则默认为dc1。Consul 对多个数据中心有一流的支持,但它依赖于正确的配置。同一数据中心中的节点应位于单个 LAN 上。 data_dir:该标志为代理提供了一个数据目录来存储状态。 node_name:节点名字,一般为主机名。 server:指定是否为server节点。 bootstrap_expect:在一个datacenter中期望提供的server节点数目,当提供该值的时候,consul一直等到达到指定sever数目才会引导整个集群,该标记不能和bootstrap公用。 bind_addr:该地址用来在集群内部的通讯,集群内的所有节点到地址都必须是可达的,默认是0.0.0.0。 client_addr:Consul 将绑定客户端接口的地址,包括 HTTP 和 DNS 服务器。默认情况下,这是127.0.0.1,仅允许环回连接。在 Consul 1.0 及更高版本中,这可以设置为要绑定到的以空格分隔的地址列表。 log_json:此标志使代理能够以 JSON 格式输出日志。默认为false。 log_level:在 Consul 代理启动后显示的日志级别。默认为 info 。可用的日志级别是trace、debug、info、warn和err。 retry_join:指定将要置入集群的IP列表,如果失败,会自动重试,知道直到成功加入。 start_join:启动时加入集群的地址 ui_config:此对象允许设置多个子键,用于控制 UI 中可用的显示或功能。 rejoin_after_leave :允许重新加入集群
consul-02节点
cat >/data/consul/config/consul.json<<EOF { "advertise_addr": "192.168.94.11", "bind_addr": "192.168.94.11", "bootstrap_expect": 3, "client_addr": "0.0.0.0", "datacenter": "DC1", "node_name": "consul-02", "data_dir": "/data/consul/data", "domain": "consul", "enable_script_checks": true, "dns_config": { "enable_truncate": true, "only_passing": true }, "enable_syslog": true, "encrypt": "F0VSq05Die32sMUimbZ2LAzUIc5Ry4jCL2ouwz/Gu8Q=", "leave_on_terminate": true, "log_level": "INFO", "rejoin_after_leave": true, "retry_join": [ "consul-01", "consul-02", "consul-03" ], "server": true, "start_join": [ "consul-01", "consul-02", "consul-03" ], "ui": true } EOF
consul-03节点
cat >/data/consul/config/consul.json<<EOF { "advertise_addr": "192.168.94.12", "bind_addr": "192.168.94.12", "bootstrap_expect": 3, "client_addr": "0.0.0.0", "datacenter": "DC1", "node_name": "consul-03", "data_dir": "/data/consul/data", "domain": "consul", "enable_script_checks": true, "dns_config": { "enable_truncate": true, "only_passing": true }, "enable_syslog": true, "encrypt": "F0VSq05Die32sMUimbZ2LAzUIc5Ry4jCL2ouwz/Gu8Q=", "leave_on_terminate": true, "log_level": "INFO", "rejoin_after_leave": true, "retry_join": [ "consul-01", "consul-02", "consul-03" ], "server": true, "start_join": [ "consul-01", "consul-02", "consul-03" ], "ui": true } EOF
3、Client 节点配置 client是consul客户端,客户端不保存数据,客户端将接收到的请求转发给Server端。Server之间通过局域网或广域网通信实现数据一致性。每个Server或Client都是一个consul agent。
创建consul-client节点配置文件
cat >/data/consul/config/consul.json<<EOF { "advertise_addr": "192.168.94.13", "bind_addr": "192.168.94.13", "client_addr": "0.0.0.0", "datacenter": "DC1", "node_name": "consul-client", "data_dir": "/data/consul/data", "domain": "consul", "enable_script_checks": true, "dns_config": { "enable_truncate": true, "only_passing": true }, "enable_syslog": true, "encrypt": "F0VSq05Die32sMUimbZ2LAzUIc5Ry4jCL2ouwz/Gu8Q=", "leave_on_terminate": true, "log_level": "INFO", "rejoin_after_leave": true, "retry_join": [ "consul-01", "consul-02", "consul-03" ], "server": false, "start_join": [ "consul-01", "consul-02", "consul-03" ], "ui": true } EOF
4、systemd 启动文件
所有节点创建systemd 服务文件/etc/systemd/system/consul.service
,所有节点具有相同内容,配置如下:
cat >/etc/systemd/system/consul.service<<EOF [Unit] Description=Consul Service Discovery Agent Documentation=https://www.consul.io/ After=network-online.target Wants=network-online.target [Service] Type=simple User=consul Group=consul ExecStart=/usr/local/bin/consul agent -config-dir=/data/consul/config/consul.json ExecReload=/bin/kill -HUP $MAINPID KillSignal=SIGINT TimeoutStopSec=5 Restart=on-failure SyslogIdentifier=consul [Install] WantedBy=multi-user.target EOF
所有节点启动consul服务
systemctl enable --now consul.service
查看consul服务运行状态
systemctl status consul
5、查看 Consul 集群状态 3 台 Server 和 1 台 Client 上的 Consul 服务都启动后会根据 consul.json 中的配置自动组成一个集群,并且 Server 会通过 Raft 协议在 Server 节点中选举出 leader 节点。
可以用如下命令在任意一台机器上查看集群节点状态:
root@consul-01:~# consul members Node Address Status Type Build Protocol DC Partition Segment consul-01 192.168.94.10:8301 alive server 1.12.3 2 dc1 default <all> consul-02 192.168.94.11:8301 alive server 1.12.3 2 dc1 default <all> consul-03 192.168.94.12:8301 alive server 1.12.3 2 dc1 default <all> consul-client 192.168.94.13:8301 alive client 1.12.3 2 dc1 default <default>
查看server节点成员状态信息:
root@consul-01:~# consul operator raft list-peers Node ID Address State Voter RaftProtocol consul-02 edefb129-e0fd-804d-bbfb-76e259077d03 192.168.94.11:8300 leader true 3 consul-01 50f9830f-45cd-683c-2382-77e1cf6d6e48 192.168.94.10:8300 follower true 3 consul-03 5dae09d2-7079-4611-1ab5-7728d0966cbe 192.168.94.12:8300 follower true 3
访问Consul UI: http://192.168.94.10:8500/ui
集群就搭建完成了