<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Solo Estoy &#187; DSR</title>
	<atom:link href="http://www.opslife.com/tag/dsr/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.opslife.com</link>
	<description>人生不过是一场旷日持久却又无法rollback的operation而已</description>
	<lastBuildDate>Mon, 16 Jan 2012 01:34:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>有关DSR的网络拓扑结构和实现方法</title>
		<link>http://www.opslife.com/dsr-implemention/</link>
		<comments>http://www.opslife.com/dsr-implemention/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 13:41:55 +0000</pubDate>
		<dc:creator>dawnh</dc:creator>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[DSR]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[network]]></category>

		<guid isPermaLink="false">http://opslife.com/dsr-implemention/</guid>
		<description><![CDATA[前两天在delphij老大的blog中看到了一篇《使用DSR模式实现单IP服务冗余》，觉得很有意思，因为这个实现方式与我以往所见到的有些不同，通过关闭ARP响应来解决虚拟IP在负载均衡设备和服务器上可能冲突的问题。随即提问了一下我所熟悉方式的实现是否可行，勤恳的delphij竟然又写了一篇来解释这个问题。不过这篇的思路似乎与我原来的想法有点出入，所以仔细又思考了一下，最终决定还是要完整的阐述一下我的思路。 我虽然见过一些DSR的实现方式，然而只不过是阅读架构文档而已，想当然来的东西跟最后实际实施出来的东西肯定有差距，所以把自己认为的设计思路记录下来，看看最终是否可行。 首先是拓扑图： 介绍一下简单的信息： Public VLAN直连Internet，LB和Router分别有一个网卡接口连在这里，用于承载Internet的虚拟IP自然也就是绑在LB连在Public VLAN的NIC上了，方便起见，随便起个IP: 202.96.100.100(202.96段是中国电信骨干IP段，很多坏事都是这里发生的:D) Internal VLAN是放服务器集群的网段，当然就用私有地址，就用典型的192.168.1.0/24吧，这里的Server使用IP 192.168.1.101 首先从数据流角度来看（红色箭头上的标号）： 客户发起到请求： 61.152.X.X:1025 –&#62; 202.96.100.100:80 负载均衡设备通过匹配包，发现目的IP为虚拟IP，根据Load balance算法挑选一台Server，将数据报直接路由到这台Server，不做任何修改（减TTL不算）61.152.X.X:1025 –&#62; 202.96.100.100:80 Server看到数据报的目的IP是虚拟IP，并发现虚拟IP绑定在自己的lo上，认为目的地是自己，OS派发到应用层Web Server处理Request并生成结果，结果数据包变为 202.96.100.100:80 –&#62; 61.152.X.X:1025 数据报发往路由器，路由器看到目的地为客户IP，路由到Internet去。 这个过程与传统NAT方式的Load Balance的区别在于，LB不修改目的地址，直接将数据报通过路由的方式转发给服务器集群。然而这里的难点就在于：如果不修改目的IP，那必须让Server能够对发往虚拟IP的请求做出响应，那就必须要把虚拟IP绑定在Server端，因此虚拟IP就同时出现在了两个地方：LB和Server，解决这个冲突就是完成DSR的关键所在。对于此点引用delphij的原话： 实现DSR结构的关键是，通往Internet路由器的那个网络上，只有负载平衡设备在网络上宣示虚拟出来的那个IP的MAC地址，这样，当请求进来的时候，数据会发到负载平衡设备，而不是某一台服务器上。 Delphij采用的方法是，将服务器上网卡的ARP功能关闭，这样服务器虽然绑定了虚拟IP，但不会对外界对于虚拟IP的MAC地址解析请求做出响应，所以完美解决了IP重复的问题。缺点是ARP一关Server自己会找不到Router或者网络内的其他服务器，因此需要手工维护一个静态ARP表。 而我所采用的方式，是不将虚拟IP绑定在实际网卡上，只是绑定在Server的还回(lo)上，这样依旧可以起到缩减ARP响应域的作用。 Delphij认为这样会需要一个额外的Public IP，不过我认为如果Server放在私有地址VLAN的话，应该是不需要额外的IP，在如图的这种拓扑中应该可以完美的工作。只要LB和Server中作出如下配置（红色罗马数字）： I.&#160; Load Balancer要特别设置的地方有： 需要有合适的负载均衡算法以便于把流量分发给不同的Server。 对于TCP这种有状态的服务，需要使用较为宽松的状态机制来维持会话。 这里引用delphij的pf命令为例，如下，round-robin是负载均衡算法，keep-state(slopppy)是宽松状态匹配，这一点对于DSR也是尤为重要，因为DSR的特点就是从Server发回的响应不经过LB，LB看不见回去的响应包，所以Session track必须能容忍这种半吊子连接。而且这里似乎也必须修改Session的timeout时间，否则会有问题，这里无关者略过： FreeBSD pf规则举例：pass in on em0 route-to { em1 内网IP1, em1 内网IP2, em1 内网IP3 } round-robin <a href='http://www.opslife.com/dsr-implemention/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>前两天在delphij老大的blog中看到了一篇《<a href="http://blog.delphij.net/archives/2009/09/dsrip.html">使用DSR模式实现单IP服务冗余</a>》，觉得很有意思，因为这个实现方式与我以往所见到的有些不同，通过关闭ARP响应来解决虚拟IP在负载均衡设备和服务器上可能冲突的问题。随即提问了一下我所熟悉方式的实现是否可行，勤恳的delphij竟然<a href="http://blog.delphij.net/archives/2009/09/dsrip-1.html">又写了一篇</a>来解释这个问题。不过这篇的思路似乎与我原来的想法有点出入，所以仔细又思考了一下，最终决定还是要完整的阐述一下我的思路。</p>
<p>我虽然见过一些DSR的实现方式，然而只不过是阅读架构文档而已，想当然来的东西跟最后实际实施出来的东西肯定有差距，所以把自己认为的设计思路记录下来，看看最终是否可行。</p>
<p>首先是拓扑图：</p>
<p><a title="DSR" href="http://www.flickr.com/photos/40857285@N03/3930778247/"><img border="0" alt="DSR" src="http://farm4.static.flickr.com/3501/3930778247_6b82459619.jpg" /></a></p>
<p>介绍一下简单的信息：</p>
<ul>
<li>Public VLAN直连Internet，LB和Router分别有一个网卡接口连在这里，用于承载Internet的虚拟IP自然也就是绑在LB连在Public VLAN的NIC上了，方便起见，随便起个IP: <strong>202.96.100.100</strong>(202.96段是中国电信骨干IP段，很多坏事都是这里发生的:D)</li>
<li>Internal VLAN是放服务器集群的网段，当然就用私有地址，就用典型的192.168.1.0/24吧，这里的Server使用IP <strong>192.168.1.101</strong></li>
</ul>
<p>首先从数据流角度来看（红色箭头上的标号）：</p>
<ol>
<li>客户发起到请求： 61.152.X.X:1025 –&gt; 202.96.100.100:80</li>
<li>负载均衡设备通过匹配包，发现目的IP为虚拟IP，根据Load balance算法挑选一台Server，将数据报直接路由到这台Server，不做任何修改（减TTL不算）61.152.X.X:1025 –&gt; 202.96.100.100:80</li>
<li>Server看到数据报的目的IP是虚拟IP，并发现<strong>虚拟IP绑定在自己的lo上</strong>，认为目的地是自己，OS派发到应用层Web Server处理Request并生成结果，结果数据包变为 202.96.100.100:80 –&gt; 61.152.X.X:1025 </li>
<li>数据报发往路由器，路由器看到目的地为客户IP，路由到Internet去。</li>
</ol>
<p>这个过程与传统NAT方式的Load Balance的区别在于，LB不修改目的地址，直接将数据报通过路由的方式转发给服务器集群。然而这里的难点就在于：如果不修改目的IP，那必须让Server能够对发往虚拟IP的请求做出响应，那就必须要把虚拟IP绑定在Server端，因此虚拟IP就同时出现在了两个地方：LB和Server，解决这个冲突就是完成DSR的关键所在。对于此点引用delphij的原话：</p>
<blockquote><p><em>实现DSR结构的关键是，通往Internet路由器的那个网络上，只有负载平衡设备在网络上宣示虚拟出来的那个IP的MAC地址，这样，当请求进来的时候，数据会发到负载平衡设备，而不是某一台服务器上。</em></p>
</blockquote>
<p>Delphij采用的方法是，将服务器上网卡的ARP功能关闭，这样服务器虽然绑定了虚拟IP，但不会对外界对于虚拟IP的MAC地址解析请求做出响应，所以完美解决了IP重复的问题。缺点是ARP一关Server自己会找不到Router或者网络内的其他服务器，因此需要手工维护一个静态ARP表。</p>
<p>而我所采用的方式，是不将虚拟IP绑定在实际网卡上，只是绑定在Server的还回(lo)上，这样依旧可以起到缩减ARP响应域的作用。</p>
<p>Delphij认为这样会需要一个额外的Public IP，不过我认为如果Server放在私有地址VLAN的话，应该是不需要额外的IP，在如图的这种拓扑中应该可以完美的工作。只要LB和Server中作出如下配置（红色罗马数字）：</p>
<p><strong>I.&#160; Load Balancer要特别设置的地方有：</strong></p>
<ul>
<li>需要有合适的负载均衡算法以便于把流量分发给不同的Server。</li>
<li>对于TCP这种有状态的服务，需要使用较为宽松的状态机制来维持会话。</li>
</ul>
<p>这里引用delphij的pf命令为例，如下，round-robin是负载均衡算法，keep-state(slopppy)是宽松状态匹配，这一点对于DSR也是尤为重要，因为DSR的特点就是从Server发回的响应不经过LB，LB看不见回去的响应包，所以Session track必须能容忍这种半吊子连接。而且这里似乎也必须修改Session的timeout时间，否则会有问题，这里无关者略过：</p>
<ol>
<blockquote>
<p><em>FreeBSD pf规则举例：pass in on em0 route-to { em1 内网IP1, em1 内网IP2, em1 内网IP3 } <strong>round-robin</strong> proto tcp from any to 公网IP port http <strong>keep state (sloppy)</strong></em></p>
</blockquote>
</ol>
<p><strong>II.&#160; Server端需要的设置：</strong></p>
<ul>
<li>在lo上绑定虚拟IP 202.96.100.100，这样Server才会认为目的地是自己。</li>
<li>Web Server本身要使用虚拟IP作为监听IP，比如Apache配置Virtualhost的话这样用：&lt;VirtualHost 202.96.100.100:80&gt; ，如此以来Web server会对到虚拟IP的请求做出响应，且响应的源地址也是虚拟IP而不是自己网卡上的私有IP。</li>
<li>Server将默认网关设置为Router的IP，这样对于请求的响应就会发往Router而不会返回LB了。</li>
</ul>
<p><strong>III. Router上应该不需要什么特殊设置，知道把发往Internet的包路由出去就行</strong></p>
<p><strong></strong></p>
<p>这样整个DSR就应该能走通了，不过这个玩法我也只是想出来而已，还没有经过实践，当初看到过F5的nPath实现，应该就是这么种玩法，不过估计实际应用时应该会有我这里没有想到得地方，所以有时间的话，最好还是找几个设备搭一下看看吧，先把设想架构放这儿，改天回来验证。说实话，delphij指出这里必须要有一个额外的公网IP才能保证知道出去的包怎么走，我这点还是没有想通。不管怎样，写出来让大家指正吧，至少在写这篇的过程中，我已经将自己以前没考虑到得一些细节补充完整了，对于自己来说，也算是不小的收获。</p>
<ul class="related_post"><li>2010/05/06 -- <a href="http://www.opslife.com/dnssec-approaching/" title="DNSSEC迫在眉睫">DNSSEC迫在眉睫</a> (6)</li><li>2009/09/11 -- <a href="http://www.opslife.com/microsoft-cisco-finally-patch-tcp-dos-flaw/" title="TCP/IP协议栈DoS漏洞">TCP/IP协议栈DoS漏洞</a> (2)</li><li>2009/06/10 -- <a href="http://www.opslife.com/weird-behivour-of-china-internet/" title="网生异象，必有妖孽出世">网生异象，必有妖孽出世</a> (2)</li><li>2008/12/22 -- <a href="http://www.opslife.com/blog-speed-optimize/" title="Blog访问速度优化">Blog访问速度优化</a> (2)</li><li>2007/11/22 -- <a href="http://www.opslife.com/upgrade-to-freebsd-7-beta-3/" title="升级至FreeBSD 7.0-BETA3">升级至FreeBSD 7.0-BETA3</a> (2)</li><li>2007/11/09 -- <a href="http://www.opslife.com/damn-sh-mobile-broadband/" title="弱智的上海移通">弱智的上海移通</a> (1)</li><li>2007/11/01 -- <a href="http://www.opslife.com/identify-diffrent-hashing-algorithm/" title="区分几种知名散列算法的散列值的方法">区分几种知名散列算法的散列值的方法</a> (0)</li><li>2007/10/30 -- <a href="http://www.opslife.com/zfs-under-freebsd-performace/" title="ZFS under FreeBSD performace">ZFS under FreeBSD performace</a> (0)</li><li>2007/09/10 -- <a href="http://www.opslife.com/use-mtree-for-freebsd-filesystem-integrity-auditing/" title="Sysadmin手记:如何利用mtree做FreeBSD操作系统文件完整性审计">Sysadmin手记:如何利用mtree做FreeBSD操作系统文件完整性审计</a> (2)</li><li>2007/09/05 -- <a href="http://www.opslife.com/damn-media-cnbeta/" title="有一点专业精神好不好?!">有一点专业精神好不好?!</a> (3)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.opslife.com/dsr-implemention/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

