基于Nginx和Consul构建高可用及自动发现的Docker服务架构


前言

如果你在大量接触或使用微服务的话,你可能会碰到一个问题:当你创建的服务数量越来越多时,这些服务之间的通信便越难管理,而且维护代价会越来越高。

针对这个问题,Consul给出了一份完美的答卷。

mark

一:Consul概述

Consul是一套开源的分布式服务发现和配置管理系统,支持多数据中心分布式高可用。Consul是HashiCorp(Vagrant的创建者)开发的一个服务发现与配置项目,用Go语言开发,基于
Mozilla Public License 2.0 的协议开源。

另外,架构里的另一个重要的角色则是Docker。Docker技术的不断成熟,孵化出了大量优秀的相关技术,比如docker监控,开源技术有cAdvisor、Cloud
Insight或Telegraf等,自定义开发方式,Docker stats、Python
API或伪文件系统;Docker管理,Forman、Kubernetes与CoreOS(都已整合各类组件),各类技术覆盖网络、监控、维护、部署、开发等方面,帮助开发、运维人员快速构建、运营Docker服务环境。

面对如此优秀和快速发展的一个生态圈技术,在企业当中,我们该如何选择并发挥Docker的强大之处?

而现实中,我们一直渴望着追求提供高质量、高可用的服务架构体系,同时减少不必要的部署和维护代价,减少容错率。

解决方法:

面对如此高的要求,我们提供了一下一种方案

Docker+Consul+Nginx

今天我将对比以上方案,给大家提供一种更加高效、快捷,并且维护代价和容错率更低,分布式支持力度更强的架构方案Docker+Consul+Nginx(如图)

mark

(1)Consul:

1、Consul 是 HashCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置;
2、Consul 特点:

consul 支持健康检查,允许存储键值对;
一致性协议采用 Raft 算法,用来保证服务的高可用;
成员管理和消息广播采用 GOSSIP
协议,支持 ACL 访问控制;

3、方便部署,与 Docker 等轻量级容器可无缝配合。

(2)建立 Consul 服务:

1、每个提高服务的节点上都需要部署和运行 consul 的 agent
2、Consul agent 两种运行模式:

server;
client;

3、server 与 client 只是 consul 群集层面的区分,与搭建在 cluster 之上的应用服务无关。

二:搭建consul群集

  • 环境准备

  • 这里,我们选用Nginx(Consul Template官方同时提供了Nginx和HAProxy的配置demo)。Nginx不仅是个强大的Web代理服务器,同时在负载均衡方面表现也不俗。更关键的,新版本的Nginx对在线升级支持做到了极致。实时配置更新更是不在话下,可以保证服务的连续性。

  • Nginx将会根据转发策略把请求转发给其中一个健康的服务实体;

    前端服务,将会通过负载策略去访问某个后端服务。这一点也是通过Nginx的自身组件实现。

IP地址 需要安装的软件
服务器1(20.0.0.41) Docker-ce、Compose3、Consul、Consul-template
服务器2(20.0.0.42) Docker-ce、registrator

架构思维图

mark

2.1:配置 consul 服务器

[root@localhost ~]# ls
anaconda-ks.cfg  docker-compose        shuai  模板  图片  下载  桌面
consul           initial-setup-ks.cfg  公共   视频  文档  音乐
[root@localhost ~]# chmod +x docker-compose 
[root@localhost ~]# mv docker-compose /usr/local/bin/

[root@localhost ~]# mkdir consul

[root@localhost ~]# cd consul/
[root@localhost consul]# ls
consul_0.9.2_linux_amd64.zip  consul-template_0.19.3_linux_amd64
[root@localhost consul]# unzip consul_0.9.2_linux_amd64.zip 
[root@localhost consul]# mv consul /usr/local/bin/

建立Concul服务:
consul agent \
-server \
-bootstrap \
-ui \
-data-dir=/var/lib/consul-data \
-bind=20.0.0.41 \
-client=0.0.0.0 \
-node=consul-server01 &> /var/log/consul.log &

2.11:查看群集信息

[root@localhost consul]# consul members
Node             Address         Status  Type    Build  Protocol  DC
consul-server01  20.0.0.41:8301  alive   server  0.9.2  2         dc1
[root@localhost consul]# consul info | grep leader
	leader = true
	leader_addr = 20.0.0.41:8300

2.12:通过httpd api可以获得群集信息

[root@localhost consul]# curl 127.0.0.1:8500/v1/status/peers                 ##查看群集server成员
[root@localhost consul]# curl 127.0.0.1:8500/v1/status/leaders               ##群集中 Raf leader
[root@localhost consul]# curl 127.0.0.1:8500/v1/catalog/services             ##注册的所有服务
[root@localhost consul]# curl 127.0.0.1:8500/v1/catalog/nodes                ##群集节点详细信息
[root@localhost consul]# curl 127.0.0.1:8500/v1/catalog/nginx                ##查看 nginx 服务信息

2.13:让容器服务自动化加入nginx群集

1.安装Gliderlabs/Registrator Gliderlabs/Registrator
可检查容器运行状态自动注册,还可注销docker容器的服务到服务配置中心。
目前支持Consul、Etcd和SkyDNS2。
在20.0.0.42节点执行以下操作

docker run -d \
--name=registrator \
--net=host \
-v /var/run/docker.sock:/tmp/docker.sock \
--restart=always \
gliderlabs/registrator:latest \
-ip=20.0.0.42 \
consul://20.0.0.41:8500

2.14:测试服务功能是否能正常访问

#创建两个容器,分别为shuai01和shuai02,指定端口为8384
[root@localhost ~]# docker run -itd -p:83:80 --name shuai-01 -h shuai01 nginx
[root@localhost ~]# docker run -itd -p:84:80 --name shuai-02 -h shuai02 nginx
  • 验证nginx服务是否注册到consul

  • 浏览器访问:20.0.0.41:8500

  • 点击“NODES”----》“consurl-serve01”会出现刚刚创建的两个服务

mark

  • 在创建两个查看一下
[root@localhost ~]# docker run -itd -p:85:80 --name shuai-03 -h shuai03 nginx

[root@localhost ~]# docker run -itd -p:86:80 --name shuai-04 -h shuai04 nginx

mark

2.15:在consul服务器查看服务

[root@localhost consul]# curl 127.0.0.1:8500/v1/catalog/services 
{
    
    "consul":[]}[root@localhost consul]# curl 127.0.0.1:8500/v1/catalog/nodes 
[{
    
    "ID":"5d0481f9-c9bb-ef56-70ba-40a5ea25ab2f","Node":"consul-server01","Address":"20.0.0.41","Datacenter":"dc1","TaggedAddresses":{
    
    "lan":"20.0.0.41","wan":"20.0.0.41"},"Meta":{
    
    },"CreateIndex":5,"ModifyIndex":6}][root@localhost consul]# curl 127.0.0.1:8500/v1/catalog/nginx 
[root@localhost consul]# curl 127.0.0.1:8500/v1/catalog/services

2.2:安装 consul-template

Consul-Template是一个守护进程,用于实时查询Consul集群信息,并更新文件系统上系统上任意数量的指定模板,生成配置文件。更新完成后,可以选择允许shell命令执行更新,重新加载Nginx。Consul-Template可以查询Consul中的服务目录,Key、Key-Values等,这种抽象的功能和查询语言模板可以使Consul-Template特别适合动态的创建配置文件

2.21:准备template nginx模板文件

  • 在consul上操作
upstream http_backend {
    
    
    {
    
    {
    
    range service "nginx"}}
     server {
    
    {
    
    .Address}}:{
    
    {
    
    .Port}};
     {
    
    {
    
    end}}
}

server {
    
    
       listen 83;
       server_name localhost 20.0.0.41;
       access_log /var/log/nginx/kgc.cn-access.log;
       index index.html index.php;
       location / {
    
    
          proxy_set_header HOST $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header Client-IP $remote_addr; 
          proxy_set_header X-Fprwarded-For $proxy_add_x_forwarded_for;
          proxy_pass http://http_backend;
       }         
}

2.3:编译安装一个nginx服务【做反向代理】

#安装环境
[root@localhost ~]# yum install gcc gcc-c++ pcre pcre-devel zlib-devel -y

[root@localhost ~]# cd /opt
[root@localhost opt]# ls
containerd  mei  nginx-1.12.0.tar.gz  rh
#解压缩
[root@localhost opt]# tar zxvf nginx-1.12.0.tar.gz 

cd nginx-1.12.0/
[root@localhost nginx-1.12.0]# ./configure --prefix=/usr/local/nginx

#编译及安装
[root@localhost nginx-1.12.0]# make && make install

#创建启动软连接
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/

2.31:配置nginx

#在http模板添加虚拟主机目录
[root@localhost nginx-1.12.0]# vim /usr/local/nginx/conf/nginx.conf

http {
    
    
    include       mime.types;
    include       vhost/*.conf;      '//添加虚拟主机目录'
    default_type  application/octet-stream;

mark

  • 创建虚拟主机目录
[root@localhost nginx-1.12.0]# mkdir /usr/local/nginx/conf/vhost
  • 创建日志文件目录
[root@localhost nginx-1.12.0]# mkdir /var/log/nginx
  • 启动nginx
/usr/local/nginx/sbin/nginx

#查看端口
[root@localhost nginx-1.12.0]# netstat -ntap | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      26370/nginx: master 
  • 配置并启动template
#进入consul解压缩包
[root@localhost ~]# cd consul/
[root@localhost consul]# ls
consul_0.9.2_linux_amd64.zip            nginx.ctmpl
consul-template_0.19.3_linux_amd64.zip
[root@localhost consul]# unzip consul-template_0.19.3_linux_amd64.zip 

复制到/bin目录下,方便直接使用
[root@localhost consul]# mv consul-template /usr/local/bin/
  • 启动
consul-template -consul-addr 20.0.0.41:8500 -template "/root/consul/nginx.ctmpl:/usr/local/nginx/conf/vhost/shuai.conf:/usr/local/nginx/sbin/nginx -s reload" --log-level=info
 '//会进入监控状态'

/root/consul/nginx.ctmpl:template        模板文件目录
/usr/local/nginx/conf/vhost/shuai.conf    文件生成的路径 【生成到vhost中】
/usr/local/nginx/sbin/nginx -s reload     重载服务配置 
log-level=info                            日志级别
  • 此时,我们可以再打开一个终端,查看一下根据模板生成的配置文件:

mark

2.4:添加一个nginx容器节点

  • 为了展示轮询处理请求,可以用logs命令,来查看三台nginx容器的容器日志,

  • 都会显示来自同一IP地址的访问

#访问shuai-01可以看到没有访问日志
[root@localhost ~]# docker logs -f shuai-01
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates

#查看shuai-02同样没有访问日志
[root@localhost ~]# docker logs -f shuai-01
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates

2.5:我们去刷新几次nginx首页:20.0.0.41:83

mark

[root@localhost ~]# docker logs -f shuai-01
/docker-entrypoint.sh: Configuration complete; ready for start up
20.0.0.41 - - [23/Sep/2020:11:31:02 +0000] "GET / HTTP/1.0" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko Core/1.70.3775.400 QQBrowser/10.6.4209.400" "-"
20.0.0.41 - - [23/Sep/2020:11:34:08 +0000] "GET / HTTP/1.0" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko Core/1.70.3775.400 QQBrowser/10.6.4209.400" "-"

[root@localhost ~]# docker logs -f shuai-02
/docker-entrypoint.sh: Configuration complete; ready for start up
20.0.0.41 - - [23/Sep/2020:11:33:58 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko Core/1.70.3775.400 QQBrowser/10.6.4209.400" "-"

[root@localhost ~]# docker logs -f shuai-03
/docker-entrypoint.sh: Configuration complete; ready for start up
20.0.0.41 - - [23/Sep/2020:11:34:00 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko Core/1.70.3775.400 QQBrowser/10.6.4209.400" "-"

2.6:新增一个nginx容器节点,测试服务器发现及配置更新功能

[root@localhost ~]# docker run -itd -p:87:80 --name shuai-05 -h shuai05 httpd
  • 刷新几次主机测试是否以轮询方式发送给后台docker进行处理,实现负载均衡
20.0.0.41 - - [23/Sep/2020:11:45:40 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko Core/1.70.3775.400 QQBrowser/10.6.4209.400" "-"
20.0.0.41 - - [23/Sep/2020:11:45:40 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko Core/1.70.3775.400 QQBrowser/10.6.4209.400" "-"
20.0.0.41 - - [23/Sep/2020:11:45:41 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko Core/1.70.3775.400 QQBrowser/10.6.4209.400" "-"
20.0.0.41 - - [23/Sep/2020:11:45:42 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko Core/1.70.3775.400 QQBrowser/10.6.4209.400" "-"
20.0.0.41 - - [23/Sep/2020:11:45:42 +0000] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko Co

mark

本次实验结束感谢观看.

猜你喜欢

转载自blog.csdn.net/weixin_47151643/article/details/108821392