部署consul+nodejs+docker集群

在这里插入图片描述

在进行部署之前我们需要了解

  • 什么是consul?

服务注册
Consul 内部侦听 8500 端口,提供给 Consul 的客户端注册服务,比如张三开发了一个购物车程序,该购物车程序包含了“加入购物车”、“清空购物车” 两个接口,张三在开发购物车程序的时候,使用了 Consul 的客户端包组件,在程序运行起来以后,购物车程序就自动的连接到 Consul 的 8500 端口,注册了一个服务,该服务被命名为“购物车程序”,此时,Consul 并不知道 “购物车程序”有多少个接口,Consul 只知道 “购物车程序”的服务地址、端口。
服务发现
在“购物车程序”注册到 Consul 后,Consul 也仅仅知道有这么一个服务注册进来了,并且还配置了健康检查, Consul 会定时的去连接 “购物车程序”,确保其还处于可提供服务的状态,任何人(程序)都可以通过 Consul 的外部地址访问 Consul 内部的已注册的服务列表,从而获得真实的服务地址,然后调用该真实地址,获得结果。
集群
Consul 是一个分布式的解决方案,可以部署多个 Consul 实例,确保数据中心的持续稳定,在 Consul 集群中,内部采用投票的方式选举出 leader,然后才开始运行整个集群,只有正确选举出 leader 后,集群才开始工作,当一个服务注册到 Consul 后,集群将该服务进行同步,确保 Consul 集群内的每个节点都存储了该服务的信息;然后,Consul 集群将对该服务进行健康检查和投票,超过半数通过,即认为该服务为正常(或者异常);一旦被投票认定为异常的服务,该服务将不会被外部发现(不可访问),在此过程中,Consul 将持续的对该异常的服务进行检查,一旦服务恢复,Consul 即刻将其加入正常服务。
服务器和客户端
Consul 支持两种运行的方式,即 server 和 client 模式,当一个 Consul 节点以 server 模式运行的时候,就表示该 Consul 节点会存储服务和配置等相关信息,并且参与到健康检查、leader 选举等服务器事务中,与之相反的是,client 模式不会存储服务信息。
数据中心
每个 Consul 节点都需要加入一个命名的数据中心(DataCenter),一个节点上,可以运行多个数据中心,数据中心的作用在于应用隔离,相当于服务分组
键值存储
在 Consul 内部,提供了简单的数据存储,也就是 key/value 系统,kv 系统非常强大,它的作用包括允许节点动态修改配置、执行 leader 选举、服务发现、集成健康检查、或者其它你想要存储到 Consul 中的内容

  • 它的优势是什么?

使用 Raft 算法来保证一致性, 比复杂的 Paxos 算法更直接. 相比较而言, zookeeper 采用的是 Paxos, 而 etcd 使用的则是 Raft.
支持多数据中心,内外网的服务采用不同的端口进行监听。 多数据中心集群可以避免单数据中心的单点故障,而其部署则需要考虑网络延迟, 分片等情况等. zookeeper 和 etcd 均不提供多数据中心功能的支持.
支持健康检查. etcd 不提供此功能.
支持 http 和 dns 协议接口. zookeeper 的集成较为复杂, etcd 只支持 http 协议.
官方提供web管理界面, etcd 无此功能.
综合比较, Consul 作为服务注册和配置管理的新星, 比较值得关注和研究

  • consul解决了什么问题?

为不同的环境提供不同的配置
提供数据共享配置中心,不用再为配置的更改导致重新发布更新
为微服务架构的业务系统解耦合

在这里博主使用了docker进行部署,nodejs负责进行注册

  • 安装Docker

安装的教程就不写了,网上有很多,步骤很简单

  • 安装Consul(最新版本)

docker pull consul:latest
sudo docker -v
sudo docker images
在这里插入图片描述

  • consul命令(更详细命令可以查看底部参考的网址)

–net=host docker参数, 使得docker容器越过了net namespace的隔离,免去手动指定端口映射的步骤
-server consul支持以server或client的模式运行, server是服务发现模块的核心, client主要用于转发请求
-advertise 将本机私有IP传递到consul
-retry-join 指定要加入的consul节点地址,失败后会重试, 可多次指定不同的地址
-client 指定consul绑定在哪个client地址上,这个地址可提供HTTP、DNS、RPC等服务,默认是>127.0.0.1
-bind 绑定服务器的ip地址;该地址用来在集群内部的通讯,集群内的所有节点到地址必须是可达的,>默认是0.0.0.0
allow_stale 设置为true则表明可从consul集群的任一server节点获取dns信息, false则表明每次请求都会>经过consul的server leader
-bootstrap-expect 数据中心中预期的服务器数。指定后,Consul将等待指定数量的服务器可用,然后>启动群集。允许自动选举leader,但不能与传统-bootstrap标志一起使用, 需要在server模式下运行。
-data-dir 数据存放的位置,用于持久化保存集群状态
-node 群集中此节点的名称,这在群集中必须是唯一的,默认情况下是节点的主机名。
-config-dir 指定配置文件,当这个目录下有 .json 结尾的文件就会被加载,详细可参考https://www.consul.io/docs/agent/options.html#configuration_files
-enable-script-checks 检查服务是否处于活动状态,类似开启心跳
-datacenter 数据中心名称
-ui 开启ui界面
-join 指定ip, 加入到已有的集群中

//这里我们启动三个server和client,client将注册的服务转发到server,服务的发现也是使用client进行获取

  • 启动consul程序

docker run --name consul-0 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul agent -server -bootstrap-expect 3 -ui -bind=0.0.0.0 -client=0.0.0.0
8500 : http 端口,用于 http 接口和 web ui访问;
8300 : server rpc 端口,同一数据中心 consul server 之间通过该端口通信;
8301 : serf lan 端口,同一数据中心 consul client 通过该端口通信; 用于处理当前datacenter中LAN的gossip通信;
8302 : serf wan 端口,不同数据中心 consul server 通过该端口通信; agent Server使用,处理与其他datacenter的gossip通信;
8600 : dns 端口,用于已注册的服务发现;

  • 我们再启动两个server加入consul-0

先查看我们需要加入的集群容器ip
docker inspect --format=’{{.NetworkSettings.IPAddress}}’ consul-0
在这里插入图片描述
docker run --name consul-1 -d -p 8501:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2
docker run --name consul-2 -d -p 8501:8500 consul agent -server -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.2

  • 再启动一个client用来同步注册的服务信息和服务发现

docker run --name consul2 -d -p 8501:8500 consul agent -client -ui -bind=0.0.0.0 -client=0.0.0.0 -join 172.17.0.4

  • 查看docker consul的集群

sudo docker exec -it consul-0 consul members
在这里插入图片描述
可以很清楚的看到我们启动了三个server,一个client

  • 打开浏览器访问8500端口

在这里插入图片描述
172.17.0.5右侧数值为2,到后面会讲到,那是注册的服务
至此,我们的consul集群就已经搭建成功了,接下来让我们进行服务的注册

服务注册

consul提供HTTP API和服务定义的模式进行注册,通常情况下都是使用服务定义的方式,那我们也采用这种方式

  • 使用nodejs的egg.js框架进行演示

https://eggjs.org/
按照以下示例搭建ts版本的egg骨架
https://github.com/eggjs/examples/tree/master/hackernews-async-ts
在这里插入图片描述

  • 在启动配置文件app.ts中加入consul的服务注册配置

app.js在egg中是一个可选项,所以我们直接建立该文件
安装consul
npm install consul
在app文件中引入,并选定一个生命周期进行配置

import { Application, IBoot } from 'egg';
import * as Consul from 'consul';

export default class AppBootHook implements IBoot {
    app: Application;
    constructor(app: Application) {
        this.app = app;
    }

    async willReady() { //该生命周期是所有插件启动完毕执行
        const serviename = 'egg-namespace'; //该服务的命名
        const consul = new Consul({ //初始化注册对象
            host: '172.16.101.79', //consul注册中心的地址,这里我用的本机地址
            port: '8503', //consul client服务的端口号
            promisify: true,
        });
        consul.agent.service.register({ //调用consul注册的方法
            name: serviename, //服务名称
            address: '172.16.101.79', //向consul中心注册的地址
            port: 7001, //该服务的端口号
            tags: [ //标签,用于区分服务
                'v1',
            ],
            checks: [
                {
                    http: 'http://172.16.101.79:7001/health', //健康检查的url
                    interval: '10s', //定时器,每隔十秒检查一次
                },
            ],
        }, error => {
            if (error) {
                console.error(error);
                throw error;
            }
            console.log(serviename + ' 注册Consul成功!');
            this.app.consul = consul; //挂载在内置对象中
        });
    }
}

//在全局app上挂载对象,由于使用的是ts框架,所以需要单独在egg模块上进行扩展
/// typings / index.d.ts中进行扩展挂载
/*
import 'egg';
import { MongoClient } from 'mongodb';
import * as Consul from 'consul';

declare module 'egg' {
    // egg.js扩展
    interface Application{
        mongo: MongoClient
        consul: Consul
    }
}
*/

健康检查

就加一个专门给consul定时检查的api,返回200状态码就可以

在这里插入图片描述

KeyValue存储配置

  • 为什么需要KeyValue存储配置

数据共享,服务发现,健康检查等

  • KeyValue配置

我们先在consul上配置键值对
在这里插入图片描述
key为配置的层级路径,value就是配置的数值,可以是任何值
继续使用npm consul模块中提供的方法

		const { ctx } = this;
        const data = await this.app.consul.kv.get('develop/config'); //配置的key
        if (!data) {
            ctx.body = `${data} **** getTest param error`;
        } else {
            ctx.body = JSON.parse(data.Value);
        }

在这里插入图片描述

服务发现

  • 服务发现就是获取你注册的服务信息,里面包含了地址和服务名称等

http://localhost:8503/v1/health/service/egg-namespace
8503是我们的client服务,用它来进行获取服务信息
在这里插入图片描述

至此,我们对consul+docker+nodejs的部署,启动,配置已经完成,但你要知道,仅仅依靠这些,还不足以站住脚跟,因为我们每次的配置,部署和启动都需要我们手动来完成,那么,重复的工作我们就把它自动化,工具化。

如何部署Consul-template+Nginx?

  • Consul-template?

在consul-template没出现之前,大家构建服务发现系统,大多采用的是zookeeper、etcd+confd这样类似的系统,之前写过一篇consul+confd的文,讲的是如何动态生成配置文件的,如今consul官方推出了自己的模板系统,就是consul-template,这样的话动态的配置系统可以分化为etcd+confd和consul+consul-template两大阵营。consul是一个和etcd类似但又强于etcd的系统,关于etcd和consul可以翻阅以前的文章,consul-template的定位就和confd差不多一样了,confd的后端可以是etcd或者consul,相信consul搭配consul-template能发挥更大的效果。consul-template提供了一个便捷的方式从consul中获取存储的值,consul-template守护进程会查询consul实例,来更新系统上指定的任何模板,当更新完成后,模板可以选择运行一些任意的命令。
consul template的使用场景:consul template可以查询consul中的服务目录、key、key-values等。这种强大的抽象功能和查询语言模板可以使consul template特别适合动态的创建配置文件。例如:创建apache/nginx proxy balancers、haproxy backends、varnish servers、application configurations

  • Nginx?

www.baidu.com

  • Consul-template和Nginx之间是如何配合的呢?

Consul-tempalte启动后能够检测到consul的服务是否发生变化,比如consul_tempalte启动后就会发现目前server下有consul-0,consul-1,consul-2和consul-3下的client服务,然后得到这些服务下注册的ip及端口号。而nginx,反向代理,consul_tempalte就是通过模板的形式,生成一个新的vhost.conf,动态改变nginx配置内代理的IP地址,从而实现自动化的反向代理,每当注册服务有变化,Consul-template都会自动检测并重新配置vhost.conf

  • 安装Consul-template和Nginx

安装就没什么好说的了,官方有工具包下载,网上资源也很多
Nginx:http://nginx.org/
Consul-template:https://learn.hashicorp.com/consul/developer-configuration/consul-template

现在,我们在已经有consul的基础上,三个server,一个client,并确保Consul-template和Nginx已经安装完成的情况下来搭建consul-template
我的本地已经安装好了,安装位置如下
在这里插入图片描述

  • 配置Consul-template

我们先在Nginx下新建consul目录
mkdir consul
进入该目录
cd consul
创建nginx.ctmpl文件用于生成和重写vhost.conf
touch nginx.ctmpl
sudo vim nginx.ctmpl

upstream egg {
  {{range service "egg-namespace"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
  {{else}}server 127.0.0.1:65535; # force a 502{{end}}
}
upstream express {
  {{range service "express-namespace"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
  {{else}}server 127.0.0.1:65535; # force a 502{{end}}
}

server {
  listen 8000; 
  server_name localhost;
  #index
  location / {
    proxy_pass http://express;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
  #映射egg后台
  location /egg/{
    proxy_pass http://egg/;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
  }
  #映射express后台
  location /express/ {
    proxy_pass http://express/;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
  }
}
  • 向consul注册服务

注册的步骤在上面已经有演示
所以我本地就直接启动两个服务并注册
在这里插入图片描述
egg-namespace
express-namespace

upstream,上游服务器,你注册在consul中的服务,把service改成你自己在consul中的命名空间即可
listen改成你服务器上没有被占用的端口号
location后配置访问的url
proxy_pass配置需要转发的upstream
location的配置要十分小心,/这个斜杠不要少,否则走绝对路径,你可能404

  • 启动Consul-template,生成vhost文件,并重新启动Nginx

把Consul-template放置在系统/usr/bin目录下,这样就可以全局使用
sudo consul-template --consul-addr localhost:8500 --template “/etc/nginx/consul/nginx.ctmpl:/etc/nginx/consul/vhost.conf:service nginx restart” --log-level=info
–consul-addr:consul server的地址,这里使用的是相对路径,当然你也可以使用绝对路径
–template:模板及生成的conf文件路径,后跟/usr/local/nginx/sbin/nginx -s reload是当agent发生变化时,自动重新加载nginx,如果不加,当agent发生变化时,需要你手动重新加载nginx,因为nginx配置发生了变化。

启动成功
在这里插入图片描述

  • vhost.conf

在这里插入图片描述
根目录指向express,/egg/和/express/也分别指向其他服务
在这里插入图片描述
如果我们注销一个服务,consul-template会自动检测并重写vhost文件
在这里插入图片描述

到现在,我们的consul,consul-template,docker,nginx,nodejs的搭配已经配置部署完成,但这仅仅只是入门,希望大家一起来学习,如果有演示的不对的地方,请及时告诉博主,感谢~

Consul配置:http://www.imooc.com/article/289385

Consul命令:https://segmentfault.com/a/1190000019424215?utm_source=tag-newest

Consul+Docker配置:https://blog.csdn.net/junmoxi/article/details/90521818
https://www.cnblogs.com/sunsky303/p/9188199.html

Consu+Consu-template+Nginx配置:https://www.cnblogs.com/xiangsikai/p/10058541.html
https://blog.csdn.net/yb223731/article/details/90057640
https://blog.csdn.net/delongcpp/article/details/80119307

Nginx upstream配置location疑难:https://www.php.cn/nginx/425693.html

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Docker+Consul+Nginx+keepalived是一种常用的云原生架构方案,它结合了容器化、服务发现、负载均衡和高可用等多种技术手段,可用于构建高可用、弹性、可扩展的应用系统。 该方案的主要组件包括: 1. Docker:用于容器化应用程序和服务,提供了高效、轻量、可移植的应用打包和部署方式。 2. Consul:用于服务发现和配置管理,支持多数据中心、跨平台、高度可扩展的分布式系统。 3. Nginx:用于负载均衡和反向代理,支持高并发、高可用的流量分发。 4. keepalived:用于实现高可用的服务和节点,提供了基于 VRRP 协议的故障转移和自动切换功能。 在该方案中,Docker 容器作为应用程序和服务的运行环境,使用 Consul 进行服务注册和发现,并通过 Nginx 进行流量分发和负载均衡。同时,使用 keepalived 实现高可用的服务和节点,确保系统的稳定性和可用性。 项目描述可以按照以下步骤进行撰写: 1. 项目背景和目的:简要介绍本项目的背景和目的,说明为什么选择 Docker+Consul+Nginx+keepalived 方案。 2. 技术架构:详细介绍该方案的技术架构和组件,包括 DockerConsulNginx 和 keepalived 的作用和使用方式。 3. 系统功能:描述系统的主要功能和特点,包括服务发现、负载均衡、高可用等方面。 4. 实现方式:介绍系统的具体实现方式和实现步骤,包括 Docker 镜像的构建、应用程序的容器化、Consul 的配置和使用、Nginx 的配置和使用、keepalived 的配置和使用等。 5. 测试和验证:对系统进行测试和验证,验证系统的功能和性能是否符合预期,是否满足高可用和弹性的要求。 6. 总结和展望:对本项目进行总结和展望,分析该方案的优缺点和适用范围,展望未来的发展方向和趋势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值