まずはNAT Gatewayの膨大な通信費を見てほしい….(驚愕)
ECS/FargateでECS Scheduled Tasksを運用していると、NAT Gatewayの通信費が膨大にかかってしまうことがあると思います。今回はこちらをどのようにコストを削減したのかブログしたいと思いますので、ぜひ参考にしてみてください。まずは経緯から!
経緯
改善する前の構成図を書いてみました。ECS/Fargateで動作しているAppコンテナ(Private subnet)ですが、デプロイ時やECS Scheduled TasksでのバッチはNAT Gatewayを経由してECRからDocker imageをpullしてきます。例えば、ECS Scheduled Tasksで毎分のバッチを動かすと、イメージのサイズが1GBあると想定して、1分おきに実行すると1GBのダウンロード通信費が発生してしまうわけです。
また、CloudWatch Logsで出力されるログもコストがかかります。EC2では特に考えなくていいのですが、ECS/Fargateの場合はホストがそもそもないということから、この問題に大打撃するわけですね。これをほっておくと月何十万という費用が発生してしまうので対策を調べてみました。
ちなみにコンテナからECRにnslookupで確認すると確かにグローバル見てますね..
1 2 3 4 5 6 |
# nslookup xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com Non-authoritative answer: xxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com canonical name = NLB1-8xxxxxxxx.elb.ap-northeast-1.amazonaws.com. Name: NLB1-8xxxxxxxxxx.elb.ap-northeast-1.amazonaws.com Address: 52.xxx.xxx.xxx |
そのトラフィック、NATゲートウェイを通す必要ありますか?適切な経路で不要なデータ処理料金は削減しましょう
https://dev.classmethod.jp/articles/reduce-unnecessary-costs-for-nat-gateway/
- VPC エンドポイントの利用
・ゲートウェイタイプ
VPC エンドポイント料金およびデータ処理料金は無料です・インタフェースタイプ
VPC エンドポイントあたり $0.014/h
データ処理料金 $0.01/GB
NAT Gateway 同様にデータイン/データアウトに関わらず発生しますが、NAT Gateway の 6分の1 のデータ処理料金に削減できます
多くの AWS サービスで同一リージョン、同一 AZ 間の通信は無料で利用できますが、VPC エンドポイント経由の場合は $0.01/GB の料金がかかります
- 改善後の構成
ECSとECRがPrivateLinkに対応していることから、VPCエンドポイントをかますことで外部のネットワークを経由せずに、プライベートからECRにアクセスできるようになります。コストもNAT Gatewayの 6分の1 のデータ処理料金に削減できるので、手っ取り早く設定できそうです。早速Terraformからいってみよう!
Terraform
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/vpc-endpoints.html
- security-group.tf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
## security-group (private-link) resource "aws_security_group" "private-link" { name = "private-link" description = "private-link" vpc_id = aws_vpc.adachin-vpc.id ingress { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["10.0.0.0/16"] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "adachin-private-link" } } |
- vpc_endpoint.tf
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
resource "aws_vpc_endpoint" "app-ecr-api" { vpc_id = aws_vpc.adachin-vpc.id subnet_ids = [aws_subnet.app-1a.id, aws_subnet.app-1c.id, aws_subnet.app-1d.id] service_name = "com.amazonaws.ap-northeast-1.ecr.api" vpc_endpoint_type = "Interface" private_dns_enabled = true security_group_ids = [ aws_security_group.private-link.id ] tags = { Name = "app-ecr-api" } } resource "aws_vpc_endpoint" "app-ecr-dkr" { vpc_id = aws_vpc.adachin-vpc.id subnet_ids = [aws_subnet.app-1a.id, aws_subnet.app-1c.id, aws_subnet.app-1d.id] service_name = "com.amazonaws.ap-northeast-1.ecr.dkr" vpc_endpoint_type = "Interface" private_dns_enabled = true security_group_ids = [ aws_security_group.private-link.id ] tags = { Name = "app-ecr-dkr" } } resource "aws_vpc_endpoint" "app-logs" { vpc_id = aws_vpc.adachin-vpc.id subnet_ids = [aws_subnet.app-1a.id, aws_subnet.app-1c.id, aws_subnet.app-1d.id] service_name = "com.amazonaws.ap-northeast-1.logs" vpc_endpoint_type = "Interface" private_dns_enabled = true security_group_ids = [ aws_security_group.private-link.id ] tags = { Name = "app-logs" } } resource "aws_vpc_endpoint" "app-s3" { vpc_id = aws_vpc.adachin-vpc.id service_name = "com.amazonaws.ap-northeast-1.s3" vpc_endpoint_type = "Gateway" tags = { Name = "app-s3" } } resource "aws_vpc_endpoint_route_table_association" "app-s3" { vpc_endpoint_id = aws_vpc_endpoint.app-s3.id route_table_id = aws_route_table.route-ngw-1a.id } |
- com.amazonaws.region.ecr.api
- com.amazonaws.region.ecr.dkr
- com.amazonaws.ap-northeast-1.s3
- com.amazonaws.ap-northeast-1.logs
上記4つエンドポイントをプライベートサブネットに設定しましょう。また、Private DNSを有効にしましょう。S3はGateway型でセキュリティーグループは新規で作成し、HTTPSを許可しないとECRにログインできないので忘れずに!
結果
- プライベート向いてるか確認
1 2 3 4 5 6 7 8 9 |
# nslookup xxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com Non-authoritative answer: Name: xxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com Address: 10.0.xxx.xxx Name: xxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com Address: 10.0.xxx.xxx Name: xxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com Address: 10.0.xxx.xxx |
大成功!!
まとめ
ECSでAppコンテナをNat Gateway経由ではなく、VPCエンドポイント経由に変更したら大幅にコストダウンした。ここもあとでブログしよう👍
— adachin👾SRE (@adachin0817) April 1, 2021
とりあえずECS/Fargateを運用している方は必須の設定になりますね。これはなかなかの盲点でした…気づいてよかった!VPCエンドポイントを設定せずに毎分でバッチ回してたらとんでもないことになりますので、この機会にNAT Gatewayの通信費をコスト削減しましょう!皆さんもお気をつけて!!!
※毎分バッチでも外部通信しているものは通信費用増えるので注意
参考:https://noname.work/?p=2386
0件のコメント