Amazon ECS Bottlerocket 简介: 在 Bottlerocket 上运行容器和任务 (Task)

Amazon ECS Bottlerocket 简介: 在 Bottlerocket 上运行容器和任务 (Task)

Amazon Elastic Container Service (ECS) 是用于管理在 Amazon Web Services (AWS) 上以容器化方式运行的容器调度服务。类似于 Kubernetes、Docker Swarm 等集成方案,Amazon ECS 提供了一种简单的功能性来帮助你启动和扩展容器化应用程序,这样简单的特性使得 ECS 成为许多企业用户快速且有效部署其容器应用程序的理想选择。

Bottlerocket 则是由 AWS 发布以 Linux 为基础的一个新的开源操作系统,专为运行容器而设计。在本篇内容,我们将延伸简介如何在 Amazon ECS 使用 Bottlerocket 操作系统启动容器任务 (Task)。

简介

Amazon ECS Bottlerocket 概览

Bottlerocket 旨在提供安全且高效、适用于运行容器执行环境优化的操作系统。提供一个轻量、不可任意修改且易于更新的操作系统,以适合大规模运行容器工作负载时使用。通过在 Amazon ECS 中使用 Bottlerocket,由于他仅提供最基本所有运行容器环境的执行需求,最主要的优化将是减少系统和容器启动的时间。

使用 Bottlerocket 和 Amazon ECS 的好处 (与一般的 ECS-optimized AMI 的区别)

最主要区别在于 Bottlerocket 以安全及轻量为宗旨设计,因此,如果你是第一次使用,通常会注意到一些显著的安全性功能差异。例如以下是在使用该 Bottlerocket 时需要知道的一些注意事项:

  • Bottlerocket 的文件系统 (Root filesystem) 被是只读 (Read-only),不能被 User space 的应用程序 (一般的 process) 直接修改。
  • 默认并没有开启 SSH 功能,除非有设定,否则无法直接 SSH 运行 Bottlerocket 的环境中。

开始使用 Bottlerocket

接下来就让我们来看看如何着手运行第一个以 Bottlerocket 为执行基础的容器部署环境。

创建 Task definition

要使用 Amazon ECS 和 Bottlerocket 启动容器应用,首先,你会需要先创建一个任务定义 (Task definition),这个 Task definition 用于描述容器化应用程序 (包含:Image、CPU、Memory 等规格)。

如果您过去使用过并且已经熟悉 Amazon ECS,则在 Task definition 的创建过程中与使用一般的 ECS-optimized AMI 没有区别,运行于 Bottlerocket 环境中通常并不需要做任何修改。如果您已经有 Task definition,则可以跳过到下一部分。

任务定义 (Task definition) 可以视为一个在 Amazon ECS 上运行你容器蓝图,用于描述容器规格和运行方式。在 Amazon ECS 上,容器应该被封装为运行单元,称为任务 (Task),这就是为什么我们需要有一个任务定义 (Task definition) 的原因。在任务定义 (Task definition) 中,您可以指定应用程序需要运行的 Image、资源、环境变量和其他设置。完成定义后,您可以创建一个任务 (ECS Task),这时候你的容器才会真正被运行。

让我们首先创建一个任务定义 (Task definition)。只需前往 Task definition 页面,然后选择 Create new task definition with JSON 创建:

Create new task definition with JSON

这个范例中,描述了如何启动一个容器并且使用我自定义的 Image (easoncao/ecs-demo-app),请求了 128 vCPU 单位的 CPU 资源和 128 MB 单位的内存资源。并且将 hostPort 设置为 0,以将容器服务的端口 (Port) 80 对应到到在 EC2 instance 上会启动的动态端口 (Port),当在 Bottlerocket instance 上运行任务时,这可以将容器服务公开到这个动态的端口设定。以下是我的 Task definition 相关 JSON 片段:

{
    "containerDefinitions": [
        {
            "name": "demo",
            "image": "easoncao/ecs-demo-app:latest",
            "cpu": 128,
            "memory": 128,
            "portMappings": [
                {
                    "containerPort": 80,
                    "hostPort": 0,
                    "protocol": "tcp"
                }
            ],
            "essential": true
        }
    ],
    "family": "easontechtalk-demo",
    "requiresCompatibilities": [
        "EC2"
    ]
}

在此任务定义 (Task definition) 中,我们定义了一个名为 demo 的容器,该容器使用 easoncao/ecs-demo-app 运行,并且有 128 vCPU128 MB 的资源使用单位。此外,我们还将容器端口 (Port) 80 对应到主机端口 0,并使用 TCP 协议。

完成创建后,后续你就可以使用这个任务定义 (Task definition) 来运行 ECS Task。

创建一个 ECS cluster

为了使用 Bottlerocket 启动 ECS Task,你同时也会需要创建一个 ECS Cluster 并将使用 Bottlerocket 为操作系统基础的 EC2 instances 注册到其中。

如果你是使用新版的 ECS Cosnole,新的 ECS Console 简化了创建的使用体验。要创建一个 ECS Cluster,你可以前往 ECS Console,选择 Clusters 并点击 Create cluster 按钮,即可按照说明步骤完成创建:

Create an ECS Cluster in ECS Console

如果你偏好使用 CLI,也可以使用 AWS CLI 提供的 ECS 命令1 完成。以下是在 eu-west-1 区域中创建一个名为 easontechtalk-bottlerocket 的 ECS Cluster 资源的范例命令:

aws ecs create-cluster --cluster-name easontechtalk-bottlerocket --region eu-west-1

如果你是使用 AWS 控制台 (ECS Console),在创建阶段的 Infrastructure 选项底下下,可以勾选 Amazon ECS instances 选项,这个选项会提示你设定 EC2 Auto Scaling Group 和启动 EC2 instances 的细节。要使用 Bottlerocket 启动,选择 Create new ASG 会有 Operating system/Architecture 一栏出现选项供你选择 Bottlerocket 作为您的操作系统:

Create cluster and select Bottlerocket OS

但如果你想自己启动 EC2 instances,也可以稍后参考后面的步骤再创建这些资源。

注册 Bottlerocket instances

如果你要自己启动 EC2 instance,首先第一步是需要找到不同 AWS 区域中提供对应最新版的 Bottlerocket AMI ID。这部分你可以使用 AWS CLI 命令或使用 AMI 对应的快速链接2来获得 AMI ID 的信息。以下是几个范例和 AWS CLI 命令:

https://console.aws.amazon.com/systems-manager/parameters/aws/service/bottlerocket/aws-ecs-1/x86_64/latest/image_id/description?region=<REGION>#

例如,以下是在 eu-west-1 地区取得最新的 Bottlerocket x86_64 AMI ID 的范例。在这个范例中返回了 AMI ID ami-0d5571466e5537410

(AWS CLI)

aws ssm get-parameter --region eu-west-1 \
    --name "/aws/service/bottlerocket/aws-ecs-1/x86_64/latest/image_id" \
        --query Parameter.Value --output text

# Output
ami-0d5571466e5537410

在取得 Bottlerocket 操作系统的 AMI ID 之后,下一个步骤便是启动 EC2 instance,并通过内建的启动程序机制自动的将 EC2 instance 注册到我们前面创建的 ECS Cluster 中 (easontechtalk-bottlerocket)。你可以前往启动 EC2 实例的页面,并输入刚刚取得的 AMI ID 信息,并且选择它:

Select Bottlerocket AMI Using Bottlerocket AMI Overview

在设定的页面也记得确保选择了必须的 IAM Profle (IAM Role),以允许 EC2 instance 启动阶段有权限具备注册到 ECS Cluster 的权限 (名称通常是 ecsInstanceRole。有关如何检查 IAM Role 的详细信息,请参考3)。

此外,要特别注意的地方是,如果你过去熟悉如何使用一般的 ECS-optimized AMI 注册 EC2 instance 至 ECS Cluster,使用 Bottlerocket 系统的区别在于 UserData 内容:

(General ECS-optimized AMI)

#!/bin/bash
echo "ECS_CLUSTER=CLUSTER_NAME" >> /etc/ecs/ecs.config

(Bottlerocket AMI: 如果你使用 Bottlerocket 需要使用这个方法启动)

[settings.ecs]
cluster = "CLUSTER_NAME"

请将 CLUSTER_NAME 替代为您自己的集群名称。在这个范例中,我将我的集群名称(easontechtalk-bottlerocket)贴到高级选项 (Advanced details) 中的 UserData 设定:

Configure UserData for Bottlerocket AMI Bootstrapping process

一旦 EC2 Instance 成功启动,将会自动注册到 ECS Cluster 并且加入到集群中。要检查 EC2 instance 是否有加入 ECS Cluster,你也可以在 ECS Console 中的 Infrastructure 选项中查看到详细的信息:

View the container instance

在 Bottlerocket 上运行一个 ECS Task

现在,你可以直接通过 ECS Console 上运行 ECS Task,点击 Run new task

Run new task

在详细设定页面中,我选择了前面步骤所创建的任务定义 (Task definition) 版本,然后在 Desired Tasks 选项中,指定运行 1 个 ECS Task 任务数量:

Run new task detail

一旦 ECS Task 启动,可以通过 ECS Console 或 AWS CLI 来监控容器运行的状态状态。如果在主控台页面,你可以直接点击 ECS Task 的详细信息,以查看更多容器的详细信息,甚至可以获取我们前面所设定有关网络相关的选项,可以看到容器对应的端口 (Container Port 以及 Host Port)。

在这个范例中,我的容器部署在 Bottlerocket instance 上,并公开服务端口 (Port) 49153

View container network binding detail

因为 ECS task 使用的是默认的容器 bridge 网络,要测试应用,我可以直接访问 EC2 instance 对应的公开 IP 地址,并且使用 ECS 上面所分配的动态端口 (49153) 来连接我的容器。要注意由于端口可能是动态的,需要确保在你尝试连接到容器之前,需要设定好对应的 Security Group (安全组) 防火墙规则,以允许你的用户端请求通过访问。

如果你使用这个范例的 Task definition 并且正确连接上,这个范例程序会通过网页显示 ECS Task 的详细信息:

View the task service web page

总结

在这篇内容中,简介了 AWS 所发布的 Bottlerocket 操作系统、简介 Bottlerocket 以轻量和安全为设计诉求所带来跟一般 ECS-optimized AMI 的显著差异。并且分享了如何 Amazon ECS 上使用 Bottlerocket 操作系统运行一个容器应用程序 (ECS Task),并且了解相关流程。

参考资源

Eason Cao
Eason Cao Eason is an engineer working at FANNG and living in Europe. He was accredited as AWS Professional Solution Architect, AWS Professional DevOps Engineer and CNCF Certified Kubernetes Administrator. He started his Kubernetes journey in 2017 and enjoys solving real-world business problems.
comments powered by Disqus