宣布在 亚马逊云科技 Fargate 上为亚马逊 ECS 任务提供更多 Linux 控件

简介

亚马逊弹性容器服务 ( Amazon ECS ) 任务是计划在 亚马逊云科技 Fargate 或 A mazon EC2 容器 实例 上运行的多个共存容器。 容器使用 Linux 命名空间 来提供工作负载隔离以及命名空间,尽管容器在 Amazon ECS 任务中一起调度,但它们仍然相互隔离,也与主机隔离。

今天我们很高兴地宣布,客户现在可以在 亚马逊云科技 Fargate 上的 ECS 任务中调整 Linux 内核参数。调整 Linux 内核参数可以帮助客户在运行容器化 网络代理 时优化网络吞吐量 ,或者通过 终止 陈旧的连接来实现更高水平的工作负载弹性。 此次启动为在 亚马逊云科技 Fargate 和 Amazon EC2 容器实例上启动的 ECS 任务提供了对等性。

此外,随着今天的发布,进程 ID (PID) 命名空间现在可以由 亚马逊云科技 Fargate 上同一 ECS 任务中的所有容器共享。在同一 ECS 任务中的容器之间共享 PID 命名空间可在 亚马逊云科技 Fargate 上获得额外的负载可观测性。可观测性工具,例如容器运行时安全工具,现在可以作为副车容器运行,并在共享 PID 命名空间中观察应用程序的进程。PID 命名空间将与 awsvpc 联网模式 一起使用的网络命名空间加入命名空间列表中 ,该命名空间可由所有容器在 亚马逊云科技 Fargate 上的 ECS 任务中共享。

在这篇文章中,我们将深入探讨 亚马逊云科技 Fargate 上的系统控制和 PID 命名空间共享。

系统控制

在 Linux 系统中,可以使用命令行实用程序 sysc tl 调整内核的参数。在本地启动容器时,例如使用 Docker finch 命令行界面,您可以传入 --sysctl 标志来更改内核参数。在 ECS 任务中,可以使用 “ 任务定义” 中的 S ystemControl 键定义 参数。

在 AWS Fargate 上运行容器化网络代理的客户 告诉我们 , 他们经常需要调整网络。 * 内核参数,允许其工作负载达到更高的吞吐量需求。 经常请求的内核参数包括与 net.core.somaxconn 的最大排队连接数 以及使用 net.ipv4.ip_local_port _range 的临时临时端口范围。

在架构工作负载以实现弹性时,客户还告诉我们,他们希望在 亚马逊云科技 Fargate 上自定义 ECS 任务的 TCP 保持活动参数。配置较短的 TCP 保持活动超时允许应用程序快速检测网络故障,关闭现有的失败连接。何时调整 TCP 保持活动状态的示例包括当容器化工作负载与 Amazon Aurora PostgreSQL 集群通信时, 以及对 Amazon VPC NAT 网关进行 故障排除 时。

在此次发布之前,S ystemControl 密钥仅适用于在 EC2 容器实例上运行 ECS 任务的客户,但现在该密钥可用于 亚马逊云科技 Fargate 上的 ECS 任务。调整了两个参数的 Amazon ECS 任务定义示例摘要如下所示:

{
    ...
    "containerDefinitions": [
        {
            "name": "myproxy",
            "image": "111222333444.dkr.ecr.eu-west-1.amazonaws.com/myproxy:latest",
            "essential": true,
            "systemControls": [
                {
                    "namespace": "net.core.somaxconn",
                    "value": "6000"
                },
                {
                    "namespace": "net.ipv4.ip_local_port_range",
                    "value": "1024    65000"
                }
            ]
        }
    ]
}

亚马逊云科技 Fargate 和亚马逊 EC2 容器实例上的 ECS 任务可用的完整参数列表可在亚马 逊 ECS 文档中找到。

如果您在 IPC 命名空间中使用内核参数,则可以为任务中的每个容器设置唯一值,因为 IPC 命名空间不共享。但是,如果您在网络命名空间中使用参数,则为一个容器设置参数会更改任务中所有容器的参数,因为这是一个共享命名空间。要对此进行扩展:

  • 如果在容器一中设置了 net.ipv4.tcp_keepalive_time=100, 则此更改也会 反映在容器二中。
  • 如果在容器一中设置了 net.ipv4.tcp_keepalive_time=100 ,并且在容器二中设置了 net.ipv4.tcp_keepalive_time =200,则命名空间的参数将设置为任务中最后启动的容器。

共享进程 ID 命名空间

进程 ID 命名空间限制了容器中进程可以看到的内容。默认情况下,容器化进程只能看到同一个容器中的进程,不能看到其他同置容器或底层主机的进程。共享进程 ID 命名空间的一个常见用例是可观察性工具。容器运行时安全工具通常在侧车容器中运行,需要观察应用程序容器中的进程。在这种模式下,侧车容器中的进程监视应用程序容器中的进程,以查看它们是否开始进行可疑的系统调用。

随着今天的发布,客户现在可以通过在任务定义中传递 PidMod e 密钥和值 任务来在同一 ECS 任务中的容器之间共享进程 ID 命名空间。

草率排练

在本演练中,我们将启动具有共享进程 ID 命名空间的 ECS 任务。该任务包含两个容器,一个应用程序容器 (nginx) 和一个 sidecar 容器(用作演示的睡眠进程)。然后,我们将展示边车容器中的进程如何与应用程序容器中的进程进行交互。

Prerequisites
  • 现有的亚马逊 ECS 集群和亚马逊 VPC。如果您需要在自己的 亚马逊云科技 账户中创建这些账户,请参阅 A mazon ECS 入门指南
  • 确保您 的 亚马逊云科技 账户和计划 执行命令的工作站上满足 ECS 执行先决条件
Run an ECS task on 亚马逊云科技 Fargate

1。使用两个容器创建任务定义,并启用 PidMode 。您需要将任务定义中的 IAM 角色(e xecutionroLearn TaskroLearn )替换为在先决条件中创建的 IAM 角色。

$ cat <<EOF > taskdef.json 
{
    "family": "fargatepidsharing",
    "executionRoleArn": "arn:aws:iam::111222333444:role/ecsTaskExecutionRole",
    "taskRoleArn": "arn:aws:iam::111222333444:role/ecsTaskExecRole",
    "networkMode": "awsvpc",
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "containerDefinitions": [
        {
            "name": "nginx",
            "image": "public.ecr.aws/nginx/nginx:1.25-perl",
            "essential": true
        },
        {
            "name": "sleeper",
            "image": "public.ecr.aws/amazonlinux/amazonlinux:2",
            "essential": true,
            "command": [
                "sleep",
                "infinity"
            ],
            "linuxParameters": {
                "initProcessEnabled": true
            }
        }
    ],
    "cpu": "256",
    "memory": "512",
    "pidMode": "task"
}
EOF

2。使用 aws ecs register-task- definition 命令注册任务 定义。

$ aws ecs register-task-definition \
    --cli-input-json file://taskdef.json

3。使用 aws ecs r un -task 命令在 AWS Fargate 上运行 Amazon EC S 任务。在以下示例中,替换 ECS 集群名称、VPC 子网和安全组值。由于无法从外部访问此任务,因此私有 VPC 子网和没有入口规则的安全组(例如默认 VPC 安全组)就足够了。

$ aws ecs \
    run-task \
    --count 1 \
    --launch-type FARGATE \
    --task-definition fargatepidsharing \
    --cluster mycluster \
    --enable-execute-command \
    --network-configuration "awsvpcConfiguration={subnets=["subnet-07bd4d10ea848a008"],securityGroups=[sg-061b33f4ed6b97c34],assignPublicIp=DISABLED}"

4。ECS 任务运行后,使用 aws ecs execute-command 命令在 EC S 任务中的 sidecar 容器中创建终端会话。如果您在运行此命令时收到错误,则可以使用 amazon-ecs-exec-checker 脚本来确保满足所有先决条件。

# Retrieve the ECS task ID
$ aws ecs list-tasks \
     --cluster mycluster
{
    "taskArns": [
        "arn:aws:ecs:us-west-2:111222333444:task/moira-prod/5ce56f226dd4477a9f57918a98fc852f"
    ]
}

# Exec into the running ECS task
$ aws ecs execute-command \
    --cluster mycluster \
    --task 5ce56f226dd4477a9f57918a98fc852f \
    --container sleeper \
    --interactive \
    --command "/bin/bash"

5。在 ECS 执行终端会话中,我们现在可以探索共享的 PID 命名空间。为此,我们需要在 sidecar 容器内安装一些诊断工具。

$ yum install procps strace -y

6。使用 ps 命令(包含在上面安装的 procps 包中),我们可以看到共享 PID 命名空间中所有正在运行的进程。输出显示来自 sidecar 容器的进程以及来自应用程序容器的 nginx 进程。还显示了用于提供 EC S 执行终端的 亚马逊云科技 系统管理会话管理器 进程。

$ ps -aef –-forest
UID        PID  PPID  C STIME TTY          TIME CMD
root        38     0  0 09:53 ?        00:00:00 /managed-agents/execute-command/amazon-ssm-agent
root        72    38  0 09:53 ?        00:00:00  \_ /managed-agents/execute-command/ssm-agent-worker
root        34     0  0 09:53 ?        00:00:00 /managed-agents/execute-command/amazon-ssm-agent
root        73    34  0 09:53 ?        00:00:00  \_ /managed-agents/execute-command/ssm-agent-worker
root       266    73  0 09:58 ?        00:00:00      \_ /managed-agents/execute-command/ssm-session-worker ecs-execute-command-0147ec3fd84d94d24
root       276   266  0 09:58 pts/1    00:00:00          \_ /bin/bash
root       286   276  0 09:59 pts/1    00:00:00              \_ ps -aef –forest
root         8     0  0 09:53 ?        00:00:00 /dev/init -- sleep infinity
root        19     8  0 09:53 ?        00:00:00  \_ sleep infinity
root         7     0  0 09:53 ?        00:00:00 nginx: master process nginx -g daemon off;
101         56     7  0 09:53 ?        00:00:00  \_ nginx: worker process
101        285     7  0 09:59 ?        00:00:00  \_ nginx: worker process
root         1     0  0 09:53 ?        00:00:00 /pause

7。使用共享的 PID 命名空间,我们可以监控应用程序容器中进程发出的系统调用。我们将使用在第五步中安装的 strace 包来监控 nginx 主进程。 为了生成系统调用,我们将使用 kill 命令强制停止 nginx 工作进程。 就我而言,主要 nginx 进程是进程 ID 7,工作进程是进程 ID 56,它们在你的环境中会有所不同,需要在下面的命令中替换。

# Start the process monitoring
$ strace -p 7 -o straceoutput.txt &
# Stop an nginx worker process
$ kill -9 56
# Show the process monitoring logs
$ cat straceoutput.txt
rt_sigsuspend([], 8)                    = ? ERESTARTNOHAND (To be restarted if no handler)
<snipped>

在本演练中,我们已经表明,通过共享进程 ID 命名空间,sidecar 容器中的进程现在可以与 ECS 任务中所有容器中所有正在运行的进程进行交互和观察。在第七步中,我们使用边车容器来监视并强制停止应用程序容器中的进程。

Cleanup

要清理此演练,请执行以下操作:

1。在终端窗口中运行带有打开会话的 退出 命令,退出 ECS 执行终端。

2。使用 aws ecs 停止任务命令 停止 EC S 任务

$ aws ecs stop-task \
    --cluster mycluster \
    --task 5ce56f226dd4477a9f57918a98fc852f

3。使用 aws ecs deregister-task-definition 命令 取消注册 EC S 任务定义。

$ aws ecs deregister-task-definition \
    --task-definition fargatepidsharing:1

共享进程 ID 命名空间的注意事项

虽然进程 ID 命名空间现在可以由 亚马逊云科技 Fargate 上同一 ECS 任务中的容器共享,但有几点需要注意。我们将在先前定义的应用程序和 sidecar ECS 任务的上下文中介绍这些注意事项:

  • Sidecar 容器中的进程可以在应用程序容器中观察、停止或重新启动进程。
  • Sidecar 容器中的进程可以查看应用程序容器的文件系统。 例如,如果应用程序以进程 ID 7 运行,则在 sidecar 容器中,您可以通过 /proc/7/root/ 访问应用程序容器的文件系统。 应用程序容器文件系统的唯一保护将通过 Unix 文件权限来完成。
  • 在 ECS 任务中共享进程时,新的 暂停 进程以 PID 1 的形式运行整个任务。
  • 可能需要将 SYS_PTRACE Linux 功能添加到 ECS 任务中,以提供应用程序容器中运行的进程的完全可追溯性。

结论

通过此次发布,我们很高兴能在 亚马逊云科技 Fargate 上解锁更多工作负载。共享进程 ID 命名空间和调整内核参数都是通过 亚马逊云科技 Fargate 的 亚马逊云科技 容器路线图 请求 的功能。我们重视您的反馈,欢迎您将任何其他功能请求或改进作为 GitHub 问题提交路线图。有关 亚马逊云科技 Fargate 安全架构的更多信息,请参阅 AW S Far gate 安全白皮书。

Olly Pomeroy

Olly Pomeroy

Olly 是亚马逊网络服务的开发者倡导者。他是容器团队的一员,负责开发 亚马逊云科技 Fargate、容器运行时和容器相关项目。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。