Consul初步了解(一)
官网地址:https://www.consul.io/ #Consul是HashiCorp公司推出的开源软件你点几下载文档之类的就会跳转到developer.hashicorp.com
一、Consul介绍
1.1 什么是Consul
Consul是由HashiCorp公司用Go语言开发得开源软件,提供了微服务系统中的服务治理、配置中心等功能。做服务发现的常用的有zookeeper/eureka/etcd/consul,具体的可自行搜索。
Consul使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接. 相比较而言, zookeeper 采用的是 Paxos, 而 etcd 使用的则是 Raft。
Consul 提供的关键功能:
服务发现:Consul的客户端可以注册服务,使用DNS或HTTP,应用程序可以轻松找到它们所依赖的服务。 运行状况检查:Consul客户端可以提供任意数量的运行状况检查,服务发现组件使用此信息将流量路由远离不健康主机。 KV存储:应用程序可以将Consul的层级键/值存储用于任何目的,包括动态配置,功能标记,协调,领导者选举等。简单的HTTP API使其易于使用。 安全服务通信:Consul可以为服务生成和分发TLS证书,以建立相互的TLS连接。当然还有ACL功能通过token控制读写权限。 多数据中心:Consul支持多个数据中心。
1.2 Glossary(术语表)
Agent:代理是在Consul集群的每个成员上长时间运行的守护进程。它是通过运行consul代理启动的。代理可以在客户端或服务器模式下运行。
由于所有节点都必须运行代理,因此将节点称为client或server更简单,但是agent还有其他实例。所有agent都可以运行DNS或HTTP接口,并负责运行检查和保持服务同步。
Client:客户端是将所有rpc转发给服务器的代理。客户机是相对无状态的。客户端执行的唯一后台活动是参与LAN gossip pool。这具有最小的资源开销,并且只消耗少量的网络带宽。
Server:服务端是一个具有扩展职责的agent,包括参与Raft仲裁、维护集群状态、响应RPC查询、与其他数据中心交换WAN gossip,以及将查询转发给领导者或远程数据中心。
Datacenter(数据中心):将数据中心定义为私有、低延迟和高带宽的网络环境。这不包括通过公共互联网的通信,但就目的而言,单个EC2区域内的多个可用区将被视为单个数据中心的一部分。
Consensus(共识): 使用共识来表示对当选leader的同意以及对交易顺序的同意。由于这些事务应用于有限状态机,对共识的定义意味着复制状态机的一致性。
Gossip:Consul建立在Serf之上,Serf提供了一个用于多种目的的完整gossip协议。Serf提供成员资格、故障检测和事件广播。
LAN Gossip:LAN gossip pool其中包含所有位于同一局域网或数据中心的节点。
WAN Gossip:WAN gossip pool这些服务器主要位于不同的数据中心,通常通过互联网或广域网进行通信。
RPC:远程过程调用。这是一种请求/响应机制,允许客户端向服务器发出请求。
Raft协议: 主要负责leader选举和日志同步。
下面是Consul Glossary
Access Control List (ACL):访问控制列表(ACL)是文件、文件夹或其他对象的用户权限列表。它定义了哪些用户和组可以访问对象以及可以执行哪些操作。Consul使用访问控制列表(ACL)来保护UI、API、CLI、服务通信和代理通信。
API Gateway:应用程序编程接口(Application Programming Interface,API)是一种允许两个应用程序进行通信的通用软件接口。大多数现代应用程序都是使用API构建的。API网关是使用API构建的这些现代应用程序的单一入口点。
Application Security:应用程序安全是通过检测和修复任何威胁或信息泄漏来使应用程序安全的过程。这可以在应用程序开发生命周期期间或之后完成;
Application Services:应用程序服务是一组服务,如部署、运行和改进应用程序所需的应用程序性能监控、负载平衡、服务发现、服务代理、安全性、自动缩放等。
Authentication and Authorization (AuthN and AuthZ):身份验证(AuthN)处理建立用户身份,而授权(AuthZ)根据用户身份允许或拒绝访问用户。
Auto Scaling Groups:自动扩展组是AWS特有的术语,表示一组Amazon EC2实例,这些实例被视为一个逻辑分组,用于自动扩展和管理。
Autoscaling:自动缩放是根据网络流量要求自动缩放计算资源的过程。自动缩放可以水平或垂直进行。水平扩展是通过向资源池中添加更多机器来实现的,而垂直扩展意味着增加现有机器的容量。
Blue-Green Deployments:蓝绿部署是一种部署方法,旨在通过运行标记为蓝色和绿色的两个相同的生产环境来减少停机时间。蓝色是活动环境,绿色是空闲环境。
Canary Deployments:金丝雀的部署是用于向用户或服务器子集推出版本的模式。目标是将更新部署到用户子集,对其进行测试,然后将更改推出给每个人。
Client-side Load Balancing:客户端负载平衡是一种负载平衡方法,它依赖于客户端调用正确服务器的决定。
Cloud Native Computing Foundation:云原生计算基金会(CNCF)是一个Linux基金会项目,成立于2015年,旨在帮助推进容器技术,并使科技行业围绕其发展保持一致。
Custom Resource Definition (CRD):自定义资源是Kubernetes API的扩展。自定义资源定义(CRD)文件允许用户定义自己的自定义资源,并允许API服务器处理生命周期。
Egress Traffic:出口流量是指从网络内部开始,通过路由器到达网络外部目的地的网络流量。
Elastic Provisioning:弹性资源调配是动态调配计算资源以满足用户需求的能力。
Envoy Proxy:Envoy Proxy是一个现代的、高性能的、占用空间小的边缘和服务代理。
Forward Proxy:转发代理用于将网络内部的传出请求转发到互联网,通常是通过防火墙。
Hybrid Cloud Architecture:混合云架构是一种混合了本地、私有云和公共云服务的IT架构方法。
Identity-based authorization:基于身份的授权是一种基于个人身份验证来限制或允许访问的安全方法。
Infrastructure as a Service:基础设施即服务,通常称为IaaS,是一种云计算方法,其中计算资源通过api在线交付。这些api与底层基础设施通信,如物理计算资源、位置、数据分区、扩展、安全性、备份等。
Infrastructure as Code:基础设施即代码(IaC)是开发人员和运营团队通过软件而不是使用配置工具自动配置和管理计算资源的能力的过程。
Ingress Controller:在Kubernetes中,"ingress"是一个允许从Kubernetes集群外部访问Kubernetes服务的对象。入口控制器负责入口,通常使用负载均衡器或边缘路由器来帮助进行流量管理。
Ingress Gateway:Ingress网关是网格负载均衡器的一个边缘,它提供从外部网络到Kubernetes集群的安全可靠的访问。
Ingress Traffic:入口流量是指源自网络外部并在网络内部有目的地的网络流量。
Key-Value Store:键值存储(或KV存储)也称为键值数据库,是一种数据模型,其中每个键与集合中的一个且仅一个值相关联。
L4 - L7 Services:L4-L7服务是开放系统互连(OSI)模型中的一组功能,如负载平衡、web应用程序防火墙、服务发现和网络层监控。
Layer 7 Observability:第7层可观察性是Consul Service Mesh的一个特性,它为度量收集、分布式跟踪和日志记录提供了统一的工作流。它还允许集中配置和管理分布式数据平面。
Load Balancer:负载平衡器是一种网络设备,它充当反向代理,并在服务器之间分配网络和应用程序流量。
Load Balancing:负载平衡是跨多个服务器分配网络和应用程序流量的过程。
Load Balancing Algorithms:负载平衡器遵循一种算法来确定如何跨服务器群路由流量。一些常用的算法是:轮循/最少连接数/加权连接/源IP散列/最小响应时间法/最小带宽法
Multi-cloud:多云环境通常在单个架构中使用来自不同供应商的两个或多个云计算服务。这是指计算资源、存储和网络方面在云环境中的分布。
Multi-cloud Networking:多云网络通过API跨多个云提供商提供网络配置和管理。
Mutual Transport Layer Security (mTLS):相互传输层安全,也称为mTLS,是一种身份验证机制,可确保客户端和服务器之间双向的网络流量安全。
Network Middleware Automation:将服务更改发布到网络中间件(如负载均衡器和防火墙)并自动化网络任务的过程称为网络中间件自动化。
Network security:网络安全是保护数据和网络的过程。它由一组策略和实践组成,旨在防止和监控对计算机网络和网络可访问资源的未经授权的访问、滥用、修改或拒绝。
Network traffic management:网络流量管理是通过使用一组网络监控工具来确保网络最佳运行的过程。网络流量管理还侧重于流量管理技术,如带宽监控、深度数据包检测和基于应用程序的路由。
Network Visualization:网络可视化是将网络和连接实体以“框和线”的形式直观地显示出来的过程。
Observability:可观察性是对部署或实例的事件进行日志记录、监视和警报的过程。
Elastic Scaling: 弹性扩展是指根据应用程序流量模式的变化自动添加或删除计算或网络资源的能力。
Platform as a Service:平台即服务(PaaS)是云计算的一个类别,它允许用户开发、运行和管理应用程序,而无需构建和维护通常与开发和启动应用程序相关的基础设施。
Reverse Proxy:反向代理处理来自外部到内部网络的请求。反向代理提供了一定级别的安全性,可以防止外部客户端直接访问公司服务器上的数据。
Role-based Access Controls:根据用户在组织中的特定角色限制或提供访问权限的行为。
Server side load balancing:服务器端负载平衡器位于客户端和服务器场之间,接受传入流量,并使用各种负载平衡方法在多个后端服务器之间分配流量。
Service configuration:服务配置包括服务的名称、描述和特定功能。在微服务应用程序架构设置中,服务配置文件包括服务定义。
Service Catalog:服务目录是经过组织和管理的服务集合,开发人员可以将这些服务绑定到他们的应用程序。
Service Discovery:服务发现是对网络中的服务和设备进行检测的过程。在微服务上下文中,服务发现是指应用程序和微服务如何在网络中相互定位。
Service Mesh:服务网格是促进微服务之间服务到服务通信的基础设施层,通常使用sidecar代理。这个微服务网络组成了微服务应用程序以及它们之间的交互。
Service Networking:服务网络将多个实体聚集在一起以提供特定的服务。服务网络是组织网络和监控操作的大脑。
Service Proxy:服务代理是微服务应用程序的客户端代理。它允许应用程序通过代理服务器发送和接收消息。
Service Registration:服务注册是让客户端(服务的)和路由器知道服务的可用实例的过程。服务实例在启动时向服务注册中心注册,在关闭时注销。
Service Registry:服务注册中心是一个服务实例的数据库,包含有关如何向这些服务实例发送请求的信息。
Microservice Segmentation:微服务的微服务分段,有时是可视化的,是微服务应用程序架构中的分段,使管理员能够查看他们的功能和交互。
Service-to-service communication:服务到服务通信,有时也称为服务间通信,是微服务应用程序实例与另一个实例通信以协作和处理客户端请求的能力。
Software as a Service:软件即服务是一种软件交付的许可和交付方法,其中软件由提供商托管,并在订阅的基础上许可给用户。
1.3 Consul所需端口
可以在agent配置文件中或使用consol代理CLI命令更改或禁用Consul的默认端口。Consul需要的确切端口取决于你的网络的特定配置。例如,仅在使用WAN联合时才需要用于WAN自定义通信的端口。Consul服务器和客户机的端口需求略有不同。当Consul服务器上注册了服务、代理或网关时,它既充当服务器,又充当客户机。HCP Consul专用服务器具有不同的端口分配。
下表列出了端口名称、它们的功能、它们的网络协议、它们的默认端口号、它们在默认情况下是启用还是禁用、HCP Consul Dedicated服务器集群的端口分配,以及从Consul服务器的角度来看的流量方向。
端口名称 | 用途 | 协议 | 默认端口 | 默认状态 | HCP专用端口 | 流量方向 |
---|---|---|---|---|---|---|
DNS | DNS server | TCP and UDP | 8600 | Enabled | 不支持 | 流入 |
HTTP | HTTP API/UI访问 | TCP | 8500 | Enabled | 不支持 | 流入 |
HTTPS | HTTPS API/UI访问 | TCP | 8501 | Disabled | 443 | 流入 |
gRPC | gRPC API | TCP | 8502 | Disabled | 不支持 | 流入 |
gRPC TLS | gRPC API with TLS | TCP | 8503 | Enabled | 8502 | 流入 |
Server RPC | Consul服务端内部通信 | TCP | 8300 | Enabled | 8300 | 流入和流出 |
LAN Serf | Serf局域网端口 | TCP and UDP | 8301 | Enabled | 8301 | 流入和流出 |
WAN Serf | Serf广域网端口 | TCP and UDP | 8302 | Enabled | 8302 | 流入和流出 |
Consul是HashiCorp所开发的免费服务网格,而HCP则是HashiCorp的云计算平台,用户在HCP可以简单地用到HashiCorp Consul和Vault等托管软件服务,且这些服务还可以连接到AWS上使用。
1.3 Consul是如何工作的
上面这张架构图也就很好理解了,首先说单个机房内部server是最少三个节点,这样可以损坏一个节点保证能够选主,当然也可以5个可以损坏2个节点,尽量就不要再多了,不然会影响选主的速度。如果客户端比较多可以考虑逻辑分组多分一些consul集群而不是不断地扩大consul集群的规模。
先说机房内部consul之间是通过8300端口进行通信的,用来进行集群内部的数据读写和复制,客户端通过该端口RPC协议调用服务端节点,服务器节点之间相互调用。然后8301端口用于单个数据中心所有节点之间的互相通信,即对LAN GOSSIP pool信息的同步。它使得整个数据中心能够自动发现服务器地址,分布式检测节点故障,事件广播(如领导选举事件)。
然后机房之间呢通过8302端口用于单个或多个数据中心之间的服务器节点的信息同步,即对 WAN GOSSIP pool信息的同步。它针对互联网的高延迟进行了优化,能够实现跨数据中心请求。
博文来自:www.51niux.com
二、Consul的安装和简单使用
2.1 Consul的安装
二进制包安装:
#wget https://releases.hashicorp.com/consul/1.19.1/consul_1.19.1_linux_amd64.zip
#mkdir consul
#mv consul_1.19.1_linux_amd64.zip consul
#cd consul/
#unzip consul_1.19.1_linux_amd64.zip
#ln -sn /opt/soft/consul/consul /usr/bin
# consul -v
2.2 Consul命令记录
# consul --help
Usage: consul [--version] [--help] <command> [<args>] Available commands are: acl #与Consul的acl交互 agent #运行Consul agent catalog #与catalog交互 config #与Consul的集中式配置交互 connect #与Consul Connect交互 debug #记录调试信息 event #触发一个新事件 exec #在Consul节点上执行命令 force-leave #强制集群成员进入"离开"状态 info #提供Info信息 intention #与intentions服务进行交互 join #加入consul集群 keygen #生成新的加密密钥 keyring #管理gossip加密密钥 kv #与key-value store进行交互 leave #优雅地离开Consul集群并关闭 lock #执行持有锁的命令 login #使用身份验证方法登录到Consul logout #销毁用login创建的Consul令牌 maint #控制节点或服务维护模式 members #列出Consul集群的成员 monitor #从Consul代理流式传输日志 operator #为Consul操作员提供集群级工具 peering #创建和管理Consul集群之间的对等连接 reload #触发代理重新加载配置文件 resource #与Consul's resources进行交互 rtt #估计节点之间的网络往返时间 services #与services进行交互 snapshot #保存、恢复和检查Consul服务器状态的快照 tls #用于创建ca和证书的内置帮助程序 troubleshoot #用于排除Consul服务网格故障的CLI工具 validate #验证配置文件/目录 version #打印Consul版本 watch #关注Consul的变化
# consul agent --help
Usage: consul agent [options] 启动Consul代理并运行,直到收到中断。这个代理代表集群中的单个节点。 HTTP API Options -datacenter=<value> #代理的数据中心。 Command Options -advertise=<value> #设置使用advertise的address -advertise-wan=<value> #设置在广域网上发布的地址,而不是-advertise address。 -allow-write-http-from=<value> #只允许来自给定网络的写端点调用。CIDR格式可以多次指定。 -alt-domain=<value> #用于DNS接口的备用域 -auto-reload-config #监视配置文件的更改,并在修改时自动重新加载文件 -bind=<value> #设置集群通信的绑定地址 -bootstrap #将服务器设置为引导模式 -bootstrap-expect=<value> #将服务器设置为期望引导模式 -check_output_max_size=<value> #设置此代理上检查的最大输出大小 -client=<value> #设置为客户端访问绑定的地址。这包括RPC、DNS、HTTP、HTTPS和gRPC(如果配置的话)。 -config-dir=<value> #读取配置文件的目录路径。这将按字母顺序读取此目录中以“.json”结尾的每个文件作为配置。可以多次指定。 -config-file=<value> #JSON或HCL格式文件的路径,具有匹配的文件扩展名。可以多次指定。 -config-format=<string> #配置文件的格式与扩展名无关。必须是“hcl”或“json” -data-dir=<value> #用于存储代理状态的数据目录的路径 -default-query-time=<value> #阻塞查询在Consul强制响应之前等待的时间。此值可以被“wait”查询参数覆盖。 -dev #在开发模式下启动agent -disable-host-node-id #将其设置为true将阻止Consul使用信息从主机生成节点ID,并将导致Consul生成一个随机的节点ID。 -disable-keyring-file #禁用将keyring备份到文件 -dns-port=<value> #要使用的DNS端口 -domain=<value> #DNS接口使用的域名 -enable-local-script-checks #从配置文件启用健康检查脚本 -enable-script-checks #启用健康检查脚本 -encrypt=<value> #提供gossip加密密钥 -grpc-port=<value> #设置gRPC API端口监听 -grpc-tls-port=<value> #设置gRPC-TLS API端口监听 -hcl=<value> #hcl配置片段。可以多次指定 -http-port=<value> #设置要侦听的HTTP API端口 -https-port=<value> #设置HTTPS API端口侦听 -log-file=<value> #日志写入文件的路径 -log-json #以JSON格式输出日志 -log-level=<value> #日志级别 -log-rotate-bytes=<value> #应该写入日志文件的最大字节数 -log-rotate-duration=<value> #需要执行日志轮换的时间 -log-rotate-max-files=<value> #要保留的日志文件存档的最大数量 -max-query-time=<value> #阻塞查询在Consul强制响应之前可以等待的最大时间。Consul将抖动应用于等待时间。抖动时间将被限制为MaxQueryTime。 -node=<value> #节点名称。必须在集群中唯一 -node-id=<value> #此节点在空间和时间上的唯一ID。默认为随机生成的ID,该ID保存在数据目录中。 -node-meta=<key:value> #此节点的任意元数据键/值对,格式为' key:value '。可以多次指定。 -pid-file=<value> #存储代理PID的文件路径 -primary-gateway=<value> #主数据中心中网状网关的地址,用于在启用重试的开始时间引导WAN联合。可以多次指定。 -protocol=<value> #设置协议版本。默认为最新 -raft-protocol=<value> #设置Raft协议版本。默认为最新 -recursor=<value> #上游DNS服务器的地址。可以多次指定 -rejoin #忽略之前的离开并尝试重新加入集群 -retry-interval=<value> #连接尝试之间的等待时间 -retry-interval-wan=<value> #join -wan尝试之间的等待时间 -retry-join=<value> #在开始时加入并启用重试的代理的地址。可以被指定多次 -retry-join-wan=<value> #要在开始时重试加入的代理的地址-wan启用。可以多次指定 -retry-max=<value> #加入尝试的最大次数。默认为0,将无限期重试 -retry-max-wan=<value> #加入wan的最大尝试次数。默认为0,这将无限期重试 -serf-lan-allowed-cidrs=<value> #Serf LAN允许的网络(例如:192.168.1.0/24)。可以是多次指定 -serf-lan-bind=<value> #将Serf LAN侦听器绑定到的地址 -serf-lan-port=<value> #设置要侦听的Serf LAN端口 -serf-wan-allowed-cidrs=<value> #允许Serf WAN(其他)的网络(例如:192.168.1.0/24)数据中心)。可以多次指定。 -serf-wan-bind=<value> #将Serf WAN侦听器绑定到的地址 -serf-wan-port=<value> #设置要侦听的Serf WAN端口 -server #将agent切换到server模式 -server-port=<value> #设置要侦听的server端口 -syslog #启用syslog日志 -ui #启用内置的静态web UI服务器 -ui-content-path=<value> #将外部UI路径设置为字符串。默认为:/UI/ -ui-dir=<value> #包含web UI资源的目录路径
# consul join --help
Usage: consul join [options] address ... 告诉正在运行的Consul代理(带有“consul agent”)加入集群通过指定至少一个现有成员。 HTTP API Options -ca-file=<value> #与Consul通信时用于TLS的CA文件的路径 -ca-path=<value> #用于TLS的CA证书目录的路径与Consul沟通 -client-cert=<value> #当'verify_incoming'时用于TLS的客户端证书文件的路径启用 -client-key=<value> #当'verify_incoming'时用于TLS的客户端密钥文件的路径启用 -http-addr=<address> #Consul HTTP agent的地址和端口 -tls-server-name=<value> #通过连接时用作SNI主机的服务器名称TLS -token=<value> #在请求中使用的ACL令牌。这也可以通过以下方式指定CONSUL_HTTP_TOKEN环境变量。如果未指定,则查询将默认为Consul代理在HTTP地址处的令牌 -token-file=<value> #包含在请求中使用的ACL令牌的文件,而不是一个通过-token参数或CONSUL_HTTP_token环境指定变量 Command Options -partition=<default> #指定要查询的管理分区。 -wan #将一个服务器连接到WAN池中的另一个server
2.3 单机启动一下consul
# consul agent -dev -client=0.0.0.0 #最简单的单机测试环境启动方式,不过我们不用这种
# consul agent -dev -client=0.0.0.0 -datacenter=csdc01 -node=csagent -ui -log-level=info -bind=192.168.1.164 -disable-host-node-id
# ps aux|grep consul #查看下进程
root 1117414 1.8 0.3 1355200 57400 pts/1 Sl+ 17:19 0:00 consul agent -dev -client=0.0.0.0 -datacenter=csdc01 -node=csagent -ui -log-level=info -bind=192.168.1.164 -disable-host-node-id
#netstat -lntup|grep 1117414 #查看下监听端口
tcp 0 0 192.168.1.164:8301 0.0.0.0:* LISTEN 1117414/consul tcp 0 0 192.168.1.164:8302 0.0.0.0:* LISTEN 1117414/consul tcp 0 0 192.168.1.164:8300 0.0.0.0:* LISTEN 1117414/consul tcp6 0 0 :::8500 :::* LISTEN 1117414/consul tcp6 0 0 :::8502 :::* LISTEN 1117414/consul tcp6 0 0 :::8503 :::* LISTEN 1117414/consul tcp6 0 0 :::8600 :::* LISTEN 1117414/consul udp 0 0 192.168.1.164:8301 0.0.0.0:* 1117414/consul udp 0 0 192.168.1.164:8302 0.0.0.0:* 1117414/consul udp6 0 0 :::8600 :::* 1117414/consul
#web访问一下URL:http://192.168.1.164:8500/=>会给转到http://192.168.1.164:8500/ui/csdc01/services
博文来自:www.51niux.com
2.4 集群模式运行
在192.168.1.164机器上面执行下面的命令:
#consul agent -server -bootstrap-expect=3 -data-dir=/data01/consul -node=192.168.1.164 -bind=192.168.1.164 -client=0.0.0.0 -datacenter=beijing-c -ui &
在192.168.1.165机器上面执行下面的命令:
#consul agent -server -bootstrap-expect=3 -data-dir=/data01/consul -node=192.168.1.165 -bind=192.168.1.165 -client=0.0.0.0 -datacenter=beijing-c -ui &
在192.168.1.166机器上面执行下面的命令:
#consul agent -server -bootstrap-expect=3 -data-dir=/data01/consul -node=192.168.1.166 -bind=192.168.1.166 -client=0.0.0.0 -datacenter=beijing-c -ui &
#然后你会发现日志一直在报错:error="leaf cert watch returned an error: No cluster leader" #这是因为三个agent互相不跟其他节点通信无法形成一个集群
然后在192.168.1.165机器上面执行下面的命令:
# consul join 192.168.1.164
Successfully joined cluster by contacting 1 nodes.
然后在192.168.1.166机器上面执行下面的命令:
# consul join 192.168.1.164
很快非leader的另外台机器都会打印:
[INFO] agent.server: New leader elected: payload=192.168.1.165 [INFO] agent: Synced node info [INFO] agent: Newer Consul version available: new_version=1.19.2 current_version=1.19.1
# consul members #查看下集群成员
# consul operator raft list-peers #查看下选举状态
Node ID Address 192.168.1.165 dc581b0a-a349-cd5b-2eb8-5e40455410e3 192.168.1.165:8300 192.168.1.166 cffa5773-2b04-712b-b170-b781dccf4ae8 192.168.1.166:8300 192.168.1.164 d12b8501-f0a5-d73c-3c48-a5fdc0d934e7 192.168.1.164:8300
# consul operator raft transfer-leader -id=d12b8501-f0a5-d73c-3c48-a5fdc0d934e7 #指定主机成为leader节点
当然我们也可以通过api进行查询如果启动了ui的8500端口的话:
# curl http://127.0.0.1:8500/v1/status/leader #查询当前的leader
# curl http://127.0.0.1:8500/v1/status/peers #查询当前的成员
# curl http://127.0.0.1:8500/v1/catalog/services #查看注册到consul上面的所有服务
# curl http://127.0.0.1:8500/v1/catalog/nodes?pretty #查询consul集群节点的详细信息,加上?pretty起到了美化输出的效果
# curl http://127.0.0.1:8500/v1/catalog/datacenters #查询数据中心列表
#上面的这些api查询命令均可参照文档:https://developer.hashicorp.com/consul/api-docs
2.5 consul指定配置文件启动
第一台node节点的配置:
# cat /opt/soft/consul/conf/consul_service.hcl
#节点名称,需要集群中唯一 node_name = "192.168.1.164" #是否以server模式运行,决定节点是否参加leader选举 server = true #只需要第一台启动的节点配置这个就可以了,其他的不要配置 bootstrap = true #是否启动WEB UI,这里不设置那个consul的Web页面是无法访问的 ui_config { enabled = true } #数据中心 datacenter = "beijing-c" #数据目录,存放consul的节点数据 data_dir = "/data01/consul" #日志级别 log_level = "INFO" #日志写入位置 log_file = "/opt/soft/consul/log/" addresses { http = "0.0.0.0" } #配置指定用于HTTP、HTTPS、DNS和gRPC服务器的IP地址,不加这里8600,8503端口默认是绑定127.0.0.1(根据启动观察的)。所以也可以指定IP如192.168.1.164 client_addr = "0.0.0.0" #启动端口绑定地址 bind_addr = "192.168.1.164" connect { enabled = true }
#consul agent -config-dir=/opt/soft/consul/conf & #直接使用加载配置文件目录的启动方式启动,你会发现一个节点也可以启动并且本身是leader节点
第二个node节点的配置:
# cat /opt/soft/consul/conf/consul_service.hcl
node_name = "192.168.1.165" server = true ui_config { enabled = true } datacenter = "beijing-c" data_dir = "/data01/consul" log_level = "INFO" log_file = "/opt/soft/consul/log/" retry_join = ["192.168.1.164"] #期望的服务节点数用于引导集群,可以加在这里哈,它和bootstrap=true是互斥的 bootstrap_expect = 3 addresses { http = "0.0.0.0" } client_addr = "0.0.0.0" bind_addr = "192.168.1.165" connect { enabled = true }
#consul agent -config-dir=/opt/soft/consul/conf & #加进集群了
第三个node节点的配置:
# cat /opt/soft/consul/conf/consul_service.hcl
node_name = "192.168.1.166" server = true ui_config { enabled = true } datacenter = "beijing-c" data_dir = "/data01/consul" log_level = "INFO" log_file = "/opt/soft/consul/log/" retry_join = ["192.168.1.164"] #期望的服务节点数用于引导集群,可以加在这里哈,它和bootstrap=true是互斥的 bootstrap_expect = 3 addresses { http = "0.0.0.0" } client_addr = "0.0.0.0" bind_addr = "192.168.1.166" connect { enabled = true }
#consul agent -config-dir=/opt/soft/consul/conf & #加进集群了
#现在你可以把leader节点关闭掉看看能不能进行重新选主了
第四个client节点的配置:
/opt/soft/consul/conf/consul_client.hcl
node_name = "client-192.168.1.220" server = false ui_config { enabled = true } datacenter = "beijing-c" data_dir = "/data01/consul" log_level = "INFO" log_file = "/opt/soft/consul/log/" retry_join = ["192.168.1.164","192.168.1.165","192.168.1.166"] bind_addr = "192.168.1.220" client_addr = "0.0.0.0" #这里注意了,默认这里是false,如果为true,当agent收到一个TERM信号的时候,它会发送leave信息到集群中的其他节点上。 #什么意思呢,就是你不设置这里,当你的consul客户端是直接Kill 进程号中断进程而不是执行的consul leave得时候,这个节点再集群中的状态是failed而不是left #consul节点状态就三种:alive,failed(服务端会进行周期性的连接失败节点,默认是72小时后不再连接,有时候需要用force-leave指定让此节点快速转变为left状态),left(离开) leave_on_terminate = true
#consul agent -config-dir=/opt/soft/consul/conf &
# consul members #随便在一台consul服务上面执行下查看成员
三、注册与发现
官网文档:https://developer.hashicorp.com/consul/docs/services/services
3.1 静态注册
对于服务发现,服务的核心Consul工作流由三个阶段组成:
定义服务和健康检查: 你可以在服务定义中定义健康检查,以验证服务的健康状况。 注册服务和健康检查:定义你的服务和健康调查后,你必须向Consul代理注册。 查询服务:在注册你的服务和健康检查后,你网络中的其他服务可以使用DNS执行静态或动态查找以访问你的服务。
我们先跟着官网记录一下注册会涉及到的服务选项:https://developer.hashicorp.com/consul/docs/services/configuration/services-configuration-reference
配置介绍
name: string | 必须填写 #指定服务名称的必选值。我们建议为服务定义名称使用有效的DNS标签,以便与外部DNS兼容。默认是none id: string #指定服务的ID。同一节点上的服务id不能重复。如果默认名称与其他服务冲突,建议指定唯一的值。默认值:name字段的值。 address: string #指定特定于服务的IP地址或主机名的字符串值。默认值:agent节点的IP地址 port: number #指定服务的端口号。默认是是agent的端口号 tags: list of strings #指定用于添加服务级别标签的字符串值列表。标记值对Consul是不透明的。例如tags = ["v2", "primary"] meta: map(其中包含custom_meta_key: string) #元字段包含将语义元数据与服务关联的自定义键值对。 tagged_addresses: map (其中包含lan:map(address: string,port: number),wan: map(address: string,port: number)) #为节点或服务配置附加地址的对象。远程代理和服务可以使用标记的地址作为地址字段中指定的地址的替代方案与服务通信。一个节点或服务可以配置多个地址。 socket_path: string #指定服务套接字路径的字符串值。如果服务监听Unix Domain套接字,则指定此参数将服务公开给mesh。默认是none enable_tag_override: boolean #设置为true以允许外部Consul代理修改Consul目录中服务的标记。默认是false checks : list of maps #定义健康检查的方式 kind: string #将服务标识为代理并确定其在服务网格中的角色的字符串值。对于非代理服务实例,不需要配置kind参数。 proxy: map #当服务被配置为在服务网格中作为代理运行时,指定代理配置的对象。 connect: map(其中包含native: boolean,sidecar_service: object) #配置Consul服务网格连接的对象。 locality: map |企业版参数(其中包含region: string,zone: string) weights: map(其中包含passing: number,warning: number) #该对象配置如何根据服务的健康状态在DNS SRV请求中对服务实例进行加权。 token: string | 如果启用了ACL,则需要 #指定在启用ACL时注册服务时要显示的ACL令牌。默认是none namespace: string | 企业版参数
先来一个最简单的配置文件:
#cat /etc/consul.d/redis01_service.hcl
service { name = "redis01" address = "192.168.1.164" port = 6379 tags = ["primary"] }
# /opt/soft/consul/consul services register /etc/consul.d/redis01_service.hcl
Registered service: redis01
# curl 127.0.0.1:8500/v1/agent/services|python -m json.tool #可以结构性的看下我们注册的服务,可以看到完整的注册服务信息
{ "redis01": { "Address": "192.168.1.164", "Datacenter": "beijing-c", "EnableTagOverride": false, "ID": "redis01", "Meta": {}, "Port": 6379, "Service": "redis01", "TaggedAddresses": { "lan_ipv4": { "Address": "192.168.1.164", "Port": 6379 }, "wan_ipv4": { "Address": "192.168.1.164", "Port": 6379 } }, "Tags": [ "primary" ], "Weights": { "Passing": 1, "Warning": 1 } } }
3.2 定义健康检查
运行状况检查是验证服务或节点运行状况的配置。运行状况检查配置嵌套在服务块中。可以在单独的检查块中为服务定义单独的运行状况检查,也可以在检查块中定义多个检查。可以创建几种不同类型的检查:
Script checks:调用外部应用程序,该应用程序执行运行状况检查,使用适当的退出代码退出,并可能生成输出。脚本检查是最常见的检查类型之一。 HTTP checks:向指定的URL发出HTTP GET请求,并等待指定的时间。HTTP检查是最常见的检查类型之一。 TCP checks:尝试通过TCP连接到IP或主机名和端口,并等待指定的时间。 UDP checks:将UDP数据报发送到指定的IP地址或主机名和端口,并等待指定的时间。 Time-to-live (TTL) checks:被动检查,等待来自服务的更新。如果在指定的持续时间之前未收到状态更新,则健康检查进入临界状态。 Docker checks: 依赖于打包在Docker容器中的外部应用程序,这些应用程序由对Docker exec API端点的调用触发。 gRPC checks:支持标准gRPC健康检查协议的探测应用 H2ping checks:测试使用http2的端点。检查连接到端点并发送ping帧。 Alias checks:表示另一个已注册节点或服务的运行状况状态。
# cat /etc/consul.d/redis01_service.hcl #我们故意把tcp探测端口改错一下,看看会有什么提示
service { name = "redis01" address = "192.168.1.164" port = 6379 tags = ["primary"] checks = [ { id = "redis" name = "Redis TCP on port 6379" tcp = "192.168.1.164:63790" interval = "10s" timeout = "1s" } ] }
# /opt/soft/consul/consul services register /etc/consul.d/redis01_service.hcl #重新加载一下配置文件
# curl 127.0.0.1:8500/v1/health/service/redis01|python -m json.tool #查看某个服务的健康状态,可以看到更详细的信息,下面为部分消息,可以看到监测失败的输出
...... { "CheckID": "redis", ... "Output": "dial tcp 192.168.1.164:63790: connect: connection refused", ... "Status": "critical", "Timeout": "1s", "Type": "tcp" } ], ......
3.3 一个服务多个后端注册
#我们把前面讲的两个功能结合一下,一个服务可以注册多个后端,然后以我们的规则进行探活,然后就可以只返回健康的节点了
#先来一个错误的示例:
services{ name = "redis01" ...... } services{ name = "redis01" ...... }
#在同一个consul机器上面,这种方式你会发现服务是注册成功了,但是下面的配置把上面的覆盖掉了,也就是最下面的配置生效了如果服务name相同的话。为什么会出现覆盖的情况呢,可以通过"consul一个服务被覆盖问题"这个关键字搜索网上的说明内容和解决办法,大概意思就是consul注册的时是通过[instance-id]来区分服务实例的。
# /opt/soft/consul/consul services deregister /etc/consul.d/redis01_service.hcl #可以通过此命令在注册client consul上面把注册服务清理掉
来个正确的示例:
#那就是重新再找一个consul client节点进行服务注册,比如192.168.1.236上面
#cat /etc/consul.d/redis01_service.hcl
services { name = "redis01" address = "192.168.1.165" port = 6379 tags = ["primary"] checks = [ { id = "redis" name = "Redis TCP on port 6379" tcp = "192.168.1.165:6379" interval = "10s" timeout = "1s" } ] }
# /opt/soft/consul/consul services register /etc/consul.d/redis01_service.hcl
[INFO] agent: Synced service: service=redis01 Registered service: redis01 [INFO] agent: Synced check: check=redis
#从过web页面可以看到,除了已经注册的consul服务是三个节点外,我们新注册的redis01服务也并非单个节点是2个节点了。
博文来自:www.51niux.com
3.4 服务发现
consul的服务发现有两种方式:HTTP和DNS两种
先说HTTP方式:
# curl -X GET http://127.0.0.1:8500/v1/agent/services?format=text #你会发现有的机器有结果,有的机器则没有,这条命令是查看本节点有哪些注册服务的命令
# curl -X GET http://127.0.0.1:8500/v1/agent/service/redis01?format=text #这个命令也是,查看本机注册的某个服务的信息
#所以使用下面正确的发现方式:
# curl -X GET http://127.0.0.1:8500/v1/catalog/services|python -m json.tool #获取所有已注册的服务
#curl -X GET http://127.0.0.1:8500/v1/catalog/service/redis01|python -m json.tool 发现某个服务的详细信息
再说DNS方式:
# dig @127.0.0.1 -p 8600 redis01.service.beijing-c.consul. ANY #记住域名格式就是"注册服务名.service.数据中心.consul"
...... ;; ANSWER SECTION: redis01.service.beijing-c.consul. 0 IN A 192.168.1.164 redis01.service.beijing-c.consul. 0 IN A 192.168.1.165 ......
#可以看到DNS的方式只返回IP,如果你是不通端口或者不确定是什么端口的情况下还是使用HTTP得方式
再说健康检查:
#我们现在故意让192.168.1.165的6379端口不通了,再看下服务发现
#通过web页面可以看到一个节点已经探测失败了
# dig @127.0.0.1 -p 8600 redis01.service.beijing-c.consul. ANY #可以看到只返回了一个健康节点
...... ;; ANSWER SECTION: redis01.service.beijing-c.consul. 0 IN A 192.168.1.164 ......
# curl 127.0.0.1:8500/v1/health/service/redis01?passing|python -m json.tool #这里要注意了,http换命令了哦,探测成功的是passing状态,这是只显示次注册服务健康的节点,你要显示失败的节点状态就是critical
#另外还有两个命令:
# curl 127.0.0.1:8500/v1/health/service/redis01|python -m json.tool #查询节点得详细信息,探测状态也在内容里面
# curl 127.0.0.1:8500/v1/health/checks/redis01|python -m json.tool #只是单纯的显示探测信息,没有address那些信息
3.5 针对consul agent做下操作
这时候你把上面那个redis01_service.hcl文件再找个consul节点然后注册一下,你会发现虽然配置完全相同,但是因为consul client不一样,依旧是可以注册成功的
# curl 127.0.0.1:8500/v1/health/service/redis01?passing|python -m json.tool |jq '.[].Service.Address'
"192.168.1.165" "192.168.1.164" "192.168.1.165"
#dig @127.0.0.1 -p 8600 redis01.service.beijing-c.consul. ANY #dns的方式是有去重功能的
...... ;; ANSWER SECTION: redis01.service.beijing-c.consul. 0 IN A 192.168.1.165 redis01.service.beijing-c.consul. 0 IN A 192.168.1.164 ......
那么这时候如果你关闭一个consul节点会怎么样呢?直接说结论:这个consul注册的服务相关的信息就查询不到了。再启动这个consul上面的注册信息就又回来了。
3.6 HTTP接口注册
除了配置文件进行服务注册外,还有api注册的方式,下面是例子,结果就不展示了:
curl http://127.0.0.1:8500/v1/agent/service/register -X PUT -i -H "Content-Type:application/json" -d '{ "Name":"redis02", "Tags": [ "primary", "v1" ], "Address":"192.168.1.164", "Port":6379, "Checks":[{ "Name":"Redis TCP on port 6379", "TCP":"192.168.1.164:6379", "Interval":"10s", "Timeout":"1s" }] }'