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

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 本文讲的是基于Nginx和Consul构建高可用及自动发现的Docker服务架构【编者的话】本文对于Docker和Consul Template以及Nginx如何结合使用做了较为详细的介绍。
本文讲的是基于Nginx和Consul构建高可用及自动发现的Docker服务架构【编者的话】本文对于Docker和Consul Template以及Nginx如何结合使用做了较为详细的介绍。

【上海站|3天烧脑式微服务架构训练营】培训内容包括:DevOps、微服务、Spring Cloud、Eureka、Ribbon、Feign、Hystrix、Zuul、Spring Cloud Config、Spring Cloud Sleuth等。

导读

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

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

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的强大之处?

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

面对如此高的要求,我们提供了以下两种架构方案:
  1. Docker+Etcd+Confd+Nginx
  2. Docker+Consul+Nginx

架构设计与架构流程

Docker+Etcd+Confd + Nginx,采用松散式的组织结构,但各个组件之间的通讯是非常严密的,且扩展性更强,定制也更加灵活,这样一个架构体系在实用环境中,确实也体现了各个组件的强大功效。Etcd用于提供分享配置和服务发现,Confd通过查询Etcd,结合配置模板引擎,保持本地配置最新,同时具备定期探测机制,配置变更自动reload;Nginx提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,为此提供一套完美的架构服务体系。

以上的一套架构方案确实也是当前用得比较普遍的方案,而今天我将对比以上方案,给大家提供另外一种更加高效、快捷,并且维护代价和容错率更低,分布式支持力度更强的架构方案Docker+Consul+Nginx(如图)。
02.jpeg

服务架构图

使用Docker将Consul、Consul Template、Registrator和Nginx组装成一个值得信任且可扩展的服务框架,这套架构让你在这个框架中添加和移除服务,不需要重写任何配置,也不需要重启任何服务,一切都能正常运行,具体工作流程如下图。
03.jpeg

架构流程图

架构优势

Docker+Consul+Nginx虽然看起来是三个组件的运用,但却证明是一个有机的整体。它们互相联系、互相作用,完全满足我们对高可用、高效服务架构方案的需求,是Docker生态圈中最理想的组合之一,具有以下优势:

自动发现与注册组件Consul(内部的架构设计参见图Consul内部的架构设计)使用Raft算法来保证一致性,比复杂的Paxos算法更直接。相比较而言,ZooKeeper 采用的是 Paxos,而etcd使用的则是Raft;

支持多数据中心(参见图Consul多数据中心分布式集群架构),多数据中心集群可以避免单数据中心的单点故障,ZooKeeper和etcd均不提供多数据中心功能的支持;

自动、实时发现及无感知服务刷新,具备资源弹性,伸缩自如(通过生成、销毁容器实现);

支持健康检查,负载能动态在可用的服务实例上进行均衡,etcd不提供此功能;

支持足够多台Docker容器(前提架构资源足以保证性能支撑);

支持HTTP和DNS协议接口,ZooKeeper的集成较为复杂,etcd只支持HTTP协议;

服务规模方便进行快速调整,官方提供Web管理界面,etcd无此功能;

Consul Template搭配Consul使用,支持多种接入层,如Nginx、Haproxy。
04.jpeg

Consul内部的架构设计

05.jpeg

Consul多数据中心分布式集群架构

模块介绍

服务发现模块

服务发现的项目已经有不少,包括之前介绍的Consul,以及etcd、SkyDNS,以及主要关注一致性的强大的ZooKeeper等。

这些项目各有优缺点,功能上大同小异,都是要通过某种机制来获取服务信息,然后通过维护一套(分布式)数据库来存储服务的信息。在这里,选用HashiCorp公司的Consul作为服务发现的管理端。

服务注册模块

服务注册的手段有很多,从发起方是谁可以分为主动注册和被动探测,它们都对网络连通性要求较高。从短期看,主动注册方式会比较容易实现一些,应用情形更广泛;但长期维护上,被动探测方式应该是更高效的设计。

这里,我们选用Registrator,它可以通过跟本地的Docker引擎通信,来获取本地启动的容器信息,并且注册到指定的服务发现管理端。

配置更新模块

服务被调整后,负载均衡器要想动态重新分配负载,就需要通过配置来获取更新。笔者本着追求简单和高效,使用HashiCorp公司的Consul Template,可以通过监听Consul的注册信息,当添加或者移除服务时,Consul Template可以通过连接Consul更新配置并重启应用。

负载均衡模块

负载均衡对性能要求很高,其实并不是软件所擅长的领域,但软件方案胜在成本低、维护方便,包括 LVS、HAProxy、Nginx都是很优秀的设计方案。

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

服务架设

这样一来我们应用的具体场景将会变成如下模式:

用户将会通过访问到我们的前端服务;

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

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

接下来,我们一步步部署实施这套架构组件(所有的组件都是基于Docker方式部署,其他部署方式参见各组件官网文档):

Consul Template创建Docker镜像,并运行:
[root@sc ~]# docker run --rm -it yeasy/nginx-consul-template:latest bash

同时我们参考一下Consul Template官方提供的Nginx配置示例:
upstream frontend { {{range service "app.frontend"}}

server {{.Address}};{{end}}

} 

为此产生的nginx.conf配置模板如下:
upstream app {

least_conn;

{{range service "app.frontend"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;

//”app.frontend”必须要和真实服务(如下面部署的“simple http server”在consul上发现的service name相同

{{else}}server 127.0.0.1:65535; # force a 502{{end}}

}

server {

listen 80 default_server;

location / {

proxy_pass http://app;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

}

}  

这个Docker容器将会运行Consul Template和Nginx,当服务有变化时,它将重写Nginx的app.conf文件并且重新加载Nginx。

Consul创建Docker镜像,并运行:

Consul是一个拥有DNS和HTTP API的服务。它主要负责服务发现,以及对服务的健康检测和“键-值”对存储库。

执行以下命令在Docker Container中运行Consul:
docker run -it -h node \

-p 8500:8500 \

-p 8600:53/udp \

progrium/consul \

-server \

-bootstrap \

-advertise $DOCKER_IP \

-log-level debug 

如果你通过浏览器能够访问$DOCKER_IP:8500,你将在控制面板上看到Consul中已经注册的所有服务。
07.jpeg

在Docker容器启动后,Registrator配置好相应的环境变量并将这个容器注册到Consul上,示例如下:
docker run -it \

-v /var/run/docker.sock:/tmp/docker.sock \

-h $DOCKER_IP gliderlabs/registrator:latest\

consul://$DOCKER_IP:8500 


最后,我们搭建一个SimpleHTTPServer作为真实服务的模拟:

为方便我们动态调控真实服务的数量,我们使用docker-compose来做批管理,编写docker-compose.yml如下:
#app application, scale this with docker-compose scale web=3

web:

image: yjli/simple-http-service:v2

environment:

SERVICE_NAME: SimpleHttpService

ports:

-"80" 

使用docker-compose创建并运行:
[root@sc ~]# docker-compose up

通过Consul的WebUI查看:
08.jpeg

查看到SimpleHTTPServer已经被Consul自动发现,显示正常服务个数是1个;

访问 http://192.168.1.107 (模拟Nginx对外提供的服务访问地址)可以看到一个 web 页面,显示实际访问的目标地址:
2016-10-07 09:37:44: <1> requests from to simple-server <172.17.0.5>
2016-10-07 09:37:45: <2> requests from to simple-server <172.17.0.5>
2016-10-07 09:37:46: <3> requests from to simple-server <172.17.0.5>
... ...

结果显示,我连续发送HTTP请求,响应的真实服务只有一个,并正常响应;

调整SimpleHTTPServer为3个:
[root@sc ~]# docker-compose scale web=3

同样,通过Consul的WebUI查看:
09.jpeg

查看到新增的2个SimpleHTTPServer也被Consul自动发现,显示正常服务个数是3个;

同样,访问 http://192.168.1.107 ,显示实际访问的目标地址:
2016-10-07 09:37:51: <1> requests from to simple-server <172.17.0.5>
2016-10-07 09:37:51: <1> requests from to simple-server <172.17.0.6>
2016-10-07 09:37:51: <1> requests from to simple-server <172.17.0.7>
2016-10-07 09:37:52: <2> requests from to simple-server <172.17.0.5>
2016-10-07 09:37:52: <2> requests from to simple-server <172.17.0.6>
2016-10-07 09:37:52: <2> requests from to simple-server <172.17.0.7>
2016-10-07 09:37:53: <3> requests from to simple-server <172.17.0.5>
... ...

结果显示,笔者连续发送多次HTTP请求,响应的真实服务目前是3个,而且响应策略是轮询方式(取决于Nginx配置策略),并全部正常响应。

技术扩展

  1. 使用Kubernetes进行Docker的统一管理,再结合Docker+Consul+Nginx架构,形成一套覆盖了高可用、自动发现、自动注册、健康检测以及Docker发布与创建的完整架构体系。
  2. 利用Consul对Docker实例端部署的真实服务进行监控,利用Consul自动发现功能,同时弥补Docker因需求快速创建、发布、终止、停用带来监控上的难点。

总结

借助于Consul这么好用的工具,使用Docker更加强大的工具来组装服务是非常有趣和有用的,现在我们就创建一种横向可扩展的框架,并且一切都能高效运行。

本文对于Docker和Consul Template以及Nginx如何结合使用做了较为详细的介绍。正如你所看到的那样,构建一套高可用及自动发现的Docker服务架构就如此方便、快捷。一旦你配好了Docker跟Consul,其余的组件自然也就变得更加容易了。在实际的场景里我们也会通过Consul让Nginx自己注册自己,这样一来其他的服务便可以轻松地发现到Nginx实例。

本文作者:李友佳(点融黑帮),就职于点融成都DevOps团队,致力于点融日志系统和监控系统的建设工作,具备中小规模集群的运维、开发、架构规划与设计工作;曾打造过一款智能路由产品,发明专利2项。

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

原文发布时间为:2017-03-23

本文作者:尼古拉斯

本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

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

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
3天前
|
存储 安全 开发者
【Docker 专栏】Docker 与云存储服务的集成
【5月更文挑战第9天】在数字化时代,Docker和云存储服务的结合为企业和开发者提供了强大工具。Docker的高效性、可移植性和隔离性,加上云存储的扩展性、高可靠性和高可用性,通过集成可以实现数据持久化、便捷部署和资源优化。常见的集成包括AWS S3、Azure Blob Storage和Google Cloud Storage。集成时需注意安全、性能和兼容性问题,未来集成将更加紧密和智能化,助力企业创造更大价值。
【Docker 专栏】Docker 与云存储服务的集成
|
3天前
|
机器学习/深度学习 监控 Kubernetes
【Docker 专栏】Docker 容器内服务的自动扩展与缩容
【5月更文挑战第9天】本文探讨了Docker容器服务的自动扩展与缩容原理及实践,强调其在动态业务环境中的重要性。通过选择监控指标(如CPU使用率)、设定触发条件和制定扩展策略,实现资源的动态调整。方法包括云平台集成和使用Kubernetes等框架。实践中,电商平台和实时数据处理系统受益于此技术。注意点涉及监控数据准确性、扩展速度和资源分配。未来,智能算法将提升扩展缩容的效率和准确性,成为关键技术支持。
【Docker 专栏】Docker 容器内服务的自动扩展与缩容
|
3天前
|
运维 安全 Linux
深入理解Docker自定义网络:构建高效的容器网络环境
深入理解Docker自定义网络:构建高效的容器网络环境
|
3天前
|
存储 弹性计算 运维
Docker数据集与自定义镜像:构建高效容器的关键要素
Docker数据集与自定义镜像:构建高效容器的关键要素
|
4天前
|
算法 计算机视觉 Docker
Docker容器中的OpenCV:轻松构建可移植的计算机视觉环境
Docker容器中的OpenCV:轻松构建可移植的计算机视觉环境
Docker容器中的OpenCV:轻松构建可移植的计算机视觉环境
|
4天前
|
开发框架 安全 网络安全
【Docker 专栏】Docker 多平台应用构建与部署
【5月更文挑战第8天】Docker作为一种关键的容器化技术,简化了多平台应用的构建与部署。它提供一致的运行环境,确保应用在不同平台无缝运行;通过分层构建机制加速镜像创建,提升开发效率。Docker的可移植性、高效部署及资源利用率是其主要优势。流程包括开发环境准备、构建镜像、测试验证及部署。然而,面临操作系统差异、网络安全和资源限制等挑战,需注意安全、版本管理和性能优化。Docker在多平台场景的应用将持续发挥价值。
【Docker 专栏】Docker 多平台应用构建与部署
|
4天前
|
数据库 Docker 容器
【Docker 专栏】使用 Dockerfile 自动化构建 Docker 镜像
【5月更文挑战第8天】Dockerfile是构建Docker镜像的关键,它包含一系列指令,用于描述应用运行环境及所需软件包。通过自动化构建,能提高效率、保证可重复性并提升灵活性。确定基础镜像、安装依赖、设置环境后,执行Dockerfile生成镜像,用于应用程序部署。虽然需要熟悉Docker技术和应用细节,但其带来的益处使其成为现代软件开发和部署的重要工具。
【Docker 专栏】使用 Dockerfile 自动化构建 Docker 镜像
|
4天前
|
存储 关系型数据库 Linux
CentOS如何使用Docker部署Plik服务并实现公网访问本地设备上传下载文件
CentOS如何使用Docker部署Plik服务并实现公网访问本地设备上传下载文件
27 4
|
5天前
|
Kubernetes Cloud Native 持续交付
【Docker专栏】Kubernetes与Docker:协同构建云原生应用
【5月更文挑战第7天】本文探讨了Docker和Kubernetes如何协同构建和管理云原生应用。Docker提供容器化技术,Kubernetes则负责容器的部署和管理。两者结合实现快速部署、自动扩展和高可用性。通过编写Dockerfile创建镜像,然后在Kubernetes中定义部署和服务进行应用暴露。实战部分展示了如何部署简单Web应用,包括编写Dockerfile、构建镜像、创建Kubernetes部署配置以及暴露服务。Kubernetes还具备自动扩展、滚动更新和健康检查等高级特性,为云原生应用管理提供全面支持。
【Docker专栏】Kubernetes与Docker:协同构建云原生应用
|
3天前
|
存储 安全 数据安全/隐私保护
【Docker 专栏】Docker 容器化应用的备份与恢复策略
【5月更文挑战第9天】本文探讨了Docker容器化应用的备份与恢复策略,强调了备份在数据保护、业务连续性和合规要求中的关键作用。内容涵盖备份的重要性、内容及方法,推荐了Docker自带工具和第三方工具如Portainer、Velero。制定了备份策略,包括频率、存储位置和保留期限,并详细阐述了恢复流程及注意事项。文章还提及案例分析和未来发展趋势,强调了随着技术发展,备份与恢复策略将持续演进,以应对数字化时代的挑战。
【Docker 专栏】Docker 容器化应用的备份与恢复策略