首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Azure Service Fabric IPv6网络问题

Azure Service Fabric IPv6网络问题
EN

Stack Overflow用户
提问于 2018-05-28 22:48:19
回答 1查看 480关注 0票数 1

我们在将Service集群部署到Azure并让它同时处理IPv4和IPv6流量时遇到了问题。

我们正在开发一个应用程序,它在iOS和安卓上都有移动客户端,它们可以与我们的Service集群通信。通信包括HTTP通信和TCP套接字通信。我们需要支持IPv6,以便让苹果在他们的应用商店中接受这个应用程序。

我们使用ARM模板部署到Azure,因为门户似乎不支持为虚拟机规模集配置带有IPv6配置的负载均衡器(ref:url)。链接的页面还说明了对IPv6支持的其他限制,例如不能将私有IPv6地址部署到VM比例集。然而,根据页面,可以在预览中将私有IPv6分配给VM规模集(尽管这是最后一次更新07/14/2017)。

对于这个问题,我试图保持尽可能的一般性,并将ARM模板建立在本教程中的一个模板上。模板名为"template_original.json“,可以从这里下载。这是服务结构集群的基本模板,没有简单的安全性。

我将链接整个修改后的ARM模板在这篇文章的底部,但将突出主要修改部分首先。

与负载均衡器相关联的公共IPv4和IPv6地址。它们与各自的后端池相关联:

代码语言:javascript
运行
复制
"frontendIPConfigurations": [
    {
        "name": "LoadBalancerIPv4Config",
        "properties": {
            "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('lbIPv4Name'),'-','0'))]"
            }
        }
    },
    {
        "name": "LoadBalancerIPv6Config",
        "properties": {
            "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(parameters('lbIPv6Name'),'-','0'))]"
            }
        }
    }
],
"backendAddressPools": [
    {
        "name": "LoadBalancerIPv4BEAddressPool",
        "properties": {}
    },
    {
        "name": "LoadBalancerIPv6BEAddressPool",
        "properties": {}
    }
],

在各自公共IP地址(包括IPv4和IPv6 )上的前端端口的负载平衡规则。这总共相当于四个规则,每个前端端口两个。我在这里为HTTP添加了端口80,为套接字连接添加了端口5607。注意到,我已经将IPv6端口80的后端端口更新为8081,IPv6端口8507更新为8517。

代码语言:javascript
运行
复制
{
    "name": "AppPortLBRule1Ipv4",
    "properties": {
        "backendAddressPool": {
            "id": "[variables('lbIPv4PoolID0')]"
        },
        "backendPort": "[parameters('loadBalancedAppPort1')]",
        "enableFloatingIP": "false",
        "frontendIPConfiguration": {
            "id": "[variables('lbIPv4Config0')]"
        },
        "frontendPort": "[parameters('loadBalancedAppPort1')]",
        "idleTimeoutInMinutes": "5",
        "probe": {
            "id": "[concat(variables('lbID0'),'/probes/AppPortProbe1')]"
        },
        "protocol": "tcp"
    }
},
{
    "name": "AppPortLBRule1Ipv6",
    "properties": {
        "backendAddressPool": {
            "id": "[variables('lbIPv6PoolID0')]"
        },
        /*"backendPort": "[parameters('loadBalancedAppPort1')]",*/
        "backendPort": 8081,
        "enableFloatingIP": "false",
        "frontendIPConfiguration": {
            "id": "[variables('lbIPv6Config0')]"
        },
        "frontendPort": "[parameters('loadBalancedAppPort1')]",
        /*"idleTimeoutInMinutes": "5",*/
        "probe": {
            "id": "[concat(variables('lbID0'),'/probes/AppPortProbe1')]"
        },
        "protocol": "tcp"
    }
},
{
    "name": "AppPortLBRule2Ipv4",
    "properties": {
        "backendAddressPool": {
            "id": "[variables('lbIPv4PoolID0')]"
        },
        "backendPort": "[parameters('loadBalancedAppPort2')]",
        "enableFloatingIP": "false",
        "frontendIPConfiguration": {
            "id": "[variables('lbIPv4Config0')]"
        },
        "frontendPort": "[parameters('loadBalancedAppPort2')]",
        "idleTimeoutInMinutes": "5",
        "probe": {
            "id": "[concat(variables('lbID0'),'/probes/AppPortProbe2')]"
        },
        "protocol": "tcp"
    }
},
{
    "name": "AppPortLBRule2Ipv6",
    "properties": {
        "backendAddressPool": {
            "id": "[variables('lbIPv6PoolID0')]"
        },
        "backendPort": 8517,
        "enableFloatingIP": "false",
        "frontendIPConfiguration": {
            "id": "[variables('lbIPv6Config0')]"
        },
        "frontendPort": "[parameters('loadBalancedAppPort2')]",
        /*"idleTimeoutInMinutes": "5",*/
        "probe": {
            "id": "[concat(variables('lbID0'),'/probes/AppPortProbe2')]"
        },
        "protocol": "tcp"
    }
}

还添加了每个负载平衡规则一个探针,但为了清楚起见,这里省略了。

根据上述预览解决方案的建议,VM刻度集的apiVerison设置为"2017-03-30“。网络接口配置也根据建议进行配置。

代码语言:javascript
运行
复制
"networkInterfaceConfigurations": [
    {
        "name": "[concat(parameters('nicName'), '-0')]",
        "properties": {
            "ipConfigurations": [
                {
                    "name": "[concat(parameters('nicName'),'-IPv4Config-',0)]",
                    "properties": {
                        "privateIPAddressVersion": "IPv4",
                        "loadBalancerBackendAddressPools": [
                            {
                                "id": "[variables('lbIPv4PoolID0')]"
                            }
                        ],
                        "loadBalancerInboundNatPools": [
                            {
                                "id": "[variables('lbNatPoolID0')]"
                            }
                        ],
                        "subnet": {
                            "id": "[variables('subnet0Ref')]"
                        }
                    }
                },
                {
                    "name": "[concat(parameters('nicName'),'-IPv6Config-',0)]",
                    "properties": {
                        "privateIPAddressVersion": "IPv6",
                        "loadBalancerBackendAddressPools": [
                            {
                                "id": "[variables('lbIPv6PoolID0')]"
                            }
                        ]
                    }
                }
            ],
        "primary": true
        }
    }
]

有了这个模板,我就能够成功地将它部署到Azure。使用IPv4与集群的通信工作正常,但是我根本无法通过任何IPv6流量。这对于端口80 (HTTP)和5607 (套接字)都是一样的。

当查看Azure门户中负载平衡器的后端池列表时,它将显示以下信息消息,但我一直无法找到有关该消息的任何信息。我不确定这有什么影响吗?

代码语言:javascript
运行
复制
Backend pool 'loadbalanceripv6beaddresspool' was removed from Virtual machine scale set 'Node1'. Upgrade all the instances of 'Node1' for this change to apply Node1

负载平衡器错误消息

我不知道为什么我不能让交通通过IPv6。可能是我在模板中漏掉了什么,或者是我自己犯了其他错误?如果需要更多的信息,请不要犹豫。

这是整个手臂模板。由于长度和后置长度的限制,我没有嵌入它,但是这里是一个与完整ARM模板的Pastebin链接(更新)

更新

有关调试IPv6连接的一些信息。我尝试稍微修改ARM模板,将端口80上的IPv6流量转发到后端端口8081。所以IPv4是80=>80和IPv6 80=>8081。ARM模板已经更新(见前一节中的链接)。

在端口80上,我将Kestrel作为无状态web服务器运行。我在ServiceManifest.xml中有以下条目:

代码语言:javascript
运行
复制
<Endpoint Protocol="http" Name="ServiceEndpoint1" Type="Input" Port="80" />      
<Endpoint Protocol="http" Name="ServiceEndpoint3" Type="Input" Port="8081" />

我一直有点不确定,确切地说,哪一个地址应该听在“凯斯雷尔”里。使用FabricRuntime.GetNodeContext().IPAddressOrFQDN总是返回IPv4地址。我们现在就是这样开始的。为了调试这一点,我目前获得了所有的IPv6地址,以及我们使用该地址的端口8081的硬编码黑客。Fort 80使用IPAddress.IPv6Any,但是这始终默认为IPAddress.IPv6Any返回的IPv4地址

代码语言:javascript
运行
复制
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    var endpoints = Context.CodePackageActivationContext.GetEndpoints()
        .Where(endpoint => endpoint.Protocol == EndpointProtocol.Http ||
                           endpoint.Protocol == EndpointProtocol.Https);

    var strHostName = Dns.GetHostName();
    var ipHostEntry = Dns.GetHostEntry(strHostName);
    var ipv6Addresses = new List<IPAddress>();

    ipv6Addresses.AddRange(ipHostEntry.AddressList.Where(
        ipAddress => ipAddress.AddressFamily == AddressFamily.InterNetworkV6));

    var listeners = new List<ServiceInstanceListener>();

    foreach (var endpoint in endpoints)
    {
        var instanceListener = new ServiceInstanceListener(serviceContext =>
            new KestrelCommunicationListener(
                serviceContext,
                (url, listener) => new WebHostBuilder().
                    UseKestrel(options =>
                    {
                        if (endpoint.Port == 8081 && ipv6Addresses.Count > 0)
                        {
                            // change idx to test different IPv6 addresses found
                            options.Listen(ipv6Addresses[0], endpoint.Port);
                        }
                        else
                        {
                            // always defaults to ipv4 address
                            options.Listen(IPAddress.IPv6Any, endpoint.Port);
                        }
                    }).
                    ConfigureServices(
                        services => services
                            .AddSingleton<StatelessServiceContext>(serviceContext))
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
                    .UseStartup<Startup>()
                    .UseUrls(url)
                    .Build()), endpoint.Name);
        listeners.Add(instanceListener);
    }

    return listeners;
}

以下是其中一个节点的Service中显示的端点:端点地址

对于套接字侦听器,我也做了修改,以便将IPv6转发到后端端口8517,而不是8507。类似于Kestrel服务器,套接字侦听器将在各自的地址上打开两个具有适当端口的侦听实例。

我希望这些信息对我们有帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-31 09:15:04

原来我犯了一个非常愚蠢的错误,这完全是我的错,我忘了验证我的ISP完全支持IPv6。原来他们不知道!

来自具有完全IPv6支持的提供者的测试可以正常工作,并且我能够获得到Service集群中节点的完全连接。

这里是任何需要IPv4和IPv6支持的服务结构集群的完全工作示例的工作ARM模板:

代码语言:javascript
运行
复制
Not allowed to post pastebin links without a accompanied code snippet...

更新:

由于长度限制,模板不能完全粘贴在这个线程中,但是在Service的GitHub pasted页面上,我交叉了这一点。ARM模板在该线程中作为注释发布,希望它比pastebin链接更长。查看它,这里

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50574231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档