반응형
250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- JavaScript
- 유니티
- API
- ssh
- logstash
- nodejs
- 영어
- docker
- Git
- error
- MySQL
- Linux
- elasticsearch
- sample
- s3
- build
- mariadb
- AWS
- 엘라스틱서치
- unity
- Ai
- MSSQL
- Python
- Windows
- 구글
- ChatGPT
- JS
- Kibana
- 설정
Archives
- Today
- Total
가끔 보자, 하늘.
CDK로 AWS 인프라 구축하기 - #4 ECS Cluster 구성 본문
이번에는 ECS를 사용해 간단한 웹 서비스를 구성하는 방법을 살펴 보겠습니다.
웹 서비스는 사내에서 docker로 빌드되어 ECR로 업데이트 되어 있다고 가정하고 아래와 같은 절차를 통해 웹 서비스가 된다고 가정합니다.
- ECS Cluster의 Task들은 private subnet에서 실행되므로 ECR 접근을 위해 VPC Endpoint를 사용합니다.(참고 문서 링크)
- 유저들은 public subnet에 설치된 ALB(80 Port)로 접속을 시도 (실 서비스에서는 앞 단에 Route53을 설정하겠지만 여기서는 ALB로 바로 연결한다고 가정합니다.)
- ALB는 private subnet의 ECS Cluster(3000 Port)로 포워딩합니다.
이를 간단히 도식화하면 아래와 같습니다.
아래 예제 코드 중 VPC와 Security Group는 이전 문서(VPC , SG)를 참고하세요. ECS 관련 공식 문서(ECS, ECR)에서 상세한 정보를 확인할 수 있습니다.
우선 ecs를 빌드할 함수를 정의합니다. 인자는 이전에 생성해 둔 vpc와 sg 리스트를 전달하겠습니다.
.
.
// interval 지정을 위해 Duration 추가
import { Duration, Stack, StackProps } from 'aws-cdk-lib';
// ecr, ecs libs
import * as ecr from "aws-cdk-lib/aws-ecr";
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2';
.
.
build_ecs(vpc:ec2.Vpc, listSG: {[name:string] : ec2.SecurityGroup}){
// vpc에서 private subnet을 리스트로 가져옵니다.
const subnetIds: string[] = [];
vpc.privateSubnets.forEach((subnet, index) => {
subnetIds.push(subnet.subnetId);
});
.
.
.
}
ECS에서 task를 생성하려면 ECR로부터 등록된 docker 이미지를 가져와야 합니다. 이를 위해서는 private subnet에서 ECR로 접근할 수 있도록 ecr.api , ecr.dkr, logs 서비스를 사용할 수 있는 VPC endpoint를 설정해야 합니다.
.
.
// ECR 접근을 위한 VPC endpoint 설정
const cfnVPCEndpoint_api = new ec2.CfnVPCEndpoint(this, 'ecs2ecr-api',{
serviceName: 'com.amazonaws.ap-northeast-2.ecr.api',
vpcId: vpc.vpcId,
privateDnsEnabled: true,
subnetIds : subnetIds,
securityGroupIds: [listSG.web_3000_for_private.securityGroupId],
vpcEndpointType: "Interface"
});
const cfnVPCEndpoint_dkr = new ec2.CfnVPCEndpoint(this, 'ecs2ecr-dkr',{
serviceName: 'com.amazonaws.ap-northeast-2.ecr.dkr',
vpcId: vpc.vpcId,
privateDnsEnabled: true,
subnetIds : subnetIds,
securityGroupIds: [listSG.web_3000_for_private.securityGroupId],
vpcEndpointType: "Interface"
});
const cfnVPCEndpoint_logs = new ec2.CfnVPCEndpoint(this, 'ecs2logs',{
serviceName: 'com.amazonaws.ap-northeast-2.logs',
vpcId: vpc.vpcId,
privateDnsEnabled: true,
subnetIds : subnetIds,
securityGroupIds: [listSG.web_3000_for_private.securityGroupId],
vpcEndpointType: "Interface"
});
.
.
그리고 ECR의 저장소를 지정합니다.
.
// 가져올 이미지의 저장소 위치
const repository = ecr.Repository.fromRepositoryName(
this,
"your_aws_id",
"repository_name"
);
.
ECS Cluster를 생성하고 task를 정의합니다.
.
// ECS Cluster를 생성합니다.
const cluster_web = new ecs.Cluster(this, 'hello-web', {
clusterName: 'hello-web',
containerInsights: false,
enableFargateCapacityProviders: false,
vpc : vpc,
});
// cluster의 capacity 설정
cluster_web.addCapacity('hello-web', {
instanceType: new ec2.InstanceType("t2.small"),
desiredCapacity: 1, // 초기 instance 생성 개수
maxCapacity: 2,
minCapacity: 1,
// vpcSubnets : default > all private subnets.
});
// task를 정의
const taskDefinition = new ecs.FargateTaskDefinition(this, "hello-web-task", {
memoryLimitMiB: 512,
cpu: 256,
});
const container = taskDefinition.addContainer('hello-web-container', {
// docker image 지정. 위에서 정의한 repository입니다.
image : ecs.ContainerImage.fromEcrRepository(repository),
memoryLimitMiB: 512,
portMappings: [{ containerPort: 3000 }], // 생성된 웹 서비스는 3000 포트를 사용한다고 가정합니다.
});
// Service를 정의
const service = new ecs.FargateService(this, 'hello-web-service', {
cluster: cluster_web,
taskDefinition,
desiredCount:1,
circuitBreaker: {rollback: true}, // // 비정상 서비스가 배포된 경우 자동으로 롤백되도록 설정
securityGroups : [listSG.web_3000_for_private],
serviceName : 'heelo-web-ecs-service'
});
.
이제 private subnet에 배포된 서비스에 접근할 수 있도록 ALB를 연결합니다. port 80번으로 접근할 수 있도록 설정합니다.
.
// 외부에서의 접근을 위한 alb 설정
const lb = new elbv2.ApplicationLoadBalancer(this, 'hello-web-alb', {vpc, internetFacing:true});
const listener = lb.addListener('hello-web-listener', {port:80});
listener.addTargets('hello-web-target', {
port: 80,
targets: [service],
healthCheck: {
path : '/index.html',
interval: Duration.minutes(1)
}
});
지금까지 CDK를 이용해 웹 서비스를 배포하는 인프라를 구축하는 방법을 알아보았습니다. 다음은 마지막으로 지금까지의 샘플 코드를 통합하고 Autoscaling 테스트 및 검증 과정을 진행 후 CDK 관련 정리를 마치겠습니다. :)
반응형
'개발 이야기 > 인프라 구축 및 운영' 카테고리의 다른 글
CDK로 AWS 인프라 구축하기 - #마지막 (0) | 2022.06.28 |
---|---|
CDK로 AWS 인프라 구축하기 - #5 scale out 테스트 (0) | 2022.06.21 |
CDK로 AWS 인프라 구축하기 - #3 보안 그룹과 RDBMS (0) | 2022.06.14 |
CDK로 AWS 인프라 구축하기 - #2 VPC 생성 코드 작성하기 (31) | 2022.06.13 |
CDK로 AWS 인프라 구축하기 - #1 CDK 둘러보기 (0) | 2022.06.07 |