我希望用 Serveless 的方式跑一些 Ruby 代码。
因为这些代码的运行次数非常低,比如一天一次,或者是事件方式触发,发生了某些事情,才触发。
最终目的是做一些数据分析工作,从一个数据库里读取内容,做一些计算,然后存入另一个数据库。
我选择了腾讯云的云函数来做这件事,
因为 AWS Lambda 不支持固定 IP 功能,而我需要固定 IP 来访问 AWS RDS 数据库。
补充(1):AWS Lambda 如果希望 能访问公网
并且 同时能访问 VPC 里的某些私有资源(比如 RDS 数据库)
,
网络配置极度复杂,而且还要支付不少费用,价格非常不划算,而腾讯云的固定 IP 功能是免费的(起码截止目前2022年8月29号)
补充(2):阿里云也有给 Serverless 函数固定 IP 的功能,不过配置同样复杂,价格同样较高。
我把 Docker Image 部署到腾讯云云函数遇到问题。
本代码仓库用于给腾讯云工单工程师复现问题。
更新:问题已解决, 工单已关闭。
读者可以参考文章末尾的建议,避免和我一样踩坑。
先安装依赖
bundle install
运行服务器
ruby ./app.rb
构建镜像
docker build --tag tencent-scf .
运行镜像
docker run -p 9000:9000 tencent-scf
- app.rb (内容很短,看一眼你就懂了)
- Dockefile
- Gemfile
- Gemfile.lock
点击此处 直接看 解决方案(简略版)
- 我的电脑是 MacBook Pro(14英寸,2021年)芯片是 Apple M1 Pro。
- 我看到腾讯云云函数的文档里有一句
云函数当前是基于 X86 架构运行的,所以暂不支持运行在 ARM 平台上构建的镜像。ARM 的平台典型如 Apple Mac 搭载 M1 芯片的 PC 端。
所以我用了 AWS Codebuild 来负责构建 Docker Image。
以下截图的意思是,我用的容器镜像是 aws/codebuild/amazonlinux2-x86_64-standard:4.0
注意:TCR 上的镜像是 AWS Codebuild 运行 docker build
和 docker push
得到的。不是我本地 M1 Pro build + push 的。
version: 0.2
env:
variables:
# (请修改这个)你要推送到腾讯 TCR 的镜像 URL。(另外,这个也会作为 docker build 的 --cache-from 参数)
IMAGE_URL: ccr.ccs.tencentyun.com/zhengcheng/zhengcheng-docker-repo:latest
# (请修改这个)腾讯云的账号 ID
TENCENT_ACCOUNT_ID: 100006309506
# (请修改这个)腾讯云 TCR 的密码。
TENCENT_TCR_PASSWORD: [密码当然填你自己的]
# 本地临时用一下的 tag 名字。
DOCKER_TAG_NAME_TEMP: tencent-serverless-image
phases:
pre_build:
commands:
- echo 登录到腾讯云
- echo $TENCENT_TCR_PASSWORD | docker login --username=$TENCENT_ACCOUNT_ID --password-stdin https://ccr.ccs.tencentyun.com
build:
commands:
# 看一下文件
- ls
- yum install -y tree
- tree
# 构建镜像
- docker build --tag $DOCKER_TAG_NAME_TEMP --build-arg BUILDKIT_INLINE_CACHE=1 --cache-from $IMAGE_URL --file Dockerfile ./
# 打标签
- docker tag $DOCKER_TAG_NAME_TEMP:latest $IMAGE_URL
# 推送镜像。
- docker push $IMAGE_URL
- 腾讯云 TCR 里显示架构 arm64 并不碍事。这个并不影响。可以正确运行。
1. 新建腾讯云的云函数时,除了选择你自己的镜像,其他设置保留默认即可。
我没空深究这些不同触发器的细枝末节,我只知道 默认触发器
的效果和我本地运行的效果一样。
而用 API 网关触发
就会返回一堆 JSON,而不是我想要的返回结果。