躲开Windows地雷使用AWS的Docker让你上天堂

Container会飞

在AWS ECS上目前有提供EC2 mode, Fargate, ECS Anywhere,分别为EC2执行Docker、Serverless方式去建立Container,以及云地混合执行Container,主要会以前两者去作深入探讨

EC2 mode

在EC2里执行Container,并透过ECS agent来确认目前执行的Container状态

运作方式

由Cluster做instance的管理以及服务功能的调用,Task则可以定义Instance里需要执行哪种Container以及数量,使用Cluster的Service指派哪个Instance去执行维护Task。主要以Cluster、Service和Task三者来建构出ECS这项服务,所以在撰写CDK时,就会需要用到这三个相关的API。

先来看Cluster的参数配置

cluster = ecs.Cluster(self, "Cluster", cluster_name="itdemo-cdk", vpc=vpc,
        capacity=ecs.AddCapacityOptions(
            can_containers_access_instance_role=True,
            instance_type=ec2.InstanceType("t3.micro"),
            desired_capacity=1,
            machine_image_type=ecs.MachineImageType.AMAZON_LINUX_2,
            key_name="itdemo",
            block_devices=[block]))

vpc:预设是跨两个AZ,两个public & subnet。这边VPC笔者采用新建立而非预设。
capacity:在ECS的cluster底下注册有安装ECS agent和Docker agent的EC2配置。
block_devices:配置EC2的硬碟空间

Cluster里的参数配置:vpc & block

vpc = ec2.Vpc(self, "vpc", 
        cidr="10.10.0.0/16",
        enable_dns_hostnames=True,
        enable_dns_support=True,
        max_azs=1,
        nat_gateways=0,
        subnet_configuration=[
            ec2.SubnetConfiguration(name="public1",
            subnet_type=ec2.SubnetType.PUBLIC,
            cidr_mask=24)
        ])

block = auto.BlockDevice(device_name="/dev/xvda",
volume=auto.BlockDeviceVolume.ebs(volume_size=30,volume_type=auto.EbsDeviceVolumeType.GP3), mapping_enabled=True)

vpc:建立一个public subnet
block:这里调用的library跟Day14/15,所用的不太一样,因为会把EC2注册到autoscaling group(ASG),会使用到autoscaling这个library,所以需要安装以及import。其他参数都跟前两天的雷同
volume_size:这边最低限制需要填30GB,否则在deploy的时侯会出现error

设定cluster SG的inbound rules

cluster.connections.allow_from_any_ipv4(ec2.Port.all_traffic())

配置TaskDefinition

task1 = ecs.TaskDefinition(self, "task-cdk",
        network_mode=ecs.NetworkMode.BRIDGE, 
        compatibility=ecs.Compatibility.EC2,
        cpu="256",
        memory_mib="512")

network_mode:这边采用Bridge的方式,透过EC2的网路来访问Container
compatibility:ECS EC2 mode
cpu:1vcpu = 1024。256 = 0.25vcpu
memory_mib:512MB

Container的设定

task1.add_container("Application",
        memory_limit_mib=128,
        # image=ecs.ContainerImage.from_registry("httpd:2.4"),
        image=ecs.ContainerImage.from_registry("johnson860312/awswebdb")
        # entry_point=["sh", "-c"],
        # command=["/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' > /usr/local/apache2/htdocs/index.html && httpd-foreground\""],
        ).add_port_mappings(ecs.PortMapping(container_port=80, 
        host_port=80, 
        protocol=ecs.Protocol.TCP))  

memory_limit_mib:限制最低的记忆体
image:选择想要的Container image,这里将Day4 build好的Container image push到自己的Docker hub中,所以这边使用同一个Container image
add_port_mappings这边采用的网路模式是Bridge可以透过EC2的port mapping到Container的port。可以透过EC2 public DNS/IP access Container,如下:
http://<EC2-DNS/IP>:

建立Service

ecs.Ec2Service(self, "Service",
        cluster=cluster,
        task_definition=task1,
        desired_count=1,
        service_name="SVC-CDK",
        ) 

desired_count:执行task的数量

结果

https://ithelp.ithome.com.tw/upload/images/20210930/201401723qr2kSX4Rb.png
https://ithelp.ithome.com.tw/upload/images/20210930/20140172BiVfXQ7Y6U.png

结论

在撰写CDK的同时,可以熟悉ECS上面的细节以及地雷,更加了解AWS的服务

程序码

from aws_cdk import core as cdk
from aws_cdk import (
    aws_ec2 as ec2,
    aws_ecs as ecs,
    aws_autoscaling as auto,
    core
)


class EcsTestStack(cdk.Stack):

    def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your stack goes here
        vpc = ec2.Vpc(self, "vpc", 
        cidr="10.10.0.0/16",
        enable_dns_hostnames=True,
        enable_dns_support=True,
        max_azs=1,
        nat_gateways=0,
        subnet_configuration=[
            ec2.SubnetConfiguration(name="public1",
            subnet_type=ec2.SubnetType.PUBLIC,
            cidr_mask=24)
        ])

        block = auto.BlockDevice(device_name="/dev/xvda",
        volume=auto.BlockDeviceVolume.ebs(volume_size=30, volume_type=auto.EbsDeviceVolumeType.GP3),
        mapping_enabled=True)

        cluster = ecs.Cluster(self, "Cluster", cluster_name="itdemo-cdk", vpc=vpc,
        capacity=ecs.AddCapacityOptions(
            can_containers_access_instance_role=True,
            instance_type=ec2.InstanceType("t3.micro"),
            desired_capacity=1,
            machine_image_type=ecs.MachineImageType.AMAZON_LINUX_2,
            key_name="itdemo",
            block_devices=[block]))
        
        cluster.connections.allow_from_any_ipv4(ec2.Port.all_traffic())
        
        task1 = ecs.TaskDefinition(self, "task-cdk",
        network_mode=ecs.NetworkMode.BRIDGE, 
        compatibility=ecs.Compatibility.EC2,
        cpu="256",
        memory_mib="512")
        
        task1.add_container("Application",
        memory_limit_mib=128,
        # image=ecs.ContainerImage.from_registry("httpd:2.4"),
        image=ecs.ContainerImage.from_registry("johnson860312/awswebdb")
        # entry_point=["sh", "-c"],
        # command=["/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' > /usr/local/apache2/htdocs/index.html && httpd-foreground\""],
        ).add_port_mappings(ecs.PortMapping(container_port=80, 
        host_port=80, 
        protocol=ecs.Protocol.TCP))        

        ecs.Ec2Service(self, "Service",
        cluster=cluster,
        task_definition=task1,
        desired_count=1,
        service_name="SVC-CDK",
        ) 

<<:  [Day 15] 阿嬷都看得懂的开始写第一支 .css 档案罗!

>>:  自动化 End-End 测试 Nightwatch.js 之踩雷笔记:getCssProperty()

Vuex 是什麽

Vuex 是 Vue 提供的一种资料状态管理的模式,它可以统一控管资料的状态,都是在小型的 SPA ...

Alpine Linux Porting (2.1) clock is _not_ ticking

这篇开始基本上是进入持续分析有哪些未完善的部份需要进行补足。 依照这几次的bootlog的部份分析,...

Day 17 - YOLO 相关概念说明

Day 17 - YOLO 相关概念说明 如果不说明一下 YOLO 的运作概念,对於如何调整 YOL...

DAY 21:Bridge Pattern,桥接人间与魔界的次元门

什麽是 Bridge Pattern? 将抽像与实现分离,让彼此变化互不影响 问题情境 PS5 有着...

Day9 重叠条件配对池 Overlapping MatchProfiles

在一些比较普通的应用场景,我们产生一个 matches 的流程会像是,由 Director 轮询呼叫...