目录

第一部分: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 服务发现与服务网格-有丰富的示例和图片-LMLPHP

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

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

发现数据中心成员

执行 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 命令,会让你进坑的。

*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 的服务。

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

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 界面,如图:

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

你可以通过 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。

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

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

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

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

详细请点击 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 服务发现与服务网格-有丰富的示例和图片-LMLPHP

可以看到,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 服务。

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

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

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

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

UI 界面查看

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

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

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

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 所有服务器节点。

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

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>记得给笔者 痴者工良 点一下赞哟~~~

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

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

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

11-21 19:48