使用NLB全端口监听功能实现多端口流量转发

对于需要监听大量端口或动态端口的场景,如果逐个配置监听,配置会非常繁琐且会加大后续运维难度,若配置错误也可能造成安全风险。此时您可以使用NLB全端口监听功能,使NLB能够监控并响应一个端口段范围内的所有网络流量,在同一个监听中实现多端口流量转发,降低配置复杂度、运维难度以及安全风险。

全端口监听功能简介

全端口监听,是指NLB能够同时监听并处理指定端口范围内的所有端口流量,而不是仅针对单个固定的端口。

启用全端口监听功能后,NLB能够对指定的端口段进行全面监听,并根据预设的规则将接收到的请求自动转发到后端服务器相应的端口上。

该功能允许在不限制特定端口的情况下,灵活管理网络流量,可以极大地简化配置复杂度和运维难度,特别适合需要监听大量端口或动态端口的场景。

关键特性

  1. 端口范围覆盖:全端口监听允许用户指定一个连续的端口范围,如1000-2000,这意味着NLB会监听这个范围内每一个端口(即从端口1000到端口2000之间的所有端口)上的连接请求。

  2. 简化配置:全端口监听可以减少在NLB上手动配置多个独立监听的需要,特别适用于那些需要暴露大量端口,且端口与后端服务端口一一对应的应用场景。对于服务端口频繁变动或者需要快速扩展的服务,全端口监听提供了极大的灵活性,无需每次新增或调整端口时都去更新NLB的监听配置。

适用场景

需要监听大量端口或动态端口的场景:

  • 在线游戏:在线单人RPG、人机对战、策略模拟SLG等游戏场景。在这种场景下,可以使用大范围的端口来处理不同场景下的游戏数据,在每个端口内配置不同的游戏场景;也可以利用端口来实现游戏分房。

  • RTC(实时通信)应用:如视频会议系统、在线教育平台等,通常使用大范围的端口来处理实时媒体流(音频、视频)和信令数据。

场景示例

某企业在阿里云华东1(杭州)地域创建了专有网络VPC,在该VPC中创建了一个NLB实例,NLB后端服务器组挂载了ECS01与ECS02,ECS中均部署了可访问的应用服务。

该企业希望VPC中的NLB实例可以使用全端口监听功能,监听后端服务器的8080-8090端口段,使用不同端口,访问不同服务。

image

使用限制

NLB开启全端口功能的监听,需要关联开启全端口转发功能的服务器组。监听与服务器组不支持修改全端口转发功能状态,因此如果您如果需要使用全端口功能,您需要新建支持全端口功能的服务器组与监听。

前提条件

  • 您已在华东1(杭州)地域创建专有网络VPC,并在两个可用区内创建两台交换机VSW1、VSW2。详细操作可参考创建专有网络和交换机

  • 您已分别在VSW1和VSW2创建ECS01和ECS02实例,且ECS01和ECS02实例中部署了8080-8090端口段的应用服务。

    部署测试服务命令参考

    以CentOS 7.9、Nginx 1.20.1版本为例,您可以参考如下脚本,部署同时支持8080-8090端口段的测试服务:

    1. 登录ECS01服务器后台:

      1. 执行vi ECS01_server_install.sh,按i键进入编辑模式。

      2. 复制并粘贴如下命令:

        #!/bin/bash
        
        # 安装nginx
        yum install -y nginx
        
        # 定义Nginx服务器块配置的目录
        NGINX_CONF_DIR=/etc/nginx/conf.d
        
        # 定义存储index.html文件的目录
        HTML_DIR=/usr/share/nginx/html
        
        # 循环创建配置和HTML文件
        for PORT in $(seq 8080 8090); do
          CONF_FILE=${NGINX_CONF_DIR}/app_${PORT}.conf
          HTML_FILE=${HTML_DIR}/index_app${PORT}.html
          
          # 创建HTML内容
          echo "Hello World! This is ECS01, server port is ${PORT}." > ${HTML_FILE}
          
          # 创建Nginx服务器块配置
          cat > ${CONF_FILE} << EOF
        server {
            listen ${PORT};
            server_name localhost;
        
            location / {
                root ${HTML_DIR};
                index index_app${PORT}.html;
            }
        }
        EOF
        
        done
        
        # 测试Nginx配置文件是否正确
        nginx -t && systemctl start nginx
        
        echo "Nginx has been configured to listen on ports 8080 to 8090."
        
        # 循环通过curl访问localhost的端口8080到8090
        for PORT in $(seq 8080 8090); do
          echo "Accessing http://localhost:${PORT}"
          curl http://localhost:${PORT}
        done
        

      3. Esc键,输入:wq保存修改。

      4. 执行sudo sh ECS01_server_install.sh命令,运行脚本。

      5. 当最后显示如下执行结果时,表示8080-8090端口服务均可以访问。

        ...
        Nginx has been configured to listen on ports 8080 to 8090.
        Accessing http://localhost:8080
        Hello World! This is ECS01, server port is 8080.
        Accessing http://localhost:8081
        Hello World! This is ECS01, server port is 8081.
        Accessing http://localhost:8082
        Hello World! This is ECS01, server port is 8082.
        Accessing http://localhost:8083
        Hello World! This is ECS01, server port is 8083.
        Accessing http://localhost:8084
        Hello World! This is ECS01, server port is 8084.
        Accessing http://localhost:8085
        Hello World! This is ECS01, server port is 8085.
        Accessing http://localhost:8086
        Hello World! This is ECS01, server port is 8086.
        Accessing http://localhost:8087
        Hello World! This is ECS01, server port is 8087.
        Accessing http://localhost:8088
        Hello World! This is ECS01, server port is 8088.
        Accessing http://localhost:8089
        Hello World! This is ECS01, server port is 8089.
        Accessing http://localhost:8090
        Hello World! This is ECS01, server port is 8090.

        如果出现curl命令访问失败,需要排查下是否端口已被占用或者执行命令错误。

    2. 登录ECS02服务器后台:

      1. 执行vi ECS02_server_install.sh,按i键进入编辑模式。

      2. 复制并粘贴如下命令:

        #!/bin/bash
        
        # 安装nginx
        yum install -y nginx
        
        # 定义Nginx服务器块配置的目录
        NGINX_CONF_DIR=/etc/nginx/conf.d
        
        # 定义存储index.html文件的目录
        HTML_DIR=/usr/share/nginx/html
        
        # 循环创建配置和HTML文件
        for PORT in $(seq 8080 8090); do
          CONF_FILE=${NGINX_CONF_DIR}/app_${PORT}.conf
          HTML_FILE=${HTML_DIR}/index_app${PORT}.html
          
          # 创建HTML内容
          echo "Hello World! This is ECS02, server port is ${PORT}." > ${HTML_FILE}
          
          # 创建Nginx服务器块配置
          cat > ${CONF_FILE} << EOF
        server {
            listen ${PORT};
            server_name localhost;
        
            location / {
                root ${HTML_DIR};
                index index_app${PORT}.html;
            }
        }
        EOF
        
        done
        
        # 测试Nginx配置文件是否正确
        nginx -t && systemctl start nginx
        
        echo "Nginx has been configured to listen on ports 8080 to 8090."
        
        # 循环通过curl访问localhost的端口8080到8090
        for PORT in $(seq 8080 8090); do
          echo "Accessing http://localhost:${PORT}"
          curl http://localhost:${PORT}
        done
        

      3. Esc键,输入:wq保存修改。

      4. 执行sudo sh ECS02_server_install.sh命令,运行脚本。

      5. 当最后显示如下执行结果时,表示8080-8090端口服务均可以访问。

        ...
        Nginx has been configured to listen on ports 8080 to 8090.
        Accessing http://localhost:8080
        Hello World! This is ECS02, server port is 8080.
        Accessing http://localhost:8081
        Hello World! This is ECS02, server port is 8081.
        Accessing http://localhost:8082
        Hello World! This is ECS02, server port is 8082.
        Accessing http://localhost:8083
        Hello World! This is ECS02, server port is 8083.
        Accessing http://localhost:8084
        Hello World! This is ECS02, server port is 8084.
        Accessing http://localhost:8085
        Hello World! This is ECS02, server port is 8085.
        Accessing http://localhost:8086
        Hello World! This is ECS02, server port is 8086.
        Accessing http://localhost:8087
        Hello World! This is ECS02, server port is 8087.
        Accessing http://localhost:8088
        Hello World! This is ECS02, server port is 8088.
        Accessing http://localhost:8089
        Hello World! This is ECS02, server port is 8089.
        Accessing http://localhost:8090
        Hello World! This is ECS02, server port is 8090.

        如果出现curl命令访问失败,需要排查下是否端口已被占用或者执行命令错误。

  • ECS01与ECS02实例加入的安全组已经放行8080-8090端口。

  • 您已在VPC中创建一个处于运行中状态的公网类型NLB实例。详细操作可参考创建和管理NLB实例

  • 已经注册域名并完成备案。具体操作,请参见注册阿里云域名ICP备案流程

步骤一:创建支持全端口功能的服务器组

  1. 登录网络型负载均衡NLB控制台

  2. 在顶部菜单栏,选择NLB实例所属的地域。

  3. 在左侧导航栏,选择网络型负载均衡 NLB服务器组

  4. 服务器组页面,单击创建服务器组

  5. 配置服务器组信息。关键配置信息可参考下表配置,其余配置项保持默认值即可,如需修改可参考创建和管理服务器组

    配置

    说明

    服务器组类型

    选择服务器类型

    服务器组名称

    自定义服务器组名称。

    VPC

    从VPC下拉列表中选择NLB所在VPC,只有该VPC下的服务器可以加入到该服务器组。

    全端口转发

    开启全端口转发功能。

    开启后添加后端服务器时无需指定端口,NLB将按照前端请求端口转发流量至后端服务器。

    重要

    当您的监听开启全端口功能时,只能选择开启了全端口转发功能的后端服务器组。

    配置健康检查

    开启健康检查。

    健康检查端口

    当开启全端口转发功能时,健康检查需要指定特定端口。

    该端口是健康检查服务访问后端时的探测端口,访问该端口的请求需要服务器能返回有效的响应,以免判断为检测失败。

    本文配置示例端口为8080

  6. 服务器组信息配置完成后,单击创建。待服务器组创建成功后,在弹窗中单击添加后端服务器

  7. 选择ECS01和ECS02,其余配置项保持默认值即可(全端口监听不需要配置服务器端口)。完成后单击确定,完成服务器添加。

步骤二:创建支持全端口功能的监听

说明

本文以TCP监听为例进行说明。

  1. 登录网络型负载均衡NLB控制台

  2. 在顶部菜单栏,选择NLB实例所属的地域。

  3. 实例页面,单击操作列的创建监听

  4. 配置监听信息。关键配置信息可参考下表配置,其余配置项保持默认值即可,如需修改可参考添加TCP监听。配置完成后单击提交

    配置监听:

    配置

    说明

    全端口功能

    开启全端口功能。

    监听端口段

    全端口监听的起始端口和结束端口段,本文配置示例端口段为80808090

    NLB将对配置的监听端口段内的所有端口进行监听,并将监听端口上接收到的请求直接转发至后端服务器的对应端口。

    重要

    全端口监听创建成功后,监听端口段的范围不支持修改。

    选择服务器组:

    配置

    说明

    选择服务器组

    选择添加了ECS01与ECS02的支持全端口功能的服务器组。

    重要

    添加至全端口监听的服务器组需开启全端口转发功能,否则无法添加。

步骤三:设置域名解析

实际业务场景中,建议您使用自有域名,通过CNAME解析的方式将自有域名指向NLB实例域名。

  1. 在左侧导航栏,选择网络型负载均衡 NLB > 实例

  2. 实例页面,复制已创建的NLB实例的DNS名称。

  3. 执行以下步骤添加CNAME解析记录。

    说明

    对于非阿里云注册域名,需先将域名添加到云解析控制台,才可以进行域名解析设置。具体操作,请参见域名管理。如果您是阿里云注册的域名,请直接执行以下步骤。

    1. 登录域名解析控制台

    2. 权威域名解析页面,找到目标域名,在操作列单击解析设置

    3. 解析设置页面,单击添加记录

    4. 添加记录面板,配置以下信息完成CNAME解析配置,然后单击确定

      配置

      说明

      记录类型

      在下拉列表中选择CNAME

      主机记录

      您的域名的前缀。本文输入@

      说明

      创建域名为根域名时,主机记录为@

      解析请求来源

      选择默认。

      记录值

      输入域名对应的CNAME地址,此处为NLB实例的DNS名称。

      TTL

      全称Time To Live,表示DNS记录在DNS服务器上的缓存时间,本文使用默认值。

步骤四:测试全端口监听效果

  1. 测试NLB可用性:

    1. 以任意一台可以访问公网的Linux客户端为例。如果未安装telnet,以CentOS系统为例可以参考执行yum install -y telnet安装telnet。

    2. 多次执行telnet 域名 端口命令(端口为8080-8090之间任意端口),收到类似下面回复报文Connected to ...,则表示NLB可以将请求转发至后端服务器。

      Trying *.*.*.*...
      Connected to www.example.com.
      Escape character is '^]'

      通过浏览器访问域名加8080-8090之间的任意端口,例如http://域名:8080,可以看到类似下图,表示客户端能够正常访问应用。

      image

  2. 模拟故障:

    1. 停用ECS01服务。在ECS01中执行systemctl stop nginx.service停用应用。

    2. 等待几分钟后,客户端再次执行telnet 域名 端口命令(端口为8080-8090之间任意端口),仍然收到下图回复报文Connected to ...

      Trying *.*.*.*...
      Connected to www.example.com.
      Escape character is '^]'

      通过浏览器访问域名加8080-8090之间的任意端口,例如http://域名:8080,可以看到类似下图,表示客户端能够正常访问应用。

      image

    3. 启用ECS01服务,停用ECS02服务。在ECS01中执行systemctl start nginx.service重新启动应用,在ECS02中执行systemctl stop nginx.service停用应用。

    4. 等待几分钟后,在客户端中再次执行telnet 域名 端口命令(端口为8080-8090之间任意端口),仍然收到下图回复报文Connected to ...

      Trying *.*.*.*...
      Connected to www.example.com.
      Escape character is '^]'

      通过浏览器访问域名加8080-8090之间的任意端口,例如http://域名:8080,可以看到类似下图,表示客户端能够正常访问应用。

      image

  3. 如上测试结果表明,后端单台服务器故障不影响NLB可用性,并且8080-8090之间的端口均可以访问服务。