各个工具介绍

(1)Docker:Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux机器上,也可以实现虚拟化,docker是集群世界中的“进程”。通过docker我们可以非常方便的管理服务以及服务之间的依赖。

(2)etcd:是一个高可用的集中配置管理和协作平台,功能和zookeeper很相似,两者的优劣势比较可以参考网上相关文档。分布式系统相关的配置信息可以集中的存储在etcd中统一管理。

(3)confd:一个轻量级的配置管理工具,后端支持etcd、consul、vault、environment variables、Redis、zookeeper等,当后端的数据发生变化时,confd会根据模板重新生成服务的配置文件,并reload。

(4)haproxy:提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机。

原理

通过docker启动nginx服务,并且把docker实例的相关信息注册到etcd中,confd监控到etcd的数据发生变化,重新生成haproxy的配置文件,并且reload haproxy。

当前端服务的负载升高时,可以发起新的docker实例,confd会把该实例添加到haproxy中。当负载降低时,可以kill 一些docker实例,confd会从haproxy中移除该实例。由于confd需要修改haproxy的配置文件,因此一般confd和haproxy运行在同一台服务器上。

本文的所有服务都运行在一台ubuntu主机上。

 

实施步骤:

(1)安装docker

curl -fsSL https://get.docker.com/gpg | sudo apt-key add -

curl -fsSL https://get.docker.com/ | sh

可以运行一个helloworld实例来测试docker是否安装成功

docker run hello-world #docker首先会下载hello-world镜像到本地,然后运行。

我们运行一个nginx实例,并测试nginx是否工作

docker run -d -P nginx #-P让docker将nginx的80、443端口映射到主机的一个随机端口上,-d以detatch模式运行

以上命令会返回创建的docker实例的id

根据返回的docker id,可以查询该实例的详细信息,包括具体映射的端口。

docker inspect cf04729a1b16232f72cab0bb89396b0acf20f36a9a38a2fa1d36f55c4baffb00|grep \"Ports\" -A 20

可以看到如下类似的输出:

"Ports": {

"443/tcp": [

{

"HostIp": "0.0.0.0",

"HostPort": "32768"

}

],

"80/tcp": [

{

"HostIp": "0.0.0.0",

"HostPort": "32769"

}

]

}

启用docker远程访问,

编辑/etc/default/docker, 设置DOCKER_OPTS="-H unix:///var/run/docker.sock -H tcp://0.0.0.0:5555"

(2)安装etcd

curl -L  https://github.com/coreos/etcd/releases/download/v3.0.0-beta.0/etcd-v3.0.0-beta.0-linux-amd64.tar.gz -o etcd-v3.0.0-beta.0-linux-amd64.tar.gz

tar xzvf etcd-v3.0.0-beta.0-linux-amd64.tar.gz

cd etcd-v3.0.0-beta.0-linux-amd64

运行etcd

./etcd #etcd支持分布式集群的搭建,这里简单的采用单机版运行。关于集群的搭建,可以参考官网相关文档或者网上文章。

etcd提供了一个工具“etcdctl”来同etcd交互,

例如:

./etcdctl set mykey "this is awesome" #设置mykey的内容为“this is awesome”

./etcdctl get mykey  #获取mykey对应的值

更多操作参考 ./etcdctl -h

(3)安装confd

confd基于Go语言开发,因此首先安装go语言。

confd的源码托管在github上,地址为:https://github.com/kelseyhightower/confd

安装参见github上的文档

由于haproxy的配置文件由confd生成,我们配置一下confd。

创建相关目录

mkdir -p /etc/confd/{conf.d,templates}

编辑资源文件 /etc/confd/conf.d/ haproxy.toml,设置内容为:

[template]

src = "haproxy.cfg.tmpl"

dest = "/etc/haproxy/haproxy.cfg"

keys = [

"/app/servers",

]

reload_cmd = "/etc/init.d/haproxy reload"

配置模板文件/etc/confd/templates/haproxy.cfg.tmpl

global

defaults

timeout client          30s

timeout server          30s

timeout connect         30s

frontend MyFrontend

mode http

bind    *:80

default_backend         TransparentBack_http

stats enable

# CHANGE: Your stats credentials

# stats auth admin:admin

stats uri /haproxy_stats

backend TransparentBack_http

mode                    http

{{range gets "/app/servers/*"}} #获取所有以/app/servers/开头的key,

server {{base .Key}} {{.Value}} check inter 5000 fall 1 rise 2 #base获取路径的最后一段

{{end}}

stats enable

stats uri /admin-status

stats auth admin:123456

stats admin if TRUE

运行confd

confd -backend etcd -interval 10 -node http://127.0.0.1:4001

查看/etc/haproxy/haproxy.conf,发现confd已经根据模板和etcd中的数据生成了一份haproxy的配置文件。

(4)安装haproxy

apt-get install haproxy

haproxy默认通过init.d脚本无法启动,编辑/etc/default/haproxy,将ENABLED设置为1

启动haproxy

/etc/init.d/haproxy start

重新加载配置

/etc/init.d/haproxy reload

(5)发起docker实例的脚本

安装docker的Python api

pip install --no-use-wheel docker-py

安装etcd的python lib

pip install --no-use-wheel python-etcd

  1. #!/usr/local/Python/bin/python
  2. # coding:utf8
  3. import docker
  4. import etcd
  5. import sys
  6. Server_ip="192.168.252.138"
  7. Image="nginx"
  8. idict={}
  9. rinfo={}
  10. Etcd_ip="127.0.0.1"
  11. Port=""
  12. Name=""
  13. try:
  14. c = docker.Client(base_url='tcp://'+Server_ip+':5555', version='1.18')
  15. except Exception,e:
  16. print "Connection docker server error:"+str(e)
  17. sys.exit()
  18. try:
  19. rinfo=c.create_container(image=Image,volumes=['/usr/share/nginx/html'],ports=[80])
  20. containerId=rinfo['Id']
  21. except Exception,e:
  22. print "Create docker container error:"+str(e)
  23. sys.exit()
  24. try:
  25. #/usr/share/nginx/html为nginx的文档根目录,这里将其映射到host的/root/htmldoc目录
  26. c.start(container=containerId, binds={'/root/htmldoc':{'bind': '/usr/share/nginx/html'}}, port_bindings={80:None}, publish_all_ports=True)
  27. except Exception,e:
  28. print "Start docker container error:"+str(e)
  29. sys.exit()
  30. try:
  31. idict=c.inspect_container(containerId)
  32. Name=idict["Name"][1:]
  33. skey='80/tcp'
  34. for _key in idict["NetworkSettings"]["Ports"].keys():
  35. if _key==skey:
  36. Port=idict["NetworkSettings"]["Ports"][skey][0]["HostPort"]
  37. except Exception,e:
  38. print "Get docker container inspect error:"+str(e)
  39. sys.exit()
  40. #更新docker实例的相关信息到etcd中
  41. if Name != "" and Port != "":
  42. try:
  43. client = etcd.Client(host=Etcd_ip, port=4001)
  44. client.write('/app/servers/'+Name, Server_ip+":"+str(Port))
  45. print Name+" container run success!"
  46. except Exception,e:
  47. print "set etcd key error:"+str(e)
  48. else:
  49. print "Get container name or port error."

(6)杀死docker实例的脚本

  1. #!/usr/local/Python/bin/python
  2. #coding:utf8
  3. import docker
  4. import etcd
  5. import sys
  6. Etcd_ip="127.0.0.1"
  7. Server_ip="127.0.0.1"
  8. if len(sys.argv) != 2:
  9. print "usage: delete_docker_instance.py containername"
  10. exit(0)
  11. try:
  12. c = docker.Client(base_url='tcp://'+Server_ip+':5555',version='1.18',timeout=10)
  13. c.stop(sys.argv[1])
  14. except Exception,e:
  15. print str(e)
  16. sys.exit()
  17. try:
  18. client = etcd.Client(host=Etcd_ip, port=4001)
  19. client.delete('/app/servers/'+sys.argv[1])
  20. print sys.argv[1]+" container stop success!"
  21. except Exception,e:
  22. print str(e)

参考资料:

spring-boot 和 docker 集成:http://www.open-open.com/lib/view/open1450684294167.html

http://www.jianshu.com/p/bc85a54f98ff

http://blog.csdn.net/weiyuanke/article/details/51425304

【Docker】基于docker+etcd+confd + haproxy构建高可用、自发现的web服务的更多相关文章

  1. 基于docker+etcd+confd + haproxy构建高可用、自发现的web服务

    基于docker+etcd+confd + haproxy构建高可用.自发现的web服务 2016-05-16 15:12 595人阅读 评论(0) 收藏 举报 版权声明:本文为博主原创文章,未经博主 ...

  2. Docker 搭建pxc集群 + haproxy + keepalived 高可用(二)

    上一节我们有了两个分片的pxc集群,这一节我们接着安装haproxy和keepalived的实现集群的高可用 一.先下载haproxy的镜像 [root@localhost ~]# docker pu ...

  3. Docker 搭建pxc集群 + haproxy + keepalived 高可用(一)

    一.首先需要安装好docker,安装方法可以参考之前一篇博文Centos7安装docker [root@localhost ~]# systemctl start docker [root@local ...

  4. 【线上测试之后的应用】基于MySQL+MHA+Haproxy构建高可用负载均衡数据库集群(详解)

    这里我们先介绍一下MHA是什么,其次就是它的应用与测试,同时为了大家呈现了数据备份案例,最后总结了使用情况以及注意事项和解决办法 一.MHA 概述 MHA(Master High Availabili ...

  5. keepalived+haproxy构建高可用负载均衡

    一.环境介绍 我用的是centos6.7,内核版本为2.6.32-573.el6.x86_64,keepalived版本为keepalived-1.2.22,haproxy版本为haproxy-1.6 ...

  6. .net core下简单构建高可用服务集群

    一说到集群服务相信对普通开发者来说肯定想到很复杂的事情,如zeekeeper ,反向代理服务网关等一系列的搭建和配置等等:总得来说需要有一定经验和规划的团队才能应用起来.在这文章里你能看到在.net ...

  7. 用HAProxy和KeepAlived构建高可用的反向代理

      用HAProxy和KeepAlived构建高可用的反向代理 用HAProxy和KeepAlived构建高可用的反向代理 前言对于访问量较大的网站来说,随着流量的增加单台服务器已经无法处理所有的请求 ...

  8. 用HAProxy和KeepAlived构建高可用的反向代理系统

    对于访问量较大的网站来说,随着流量的增加单台服务器已经无法处理所有的请求,这时候需要多台服务器对大量的请求进行分流处理,即负载均衡.而如果实现负载均衡,必须在网站的入口部署服务器(不只是一台)对这些请 ...

  9. (七) Docker 部署 MySql8.0 一主一从 高可用集群

    参考并感谢 官方文档 https://hub.docker.com/_/mysql y0ngb1n https://www.jianshu.com/p/0439206e1f28 vito0319 ht ...

随机推荐

  1. [ 原创 ]学习笔记-Android 中关于Cursor类的介绍

    此博文转载自:http://www.cnblogs.com/TerryBlog/archive/2010/07/05/1771459.html 主讲Cursor的用法 使用过 SQLite 数据库的童 ...

  2. HNOI2018 两天扫雷训练营

    Day -1 不知道干什么 学了下插头DP,随意看了几道题 Day 0 还是不知道干什么 打了一天的模板,1700多行.... 随意学了下回文树 Day 1 上午:各种丢人(好像没人注意) 电脑一开就 ...

  3. [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)

    显然有决策单调性,但由于逆序对不容易计算,考虑分治DP. solve(k,x,y,l,r)表示当前需要选k段,待更新的位置为[l,r],这些位置的可能决策点区间为[x,y].暴力计算出(l+r)/2的 ...

  4. [CodeChef-QTREE6]Query on a tree VI

    题目大意: 给你一棵黑白树,每个点默认是白色,要求支持以下两种操作: 1.改变一个点的颜色: 2.除去连接不同颜色的点的边,求某个点连通块的大小. 思路: 对原树维护两个树链剖分, 一棵维护当点x为白 ...

  5. Java中的Runnable、Callable、Future、FutureTask的区别

    本文转载自:http://blog.csdn.net/bboyfeiyu/article/details/24851847 Runnable 其中Runnable应该是我们最熟悉的接口,它只有一个ru ...

  6. java的注解

    本文转载自:http://www.cnblogs.com/mandroid/archive/2011/07/18/2109829.html 一.概念 Annontation是Java5开始引入的新特征 ...

  7. 【洛谷】4917:天守阁的地板【欧拉函数的应用】【lcm与gcd】【同除根号优化】

    P4917 天守阁的地板 题目背景 在下克上异变中,博丽灵梦为了找到异变的源头,一路打到了天守阁 异变主谋鬼人正邪为了迎击,将天守阁反复颠倒过来,而年久失修的天守阁也因此掉下了很多块地板 异变结束后, ...

  8. hdoj 5182 PM2.5 排序

    PM2.5 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Descr ...

  9. git push时提示"fatal: The current branch master has no..."

    git push到远程仓库时提示:fatal: The current branch master2 has no upstream branch. To push the current branc ...

  10. 轨至轨运算放大器 rail to rail

    http://www.360doc.com/content/10/1102/16/2285160_66006645.shtml Rail to rail: 轨至轨,指器件的输入输出电压范围可以达到电源 ...