问题
在缺省网络模型中,容器每次重启后,IP会发生变动,在一个大的分布式系统保证IP地址不变是比较复杂的事情
IP频繁发生变动,动态应用部署无法预知容器的IP地址,client端如何发现server端的访问端点?
解决方案
- DNS解析到多个IP
- 优点:Docker 版本大于1.10即原生支持容器集群内部DNS的服务发现。
- 缺点:由于DNS TTL生效时间的存在,解析的结果不能做到实时,即使TTL设置为0,某些应用或者方法库会缓存DNS解析的结果,导致会解析到已经失效的地址上
- 内核空间 LVS/IPVS
- 优点:IPVS的方案是docker在未来会正式发布的1.12版本中采用的方案,主要是做到了4层的负载均衡,请求的转发实现在内核中,不需要二次拷贝请求和响应的内容,不需要解析和处理7层HTTP协议,效率高
- 缺点:缺少7层负载均衡的支持,一个服务的负载均衡会占用主机的一个端口,服务与服务之间暴露的端口如果相同会产生冲突
- 用户空间 Nginx
- 优点:同时支持4层和7层负载均衡的代理,多进程模型方便利用多核性能,具有cache功能,亦可作为静态文件web服务器,7层可以根据区分HOST字段来复用同一个80端口,解决端口冲突的问题。7层负载会解析HTTP协议,支持多层路由,包括根据域名不同进行路由,根据路径不同进行路由,内部重定向等多种HTTP协议层的功能。
- 缺点:负载均衡调度算法较少,对后端进行健康检查的策略较少
- 用户空间 HAProxy
- 优点:同时支持用户空间4层和7层负载均衡的代理,是一个纯粹的软负载均衡器,支持Round-Robin,static-rr,least-conn,source-IP等多种调度算法,对后端进行健康检查的策略完备,包括TCP端口检查,HTTP请求检查,可执行程序检查等带外检查。7层可以根据区分HOST字段来复用同一个80端口,解决端口冲突的问题。7层负载会解析HTTP协议,支持多层路由,包括根据域名不同进行路由,根据路径不同进行路由,内部重定向等多种HTTP协议层的功能。
- 缺点:不能作为静态文件服务器,不支持cache缓存功能aliyun容器服务的负载均衡解决方案。
案例:利用nginx和docker实现一个简易的负载均衡
测试步骤:
1.在服务器中搭建一个nginx服务器并启动,具体过程可参考 http://www.cnblogs.com/pangziyibudong/p/6183692.html,这里不在建立
2.在docker中从源中拉一下nginx的官方镜像,docker pull nginx,留着备用
3.在本地目录新建两个文件夹,我这里的新建在/mydata/test1,/mydata/test2/
4.分别在两个test文件夹中新建index.html来标志,在第一个html中输出this is nginx1,在第二个html中输出this is nginx2,
5.通过docker运行两个nginx服务器的容器,并分别将静态目录映射到我们刚刚创建的目录中
[root@catchtouch test2]# docker run --name nginx-test -d -p 8080:80 -v /mydata/test1:/usr/share/nginx/html nginx #第一个,将8080端口映射到容器中的80端口
[root@catchtouch test2]# docker run --name nginx-test1 -d -p 8081:80 -v /mydata/test2:/usr/share/nginx/html nginx #第二个,将容器中的8081端口映射到容器中的80端口
6.修改宿主机中的nginx的配置文件
在http{}中添加如下代码
upstream myweb { #myproject为自定义名字
#ip_hash; #开启则代表用ip地址的形式来分配,可解决sesson问题
server 127.0.0.1:8080 weight=1; #weight越大,权重越高,被分配的几率越大
server 127.0.0.1:8081 weight=1; #我全部在本机,因此用了本地的ip,只要相应换成对应的ip或者域名即可
}
7.进入conf.d目录,修改default.conf(conf.d中没有此文件可以新建,文件名随意,后缀必须是.conf)
location / {
#如果服务器要获取客户端真实IP,可以用下三句设置主机头和客户端真实地址
#proxy_set_header Host $host;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
root /usr/share/nginx/html;
index index.html index.htm;
proxy_pass http://myweb; #myweb为之前在nginx.conf中upstream后定义的名字
}
8.保存后退出,重启服务器:systemctl restart nginx
9.通过浏览器输入当前域名,并刷新页面,有时输出nginx1,有时输出nginx2,配置成功
至此,一个简答的负载均衡模型配置完成