こんにちは。
初めまして、Simplineのキテレツでございます。
日々の業務での発見や課題について記載していけたらと思いますが、今年に入ってから初めて業務でAWSを扱うようになったため暖かい目で見守っていただければと思います。
何卒よろしくお願い致しますm(_ _)m
早速ですが表題の件を題材にして、ECSやコンテナ化について触れていこうと思います。
私が現在利用している環境ではEC2上にインストールされているFluentd がEndpointに送られてくるセキュリティログやらアプリログなどを受け取り、種類によって振り分けを行っています。図1のようなEC2上で稼働しているFluentdをコンテナ化して、図2のような構成に変更したいと考えております。
図1

図2

とまあこんな具合にコンテナ上でFluetdを走らせるようにしたいのですが、これがなかなかどうして…。
※余談ですが、上記の図はdraw.ioで書きましたが便利ですね!
まあごにょごにょ言っていても始まらないのでさっさと進めていきましょう。
まずはECSを利用してクラスターを作成していきます。
これをベースに適当なVPCを用意してterraformを利用して環境を作成していきます。
そこにECSを作成するためfluentd_ecs.tfとユーザーデータとして利用するcluster_ecs.shを追加して、こんな感じのフォルダ構成でterraform applyしていきます。
└─two-tier main.tf outputs.tf README.md variables.tf fluentd_ecs.tf cluster_ecs.sh
ファイルの中身としてはざっくりこんな感じです。
fluentd_ecs.tf
#Create ECS cluster
resource "aws_ecs_cluster" "fluentd-cluster" {
name = "fluentd-ecs"
}
resource "aws_launch_configuration" "fluentd-ecs" {
name_prefix = "fluentd-ecs-launch-config-"
image_id = "${var.ecs_amis}"
instance_type = "t2.micro"
iam_instance_profile = "${aws_iam_instance_profile.fluentd-ecs.name}"
key_name = "${var.common_key}"
user_data = "${data.template_file.fluentd-ecs-userdata.rendered}"
security_groups = ["${aws_security_group.default.id}"]
lifecycle {
create_before_destroy = true
}
}
#ECS autoscaling group
resource "aws_autoscaling_group" "fluentd-ecs" {
name = "fluentd-ecs-sg"
max_size = 10
min_size = 1
health_check_grace_period = 300
health_check_type = "ELB"
desired_capacity = 1
force_delete = true
launch_configuration = "${aws_launch_configuration.fluentd-ecs.name}"
vpc_zone_identifier = ["${aws_subnet.default.id}"]
tag {
key = "Name"
value = "${var.aws_region}-fluentd-ecs"
propagate_at_launch = true
}
lifecycle {
create_before_destroy = true
ignore_changes = ["desired_capacity"]
}
}
data "template_file" "fluentd-ecs-userdata" {
template = "${file("./cluster_ecs.sh")}"
vars {
cluster_name = "${aws_ecs_cluster.fluentd-cluster.name}"
}
}
resource "aws_iam_instance_profile" "fluentd-ecs" {
depends_on = ["aws_iam_role.fluentd-ecs"]
name = "${var.aws_region}-fluentd-ecs"
role = "${aws_iam_role.fluentd-ecs.name}"
}
resource "aws_iam_role" "fluentd-ecs" {
name = "${var.aws_region}-fluentd-ecs"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "fluentd-ecs" {
depends_on = ["aws_iam_role.fluentd-ecs"]
role = "${aws_iam_role.fluentd-ecs.id}"
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
}
cluster_ecs.sh
#!/bin/bash
cat <<'EOF' >> /etc/ecs/ecs.config
ECS_CLUSTER=${cluster_name}
ECS_AVAILABLE_LOGGING_DRIVERS=[\"json-file\",\"syslog\",\"fluentd\", \"awslogs\"]
EOF
公式ドキュメントを参考にユーザーデータを利用してクラスター参加させないと折角autoscalingで立ち上げてもECS側で認識してくれないので注意です。
またECS内で利用するEC2ですが、特に要件が無い場合はこちらも公式ドキュメントに記載があるAmazon ECS-optimized Amazon Linux 2 AMIを利用しましょう。
先日CVE-2019-5736で指摘がありましたので、可能な限り最新のAMIを使う方が安心ですね。
あとは上記を利用してterraform applyすると、クラスターとEC2を含む各種リソースが立ち上がります。
この後の工程まで含めると長くなりそうなので、今回はここまでにします。←
後工程としてはDockerimageを作成してECRにPushしたり、既存のロードバランサーに参加するためにサービスを設定したり、autoscaling ポリシーをクラスター側とタスク定義側に設定したりとまだまだありますので、次回以降触れていきたいと思います。
まだまだ寒い時期が続きますので、どうぞご自愛くださいませ。
ありがとうございました。