【入門編】 クロスAZ通信コスト(データ転送料金)の最適化とNATゲートウェイの配置パターン – クラウド&コンテナネットワーク実践ガイド

こんにちは!クラウドの世界へ足を踏み入れたばかりの皆さん、日々のインフラ構築や運用、本当にお疲れ様です。

AWSやGCPといったパブリッククラウドを使い始めると、可用性を高めるために「マルチAZ(アベイラビリティゾーン)」という言葉を嫌というほど耳にしますよね。「サーバーは複数のAZに分散させましょう」「データベースもマルチAZで!」と、教科書には必ず書いてあります。

でも、実際にシステムを動かして月末の請求書を見たとき、「あれ……? なんか通信費(データ転送料金)が予想より高いぞ?」と冷や汗をかいた経験はありませんか?

その犯人の多くは、実は「NATゲートウェイの配置ミス」にあります。今回は、この厄介なクロスAZ通信コストの罠と、それを華麗に回避するインフラ設計のコツについて、身近な例えを交えながら一歩ずつ優しく紐解いていきましょう!

—

1. そもそも「NATゲートウェイ」ってなに? 身近な例えで理解する

クラウド上のプライベートサブネット(外の世界から直接アクセスできない安全な部屋)にあるサーバーたちが、ソフトウェアのアップデートや外部APIの呼び出しのために、インターネットへお出かけしたいときがあります。

しかし、プライベートな部屋にいるサーバーたちは直接外の世界に出られないため、代理で門番をしてくれる存在が必要です。それが「NAT(Network Address Translation)ゲートウェイ」です。

郵便局の本店に例えてみましょう

想像してみてください。あなたは「AZ-A」という地域にあるお家のリビング(プライベートサブネット)にいます。そこから外の友達に手紙を出したいのですが、直接外には行けません。

そこで、あなたの地域にある「AZ-Aの郵便局(NATゲートウェイ)」まで手紙を持っていき、そこから外の世界へ発送してもらいます。

  • 同一AZ内でのやり取り: AZ-Aにあるお家から、AZ-Aにある郵便局を使う(スムーズで追加料金なし!)
  • 異なるAZをまたぐやり取り: AZ-Aにあるお家から、わざわざ山を越えて遠くの「AZ-Cにある郵便局」まで手紙を持っていって発送する(時間もコストもかかる!)

クラウドの世界でも全く同じことが起きています。サーバーがいるAZと違うAZにあるNATゲートウェイへ通信を飛ばすと、クラウド事業者から「AZ間データ転送料金」という名の通行料をしっかり請求されてしまうのです。

—

2. 恐怖の「クロスAZ通信コスト」が発生するメカニズム

マルチAZ構成を組むとき、「とりあえずコスト削減のために、NATゲートウェイは1つだけ作って、すべてのAZのサーバーからそこに向かわせよう」と考える初学者は少なくありません(私も昔やりました!)。

しかし、これが大きな落とし穴です。

罠だらけの「NATゲートウェイ1台集中構成」

例えば、AZ-A、AZ-B、AZ-Cの3つのAZにサーバーを配置し、NATゲートウェイをAZ-Aに1台だけ置いたとします。

1. AZ-Bのサーバーがインターネットへ通信したい!
2. ルーティング設定に従い、AZ-AにあるNATゲートウェイへパケットを飛ばす。
3. この瞬間、AZ-BからAZ-Aへの「AZ間データ転送」が発生する。
4. 月末に「AZ間をまたいだ通信量が多すぎます」という理由で、高額な請求書が届く。

システムの規模が大きくなり、外部APIとの通信やファイルのダウンロード・アップロードが増えれば増えるほど、このクロスAZの通行料は雪だるま式に膨れ上がっていきます。「動いているのに、なぜかお金がかかる」というクラウドアルアルの正体はこれなんです。

—

3. 解決策:すべてのAZにNATゲートウェイを配置せよ!

このコストの幽霊を退治する特効薬は非常にシンプルです。それは、「サーバーがあるすべてのAZに、それぞれNATゲートウェイを置く(マルチAZ配置)」という原則を守ることです。

郵便局の「各街への支店設置」作戦

先ほどの例えに戻りましょう。AZ-A、AZ-B、AZ-Cのすべてのお家から遠くの郵便局まで行かせるのではなく、それぞれの街(AZ)に専用の郵便局を1つずつ建ててあげます。

  • AZ-Aのサーバーは、AZ-AのNATゲートウェイを使う。
  • AZ-Bのサーバーは、AZ-BのNATゲートウェイを使う。
  • AZ-Cのサーバーは、AZ-CのNATゲートウェイを使う。

これで、通信は常に同じAZ内で完結し、余計なAZ間データ転送料金を綺麗にゼロに(あるいは最小限に)抑えることができます!

—

4. 実践!AWS(Terraform)でのコスト最適化構成の書き方

理屈が分かったところで、実際にインフラをコードで構築する際のサンプルを見てみましょう。今回は、インフラ界の共通言語であるTerraformを使って、各AZに綺麗にNATゲートウェイを配置する設定を覗いてみます。

# ----------------------------------------------------
# 1. 各AZ(可用性ゾーン)ごとのパブリックサブネットとNATゲートウェイの定義
# ----------------------------------------------------

# AZ-1a 用のパブリックサブネット
resource "aws_subnet" "public_az_a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-1a" # 東京リージョン 1a
  tags = {
    Name = "public-subnet-az-a"
  }
}

# AZ-1c 用のパブリックサブネット
resource "aws_subnet" "public_az_c" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "ap-northeast-1c" # 東京リージョン 1c
  tags = {
    Name = "public-subnet-az-c"
  }
}

# AZ-1a 用のEIP(固定IP)
resource "aws_eip" "nat_az_a" {
  domain = "vpc"
  tags = {
    Name = "nat-eip-az-a"
  }
}

# AZ-1c 用のEIP(固定IP)
resource "aws_eip" "nat_az_c" {
  domain = "vpc"
  tags = {
    Name = "nat-eip-az-c"
  }
}

# 【重要】AZ-1a に配置するNATゲートウェイ
resource "aws_nat_gateway" "nat_a" {
  allocation_id = aws_eip.nat_az_a.id
  subnet_id     = aws_subnet.public_az_a.id
  tags = {
    Name = "nat-gw-az-a"
  }
}

# 【重要】AZ-1c に配置するNATゲートウェイ(AZごとの分散配置!)
resource "aws_nat_gateway" "nat_c" {
  allocation_id = aws_eip.nat_az_c.id
  subnet_id     = aws_subnet.public_az_c.id
  tags = {
    Name = "nat-gw-az-c"
  }
}


# ----------------------------------------------------
# 2. プライベートサブネットから各AZのNATへ向けるルートテーブルの定義
# ----------------------------------------------------

# AZ-1a のプライベートサブネット用ルートテーブル
resource "aws_route_table" "private_az_a" {
  vpc_id = aws_vpc.main.id

  # AZ-1a のサーバーからの外部通信は、必ず同じAZ-1aにあるNATゲートウェイへ流す!
  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat_a.id
  }

  tags = {
    Name = "private-rt-az-a"
  }
}

# AZ-1c のプライベートサブネット用ルートテーブル
resource "aws_route_table" "private_az_c" {
  vpc_id = aws_vpc.main.id

  # AZ-1c のサーバーからの外部通信は、必ず同じAZ-1cにあるNATゲートウェイへ流す!
  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat_c.id
  }

  tags = {
    Name = "private-rt-az-c"
  }
}

このコードのポイントは、aws_route_table の中で、「自分のいるAZと同じ場所にあるNATゲートウェイのID(nat_gateway_id)」を指し示している点です。

これにより、パケットが余計な山(AZ)を越えることなく、最短距離でインターネットへ飛び出していく美しいルーティングが完成します。

—

5. 「でも、NATゲートウェイの台数が増えると固定費が上がるのでは?」という疑問

ここで鋭い読者の皆さんなら、こう気付くはずです。
「おいおい、NATゲートウェイって1台あたりにもう稼働費(時間あたりの料金)がかかるよね? 各AZに置いたら、固定費が爆上がりするんじゃないの?」

その通り!ここはインフラ設計のとても悩ましいトレードオフ(ジレンマ)です。

  • パターンA:NATゲートウェイを1台にする
  • 固定費:安く済む(1台分の稼働費)
  • 変動費(通信費):クロスAZのデータ転送料金で月末に爆発する可能性がある
  • パターンB:すべてのAZにNATゲートウェイを置く
  • 固定費:AZの数だけ高くなる(例:3AZなら3台分の稼働費)
  • 変動費(通信費):クロスAZ料金がゼロになり、予測しやすい

現場で使えるSREの判断基準

一般的に、トラフィック(通信量)が少ない開発環境や検証環境であれば、コスト削減のために「NATゲートウェイ1台構成」や「VPCエンドポイントの活用」で逃げるのも一つの手です。

しかし、本番環境(プロダクション環境)で、外部との通信量(API連携やログ送信、S3との大量データやり取りなど)が多いシステムであれば、迷わず「全AZ配置(パターンB)」を選ぶべきです。
なぜなら、トラフィックが増えれば増えるほど、クロスAZのデータ転送料金はNATゲートウェイの固定費を遥かに超えて高額になるからです。

さらに言えば、もし1つのAZが障害でダウンしたとき、別AZのNATゲートウェイに頼る構成にしていると、そのAZが復旧するまで外部通信が全滅するリスク(可用性の低下)も抱えることになります。コストと可用性の両面から見ても、基本は「マルチAZに各1台」がベストプラクティスです。

—

まとめ

今回は、クロスAZ通信コストの最適化とNATゲートウェイの配置パターンについて解説しました。

1. クロスAZ通信の罠: 異なるAZをまたぐ通信には、目に見えないデータ転送料金(通行料)が発生する。
2. 原因: NATゲートウェイを1箇所に集中させると、他のAZからの通信ですぐにコストが膨れ上がる。
3. 解決策: 基本はサーバーがあるすべてのAZにNATゲートウェイを配置し、通信を同じAZ内で完結させる。
4. トレードオフ: システムの規模や通信量に合わせて、固定費と変動費のバランスを冷静に見極める。

インフラやネットワークの世界は、一見難しそうに見えても、今回のように「郵便配達」や「道路の最短ルート」に置き換えてみると、とてもスッキリ理解できるようになります。

「動けばいいや」から一歩進んで、「お財布にも優しく、災害にも強い美しいネットワーク」をデザインできるエンジニアを目指して、一緒に一歩ずつ進んでいきましょう!

それでは、また次回の技術解説でお会いしましょう。SREチームの主筆ライターより、愛を込めて!

コメント

タイトルとURLをコピーしました