AWS Fargate에 Consul 배포
AWS Fargate에 Consul 배포 (Deploy Consul to AWS Fargate)
이 페이지는 AWS ECS 런타임의 Consul 태스크를 지원하기 위해 Consul 서버를 Amazon Web Services Fargate에 배포하는 과정을 설명해요. Fargate를 사용하면 서버리스 컴퓨팅 엔진에서 Consul 서버 에이전트를 ECS 태스크로 실행할 수 있어요.
출처: 문서
본문
이 페이지는 AWS ECS 런타임의 Consul 태스크를 지원하기 위해 Consul 서버를 Amazon Web Services Fargate에 배포하는 과정을 설명해요. 다른 런타임에서 동작하는 Consul 서버와 함께 ECS에서 Consul을 실행하려면 AWS ECS 서비스를 Consul 서비스 메시에 통합을 참고해요.
완전한 엔드투엔드 예시는 Consul on Fargate Github 저장소를 참고해요.
개요 (Overview)
AWS Fargate는 Consul 서버 에이전트를 ECS 태스크로 실행할 수 있는 서버리스 컴퓨팅 엔진이에요. Fargate는 런타임 환경을 사용자가 관리하지 않으므로 배포와 유지보수를 단순화해요.
Consul이 AWS Fargate에서 실행될 때 Consul 클러스터에 영구 스토리지(persistent storage)가 있는 것이 중요해요. AWS Elastic File System(EFS) 사용을 권장해요. 기능하는 Consul 서버 클러스터가 있으면 ECS 워크로드와 함께 Consul 데이터플레인을 실행해 서비스 디스커버리와 서비스 메시를 사용할 수 있어요.
워크플로 (Workflow)
AWS Fargate에 Consul 서버를 배포하는 과정은 다음 단계로 구성돼요:
- Fargate가 활성화된 ECS 클러스터 생성
- Fargate와 호환되는 Consul 서버용 ECS 태스크 정의 생성
- Fargate 실행 유형(launch type)을 가진 Consul 서버 태스크용 ECS 서비스 생성
- Consul 태스크용 EFS 영구 스토리지 생성 및 연결
Fargate에서 실행되도록 Consul 서버 구성 (Configure Consul servers to run on Fargate)
Fargate에서 Consul 서버를 실행하려면 먼저 대상 ECS 클러스터에서 FARGATE 용량 제공자(capacity provider)를 활성화해야 해요.
ecs-cluster.tf:
resource "aws_ecs_cluster" "consul-ecs-cluster" {
name = "consul-ecs"
capacity_providers = ["FARGATE"]
}
다음으로 Consul 서버용 태스크 정의를 생성해요. Fargate에서 Consul 서버를 실행하려면 태스크 정의의 requires_compatibilities 필드에 FARGATE를 지정해요. 이 필드는 태스크 정의가 Fargate 실행 유형과 호환됨을 나타내요.
consul-server-task.tf:
resource "aws_ecs_task_definition" "consul-server-task" {
family = "consul-ecs-consul-server"
requires_compatibilities = ["EC2", "FARGATE"]
network_mode = "awsvpc"
cpu = 256
memory = 512
# [...]
}
마지막으로 Consul 서버 태스크를 실행할 ECS 서비스를 정의해요. 서비스 정의에서 실행 유형을 FARGATE로 지정해야 해요. network_configuration 블록의 subnets와 security_groups 매개변수가 환경의 값과 일치하는지 확인해요.
consul-ecs-service.tf:
resource "aws_ecs_service" "consul-ecs-service" {
name = "consul-ecs-consul-server"
cluster = aws_ecs_cluster.consul-ecs-cluster.arn
task_definition = aws_ecs_task_definition.consul-server-task.arn
desired_count = 1
network_configuration {
subnets = module.vpc.private_subnets
assign_public_ip = false
security_groups = [aws_security_group.ecs_service.id]
}
launch_type = "FARGATE"
service_registries {
registry_arn = aws_service_discovery_service.server.arn
container_name = "consul-server"
}
# [...]
}
Fargate의 Consul 서버가 영구 EFS 스토리지를 사용하도록 구성 (Configure Consul servers on Fargate to use persistant EFS storage)
Fargate에서 Consul을 실행할 때 Amazon Elastic File System(EFS) 사용을 권장해요. EFS 서비스는 AWS Fargate의 Consul 컴퓨팅 인스턴스에 영구적이고 완전 관리되는 탄력적 NFS 파일 시스템 스토리지를 제공해요. Fargate 및 ECS에서 AWS EFS 볼륨 사용에 대한 자세한 내용은 관련 AWS EFS 문서와 Terraform Provider 문서의 aws_efs_file_system 리소스를 참고해요.
Consul 서버 컨테이너 데이터 디렉터리에 영구 스토리지를 제공하려면 먼저 Terraform 파일에서 필요한 EFS 리소스를 정의해요:
- 파일 시스템(file system)
- 마운트 대상(mount target)
- EFS 액세스 포인트(access point)
이러한 리소스를 통해 Consul 서버는 태스크 재시작, 재스케줄링, 업데이트에도 상태를 유지할 수 있어요. subnet_id와 security_groups 매개변수는 환경에 따라 달라질 수 있어요.
aws-efs.tf:
resource "aws_efs_file_system" "efs-consul-server" {
creation_token = "efs-example"
performance_mode = "generalPurpose"
throughput_mode = "bursting"
encrypted = "true"
tags = {
Name = "StorageConsulEFS"
}
}
resource "aws_efs_mount_target" "efs-mt-consul-server" {
file_system_id = "${aws_efs_file_system.efs-consul-server.id}"
subnet_id = "${module.vpc.private_subnets[0]}"
security_groups = ["${data.aws_security_group.vpc_default.id}"]
depends_on = [ aws_efs_file_system.efs-consul-server ]
}
resource "aws_efs_access_point" "efs-consul-server-ap" {
file_system_id = aws_efs_file_system.efs-consul-server.id
}
다음으로 Consul 서버가 NFS 프로토콜로 EFS 파일 시스템에 접근할 수 있도록 보안 그룹 규칙을 추가해요. 다음 예시는 VPC의 기본 보안 그룹에 어떤 소스 IP에서든 포트 2049의 TCP 트래픽을 허용하는 인그레스 규칙을 추가해요. 이 보안 그룹 규칙 정의는 cidr_blocks 필드가 모든 클라이언트에 열려 있어요.
프로덕션 환경에서는 이 보안 그룹 규칙을 EFS 파일 시스템에 접근할 수 있는 신뢰할 수 있는 소스의 트래픽만 허용하도록 제한해야 해요.
networking.tf:
resource "aws_security_group_rule" "consul_server_efs_storage" {
description = "Access to EFS storage from Consul server"
type = "ingress"
from_port = 2049
to_port = 2049
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
security_group_id = module.vpc.default_security_group_id
}
그런 다음 Consul 서버가 EFS 액세스 포인트를 데이터 디렉터리로 사용하도록 구성해요. 다음 Terraform 코드에서 Consul 서버 컨테이너 정의의 local.consul_server_command 필드는 Consul이 AWS Fargate 마운트 경로에 자신의 노드 이름으로 하위 폴더를 만들고 그 경로를 데이터 디렉터리로 사용하도록 하는 부팅 지침을 전달해요.
consul-server-task.tf:
locals {
node_name = "consul-ecs-consul-server"
consul_server_command = <<EOF
ECS_IPV4=$(curl -s $ECS_CONTAINER_METADATA_URI_V4 | jq -r '.Networks[0].IPv4Addresses[0]')
exec consul agent -server \
-bootstrap \
-ui \
-advertise "$ECS_IPV4" \
-client 0.0.0.0 \
-data-dir '/consul/${local.node_name}/consul-data' \
-hcl 'node_name = "${local.node_name}"' \
-hcl 'datacenter = "dc1"' \
-hcl 'connect { enabled = true }' \
-hcl 'enable_central_service_config = true' \
-hcl='ports { grpc = 8502 }' \
EOF
}
마지막으로 Consul 서버 ECS 태스크 리소스 정의에 volume과 mountPoints 구성을 추가해요. volume 블록은 이전 단계에서 생성한 EFS 파일 시스템을 사용하는 consul-data라는 볼륨을 정의해요. mountPoints 블록은 consul-data 볼륨을 Consul 서버 컨테이너의 /consul 디렉터리에 마운트하는데, 이는 Consul 서버 컨테이너의 기본 데이터 디렉터리예요.
이 구성은 Consul 서버가 데이터를 EFS 파일 시스템에 유지할 수 있게 하여 태스크 재시작과 재스케줄링에도 데이터 내구성과 가용성을 보장해요.
consul-server-task.tf:
resource "aws_ecs_task_definition" "consul-server-task" {
family = "consul-ecs-consul-server"
requires_compatibilities = ["EC2", "FARGATE"]
# [...]
volume {
name = "consul-data"
efs_volume_configuration {
file_system_id = aws_efs_file_system.efs-consul-server.id
}
}
container_definitions = jsonencode(
[
{
name = "consul-server"
image = "hashicorp/consul:1.22.0"
essential = true
# [...]
entryPoint = ["/bin/sh", "-ec"]
command = [replace(local.consul_server_command, "\r", "")]
mountPoints = [
{
sourceVolume = "consul-data"
containerPath = "/consul"
}
]
# [...]
}
])
}
다음 단계 (Next steps)
Fargate에 Consul 서버를 배포한 후 ECS에 Consul 데이터플레인을 배포해 ECS 워크로드에 서비스 디스커버리와 서비스 메시를 활성화할 수 있어요. ECS에 Consul 데이터플레인을 배포하는 방법에 대한 자세한 내용은 다음 문서를 참고해요: