文章目录
- [aws(学习笔记第五十课) ECS集中练习(2)](#aws(学习笔记第五十课) ECS集中练习(2))
- 学习内容:
-
- [1. 代码连接](#1. 代码连接)
-
- [1.1 代码链接](#1.1 代码链接)
- [2. 练习设定`ecs`的`placement`](#2. 练习设定
ecs
的placement
) -
- [2.1 全体架构](#2.1 全体架构)
- [2.2 全体代码](#2.2 全体代码)
- [2.3 执行代码](#2.3 执行代码)
- [2.4 检测`service`的运行实例数](#2.4 检测
service
的运行实例数) -
- [2.4.1 确认`service`的名字](#2.4.1 确认
service
的名字) - [2.4.2 确认`cluster`的名字](#2.4.2 确认
cluster
的名字) - [2.4.3 使用`cli`确认`service`的运行`count`数](#2.4.3 使用
cli
确认service
的运行count
数) - [2.4.4 增加`service`的运行`count`数](#2.4.4 增加
service
的运行count
数)
- [2.4.1 确认`service`的名字](#2.4.1 确认
- [3. 练习设定`ecs`的`network`](#3. 练习设定
ecs
的network
) -
- [3.1 全体架构](#3.1 全体架构)
- [3.2 代码](#3.2 代码)
- [3.3 执行代码,破碎的心](#3.3 执行代码,破碎的心)
- [3.4 尝试使用`NetworkMode.HOST`](#3.4 尝试使用
NetworkMode.HOST
) -
- [3.4.1 代码](#3.4.1 代码)
- [3.4.2 执行代码](#3.4.2 执行代码)
aws(学习笔记第五十课) ECS集中练习(2)
- 深入练习设定
ecs
的其他设定
学习内容:
- 练习设定
ecs
的placement
- 练习设定
ecs
的network
1. 代码连接
1.1 代码链接
2. 练习设定ecs
的placement
2.1 全体架构

这里对于使用了三种placement
:
PlacementConstaint.distinct_instances
: 强制同一个服务的多个任务必须运行在不同的ec2
实例上。PlacementStrategy.packed_by
: 将任务紧密打包到尽可能少的ec2
实例上,有限选择剩余资源最少的可用实例。PlacementStrategy.spread_accross
: 将任务均匀分散到不同的可用去(AZ
)。
2.2 全体代码
python
from aws_cdk import (
aws_autoscaling as autoscaling,
aws_ec2 as ec2,
aws_ecs as ecs,
App, Stack
)
app = App()
stack = Stack(app, "sample-ecs-task-placement")
# Create a cluster
vpc = ec2.Vpc(
stack, "Vpc",
max_azs=2
)
cluster = ecs.Cluster(
stack, "EcsCluster",
vpc=vpc
)
asg = autoscaling.AutoScalingGroup(
stack, "DefaultAutoScalingGroup",
instance_type=ec2.InstanceType("t2.micro"),
machine_image=ecs.EcsOptimizedImage.amazon_linux2(),
vpc=vpc,
)
capacity_provider = ecs.AsgCapacityProvider(stack, "AsgCapacityProvider",
auto_scaling_group=asg
)
cluster.add_asg_capacity_provider(capacity_provider)
# Create a task definition with placement constraints
task_definition = ecs.Ec2TaskDefinition(
stack, "TaskDef"
)
container = task_definition.add_container(
"web",
image=ecs.ContainerImage.from_registry("nginx:latest"),
memory_limit_mib=256,
)
port_mapping = ecs.PortMapping(
container_port=80,
host_port=8080,
protocol=ecs.Protocol.TCP
)
container.add_port_mappings(port_mapping)
# Create Service
service = ecs.Ec2Service(
stack, "Service",
cluster=cluster,
task_definition=task_definition,
placement_constraints=[
ecs.PlacementConstraint.distinct_instances()
]
)
service.add_placement_strategies(
ecs.PlacementStrategy.packed_by(ecs.BinPackResource.MEMORY))
service.add_placement_strategies(
ecs.PlacementStrategy.spread_across(
ecs.BuiltInAttributes.AVAILABILITY_ZONE))
app.synth()
2.3 执行代码
python
python -m venv ./.venv
source ./.venv/Scripts/activate
pip install -r requirements.txt
cdk --require-approval never deploy

2.4 检测service
的运行实例数
2.4.1 确认service
的名字
进入cluster
-->service
,可以看到选择的部分即为service name
2.4.2 确认cluster
的名字
进入cluster
,可以看到选择的部分即为cluster name
。
2.4.3 使用cli
确认service
的运行count
数
shell
$ aws ecs describe-services \
--cluster sample-ecs-task-placement-EcsCluster97242B84-UPtLnBUmifKa \
--services sample-ecs-task-placement-ServiceD69D759B-zq6tlpUpZQBy \
--query "services[0].runningCount"
1
可以看出,service
的执行count
数是1,因为在service
创建的时候,没有指定desired_count
,所以默认是1
。
2.4.4 增加service
的运行count
数
python
service = ecs.Ec2Service(
stack, "Service",
cluster=cluster,
desired_count=2,
task_definition=task_definition,
placement_constraints=[
ecs.PlacementConstraint.distinct_instances()
]
)
这里,增加service
的属性desired_count=2
。
3. 练习设定ecs
的network
3.1 全体架构

3.2 代码
python
from aws_cdk import (
aws_autoscaling as autoscaling,
aws_ec2 as ec2,
aws_ecs as ecs,
App, Stack,
aws_iam as iam,
)
# Based on https://aws.amazon.com/blogs/compute/introducing-cloud-native-networking-for-ecs-containers/
app = App()
stack = Stack(app, "ec2-service-with-task-networking")
# Create a cluster
vpc = ec2.Vpc(
stack, "Vpc",
max_azs=2
)
cluster = ecs.Cluster(
stack, "awsvpc-ecs-demo-cluster",
vpc=vpc
)
ecs_role = iam.Role(
stack, "EcsInstanceRole",
assumed_by=iam.ServicePrincipal("ec2.amazonaws.com"),
managed_policies=[
iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AmazonEC2ContainerServiceforEC2Role")
]
)
# 替换 AutoScalingGroup 的启动配置为启动模板
launch_template = ec2.LaunchTemplate(
stack, "LaunchTemplate",
instance_type=ec2.InstanceType("t2.micro"),
machine_image=ecs.EcsOptimizedImage.amazon_linux2(),
security_group=ec2.SecurityGroup(stack, "SG", vpc=vpc),
user_data=ec2.UserData.for_linux(),
role = ecs_role
)
asg = autoscaling.AutoScalingGroup(
stack, "DefaultAutoScalingGroup",
launch_template=launch_template,
vpc=vpc,
vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC),
)
capacity_provider = ecs.AsgCapacityProvider(stack, "AsgCapacityProvider",
auto_scaling_group=asg
)
cluster.add_asg_capacity_provider(capacity_provider)
# Create a task definition with its own elastic network interface
task_definition = ecs.Ec2TaskDefinition(
stack, "nginx-awsvpc",
network_mode=ecs.NetworkMode.AWS_VPC,
)
web_container = task_definition.add_container(
"nginx",
image=ecs.ContainerImage.from_registry("nginx:latest"),
cpu=100,
memory_limit_mib=256,
essential=True
)
port_mapping = ecs.PortMapping(
container_port=80,
protocol=ecs.Protocol.TCP
)
web_container.add_port_mappings(port_mapping)
# Create a security group that allows HTTP traffic on port 80 for our
# containers without modifying the security group on the instance
security_group = ec2.SecurityGroup(
stack, "nginx--7623",
vpc=vpc,
allow_all_outbound=False
)
security_group.add_ingress_rule(
ec2.Peer.any_ipv4(),
ec2.Port.tcp(80)
)
# Create the service
service = ecs.Ec2Service(
stack, "awsvpc-ecs-demo-service",
cluster=cluster,
task_definition=task_definition,
security_groups=[security_group]
)
app.synth()
这里,可以为service
设定专门的security group
,期待执行之后,通过http://{ec2_ip}:80
能访问创建的nginx
服务。但是事实上心如所愿吗?
3.3 执行代码,破碎的心
执行cdk --require-approval never deploy
,之后访问http://{ec2_ip}:80
,非常遗憾,不能访问这个网页。
知之为知之,不知ai
知。
通过ai
,很快知道aws
中的ecs ec2
下支持两种网络模式。
# | 模式 | 说明 | 代码注意点 |
---|---|---|---|
1 | HOST | host 网络模式(直接通过 EC2 IP 访问) | security_group设定在launchTemplate上 allow_all_outbound=True 使用network_mode=ecs.NetworkMode.HOST |
2 | AWS_VPC | awsvpc 模式 + 添加 ALB(推荐生产环境) | security_group设定在service上 allow_all_outbound=false 使用network_mode=ecs.NetworkMode.AWS_VPC |
3.4 尝试使用NetworkMode.HOST
3.4.1 代码
python
from aws_cdk import (
aws_autoscaling as autoscaling,
aws_ec2 as ec2,
aws_ecs as ecs,
App, Stack,
aws_iam as iam,
)
# Based on https://aws.amazon.com/blogs/compute/introducing-cloud-native-networking-for-ecs-containers/
app = App()
stack = Stack(app, "ec2-service-with-task-networking")
# Create a cluster
vpc = ec2.Vpc(
stack, "Vpc",
max_azs=2
)
cluster = ecs.Cluster(
stack, "awsvpc-ecs-demo-cluster",
vpc=vpc
)
ecs_role = iam.Role(
stack, "EcsInstanceRole",
assumed_by=iam.ServicePrincipal("ec2.amazonaws.com"),
managed_policies=[
iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AmazonEC2ContainerServiceforEC2Role")
]
)
# Create a security group that allows HTTP traffic on port 80 for our
# containers without modifying the security group on the instance
security_group = ec2.SecurityGroup(
stack, "nginx--7623",
vpc=vpc,
allow_all_outbound=True
)
security_group.add_ingress_rule(
ec2.Peer.any_ipv4(),
ec2.Port.tcp(80)
)
# 替换 AutoScalingGroup 的启动配置为启动模板
launch_template = ec2.LaunchTemplate(
stack, "LaunchTemplate",
instance_type=ec2.InstanceType("t2.micro"),
machine_image=ecs.EcsOptimizedImage.amazon_linux2(),
#security_group=ec2.SecurityGroup(stack, "SG", vpc=vpc),
security_group=security_group,
user_data=ec2.UserData.for_linux(),
role = ecs_role
)
asg = autoscaling.AutoScalingGroup(
stack, "DefaultAutoScalingGroup",
launch_template=launch_template,
vpc=vpc,
vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC),
)
capacity_provider = ecs.AsgCapacityProvider(stack, "AsgCapacityProvider",
auto_scaling_group=asg
)
cluster.add_asg_capacity_provider(capacity_provider)
# Create a task definition with its own elastic network interface
task_definition = ecs.Ec2TaskDefinition(
stack, "nginx-awsvpc",
network_mode=ecs.NetworkMode.HOST,
)
web_container = task_definition.add_container(
"nginx",
image=ecs.ContainerImage.from_registry("nginx:latest"),
cpu=100,
memory_limit_mib=256,
essential=True
)
port_mapping = ecs.PortMapping(
container_port=80,
protocol=ecs.Protocol.TCP
)
web_container.add_port_mappings(port_mapping)
# Create the service
service = ecs.Ec2Service(
stack, "awsvpc-ecs-demo-service",
cluster=cluster,
task_definition=task_definition,
#security_groups=[security_group]
)
app.synth()
3.4.2 执行代码
shell
python -m venv ./.venv
source ./.venv/Scripts/activate
pip install -r requirements.txt
cdk --require-approval never deploy

访问http://35.78.68.247:80
,可以看到正常打开。
接下来的练习:未完待续。。。
- 如何使用
nlb
+farget service
- 设定
fargate
的AutoScaling policy
- 设定
fargate
的efs