当您通过MaxCompute访问位于公网或VPC网络中的目标服务时,默认情况下,MaxCompute与目标服务之间的网络不可达。您需要开通网络连接以便访问公网或VPC中的目标服务(例如指定IP或域名、RDS、HBase集群、Hadoop集群等)。本文为您介绍MaxCompute与目标服务间的网络结构及支持的网络开通方案。
免责声明
MaxCompute提供的公网与VPC访问能力目前属于免费服务,存在以下限制:
保障网络连通性,但是对用户代码触发的网络行为,平台可能因为故障切换的原因导致节点重跑,用户需要在代码层面做兼容,建议只做数据读取操作,写操作需要自行防止多次写入可能产生的脏数据。
访问需要经过代理,代理的转发能力有限,尽量使用长连接,并控制节点规模,并发过大或连接过多可能导致网络请求失败。
不保障带宽,因此可能存在任务运行慢情况,平台不承担相应责任。
经过代理后的出口IP有限,因此出现的连接行为异常,此时需要与阿里云技术支持确认。
出口IP存在变更的可能性,被访问的服务不应该开启访问控制,对于针对代理出口配置IP白名单的情况,平台不保障出口IP不变。
如果完成MaxCompute的网络连通后,运行MaxCompute任务时仍然出现了无法访问等问题,可能是运行MaxCompute任务的工具存在网络限制。例如,使用DataWorks进行数据同步或数据清洗时,需保障DataWorks的资源组与数据源网络连通、DataWorks的沙箱白名单没有限制数据源的访问,DataWorks的资源组网络连通与沙箱配置请参见:网络连通方案。
功能介绍
MaxCompute与目标服务间的网络结构及支持的网络开通方案如下:
MaxCompute访问目标服务有如下四种场景:
场景一:访问公网方案。
适用于通过MaxCompute自定义函数(UDF)、Spark 、MR、PyODPS/Mars访问处于公网中的目标IP或域名的场景。对于常用的公网或域名(如aliyun.com),您可以直接通过MaxCompute控制台的项目管理进行添加与删除,无法通过自动校验的公网IP或域名需要您填写MaxCompute项目访问外部网络申请表单,如果目标IP或域名不存在安全限制,审核通过后即可访问,审核周期为3个工作日内。
说明当服务端访问的目标公网IP或域名存在安全准入限制时,请联系您组织内对应责任人根据相应的安全限制进行处理,确保MaxCompute访问公网IP或域名不受限制。
场景二:访问VPC方案(专线直连)。
适用于通过MaxCompute SQL、UDF、Spark 、MR、PyODPS/Mars、外部表或基于湖仓一体架构访问处于VPC网络下的RDS、HBase集群、Hadoop集群等场景。您需要登录VPC所属主账号对MaxCompute进行授权,并在MaxCompute控制台创建MaxCompute与VPC网络之间的连接,创建完成后,您可以在控制台下看到MaxCompute创建的ENI网卡,该ENI网卡的访问规则由创建专有网络连接时您提供的安全组控制,以此来建立MaxCompute与目标服务间的网络通路。
说明如果目标服务存在访问控制,需要您将ENI网卡IP或者vSwitch网段添加到目标服务的访问白名单中。
MaxCompute访问VPC网络时,MaxCompute侧仅打通到所填VPC ID的网络连接,如需跨Region访问或者访问该Region的其他VPC,请根据云上VPC现有打通方案,打通专线直连方案中所配置的VPC和其他VPC之间的网络。
场景三:访问部分阿里云服务。
适用于通过MaxCompute SQL、UDF、Spark 、MR、PyODPS/Mars、外部表或基于湖仓一体架构访阿里云OSS、DLF、OTS(Tablestore)、Hologres等服务的场景,连接使用阿里云内部服务提供的云产品互联网络地址。
如果您创建了OSS或OTS外部表,可以通过OSS、OTS的内网Endpoint访问。
如果您调用UDF访问OSS、OTS,只能通过OSS、OTS的公网Endpoint访问。
不同场景下的配置与访问Endpoint详情请参见下文的访问部分阿里云服务章节。
前提条件
当您申请开通MaxCompute与目标服务间的网络连接前,请确认已满足以下条件:
已创建MaxCompute项目。如果已有MaxCompute项目,直接使用即可,不必再创建新项目。在湖仓一体场景中,建议设置MaxCompute项目的数据类型为Hive兼容类型。更多创建MaxCompute项目信息,请参见创建MaxCompute项目。
如果需要访问位于VPC网络中的目标服务,请确保VPC所有者账号、访问MaxCompute项目的阿里云账号,以及目标服务环境或集群的管理员账号是同一个主账号或同在一个主账号下。
地域支持情况
MaxCompute仅支持在如下地域通过访问公网或VPC网络方案开通网络连接。
方案类型 | 支持地域 | 支持连通的目标 |
访问公网方案 |
| 公网IP或域名 |
访问VPC方案(专线直连) |
|
|
访问公网方案
通过项目管理编辑外部网络地址
对于常用的公网IP或域名(如aliyun.com),您可以直接通过MaxCompute控制台的项目管理进行添加与删除:
登录MaxCompute控制台,在左上角选择地域。
在左侧导航栏单击项目管理。
在项目管理页面,单击目标项目操作列的管理。
在参数配置页签的外部网络区域,设置可用的外部网络地址。
单击提交。
支持的一级域名包括:aliyuncs.com、aliyun.com、amap.com、dingtalk.com、alicloudapi.com、cainiao.com、alicdn.com、taobao.com、alibaba.com、alipaydev.com、alibabadns.com。
不支持配置IPv6地址,公网IP数量无限制。
如果您遇到某外部网络地址无法通过自动校验的问题,则需要删除该地址后重新提交。如仍有需要,您可以通过提交表单申请的方式,申请配置外部网络地址,具体操作请参见下述的提交申请。
提交申请
无法通过自动校验的公网IP或域名需要按照如下步骤进行操作:
填写MaxCompute项目访问外部网络申请表单,申请配置公网的IP或域名、端口的白名单。
表单中需要填写目标IP或域名、端口,如果需要访问多个域名或端口,请使用英文逗号(,)分隔。例如访问阿里云域名,需要提供的网络配置信息为
www.aliyun.com:80
;访问高德服务,需要提供的网络配置信息为restapi.amap.com:443,restapi.amap.com:80
。MaxCompute技术支持团队接收到提交的申请信息后,会进行审核并完成配置。确认处理完毕后(通常处理周期为3个工作日),即可继续执行后续步骤。若对审核结果有异议,您可通过单击申请链接或搜索(钉钉群号:11782920)加入MaxCompute开发者社区钉群与我们沟通交流。
SQL自定义函数(UDF)任务
参数设置如下:
--设置网络连接申请表单中配置的公网IP或域名、端口。即下方SQL语句要访问的公网IP或域名。 --如果需要访问多个域名或端口,请使用英文逗号(,)分隔 set odps.internet.access.list=<ip_address:port|realm_name:port>; --执行SQL语句调用UDF。 select <UDF_name>("<http://ip_address|realm_name>");
ip_address:port | realm_name:port:必填。目标公网IP或域名、端口。
UDF_name:访问公网IP或域名的UDF。
任务示例代码如下:
package com.aliyun.odps.test.udf; import com.aliyun.odps.udf.UDF; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; public class <UDF_name> extends UDF { public String evaluate(String urlStr) throws IOException { URL url = new URL(urlStr); StringBuilder sb = new StringBuilder(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) { String line; while ((line = reader.readLine()) != null) { sb.append(line).append('\n'); } } return sb.toString(); } }
执行:基于UDF示例代码创建的自定义函数名称为
url_fetch
,网络连接审核通过后,执行命令示例如下。set odps.internet.access.list=www.aliyun.com:80; select url_fetch("http://www.aliyun.com");
Spark on MaxCompute任务
参数设置:此配置项需加在Spark客户端的conf文件中或DataWorks提交Spark作业时的配置项中。
spark.hadoop.odps.cupid.smartnat.enable = true;
spark.hadoop.odps.cupid.internet.access.list=<ip_address:port>
白名单
如果用户服务端有访问控制,需要将MaxCompute访问公网方案的出口IP添加到用户服务白名单,出口IP请提交工单申请获取。
访问VPC方案(专线直连)
开通专线网络连接
操作流程
授权操作:
需要针对登录用户授予能够创建网络连接对象Networklink(详情请参见Networklink),授权的用户需要是项目所有者(Project Owner),以及具备租户级别的Super_Administrator或Admin角色的用户(详情请参见角色规划),授权过程可参见租户内对象权限一览表。
对MaxCompute进行授权:授权的目的在于允许MaxCompute在VPC内创建ENI网卡,以实现MaxCompute到用户VPC的连通。用户只要在阿里云账号登录态下单击授权即可。
说明MaxCompute访问VPC时的计费规则请参考功能计费。
配置安全组规则:在VPC实例下,创建独立安全组用于控制MaxCompute对VPC网络内的各种资源的访问权限。
登录专有网络管理控制台,单击目标VPC实例ID后,单击资源管理页签。
在资源管理页签的专有网络资源区域,将鼠标悬停至安全组数值上方后,单击添加(注意:选择安全组为普通安全组,不是企业安全组。普通安全组的出口是默认开启的。企业安全组的出口是默认关闭的,会导致无法访问VPC内的任何服务)为MaxCompute创建独立安全组并记录安全组ID。需要选择与连通服务相同的VPC网络。更多创建安全组操作,请参见创建安全组。
添加安全组:
配置安全组:
说明MaxCompute在后续的创建网络通路过程中会默认自动根据带宽需求创建2个ENI,不收取费用,由MaxCompute创建的ENI将位于这个安全组内。在HBase场景,如果用户的HBase无法对某个安全组开放网络权限,您可以将MaxCompute创建的ENI IP添加至白名单即可。由于ENI IP可能会发生变化,推荐您添加VPC实例对应交换机的IP网段至白名单。您可以登录ECS管理控制台,在左侧导航栏,单击弹性网卡,获取ENI IP。
创建MaxCompute与目标VPC网络间的网络连接。
阿里云账号(主账号)或拥有MaxCompute租户级别的Super_Administrator或Admin角色的RAM子账号(详情请参见MaxCompute租户级别角色),可以在MaxCompute控制台创建MaxCompute与VPC网络之间的连接。操作如下:
在MaxCompute控制台的左侧导航栏单击
。在新增网络连接对话框中,按下表填写参数后单击确定。
参数名称
说明
连接名称
自定义网络链接名称。格式如下:
字母开头。
只能包含字母、下划线(_)和数字。
长度在1-63个字符。
类型
网络连接类型。默认为直通链接(passthrough)。
说明直通链接对应的即是专有网络连接方案。
区域
MaxCompute支持的通过专有网络连接方案开通网络连接的地域。详情请参见开通地域。
已选择VPC
VPC实例ID。
获取方式如下:
连接HBase、Hadoop集群时:您可以在对应控制台的网络连接信息处获取该信息。
其他情况:登录专有网络管理控制台,在专有网络页面即可获取VPC ID。
交换机
VPC网络绑定的交换机ID。
获取方式如下:
连接HBase、Hadoop集群时:您可以在对应控制台的网络连接信息处获取该信息。
其他情况:登录专有网络管理控制台,在左侧导航栏单击交换机,即可在右侧通过VPC实例ID获取到交换机ID。
安全组
步骤【开通专线网络连接】中记录的安全组ID。
配置目标服务的安全组。
在完成ENI专线开通后,用户还需要在待访问的服务中增加相关安全规则,授权代表MaxCompute的安全组,即就上述第二步中提供的安全组能访问哪些服务的具体端口。例如9200、31000等。例如,用户需要访问阿里云RDS,则需要在RDS中增加规则,允许第二步中创建的安全组访问。如果用户需要访问的服务无法添加安全组,只能添加IP,那么需要将目标服务所在vSwitch网段都添加进来。
配置Hadoop集群安全组。
为Hadoop集群的安全组配置如下信息,确保MaxCompute可以访问Hadoop集群。安全组配置内容如下:
配置Hadoop集群所在安全组的入方向访问规则。
授权对象为ENI所在的安全组,即步骤2中创建的安全组。
HiveMetaStore端口:9083。
HDFS NameNode端口:8020。
HDFS DataNode端口:50010。
例如,当您连接在阿里云E-MapReduce上创建的Hadoop集群时,您需要配置的安全组规则如下图所示。更多配置操作,请参见创建安全组。
配置HBase集群安全组。
将为MaxCompute创建的安全组或ENI IP加入HBase集群的安全组或IP白名单中。
例如,当您连接阿里云HBase集群时,可以登录HBase管理控制台,在集群列表页面单击目标集群名称后,在左侧导航栏单击访问控制,即可在安全组或白名单设置页签添加安全组或IP白名单。更多添加安全组或IP白名单操作,请参见设置白名单和安全组。
说明如果不允许添加安全组,您可以在白名单设置页签添加MaxCompute创建的ENI IP。当MaxCompute配置变更时,ENI IP可能会发生变化,推荐您添加交换机ID的IP网段添加至白名单。
配置RDS安全组。
将为MaxCompute创建的安全组或ENI IP加入RDS安全组或IP白名单中。
例如,当您连接阿里云RDS时,可以登录RDS管理控制台,在实例列表页面单击目标实例名称后,在左侧导航栏单击白名单与安全组,即可在安全组或白名单设置页签添加安全组或IP白名单。更多添加安全组或IP白名单设置操作,请参见设置安全组或设置IP白名单。
说明当MaxCompute配置变更时,ENI IP可能会发生变化,推荐您将交换机ID的IP网段添加至白名单。
SQL任务
添加配置项
UDF访问VPC网络(详情请参见:通过UDF访问VPC网络资源)。代码如下:
--设置网络连接名称,即基于专有网络连接方案配置的网连接名称,仅本Session有效: set odps.session.networklink=testLink;
外部表访问VPC网络(详情请参见:RDS外部表、HBase外部表、Lindorm外部表)。代码如下:
-- 在建表语句中设置参数 TBLPROPERTIES( 'networklink'='<networklink_name>')
湖仓一体配置Networklink(详情请参见:MaxCompute湖仓一体概述)。
Spark on MaxCompute 任务
完成上述【开通专线网络连接】操作后,可添加以下配置。
运行Spark作业,需要增加如下配置,即可使用ENI专线连通目标VPC内的服务(详情请参见:Spark访问VPC实例)。
spark.hadoop.odps.cupid.eni.enable = true
spark.hadoop.odps.cupid.eni.info=regionid:vpc id
白名单
如果用户服务端有访问控制,需要将创建专线网络连接的安全组添加进服务端白名单。
访问部分阿里云服务
适用于通过MaxCompute SQL、UDF、Spark 、MR、PyODPS/Mars、外部表或基于湖仓一体架构访问阿里云OSS、DLF、OTS(Tablestore)、Hologres等服务的场景,连接使用阿里云内部服务提供的云产品互联网络地址。
通过外部表访问OSS、OTS
如果您创建了OSS或OTS外部表,可以通过OSS、OTS的内网Endpoint访问。
各地域的OSS内网Endpoint请参见OSS地域和访问域名文档中,内网Endpoint列。
各地域的OTS内网Endpoint请参见服务地址中的经典网地址。
其他通过外部表访问的示例可参考:创建Hologres外部表。
通过UDF访问OSS、OTS
如果您调用UDF访问OSS、OTS,只能通过OSS、OTS的公网Endpoint访问,且在使用公网Endpoint访问前,您需要先将对应Endpoint添加至MaxCompute的白名单中。
将待访问的OSS、OTS的公网Endpoint添加至MaxCompute的白名单中。
您可以填写MaxCompute项目访问外部网络申请表单,申请将待访问的OSS、OTS的公网Endpoint添加到MaxCompute的白名单中。各地域的公网Endpoint获取详情如下。
各地域的OSS公网Endpoint请参见OSS地域和访问域名文档中,公网Endpoint列。
各地域的OTS公网Endpoint请参见服务地址中的公网地址。
使用公网Endpoint访问OSS或OTS。
Spark on MaxCompute任务示例可参考:Spark访问OSS。
常见问题
并发量过大导致DNS解析失败
问题描述:UDF或Spark任务在运行过程中,产生了大量的并发请求以访问对端域名,导致DNS解析失败。
解决方案:建议您在任务的初始化阶段将域名解析为IP地址,并在执行阶段使用解析得到的IP地址进行访问。示例如下:
# -*- coding:UTF-8 -*- from odps.udf import annotate @annotate("string->string") class test_udf(object): __ip_address = '' def evaluate(self, inputPath): import requests output = 'false' retries = 3 print(self.__ip_address) url = f"http://{self.__ip_address}/{inputPath}" print(url) for i in range(retries): try: response = requests.get(url) if response.status_code == 200: output = 'true' else: raise except Exception as e: if i < retries: print('connect retry:' + str(i + 1)) print('error: ' + e.message) continue else: raise break return output def __init__(self): import socket retries = 3 for i in range(retries): try: self.__ip_address = socket.gethostbyname("xxx-vpc.cn-shanghai.aliyuncs.com") print(self.__ip_address) except socket.gaierror as e: print('Failed to resolv domain' + e.strerror) if i < retries: print('resolv domain retry:' + str(i + 1)) continue else: raise break