学习搭建 Consul 服务发现与服务网格-有丰富的示例和图片

2020年11月21日 2005点热度 0人点赞 0条评论
内容纲要

第一部分:Consul 基础

1,Consul 介绍

官网文档描述:Consul 是一个网络工具,提供功能齐全的服务网格和服务发现。

它可以做什么:自动化网络配置,发现服务并启用跨任何云或运行时的安全连接。

那么,我们对 Consul 的理解,就是服务网格、服务发现,官网文档说的这两个特征,到底是啥意思?跨什么云?

下面,我们将通过实践操作,逐渐了解 Consul,搭建出一个真实的 Consul 服务来体验。

2,安装 Consul

两台服务器上都需要安装 Consul,具体步骤可以参考下面的说明。

Ubuntu/Debian 系统

# 添加 GPG key

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -

# 添加 仓库
# 如果执行后提示  apt-add-repository: command not found
# 可先安装: apt-get install software-properties-common

sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"

# 更新源以及安装 consul

sudo apt-get update && sudo apt-get install consul

Centos/RHEL 系统

# 使用 yum-config-manager 管理仓库
sudo yum install -y yum-utils

# 连接仓库
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo

# 安装
sudo yum -y install consul

检查安装

可输入 consul 检查是否安装成功,如果有信息输出即说明安装成功。

root@50skbjiynxyxkcfh:~# consul
Usage: consul [--version] [--help] <command> [<args>]

Available commands are:
    acl            Interact with Consul's ACLs
    agent          Runs a Consul agent
    catalog        Interact with the catalog
    config         Interact with Consul's Centralized Configurations
    connect        Interact with Consul Connect
    debug          Records a debugging archive for operators
    event          Fire a new event
    exec           Executes a command on Consul nodes
... ...

3,运行 Consul Agent

文章一般都会说一个 Consul 服务或者一个 Consul 实例,官网文档称为 Agent,这个要记住。为了避免误解,本文提到的代理指 proxy,一般使用 proxy 和 agent 单词说明。

Agent 可以以服务器模式(server mode)或客户端模式(client mode)运行,多个Agent 组成一个 Consul datacenter,每个 Consul datacenter 至少有一个 Agent 属于 服务器模式。

官方不建议单服务器部署。

启动 agent

前面说到过,agent 表示一个 Consul 实例。

因为现在处于探索实践阶段,为了避免各种加密安全问题等,我们需要使用 -dev 参数,以开发模式启动。

# $> consul agent
# Runs a Consul agent

consul agent -dev

执行这个命令后,consul 会被启动起来,并且占用终端。

启用Consul成功

启动过程中注意留意信息,如果启动失败,需要自行根据提示解决问题。如端口冲突:

启用Consul失败

发现数据中心成员

执行 consul members 命令可以发现数据中心成员。

root@50skbjiynxyxkcfh:~# consul members
Node              Address          Status  Type    Build  Protocol  DC   Segment
50skbjiynxyxkcfh  172.31.0.6:8301  alive   client  0.5.2  2         dc1  <default>

意思是检查当前 Consul 服务的成员组成,目前是单服务器,所以只有一个成员。

这里不需要留意有什么用途,只要记得这个命令就行,后面我们会使用到这个命令查看信息。

查看 UI

假如服务器 IP 是 172.31.0.6 ,则可以通过 http://172.31.0.6:8500 访问 consul 的 UI服务(http apis)。

4,在 Consul Service Discovery 中注册服务

本小节将介绍 Consul 中的一些网络知识,端口与dns的说明;

然后通过实例讲解如何定义服务以及注册服务到 Consul 中 -- Consul 服务发现。

端口

这里先说明一些 Consul 的端口。

官网文档:Before running Consul, you should ensure the following bind ports are accessible.

翻译:在运行 Consul 之前,需要确保以下端口都是可以访问的。

文档地址:https://www.consul.io/docs/install/ports.html

对于一些重要的配置,要查看官方文档原版,别百度,很多文章只是机器翻译或者 copy 命令,会让你进坑的。

Use Default Ports
DNS: The DNS server (TCP and UDP) 8600
HTTP: The HTTP API (TCP Only) 8500
HTTPS: The HTTPs API disabled (8501)*
gRPC: The gRPC API disabled (8502)*
LAN Serf: The Serf LAN port (TCP and UDP) 8301
Wan Serf: The Serf WAN port (TCP and UDP) 8302
server: Server RPC address (TCP Only) 8300
Sidecar Proxy Min: Inclusive min port number to use for automatically assigned sidecar service registrations. 21000
Sidecar Proxy Max: Inclusive max port number to use for automatically assigned sidecar service registrations. 21255

*For HTTPS and gRPC the ports specified in the table are recommendations.

  • 8500(http)、8501(https)、8502(gRPC) 三个接口可以通过远程请求调用相关的服务,或者直接访问。

  • 8501,8502 两个端口都是 disabled,所以我们可以先看一下 8500 端口的作用,其他端口后面慢慢用到再解释。

​ 打开你的浏览器,访问 http://{你的ip}:8500,会发现跳到了一个 UI 界面。

  • 如果要查看端口被哪个进程占用,可以使用 lsof -i:8081 命令,8081 是要查询的端口。

定义服务

本小节讲解如何通过配置文件以及命令形式,定义服务并向 Consul 注册服务。

打开或新建(如果不存在) /etc/consul.d 目录,后面使用此目录作为 Consul 配置文件的存放位置。

在目录中新建一个 web.json 文件,用于定义服务。

touch web.json

编辑文件,修改其内容为:

{
  "service": {
    "name": "web",
    "tags": [
      "rails"
    ],
    "port": 8080
  }
}

端口可自由设置;这里定义了一个名称为 web 的服务,其端口为 8080。

使用配置启动服务

我们定义配置目录和配置文件后,可以使用配置文件重新启动节点:

consul agent -dev -enable-script-checks -config-dir=/etc/consul.d

-enable-script-checks 可以开启配置文件检查,增强安全性,因为配置文件可以启用脚本,导致可能会引入一个远程执行漏洞。当然,本文的实践步骤还用不上,这里先预热。

如无意外,会提示以下信息:

2020/11/21 10:09:25 [INFO] agent: Synced service "web"
2020/11/21 10:09:25 [DEBUG] agent: Node info in sync
2020/11/21 10:09:25 [DEBUG] agent: Service "web" in sync
2020/11/21 10:09:25 [DEBUG] agent: Node info in sync

如何重新加载配置文件

如果你修改了配置文件,可以使用命令让 Consul 重新加载配置文件,而无需重启。

$ consul reload
Configuration reload triggered

5,查询服务

我们将服务添加到 Consul 后,可以使用 DNS接口 或 HTTP API 对其进行查询,其它应用可以通过 Consul 网络接口查询到 Consul 提供了什么服务,这就是服务发现(不知道我的理解对不对)。

通过 HTTP API

通过 Consul HttpAPI 服务,我们可以查询到服务列表,其 URL 为 /v1/catalog/service/web

通过命令查询:

curl http://localhost:8500/v1/catalog/service/web

也可以使用浏览器访问。

返回的 json 中列出了所有服务节点,以及每个服务实例的信息、状态,根据 json 信息,可以发现服务。

当你发现服务后,可以通过 json 中的信息,获取服务的 ip 和端口,这样就可以正式连接到这个服务了。

通过 UI 查询

访问 http://{你的ip}:8500 ,在 UI 上会发现注册了一个叫 web 的服务。

注册web服务

6,DNS 知识与查询

基础知识

Linux 中,dig 命令用于查询一个域名的 DNS 信息,使用示例:

dig baidu.com
... ...
baidu.com.      375 IN  A   220.181.38.148
baidu.com.      375 IN  A   39.156.69.79
... ...

DNS 查询的标准端口号是 53,通过这个端口号,可以向 DNS 服务器查询更多的域名信息。

DNS 有 A 记录(解析到 IP)、CNAME(别名,解析到域名)等类型,有兴趣的话自行查找资料了解。

dig 命令请参考 https://linux.die.net/man/1/dig

dig 的其中一个查询格式为:

dig [@server] [-p {port}] [name]

dig @127.0.0.1 -p 8600 是指定 8600 端口作为 DNS 服务查询的端口;name 名称则表示要指定查询的资源名称。

记住这个查询格式。

通过 DNS 查询 Consul 服务信息

前面已经注册了 web 服务,那么 如何通过 Consul 的 DNS 接口(8600端口)查询 web 服务的信息?

可在在默认主机上执行:

dig @127.0.0.1 -p 8600 web.service.consul

关于 dig 命令,前面已经讲解了,web.service.consul 就是 [name] 部分。 Consul 会将注册的服务名称加上 .service.consul 做为命名。

那么,查询这个 DNS 有啥用?这里先记下来,后面我们继续捣鼓。

小结

目前我们已经学会使用 命令注册服务,但是因为只是 “配置” 了一下,web(8080端口)服务,压根不存在真正的服务。后面我们将通过部署真实的 web 服务,然后注册到 Consul 中。

7,将数据存储在Consul KV 中

打开你的 Consul UI 界面,如图:

KVUI

你可以通过 UI 界面创建键值数据,也可以通过命令行形式 CURD 键值数据。命令行示例如下:

增加或修改:

consul kv put {key} {value}

获取值:

consul kv get {key}

删除键:

consul kv delete {key}

示例:

consul kv put name 痴者工良

第二部分:深入 Consul

本章内容介绍如何使用 Consul Service Mesh 连接服务、代理服务;建立数据中心,部署多个实例;

8,Consul Service Mesh

了解 Consul Service Mesh

Consul Service Mesh 是通过基于身份的授权、L7流量管理和服务对服务加密,为现代应用程序网络和安全性创建一致的平台。

它有什么用处?

例如,在多个集群和环境之间联合领事,创建一个全球服务网格。跨平台一致地应用策略和安全。如下图所示:

笔者注:envoy 是第三方开源边缘和服务代理,并不是 Consul 的功能,Consul 自带的是 Consul connect。

ConsulServiceMesh

Consul Service Mesh 应用场景可参考:https://www.consul.io/use-cases/multi-platform-service-mesh

Consul Service Mesh 可以通过代理将多台服务器中的服务关联起来,使得其能够通过专用网络相互访问。

gateway

详细请点击 https://www.consul.io/docs/connect/gateways/mesh-gateway

部署真实服务

在 Consul 官网文档,使用了 socat 来演示一个服务,并注册到 Consul 中,,笔者觉得过于麻烦,这里笔者为了更好地学习 Consul ,使用 rust 编写了一个轻量的 web 服务,Windows 大小 4MB,Linux 下 8MB,无需安装任何依赖。

建议读者使用笔者写的这个 Web demo 作为真实服务部署,这个 demo 已开源,下载地址:

https://github.com/whuanles/consulweb/releases

下载文件完毕后,上传到服务器空目录中。

为了自定义绑定 web 服务地址,需要新建一个 option.txt 文件,其内容如下:

0.0.0.0:8081

快速创建文件命令:

echo "0.0.0.0:8081" > option.txt

Web 服务支持部署静态文件,你可以新建静态网页文件如 index.html,放到程序目录下,然后通过绑定的 ip 和端口即可访问。

记得给 web 赋予权限:

chmod +x web

执行 ./web 启动 web 服务,执行 nohup ./web & 后台 运行 web 服务。

这样我们就有一个真实的 web 服务了,大家可以使用浏览器访问测试。

真实注册服务

使用笔者或者自定义编写的服务后,需要将这个服务注册到 Consul 中。

在 /etc/consul.d 目录,新建 realweb.json 文件。

{
  "service": {
    "name": "realweb",
    "port": 8081,
    "connect": {
      "sidecar_service": {}
    }
  }
}

然后执行 consul reload 重新加载配置文件。

注册代理

为啥要注册代理呢?

前面经过实践,我们已经学会了注册服务以及服务发现,一开始介绍 Consul 时,我们还看到 “Consul 提供功能强大的 服务网格”、“安全的连接” 等,那么我们通过这里的步骤(代理),就是体会 Consul 的这个特征功能。

前面已经注册了 realweb 这个服务,现在我们开启代理,在新的终端窗口,执行:

 consul connect proxy -sidecar-for realweb

注册代理

可以看到,Consul 使用 21000 端口来代理 realweb 服务。

这个代理功能称为 Consul Connect。

但是这个端口是不能访问的,其基本结构如下:

        源                       代理后
------------------        ------------------
|8081 <---> 21000| <----> |21001 <---> 9191|
------------------        ------------------

8081(源) 和 9191(代理的端口) 都可以访问,21000 和 21001 都是属于桥接端口,不能访问。

代理服务

前面注册 realweb 代理服务后(8081 <---> 21000),我们开始对其进行代理(21001 <---> 9191)。

这里的代理,是通过 Consul Service Mesh 使用 Sidecar 代理将服务相互连接,这种功能就叫 服务网格

        源                                            代理后
--------------------------                --------------------------
|8081 <-----------> 21000|   <-------->   |21001 <-----------> 9191|
|     Consul Connect     |     Sidecar    |      Consul Connect    |
--------------------------                --------------------------

为了实现代理,需要创建新的配置文件,注册服务。

新建一个终端窗口,在 /etc/consul.d/ 目录新建一个 proxyweb.json 文件。

其内容如下:

{
  "service": {
    "name": "proxyweb",
    "connect": {
      "sidecar_service": {
        "proxy": {
          "upstreams": [
            {
              "destination_name": "realweb",
              "local_bind_port": 9191
            }
          ]
        }
      }
    }
  }
}  

可以将 Connect 代理的每个上游配置为通过网状网关进行路由。local_bind_port 表示代理服务后,使用哪个端口作为代理端口。

绑定的代理端口可能是以下几种情况(这里直接搬文档):

  • local-在这种模式下,Connect代理建立与同一数据中心中运行的网关的出站连接。然后,该网关负责确保将数据转发到目标数据中心中的网关。

  • remote-在此模式下,Connect代理建立与目标数据中心中运行的网关的出站连接。然后,该网关将数据转发到最终目标服务。

  • none -在此模式下,不使用网关,并且Connect代理将其出站连接直接连接到目标服务。

创建配置完毕后(注册服务),执行 consul reload 重新加载配置文件。

然后执行命令开始代理服务。

consul connect proxy -sidecar-for proxyweb

验证代理

创建代理完毕后,我们检查代理是否正常。

新建一个终端窗口,执行访问目录:

 curl http://127.0.0.1:9191
root@50skbjiynxyxkcfh:~# curl http://127.0.0.1:9191
<h3>恭喜你,部署 Consul 服务成功!</h3><br><br><br><br>记得给笔者 痴者工良 点一下赞哟~~~

原本 realweb 服务暴露的端口为 8081,然后创建一个叫 proxyweb 的代理,其端口变成 9191,之后我们可以使用 9191 来访问这个 realweb 服务。

下图是从官网淘过来的,大家可以根据图片理解一下

proxy

假如搭建了一个微服务,其中一台主机有个服务是 redis,端口是 9003,你会把 redis 暴露到公网上么?肯定不能呀,于是通过代理功能,将 redis 服务代理到另一台 web 服务器,端口变成 5000,web 程序可以访问 redis 服务,但是外界不能访问。

然后 web 提供 9002 端口给用户,用户可以访问 web 网页服务。

UI 界面查看

打开 Consul 界面,可以看到代理服务。

ServiceProxyUI1

ServiceProxyUI2

9,Consul 集群/数据中心

本章内容将介绍如何将两台服务器的 Agent 关联起来,建立数据中心。

开始准备

这里需要两台服务器才行,当然官方文档提供了使用虚拟机的方法部署另一个系统,但是这里不提倡,还是老老实实搞两台服务器实际,不然你学啥集群和微服务。。。

在 Linux 快速部署虚拟机:https://learn.hashicorp.com/tutorials/consul/get-started-create-datacenter?in=consul/getting-started

切换到副服务器/虚拟机中,按照前面第二小节的安装教程,安装 consul。

主服务器上,停止 Consul,并关闭其它终端窗口,只留一个终端窗口就行。

root@50skbjiynxyxkcfh:~# top | grep consul
32318 root      20   0  785168  66096  49008 S  1.3  3.2  13:52.93 consul                                                                                  
root@50skbjiynxyxkcfh:~# kill 32318

启动 Consul 中心

在主服务器中执行以下命令,启动 Consul 实例。

# -bind 填写子网ip或公网ip,另一台服务器可以访问的ip
consul agent \
  -dev
  -server \
  -bootstrap-expect=1 \
  -node=agent-one \
  -bind=172.31.0.6 \
  -data-dir=/tmp/consul \
  -config-dir=/etc/consul.d
  • server-提供此标志表示您希望代理以服务器模式启动。

  • -bootstrap-expect-这告诉 Consul datacenter 总共应该有多少台服务器。

  • -node-数据中心中的每个节点必须具有唯一的名称。

  • -bind-这是该代理将侦听其他 Consul 成员进行通信的地址。填子网ip或公网ip。

  • data-dir-此标志告诉 Consul Agent 他们应将状态存储在哪里,其中可以包括服务器和客户端的敏感数据(如ACL令牌)。

  • config-dir-此标志告诉Consul在哪里寻找其配置。

启动成功后,会提示:

    2020-11-21T07:46:59.903+0800 [INFO]  agent.server: federation state anti-entropy synced
    2020-11-21T07:46:59.903+0800 [INFO]  agent: Synced node info
    2020-11-21T07:46:59.911+0800 [INFO]  agent: Synced service: service=web
    2020-11-21T07:46:59.923+0800 [INFO]  agent: Synced service: service=proxyweb
    2020-11-21T07:46:59.939+0800 [INFO]  agent: Synced service: service=proxyweb-sidecar-proxy
    2020-11-21T07:46:59.961+0800 [INFO]  agent: Synced service: service=realweb
    2020-11-21T07:46:59.971+0800 [INFO]  agent: Synced service: service=realweb-sidecar-proxy
  • 如果有报 realweb、proxy 代理错误的信息,可以忽略掉。

启动客户端

在副服务器上,执行以下命令启动一个新的 Agent。

consul agent \
  -node=agent-two \
  -bind=172.31.0.7 \
  -enable-script-checks=true \
  -data-dir=/tmp/consul \
  -config-dir=/etc/consul.d

检查成员信息

到目前为止,我们有两台服务器,每台服务器都部署了 Consul 实例,但是他们都是独立的,还没有被关联起来。

我们可以在每台服务器上执行以下命令检查其成员信息:

consul members
# consul server 1
Node       Address          Status  Type    Build  Protocol  DC   Segment
agent-one  172.31.0.6:8301  alive   server  1.8.6  2         dc1  <all>

# consul server 2
Node       Address          Status  Type    Build  Protocol  DC   Segment
agent-two  172.31.0.7:8301  alive   client  1.8.6  2         dc1  <default>

关联服务器

现在,我们把副服务器(172.31.0.7)加入到主服务器(172.31.0.6)中。

在副服务器上执行以下命令:

consul join 172.31.0.6

重新在每台服务器下执行 consul members 命令查看成员信息:

# consul server 1
Node       Address          Status  Type    Build  Protocol  DC   Segment
agent-one  172.31.0.6:8301  alive   server  1.8.6  2         dc1  <all>
agent-two  172.31.0.7:8301  alive   client  1.8.6  2         dc1  <default>

# consul server 2
Node       Address          Status  Type    Build  Protocol  DC   Segment
agent-one  172.31.0.6:8301  alive   server  1.8.6  2         dc1  <all>
agent-two  172.31.0.7:8301  alive   client  1.8.6  2         dc1  <default>

打开 UI 查看服务节点信息

打开 Consul UI 界面(8500端口),点击 Nodes ,即可看到 Consul 所有服务器节点。

Nodes

10,集群代理服务

本章内容讲述如何通过代理功能,将一台主机的服务在代理到另一台服务器中访问。

提供代理服务

在主服务器上把 proxyweb 终端关掉(已关掉请忽略),进入 /etc/consul.d 目录把 proxyweb.json
删除,重新加载配置:

consul reload

然后启动代理功能(Consul connect):

consul connect proxy -sidecar-for realweb

另一台服务器代理

在副服务器的 /etc/consul.d/ 目录中,新建一个 proxyweb.json 文件,其内容如下:

{
  "service": {
    "name": "proxyweb",
    "connect": {
      "sidecar_service": {
        "proxy": {
          "upstreams": [
            {
              "destination_name": "realweb",
              "local_bind_port": 9191
            }
          ]
        }
      }
    }
  }
}  

重新加载配置:

consul reload

启动代理服务

 consul connect proxy -sidecar-for proxyweb

验证代理

在副服务器打开新的窗口,执行:

curl http://127.0.0.1:9191

发现

<h3>恭喜你,部署 Consul 服务成功!</h3><br><br><br><br>记得给笔者 痴者工良 点一下赞哟~~~

说明通过代理服务,可以将一台主机的服务(端口),在另一台主机上使用别的端口(相同端口也可以)访问这个服务。

TwoServerProxy

关于 Consul 入门的教程就到这里为止~后面笔者会继续写 Consul ,欢迎关注~

痴者工良

高级程序员劝退师

文章评论