我们可以在service definition文件中为每个Role定义 Input Endpoint 和 Internal Endpoint, 一开始我的理解就是 Input 就是在Azure 的Load Balancer上建立一个外部端口到内部端口的映射,本质上Azure的LB是一个LB+NAT。 而Internal Endpoint就不会在LB上设计NAT,所以外部应用是没有办法访问到Internel Endpoint的。
其实,出了我上面说到的区别以外,这两者的区别还在Azure 的防火墙的设置上面。下面给个例子:
如果我们定义一个 Input Endpoint, 协议是 TCP,注意定义Input endpoint的时候是可以选择是 TCP 还是HTTP的,我这里就用TCP就可以了,从字面意思上理解,也就是说LB根本不关心你从这个端口上走的是HTTP,还是SSH,还是TCP, LB不做协议分析。当我们定义一个80到8080的端口映射,就相当于告诉Azure:
任何在这个Role(Role A)中的Role Instance, 你可以接受来自Role A 中任何其他机器和LB发来的到你的8080端口的链接 (其实,如果我们Remote Desktop到某一个Role Instance, 你会发现,其实是是打开了任何IP, 0.0.0.0 到该Role Instance 8080端口的链接)。--> 注意,其实上面我写的并不准确,稍后我会解释。
如果我们定义一个Internal Endpoint: 7070, 如果我们登陆到某个Instance,查看操作系统的防火墙设置的时候,7070和8080的唯一区别是: 8080接受任何IP:0.0.0.0送来的请求;而7070这个端口的防火墙上会罗列出所有Role A 中的机器的IP,也就是说LB发过来的请求是不被接受的。
看下面的截图:
这里我来解释一下,大家注意一下上面这张图的第一和第二列: 如果你定义了7070, 假设你有一个程序在listen 7070, 要让这个程序能够拿到情求,这个listen 程序必须是属于特定的Group的,这个Group的名字在这里以CIS 开头,其实你的这个程序必须是Azure 的Worker role拉起来的程序,不能是我们Remote Desktop到这台机器后手动起一个Server 去 Listen 7070. 因为我们手工启动的程序不属于Azure 防火墙放行的Group.
为了证实这一点,我做了以前实验:
实验a)
如果我不定义Internel Endpoint 7070, 我登陆到一个Role Instance A, 手动打开防火墙,该防火墙放行所有连接到7070的请求,而且也不检查侦听程序所在的Group, 按道理,做了这个改动以后,从Role Instance B 应该可以telnet Role Instance A的 7070端口了,可以结果是 不能通讯。
这说明了,出了我们登陆到的系统(这里是Guest OS)里面的防火墙之外,Azure 应该还在某处配置了其他防火墙,或许是在Host OS层吧。
实验b)
如果我定义Internal Endpoint 7070, 远程登陆到Role Instance A, 手工起一个server listen在7070端口,然后在Role Instance B上telnet RoleInstane A 的7070, 结果是 失败, 原因是: Role Instance A上listen 7070的程序不属于Azure 防火墙放行的Group,所以失败。
实验c)
先定义internal endpoint 7070, 再登陆到role instance A上 打开防火墙,更改防火墙是他不检查侦听程序所在的Group,然后手工启动一个server listen 7070, 然后在Role Instance B上telnet RoleInstane A 的7070, 成功了。