当函数计算平台的标准运行时无法满足您的业务需求时,可以选择自定义容器函数。本文介绍如何在函数计算控制台或使用Serverless Devs工具创建Custom Container函数。
注意事项
在函数计算中,创建Custom Container函数必须使用同一账号下相同地域内阿里云镜像服务仓库中的镜像。针对搭载Apple芯片的Mac电脑(或其他ARM架构的机器),构建镜像时需要指定镜像的编译平台为Linux/Amd64,示例命令如
docker build --platform linux/amd64 -t $IMAGE_NAME .
。函数计算在解析ACR企业版镜像域名时,使用镜像仓库实例配置的专有网络默认解析或云解析PrivateZone自动解析的访问IP地址。具体场景如下:
场景一:如果ACR企业版实例的访问控制页面的访问 IP中不存在默认解析标识时,该列表下的所有IP地址均为云解析PrivateZone自动解析的IP地址,任意一个VPC配置均可使用。
场景二:如果ACR企业版实例的访问控制页面的访问 IP中存在默认解析标识的IP地址为专有网络默认解析的IP地址,以下图为例,只能选择第一个VPC。
使用企业版实例时只能选择非加速镜像,并且每次更新函数的镜像配置时,都会基于最新选择的原始镜像生成最新的加速镜像(如果加速镜像已存在会覆盖生成)。请不要删除原始镜像以及加速镜像,否则会影响函数调用。
请确保您在函数配置中的镜像在发生任何变化后,及时更新您的函数,否则函数调用会失败。
请确保原始镜像存在,否则函数会进入Failed状态,并且无法调用。函数计算虽然对您的函数做了缓存以加速冷启动速度,但是在调用过程中依然依赖您的原始镜像的存在。
请确保您在任何函数中使用的镜像不要被覆盖,如果被覆盖为其他的Digest,请及时使用最新的镜像信息重新部署您的函数。函数计算会同时记录您在创建和更新配置时所选择的镜像版本Tag和Digest,如果您的镜像版本在别的地方被更新为其他的Digest,函数将调用失败。
前提条件
容器镜像服务
- 说明
容器镜像个人版ACR面向个人开发者,公测限额免费试用,无SLA承诺和受损赔偿,且有使用限制。关于使用限制说明,请参见创建个人版实例注意事项。
Serverless Devs(仅选择使用Serverless Devs创建函数时需要)
- 说明
需安装19.03及以上版本的Docker。
在控制台创建函数
登录函数计算控制台,在左侧导航栏,单击函数。
在顶部菜单栏,选择地域,然后在函数页面,单击创建函数。
在创建函数页面,选择使用容器镜像方式,按需设置以下配置项,然后单击创建。
基本设置:设置函数名称。
镜像配置:配置创建函数的镜像。
配置项
说明
镜像选择方式
您可以使用示例镜像或者您自己的镜像创建函数。
使用示例镜像:选择函数计算自带的示例镜像。
使用 ACR 中的镜像:单击配置项容器镜像下方的选择 ACR 中的镜像,在弹出的选择容器镜像面板,选择已创建的容器镜像实例和ACR 镜像仓库,然后在下方选择镜像区域找到目标镜像并在其右侧操作列单击选择。
启动命令
容器的启动命令。如果不填写,则默认使用镜像中的Entrypoint或者CMD。
监听端口
容器镜像中的HTTP Server所监听的端口。默认端口为9000。
高级配置:配置函数的实例相关信息、执行超时时间和网络设置等。
配置项
说明
是否使用GPU
根据您的业务情况,选择是否使用GPU实例。默认使用弹性实例,不使用GPU实例。更多信息,请参见实例类型及使用模式。关于各种实例类型的计费详情,请参见计费概述。
使用GPU
不使用GPU
规格方案
选择使用GPU
根据您的业务情况,选择合理的GPU规格。函数计算将根据您选择的GPU规格自动选定vCPU规格和内存规格,不支持灵活配比。
选择不使用GPU
根据您的业务情况,选择或手动输入合理的vCPU规格和内存规格组合。
关于各资源使用的计费详情,请参见计费概述。
说明vCPU大小(单位为核)与内存大小(单位为GB)的比例必须设置在1∶1到1∶4之间。
临时硬盘大小
根据您的业务情况,选择硬盘大小。函数计算为您提供512 MB以内的磁盘免费使用额度。更多信息,请参见计费概述。
执行超时时间
设置超时时间。默认为60秒,最长为86400秒,推荐您设置为600秒。
说明超过设置的超时时间,函数将以执行失败结束。如需更长的超时时间限制,请加入钉钉用户群(钉钉群号64970014484)申请。
单实例并发度
设置函数实例的并发度。具体信息,请参见设置实例并发度。
时区
选择函数的时区。此处设置函数的时区后,将自动为函数添加一条环境变量TZ,其值为您设置的目标时区。
函数角色
如果您的代码逻辑需访问其他云服务,请创建角色并为角色最小化授予访问其他云服务的权限。更多信息,请参见授予函数计算访问其他云服务的权限。
允许访问 VPC
是否允许函数访问VPC内资源。更多信息,请参见配置网络。
专有网络
允许访问 VPC选择是时必填。创建新的VPC或在下拉列表中选择要访问的VPC ID。
交换机
允许访问 VPC选择是时必填。创建新的交换机或在下拉列表中选择交换机ID。
安全组
允许访问 VPC选择是时必填。创建新的安全组或在下拉列表中选择安全组。
允许函数默认网卡访问公网
是否允许函数可以通过默认网卡访问公网。关闭后,当前函数将无法通过函数计算的默认网卡访问公网。
重要使用固定公网IP地址功能时,您必须关闭允许函数默认网卡访问公网,否则配置的固定公网IP地址不生效。更多信息,请参见配置固定公网IP地址。
日志功能
是否启用日志功能,取值说明如下:
启用:启用后,您可以查看函数的调用日志,函数的调用日志将通过日志服务存储和查询。
禁用:不启用日志功能。
环境变量:设置函数运行环境中的环境变量。更多信息,请参见配置环境变量。
创建完成后,您可以在函数列表中查看和更新已创建的函数。
更新函数时,只能变更已设置的监听端口,不能删除或添加额外的监听端口。如果创建函数时,配置了监听端口,更新该函数时,不指定监听端口,将保留创建函数时的监听端口。
使用Serverless Devs创建函数
使用Serverless Devs可以一键构建、推送容器镜像并部署函数。
执行以下命令,初始化项目。
sudo s init
根据界面提示,依次选择阿里云账号、Custom Container模板和具体的语言(本文以Node.js为例),设置工程名称、选择项目部署地域并输入您的ACR镜像等。
执行以下命令,进入项目目录。
cd start-fc3-custom-container-nodejs
编辑
s.yaml
文件。关于YAML文件的参数解释,请参见YAML规范。示例如下。
示例中
image
为您的ACR镜像,需要分别将<your namespace>、<your image>和<your tag>替换为实际的命名空间名称、镜像仓库名称和镜像版本。如果您在步骤1初始化项目时已填入正确的ACR镜像,此处无需修改。edition: 3.0.0 name: hello-world-app # access 是当前应用所需要的密钥信息配置: # 密钥配置可以参考:https://www.serverless-devs.com/serverless-devs/command/config # 密钥使用顺序可以参考:https://www.serverless-devs.com/serverless-devs/tool#密钥使用顺序与规范 access: "default" vars: # 全局变量 region: "cn-hangzhou" resources: hello_world: # 如果只想针对 hello_world 下面的业务进行相关操作,可以在命令行中加上 hello_world,例如: # 只对 hello_world 进行构建:s hello_world build # 如果不带有 hello_world ,而是直接执行 s build,工具则会对当前Yaml下,所有和 hello_world 平级的业务模块(如有其他平级的模块,例如下面注释的next_function),按照一定顺序进行 build 操作 component: fc3 # 组件名称 actions: # 自定义执行逻辑 pre-deploy: # 在deploy之前运行 - component: fc3 build --dockerfile ./code/Dockerfile # 要运行的组件,格式为“component: 组件名 命令 参数” props: region: ${vars.region} # 关于变量的使用方法,可以参考:https://docs.serverless-devs.com/serverless-devs/yaml#%E5%8F%98%E9%87%8F%E8%B5%8B%E5%80%BC functionName: "start-nodejs-ufrz" runtime: "custom-container" description: 'hello world by serverless devs' timeout: 30 memorySize: 512 cpu: 0.5 diskSize: 512 code: ./code customContainerConfig: image: 'registry.${vars.region}.aliyuncs.com/<your namespace>/<your image>:<your tag>' # 您的ACR镜像,需要分别将<your namespace>、<your image>和<your tag>替换为实际的命名空间名称、镜像仓库名称和镜像版本 # triggers: # - triggerName: httpTrigger # 触发器名称 # triggerType: http # 触发器类型 # description: 'xxxx' # qualifier: LATEST # 触发服务的版本 # triggerConfig: # authType: anonymous # 鉴权类型,可选值:anonymous、function # disableURLInternet: false # 是否禁用公网访问 URL # methods: # HTTP 触发器支持的访问方法,可选值:GET、POST、PUT、DELETE、HEAD # - GET # - POST
执行以下命令,部署项目。
sudo s deploy
输出示例:
Steps for [deploy] of [hello-world-app] ==================== DEPRECATED: The legacy builder is deprecated and will be removed in a future release. BuildKit is currently disabled; enable it by removing the DOCKER_BUILDKIT=0 environment-variable. Sending build context to Docker daemon 5.12kB Step 1/7 : FROM node:14-buster 14-buster: Pulling from library/node 2ff1d7c41c74: Already exists b253aeafeaa7: Already exists 3d2201bd995c: Already exists 1de76e268b10: Already exists d9a8df589451: Already exists 6f51ee005dea: Already exists 5f32ed3c3f27: Already exists 0c8cc2f24a4d: Already exists 0d27a8e86132: Already exists Digest: sha256:a158d3b9b4e3fa813fa6c8c590b8f0a860e015ad4e59bbce5744d2f6fd8461aa Status: Downloaded newer image for node:14-buster ---> 1d12470fa662 Step 2/7 : WORKDIR /usr/src/ ---> Running in 70a8e2e4d1ea Removing intermediate container 70a8e2e4d1ea ---> 0d67b8fa2901 Step 3/7 : COPY package*.json ./ ---> 09eb15f8770a Step 4/7 : RUN npm install ---> Running in 8ae492be973b Step 5/7 : COPY . . ---> 7560c7b14431 Step 6/7 : EXPOSE 9000 ---> Running in 66b38e54ced0 Removing intermediate container 66b38e54ced0 ---> f73cce48d2ae Step 7/7 : ENTRYPOINT [ "node", "server.js" ] ---> Running in 2fb2f83fd6c0 Removing intermediate container 2fb2f83fd6c0 ---> fe51ae71448c Successfully built fe51ae71448c Successfully tagged registry.cn-hangzhou.aliyuncs.com/z****/z****:latest [2024-01-29 16:33:06][INFO][hello_world] get instanceName= and region=cn-hangzhou from registry.cn-hangzhou.aliyuncs.com/z****/z**** [2024-01-29 16:33:06][INFO][hello_world] try to docker push registry.cn-hangzhou.aliyuncs.com/z****/z**** ... WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded Using default tag: latest The push refers to repository [registry.cn-hangzhou.aliyuncs.com/z****/z****] 85c1ec915b45: Pushed 37c36543a431: Pushed e4afd7f70434: Pushed 0d5f5a015e5d: Layer already exists 3c777d951de2: Layer already exists f8a91dd5fc84: Layer already exists cb81227abde5: Layer already exists e01a454893a9: Layer already exists c45660adde37: Layer already exists fe0fb3ab4a0f: Layer already exists f1186e5061f2: Layer already exists b2dba7477754: Layer already exists latest: digest: sha256:6bf1ed4119d197a46c99082577632957056cb625f2ee0276d2af53f60d22837d size: 2841 [hello_world] completed (688.45s) Result for [deploy] of [hello-world-app] ==================== region: cn-hangzhou cpu: 0.5 customContainerConfig: image: registry.cn-hangzhou.aliyuncs.com/z****/z**** resolvedImageUri: registry.cn-hangzhou.aliyuncs.com/z****/z****@sha256:6bf1ed4119d197a46c99082577632957056cb625f2ee0276d2af53f60d22837d description: hello world by serverless devs diskSize: 512 functionName: start-nodejs-ufrz handler: handler instanceConcurrency: 1 internetAccess: true lastUpdateStatus: Successful memorySize: 512 role: runtime: custom-container state: Active timeout: 30 A complete log of this run can be found in: /root/.s/logs/0129162246
执行以下命令,调试函数。
sudo s invoke -e "{\"key\":\"val\"}"
输出示例:
Steps for [invoke] of [hello-world-app] ==================== ========= FC invoke Logs begin ========= FC Invoke Start RequestId: 1-65b764db-15eb737f-0c67ab5cd968 FC Invoke Start RequestId: 1-65b764db-15eb737f-0c67ab5cd968 hello world! FC Invoke End RequestId: 1-65b764db-15eb737f-0c67ab5cd968 Duration: 42.27 ms, Billed Duration: 43 ms, Memory Size: 512 MB, Max Memory Used: 47.77 MB ========= FC invoke Logs end ========= Invoke instanceId: c-65b764db-15fa2aa8-bc50f7839399 Code Checksum: undefined Qualifier: LATEST RequestId: 1-65b764db-15eb737f-0c67ab5cd968 Invoke Result: OK [hello_world] completed (4.96s) A complete log of this run can be found in: /root/.s/logs/0129164202
相关文档
如果您要使用GPU实例,则只能创建Custom Container函数。关于GPU实例规格的选择,请参见创建Web函数。
使用Custom Container函数,容器镜像依赖的基础环境会带来额外的数据下载和解压的时间,为了降低冷启动时间,请参见函数计算冷启动优化最佳实践。
您也可以调用API来创建函数,更多信息,请参见CreateFunction - 创建函数。
关于函数计算提供的内置运行时、自定义运行时和自定义容器运行时适用场景及差异,请参见函数运行时选型。