#aws-lambda #run-command #command-line #lambda #docker-image #aws #aws-cli

app run-command-on-aws-lambda

在 AWS Lambda 上运行任意命令行

2 个稳定版本

1.1.0 2022 年 4 月 30 日
1.0.0 2022 年 3 月 21 日

#2065 in 命令行工具

Apache-2.0

23KB
252

在 AWS Lambda 上运行命令

Build Status Contributor Covenant Apache License Github Release Crates.io

目标

使在 AWS Lambda 上运行 Docker 镜像中的命令行变得容易。

这将与许多不同的 Docker 镜像一起工作,从简单的 Linux 发行版到 AWS 命令行工具,再到大型独立工具,如 SchemaSpy

概述

首先创建一个包含此工具的 Docker 镜像,并将其添加到包含您希望看到的任何内容的基 Docker 镜像中,请参阅:示例 Dockerfile

将镜像部署到 AWS Lambda 并调用它。调用消息包括要运行的程序、可选的命令行参数列表以及可选的环境变量列表。

{
  "program": "mysql",
  "arguments": [
    "store",
    "--password",
    "fancy-password",
    "--execute",
    "SELECT * from purchase_orders"
  ],
  "environment": [
    "MYSQL_HOST": "my-database.example.com",
    "MYSQL_TCP_PORT": "3306",
  ]
}

在 Alpine Linux 基础镜像上的一些示例运行

运行时用户是谁? id

使用测试事件 {"program": "id"} 结果如下

START RequestId: 955381a3-859a-4bf0-b560-acd0e76d6015 Version: $LATEST
Running id [].
Waiting for id completion.
uid=993(sbx_user1051) gid=990
Child id exited successfully.
END RequestId: 955381a3-859a-4bf0-b560-acd0e76d6015
REPORT RequestId: 955381a3-859a-4bf0-b560-acd0e76d6015	Duration: 1.29 ms	Billed Duration: 2 ms	Memory Size: 128 MB	Max Memory Used: 13 MB

尽管镜像的默认运行时用户是 root,但 AWS Lambda 以非特权用户身份运行镜像。AWS 团队的出色安全工作!

文件系统有哪些? mount

使用测试事件 {"program": "mount"} 结果如下

START RequestId: 2602928d-b146-44f6-b684-bfe95e8b0714 Version: $LATEST
Running mount [].
Waiting for mount completion.
/mnt/root-rw/opt/amazon/asc/worker/tasks/rtfs/inline-manifest on / type overlay (ro,nosuid,nodev,relatime,lowerdir=/tmp/es2088019054/8c01de2338356980:/tmp/es2088019054/34f08a2940031490)
/dev/vdb on /dev type ext4 (rw,nosuid,noexec,noatime,data=writeback)
/dev/vdd on /tmp type ext4 (rw,relatime,data=writeback)
none on /proc type proc (rw,nosuid,nodev,noexec,noatime)
/dev/vdb on /proc/sys/kernel/random/boot_id type ext4 (ro,nosuid,nodev,noatime,data=writeback)
/dev/root on /etc/passwd type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/root on /var/rapid type ext4 (ro,nosuid,nodev,relatime,data=ordered)
/dev/vdb on /etc/resolv.conf type ext4 (ro,nosuid,nodev,noatime,data=writeback)
Child mount exited successfully.
END RequestId: 2602928d-b146-44f6-b684-bfe95e8b0714
REPORT RequestId: 2602928d-b146-44f6-b684-bfe95e8b0714	Duration: 1.44 ms	Billed Duration: 2 ms	Memory Size: 128 MB	Max Memory Used: 13 MB

注意,根文件系统(/ 挂载点)是只读的。AWS 团队再次进行了更多优秀的安全工作,但对于预期能够写入磁盘的运行时来说,这可能会是个惊喜。

/tmp 上有多少可用空间?

在上面的文件系统列表中,我们可以看到 /tmp 是可写的。现在的问题是:有多少可用空间?使用以下测试事件

{
  "program": "df",
  "arguments": ["-h", "/tmp"]
}

结果是

START RequestId: 59a5bbb8-2ec6-42a3-8c5f-1b4a1fac476f Version: $LATEST
Running df ["-h", "/tmp"].
Waiting for df completion.
Filesystem                Size      Used Available Use% Mounted on
/dev/vdd                525.8M    872.0K    513.4M   0% /tmp
Child df exited successfully.
END RequestId: 59a5bbb8-2ec6-42a3-8c5f-1b4a1fac476f
REPORT RequestId: 59a5bbb8-2ec6-42a3-8c5f-1b4a1fac476f	Duration: 1.57 ms	Billed Duration: 2 ms	Memory Size: 128 MB	Max Memory Used: 12 MB

我们可以看到大约有半GB的可用空间在 /tmp 上。

起源故事

我与一家提供基于Microsoft .NET服务的软件合作伙伴合作。该服务的长期生命周期包括数据库迁移。我们与合作伙伴商定,将迁移操作与主服务分开处理。(我们预计将运行一个主服务的服务器集群。我们希望避免在首次启动或升级集群时发生数据库迁移冲突。)

合作伙伴提供的服务被打包成Docker镜像。其中一个镜像负责数据库迁移。这个项目让我能够方便地在AWS上运行数据库迁移,并知道迁移何时完成或是否发生故障。

包装合作伙伴镜像

我们创建了一个新的Docker镜像,在合作伙伴提供的镜像基础上添加了run-command-on-aws-lambda作为入口点。

FROM partner/dotnet-service-with-migrations:1.0

ARG WRAPPER=https://github.com/bruceadams/run-command-on-aws-lambda/releases/download/v1.1.0/run-command-on-aws-lambda.linux.x86_64
ADD ${WRAPPER} /usr/local/bin/run-command-on-aws-lambda
RUN chmod +x /usr/local/bin/run-command-on-aws-lambda

ENTRYPOINT [ "run-command-on-aws-lambda" ]

运行迁移

我们将这个镜像部署为AWS Lambda,包括AWS VPC配置,以便我们可以访问数据库。然后我们调用Lambda并提供所需信息。

在我们的Terraform配置中,我们通过环境变量调用Lambda,并为其提供数据库连接信息。

data "aws_lambda_invocation" "example" {
  depends_on    = [aws_lambda_function.migration]
  function_name = local.function_name
  input = jsonencode({
    program     = "dotnet"
    arguments   = ["DatabaseMigrations.dll"]
    environment = var.database_environment
  })
}

一旦Lambda调用完成,我们就继续设置或升级服务集群。如果Lambda调用失败,我们不会对集群进行任何更改。

依赖关系

~8–20MB
~273K SLoC