常见的集群架构及相关软件,可以参考下面的导图:

互联网企业常用的是负载均衡集群和高可用性集群,负载均衡集群强调“分担”,通过一定的调度算法 ,可以实现用多个节点服务器来分担用户的访问请求和数据流量;高可用性集群强调“高可用”,即一个节点失效了,它的任务可以立刻转移到另一个备份的节点上(即一般通过设置主备来实现)。显然因为负载均衡集群使用多个节点来分担服务,即使其中一个节点失效了,其它节点也可以继续工作,因此它也具有高可用性。
下面介绍的是Nginx负载均衡的配置,同时也给出了实验环境。
1.实验环境说明
本次实验的测试环境使用的宿主机操作系统为Windows 7,在Vmware虚拟机安装CentOS 6.5(3台),说明如下:
主机类型操作系统IP地址作用
宿主机Windows 710.0.0.1/24
(VMnet8的IP地址)远程3台虚拟机,进行配置,同时也作为后面测试使用的客户端
虚拟机1: lb01CentOS 6.510.0.0.7/24负载均衡服务器lb01,将请求分担到Web节点服务器中
虚拟机2: web01CentOS 6.510.0.0.9/24Web节点服务器web01
虚拟机3: web02CentOS 6.510.0.0.10/24Web节点服务器web02
而当使用NAT的方式进行上网时虚拟机、宿主机之间的网络连接关系可如下所示:

关于为什么网络拓扑结构是这样的,见参考
------------------------------------------参考资料分割线------------------------------------------
VMware虚拟机在我们学习过程中必不可少,不管是安装Linux操作系统来进行学习、搭建各种网络服务,拟或者是用来做集群测试、云计算平台OpenStack等的搭建,可以说,VMware虚拟机为我们带来了极大的便利,最直观的好处就是,我们可以节省很多用来购买各种设备的资金,同时也可以达到了学习各种技术的目的。
然而只要涉及到通过宿主机与VMware虚拟机中的操作系统进行通信,或者是VMware虚拟机中安装的各个操作系统之间需要通信,都离不开计算机网络的内容,事实,让虚拟机中的各个操作系统进行网络通信,也或者是让我们的宿主机与虚拟机进行通信,都是平常我们使用VMware虚拟机进行各种服务测试所离不开的话题。
因此,很有必要理解清楚VMware虚拟机所提供给我们的各种上网方式其中的较为深入的计算机网络通信原理,这样一来,对于我们需要搭建的各种环境,网络上的问题都可以迎刃而解,而不再需要到处查找各种资料,并且这对于以后要搭建的涉及到多台设备通信的实验环境都会有非常大的帮助。
博主较为深入地学习过华为与思科的相关级别认证的网络知识,并在去年通过了华为ICT最高级别认证HCIE-RS,因此本博文的撰写是站在一个网络工程师的角度来理解VMware虚拟机中各种上网模式的通信原理,虽还是难以真正透彻理解其中的一些细节,但是相信还是可以为各位朋友带来很大的帮助。
本博文的撰写方式还是以理论为主线,结合实际操作,在实践中深入理解VMware虚拟机的各种上网方式。
VMware虚拟机的上网方式有三种:NAT、桥接、仅主机模式,本篇介绍NAT模式。
1.实验环境
实验环境如下:
宿主机操作系统:Windows 7
VMware Workstation版本:12.5.2 build-4638234
虚拟机操作系统:Windows 7
虚拟机操作系统上网方式:NAT模式
说明:为了后面的测试正常,请务必将宿主机和虚拟机的操作系统的防火墙功能关闭。
对于上网模式的设置,可以参考下面的图示:
Windows 7的上网方式设置:

2.NAT模式的理论知识
当把我们的虚拟机的上网方式设置为NAT模式时,虚拟机、宿主机、各网卡之间的连接关系可用下图来表示:

其实在看了上面的图解分析之后,整体的网络拓扑是非常清晰的,在接下来的步骤,就通过我们的实验环境来进行验证。
3.在实践中深入理解NAT模式的网络原理
在实验环境中我们可以看到,我们是通过NAT方式来进行上网的,当设置好了NAT方式后,在虚拟机操作系统Windows 7中,查看IP地址信息:

而这时候,你会发现,宿主机跟虚拟机的通信是没有问题的:
在宿主机上ping虚拟机:

那么为什么可以正常通信呢?以及虚拟机中的IP地址网段为什么是10.0.0.0/24的呢?
当使用NAT模式上网时,VMware会自动为我们的虚拟机操作系统进行IP地址的分配,此时在虚拟机内部有一个DHCP服务器,而其所分配的地址网段是可以在VMware中进行设置的。
在VMware Workstation中选择“编辑”—“虚拟网络编辑器”,即可以进行设置:

从上面可以看到,这里我们设置的网段就是10.0.0.0/24了。
另外我们的宿主机是通过VMnet8这块虚拟网卡来与虚拟机操作系统进行通信的,你可以在宿主机的网络设置中看到这块虚拟网卡:

因为这块虚拟网卡是用来与虚拟机操作系统进行通信的,所以它所被分配的地址也是10.0.0.0/24的,可以查看一下其地址:

所以实际上,当我们的宿主机与虚拟机操作系统进行通信时,是使用10.0.0.1这个源地址向虚拟机的操作系统发送数据包的。我们可以在虚拟机操作系统上去ping这个地址,会发现通信是没有问题的:

那么对于虚拟机操作系统的网关10.0.0.2这个地址是在哪里的呢?
其实就是对应我们上面网络图解中的NAT服务器的虚拟网卡地址,只是这个地址我们只能通过在虚拟机操作系统中看到。
所以将上面我们所提及的地址以及网段信息,对应到我们的图解中去,如下:

这样一来,整体的网络信息就非常清晰了,另外上面可以看到,宿主机物理网卡的地址为192.168.1.100/24,这是我的笔记本所在局域网所分配给我的IP地址。
通过上面的图解分析,对于虚拟机操作系统的网络通信就可以有很清楚的认识了:
当虚拟机与宿主机进行通信时:其实就是10.0.0.1/24与10.0.0.132/24这两个地址进行通信;
当虚拟机与外网进行通信时:虚拟机先把数据发送到网关10.0.0.2/24,然后再通过NAT服务器把地址转换为192.168.1.100/24,然后再与外网进行通信;
如果把Vmnet8这块虚拟网卡禁用,还是不影响虚拟机访问互联网,只是宿主机与虚拟机的通信会受到影响,从上面的图示中不难看出。
这样一来,通信的过程就非常清晰了!此外,如果我们有很多台虚拟机,并且上网方式都为NAT模式,那么实际上就相当于这些虚拟机都位于同一个局域网当中,那么虚拟机与宿主机的通信、虚拟机访问外网与上面的过程是一样的,而虚拟机与虚拟机之间的通信则是同一个局域网中的通信,所以也没有什么问题,相应有了上面的图解,这一切都会变得清晰很多。
需要补充的是,对于虚拟机提供的DHCP服务和NAT服务,其实在我们安装VMware Workstation的宿主机上是可以看到这些服务的:

这样一来也可以与我们的理论进行了一定的对应。
4.下一步应该做什么
可以考虑有多台虚拟机的情况,正如上面所说的,可以尝试测试它们的连通性,对上面的图解(尤其重要)进行验证,但是前提是你一定要具备一定的网络知识。
5.在实际当中的应用
首先第一点是,当我们的虚拟机出现网络问题的时候,都是需要先了解清楚网络的拓扑结构再进行网络排错的,所以上面的内容就为我们提供了非常好的理论与实践知识。
另外,如果可以在理解这些网络知识的前提下再去搭建各种服务,做各种测试,可以让我们做到胸有成竹的一种状态,而不再是“雾里看花,水中望月”了,相应在这样的不断尝试中,我们的综合操作能力一定会变得更强。
不过仍然需要说明的是,上面的图解仍然只是做参考,其中的很多细节都是需要了解VMware Workstation的网络虚拟化的细节才可以真正了解清楚的,但不管怎么说,上面的内容对于在网络通信上面,还是可以给我们带来很大的帮助的。
------------------------------------------参考资料分割线------------------------------------------
所以首先,应该是自己先配置好网络环境,让宿主机跟我们的虚拟机可以通信,实际上,如果理解了VMware虚拟机上网方式的原理,同时对CentOS的网络配置也很熟悉,这一步是可以很轻松完成的,这里就不给出过程了,这里所用的IP地址跟上面的图示是一样的。
这里,对于Nginx的负载均衡,希望达到的效果逻辑如下:

当用户访问我们的Web Server时,实际上请求是先到达Nginx负载均衡器,这就是一个反向代理的过程了,然后Nginx负载均衡器再将请求按照一定的调度算法分发给相应的节点服务器。
在整个实验环境中,我们假定web01和web02提供bbs.xpleaf.org的网站内容服务,Nginx在web01和web02前面作为反向代理服务器与负载均衡服务器,当用户访问bbs.xpleaf.org时,Nginx负载均衡器会把请求分发到web01和web02节点服务器上,由节点服务器返回实际的内容数据。
2.配置与测试实战:节点服务器单虚拟机场景
这里使用的Nginx的版本为:1.6.3,关于Nginx的安装与基本配置,这里不再做说明,可以参考博主前面关于Nginx的博文,同样也是给出了详细的实验环境,可以去实践一下。
下面在每台web服务器上,我们只配置了一个虚拟机,即www.1937wwgc.com。
(1)web01配置与测试
web01作为节点服务器,配置它的虚拟机域名为www.1937wwgc.com
[root@web01conf]#catnginx.conf
worker_processes1;
events{
worker_connections1024;
}
http{
includemime.types;
default_typeapplication/octet-stream;
sendfileon;
keepalive_timeout65;
log_formatmain'$remote_addr-$remote_user[$time_local]"$request"'
'$status$body_bytes_sent"$http_referer"'
'"$http_user_agent""$http_x_forwarded_for"';
server{
listen80;
server_namewww.1937wwgc.com;
location/{
roothtml/bbs;
indexindex.htmlindex.htm;
}
access_loglogs/access_bbs.logmain;
}
}
添加相应的站点目录和内容
[root@web01conf]#cd../html/bbs/
[root@web01bbs]#echo"bbs.xpleaf.orgnode110.0.0.9">index.html
[root@web01bbs]#catindex.html
bbs.xpleaf.orgnode110.0.0.9
配置hosts解析
[root@web01bbs]#echo"127.0.0.1www.1937wwgc.com">>/etc/hosts
[root@web01bbs]#tail-1/etc/hosts
127.0.0.1www.1937wwgc.com
检查配置文件与启动
[root@web01bbs]#/application/nginx/sbin/nginx-t
nginx:theconfigurationfile/application/nginx-1.6.3//conf/nginx.confsyntaxisok
nginx:configurationfile/application/nginx-1.6.3//conf/nginx.conftestissuccessful
[root@web01bbs]#/application/nginx/sbin/nginx-sreload
本机上进行测试
[root@web01bbs]#curlwww.1937wwgc.com
www.1937wwgc.comnode110.0.0.9
(2)web02配置与测试
web02作为节点服务器,配置它的虚拟机域名为bbs.xpleaf.org
[root@web02conf]#catnginx.conf
worker_processes1;
events{
worker_connections1024;
}
http{
includemime.types;
default_typeapplication/octet-stream;
sendfileon;
keepalive_timeout65;
log_formatmain'$remote_addr-$remote_user[$time_local]"$request"'
'$status$body_bytes_sent"$http_referer"'
'"$http_user_agent""$http_x_forwarded_for"';
server{
listen80;
server_namewww.1937wwgc.com;
location/{
roothtml/bbs;
indexindex.htmlindex.htm;
}
access_loglogs/access_bbs.logmain;
}
}
添加相应的站点目录和内容
[root@web01conf]#cd../html/bbs/
[root@web01bbs]#echo"www.1937wwgc.comnode210.0.0.10">index.html
[root@web01bbs]#catindex.html
bbs.xpleaf.orgnode210.0.0.10
配置hosts解析
[root@web01bbs]#echo"127.0.0.1www.1937wwgc.com">>/etc/hosts
[root@web01bbs]#tail-1/etc/hosts
127.0.0.1www.1937wwgc.com
检查配置文件与启动
[root@web01bbs]#/application/nginx/sbin/nginx-t
nginx:theconfigurationfile/application/nginx-1.6.3//conf/nginx.confsyntaxisok
nginx:configurationfile/application/nginx-1.6.3//conf/nginx.conftestissuccessful
[root@web01bbs]#/application/nginx/sbin/nginx-sreload
本机上进行测试
[root@web02bbs]#curlwww.1937wwgc.com
www.1937wwgc.comnode210.0.0.10
(3)lb01配置
配置文件内容
[root@lb01conf]#catnginx.conf
worker_processes1;
events{
worker_connections1024;
}
http{
includemime.types;
default_typeapplication/octet-stream;
sendfileon;
keepalive_timeout65;
upstreambbs_server_pools{
server10.0.0.9:80weight=1;
server10.0.0.10:80weight=1;
}
server{
listen80;
server_namewww.1937wwgc.com;
location/{
proxy_passhttp://bbs_server_pools;
}
}
}
配置hosts解析
[root@web01bbs]#echo"127.0.0.1www.1937wwgc.com">>/etc/hosts
[root@web01bbs]#tail-1/etc/hosts
127.0.0.1www.1937wwgc.com
检查配置文件与启动
[root@web01bbs]#/application/nginx/sbin/nginx-t
nginx:theconfigurationfile/application/nginx-1.6.3//conf/nginx.confsyntaxisok
nginx:configurationfile/application/nginx-1.6.3//conf/nginx.conftestissuccessful
[root@web01bbs]#/application/nginx/sbin/nginx-sreload
(4)Nginx负载均衡效果测试
可以通过命令行的方式在lb01上进行测试,如下:
[root@lb01conf]#curlwww.1937wwgc.com
www.1937wwgc.comnode110.0.0.9
[root@lb01conf]#curlwww.1937wwgc.com
www.1937wwgc.comnode210.0.0.10
[root@lb01conf]#curlwww.1937wwgc.com
www.1937wwgc.comnode110.0.0.9
[root@lb01conf]#curlwww.1937wwgc.com
www.1937wwgc.comnode210.0.0.10
[root@lb01conf]#curlwww.1937wwgc.com
www.1937wwgc.comnode110.0.0.9
[root@lb01conf]#curlwww.1937wwgc.com
www.1937wwgc.comnode210.0.0.10
通过上面的测试可以知道,访问请求都被分担到两台节点服务器上,也可以通过在windows 7的浏览器上输入地址来进行测试(需要先把"127.0.0.1 www.1937wwgc.com"添加到windows 7的hosts文件中):

3.进阶1:记录访问用户的实际IP地址
(1)原理
上面我们通过windows 7进行访问时,查看web服务器的日志:
[root@web01bbs]#tail-2/application/nginx/logs/access_bbs.log
10.0.0.7--[04/Mar/2017:11:33:00+0800]"GET/HTTP/1.0"20030"-""Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/56.0.2924.87Safari/537.36""-"
10.0.0.7--[04/Mar/2017:11:33:29+0800]"GET/HTTP/1.0"3040"-""Mozilla/5.0(WindowsNT6.1;
因为在配置web服务器节点时,配置的日志格式是这样的:
log_formatmain'$remote_addr-$remote_user[$time_local]"$request"'
'$status$body_bytes_sent"$http_referer"'
'"$http_user_agent""$http_x_forwarded_for"';
所以前面日志的第一个字段用来记录Nginx均衡服务器的地址,这没有问题,但是最后一个字段是'-',也就是没有记录,该字段是用来记录用户的实际IP的。
(2)配置Nginx携带用户实际IP
为了能够让web服务器记录用户的实际IP,需要在Nginx负载均衡服务器上做如下配置:
[root@lb01conf]#catnginx.conf
worker_processes1;
events{
worker_connections1024;
}
http{
includemime.types;
default_typeapplication/octet-stream;
sendfileon;
keepalive_timeout65;
upstreambbs_server_pools{#定义节点资源池
server10.0.0.9:80weight=1;
server10.0.0.10:80weight=1;
}
server{
listen80;
server_namewww.1937wwgc.com;
location/{
proxy_passhttp://bbs_server_pools;#把请求转发到节点资源池中指定的主机中
proxy_set_headerX-Forwarded-For$remote_addr;
}
}
}
实际上就是多加了最后一行。
(3)测试
这时再用windows 7去访问bbs.xpleaf.org,然后在web服务器上查看日志信息:
[root@web01bbs]#tail-2/application/nginx/logs/access_bbs.log
10.0.0.7--[04/Mar/2017:11:49:10+0800]"GET/HTTP/1.0"20030"-""Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/56.0.2924.87Safari/537.36""10.0.0.1"
10.0.0.7--[04/Mar/2017:11:49:11+0800]"GET/HTTP/1.0"20030"-""Mozilla/5.0(WindowsNT6.1;WOW64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/56.0.2924.87Safari/537.36""10.0.0.1"
可以看到日志的最后一个字段就记录了客户端的真实IP地址。
4.进阶2:节点服务器多虚拟机场景
前面在每台web服务器上,只配置了一个站点www.1937wwgc.com,所以上面的负载均衡是没有问题,但是如果再配置一个站点wap.1937wwgc.com(即在www.1937wwgc.com后面再增加一个server域),当去测试时就会发现,无论是访问wap.1937wwgc.com,还是访问www.1937wwgc.com,返回的内容都是站点www.1937wwgc.com的内容。
究其原因是当用户访问域名时确实是携带了wap.1937wwgc.com主机头请求Nginx反向代理服务器,但是是反向代理服务器向下面节点重新发起请求时,默认并没有在请求头里告诉节点服务器要找哪台虚拟主机,所以web节点服务器接收到请求后发现没有主机头信息,因此,就把节点服务器的第一个 虚拟机发给了反向代理。
解决方法是,当反向代理向后重新发起请求时,要携带主机头信息,以明确告诉节点服务器要找哪个虚拟机。只需要在Nginx负载均衡服务器上增加下面一行配置:
proxy_set_headerHost$host;
此时配置文件内容如下:
[root@lb01conf]#catnginx.conf
worker_processes1;
events{
worker_connections1024;
}
http{
includemime.types;
default_typeapplication/octet-stream;
sendfileon;
keepalive_timeout65;
upstreambbs_server_pools{
server10.0.0.9:80weight=1;
server10.0.0.10:80weight=1;
}
server{
listen80;
server_namewww.1937wwgc.com;
location/{
proxy_passhttp://bbs_server_pools;
proxy_set_headerX-Forwarded-For$remote_addr;
proxy_set_headerHost$host;
}
}
}
由于原理比较简单,这里就不给出完整过程了,可以参考老男孩老师的书籍。
5.进阶3:根据URL中的目录地址实现代理转发
根据HTTP的URL进行转发的应用情况,被称为第7层(应用层)的负载均衡,而LVS的负载均衡一般用于TCP等的转发,因此被称为第4层转发(传输层)的负载均衡。
在上面的案例中,如果需要实现一个需求,希望www.1937wwgc.com可以使用www.1937wwgc.com/upload来提供上传服务,而www.1937wwgc.com则保持默认提供网站的主页内容,这时就可以使用Nginx基于URL来实现代理转发了。
可以把lb01的Nginx配置修改为如下:
[root@lb01conf]#catnginx.conf
worker_processes1;
events{
worker_connections1024;
}
http{
includemime.types;
default_typeapplication/octet-stream;
sendfileon;
keepalive_timeout65;
upstreambbs_server_pools{
server10.0.0.9:80weight=1;
}
upstreambbs_upload_server_pools{
server10.0.0.10:80weight=1;
}
server{
listen80;
server_namewww.1937wwgc.com;
location/{
proxy_passhttp://bbs_server_pools;
}
location/static{
proxy_passhttp://bbs_upload_server_pools;
}
}
}
这样,实际上就相当于bbs.xpleaf.org提供了两种不同的业务,一种是普通的bbs论坛内容业务,另外一种则是上传业务,上面我们定义了两个地址池,在每个地址池中,如果有多台节点服务器,就可以根据upstream的相关调度算法来实现不同业务的负载均衡了,总结来说就是,只使用一个域名对外提供服务,同时该域名对外提供不同的产品业务。
当然,基于这种思想,通过location的正则匹配,可以根据用户不同的浏览器版本来访问不同的服务器群、根据设备的不同类型来访问不同的服务器群(PC端和移动端)、根据文件扩展名来访问不同的服务器群(实现动静分离),从而可以提升用户的体验。相关案例可以参考老男孩老师的书籍。
6.原理解析:http proxy模块和upstream模块
Nginx的反向代理功能和负载均衡功能是通过http proxy模块和upstream模块来实现的:
Nginx http功能模块模块说明
ngx_http_proxy_moduleproxy代理模块,用于把请求后抛给服务器节点或upstream服务器池
ngx_http_upstream_module负载均衡模块,可以实现网站的负载均衡功能及节点的健康检查
(1)http proxy模块
配置方法可以参考上面的案例,实际上还有很多参数可以使用,这里不详细给出。
(2)upstream模块
主要介绍一下upstream模块在实现负载均衡功能时的调度算法,其实关于upstream的调度算法,如果学习过QoS,看起来就会觉得很熟悉了。
静态调度算法:负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器的情况
主要有rr、wrr、ip_hash
(1)rr轮询
如果节点服务器不宕机,请求将会平均分发到各节点服务器上;
(2)wrr权重轮询
按照设置的weight权重,将请示按比例分发到各节点服务器上;
(3)ip_hash
按照客户端IP的hash结果分配;
可以解决动态网页的session共享问题(会话保持),但无法保证1:1的负载均衡;
动态调度算法:负载均衡器会根据后端节点的当前状态来决定是否分发请求
主要有fair、least_conn、url_hash、一致性hash算法
(1)fair
根据后端节点服务器的响应时间来分配请求,响应时间短的优先分配;
Nginx本身不支持该算法,需要下载相关模块upstream_fair;
(2)least_conn
根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发;
(3)url_hash(第三方调度算法)
与ip_hash类似,根据访问URL来分配请求,让每个URL定向到同一个后端服务器;
后端服务器为缓存服务器时效果显著;
(4)一致性hash算法(第三方调度算法)
比较复杂,这里不做介绍。
7.下一步做什么
首先当然是要能够把Nginx负载均衡的环境搭建出来,否则是没有办法继续往下面学习的,然后就是继续加深Nginx负载均衡的理解,同时也在实际场景中多分析和尝试使用。