【入門編】 マルチAZ配置におけるNATゲートウェイの冗長化とゾーン障害耐性 – クラウド&コンテナネットワーク実践ガイド

クラウドの世界へようこそ!SRE(サイト信頼性エンジニア)として日夜インフラと格闘している私ですが、今回は「クラウドネットワークの要」とも言える、とても大切なテーマについてお話ししていきますね。

インフラやネットワークの世界に初めて足を踏み入れたとき、「サブネットって何?」「NATゲートウェイって、いったいどんな仕事をしているの?」と、次々に現れる専門用語に圧倒されてしまいますよね。でも、一歩ずつ紐解いていけば大丈夫です。今回は、私たちが普段当たり前のように使っているクラウドの裏側で、システムが止まらないように奮闘している「マルチAZ配置におけるNATゲートウェイの冗長化」について、身近な例えを交えながら優しく解説していきます!

—

1. パブリックとプライベート、そして「NATゲートウェイ」の役割とは?

まずは、クラウドのネットワークの基本から整理していきましょう。
皆さんがよく耳にする「アベイラビリティゾーン(AZ)」とは、簡単に言うと「独立した電源や回線を持った、物理的に離れたデータセンターのエリア(東京リージョンなら ap-northeast-1a や ap-northeast-1c など)」のことです。

このAZの中に、私たちはサーバー(仮想マシン)を配置していくわけですが、セキュリティの観点から部屋が2つに分かれています。

  • パブリックサブネット: インターネットの世界と直接つながっている「表玄関」です。
  • プライベートサブネット: インターネットからは直接見えない、セキュアな「奥の部屋」です。

郵便配達の例えで考えてみましょう

プライベートサブネットにいるサーバーたちは、外のインターネット(例えば、外部のAPIサービスやソフトウェアのアップデート元)に手紙(データ)を出したいことがあります。でも、彼らは「表玄関」に出るパスポートを持っていません。

そこで登場するのが、NATゲートウェイ(Network Address Translation Gateway)です。
NATゲートウェイは、プライベートサブネットのサーバーたちから手紙を受け取ると、「よし、代わりに私が外に出してきてあげるね。送り主の住所も私のものに書き換えておくから、返事は私宛に送ってね」と、こっそり外の世界とやり取りをしてくれる「優秀な代理人(窓口スタッフ)」なんです。

—

2. もし、この代理人が1人しかいなかったら…?(単一障害点の恐怖)

さて、ここで可用性(システムが止まらない性質)を考える上で、大きな問題に直面します。

もし、とても優秀な代理人(NATゲートウェイ)を、ある1つのAZ(例えば AZ-a)にだけポツンと配置していたとしましょう。普段は何も問題なくスイスイ仕事をしてくれます。

しかし、ある日突然、自然災害やハードウェアの故障によって、AZ-a のデータセンター全体が停電してしまったらどうなるでしょうか?

「ああっ!代理人がいる建物ごと連絡が取れなくなってしまった!プライベートサブネットにいるサーバーたちが、外の世界と一切通信できなくなっちゃったぞ……!」

これが、インフラエンジニアが最も恐れる「単一障害点(SPOF:Single Point of Failure)」という状態です。どれだけサーバーをたくさん並べて頑丈に作っても、外へ出るための窓口が1つだけでは、その窓口が潰れた瞬間にシステム全体が機能不全に陥ってしまいますよね。

—

3. 解決策:すべてのAZに代理人を置く「マルチAZ配置」とルートテーブルの魔法

この問題を鮮やかに解決するのが、今回の本題である「マルチAZ配置におけるNATゲートウェイの冗長化」です。

やり方はとってもシンプル。「すべてのAZ(例えば AZ-a と AZ-c)に、それぞれ独立したNATゲートウェイを1台ずつ置いちゃおう!」というアプローチです。

賢い交通整理役:ルートテーブルの切り替え

ここで重要になるのが、プライベートサブネットから「どちらの代理人に手紙を渡しに行くか」を決める案内板、つまりルートテーブルの設定です。

各AZのプライベートサブネットごとに専用のルートテーブルを用意し、次のような交通整理を行います。

  • AZ-a のプライベートサブネットにあるサーバーは、近所にある AZ-a のNATゲートウェイへ向かう。
  • AZ-c のプライベートサブネットにあるサーバーは、近所にある AZ-c のNATゲートウェイへ向かう。

もし、万が一 AZ-a で障害が発生しても、AZ-c 側のルートとNATゲートウェイは元気なまま生き残っています。クラウドのモニタリング機能や自動フェイルオーバーの仕組みを組み合わせることで、「あれ、AZ-a の代理人が応答しないぞ?じゃあ、ルートの向き先を元気な AZ-c の方に切り替えよう!」という動的な耐障害設計が可能になるのです。

—

4. 実務で役立つ!TerraformによるマルチAZ・NATゲートウェイの構築サンプル

「理屈はわかったけれど、実際のコードではどう書くの?」という声にお応えして、インフラのコード化ツールであるTerraformを使った実践的な設定サンプルをご紹介します。日本語のコメントを丁寧に添えましたので、ぜひ現場での構築の参考にしてみてくださいね。

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

# AZ-a用のパブリックサブネット
resource "aws_subnet "public_a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-northeast-1a"
  tags = {
    Name = "prod-public-subnet-a"
  }
}

# AZ-c用のパブリックサブネット
resource "aws_subnet "public_c" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = "ap-northeast-1c"
  tags = {
    Name = "prod-public-subnet-c"
  }
}

# AZ-a用のElastic IP(外向きの固定IPアドレス)の確保
resource "aws_eip "nat_eip_a" {
  domain     = "vpc"
  depends_on = [aws_internet_gateway.igw]
  tags = {
    Name = "prod-nat-eip-a"
  }
}

# AZ-c用のElastic IPの確保
resource "aws_eip "nat_eip_c" {
  domain     = "vpc"
  depends_on = [aws_internet_gateway.igw]
  tags = {
    Name = "prod-nat-eip-c"
  }
}

# AZ-aに配置するNATゲートウェイ(1人目の代理人)
resource "aws_nat_gateway "nat_a" {
  allocation_id = aws_eip.nat_eip_a.id
  subnet_id     = aws_subnet.public_a.id
  tags = {
    Name = "prod-nat-gw-a"
  }
}

# AZ-cに配置するNATゲートウェイ(2人目の代理人)
resource "aws_nat_gateway "nat_c" {
  allocation_id = aws_eip.nat_eip_c.id
  subnet_id     = aws_subnet.public_c.id
  tags = {
    Name = "prod-nat-gw-c"
  }
}


# ----------------------------------------------------------------------
# 2. プライベートサブネットとルートテーブル(案内板)の設定
# ----------------------------------------------------------------------

# AZ-aのプライベートサブネット
resource "aws_subnet "private_a" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.10.0/24"
  availability_zone = "ap-northeast-1a"
  tags = {
    Name = "prod-private-subnet-a"
  }
}

# AZ-a用プライベートサブネットのルートテーブル
# (AZ-aのサーバーは、同AZにある「nat_a」をデフォルトゲートウェイとして使う)
resource "aws_route_table "private_rt_a" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.nat_a.id # AZ-aのNATへ向ける
  }

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

# ルートテーブルとサブネットの関連付け
resource "aws_route_table_association "private_assoc_a" {
  subnet_id      = aws_subnet.private_a.id
  route_table_id = aws_route_table.private_rt_a.id
}

このように、それぞれのAZで「自分のゾーンにあるNATゲートウェイを向くルートテーブル」を独立して持たせてあげることで、片方のAZが被災しても、もう片方のルートが生き残り、システム全体の耐障害性を飛躍的に高めることができるのです。

—

5. まとめ:ゾーン障害に強いインフラを目指して

今回は、マルチAZ配置におけるNATゲートウェイの冗長化とゾーン障害耐性について、郵便配達の例えやTerraformの設定コードを交えながら解説しました。

  • 単一のNATゲートウェイに依存すると、そのAZが被災したときにシステム全体が止まってしまう(SPOF)。
  • 各AZにNATゲートウェイを独立して配置し、それぞれのサブネットに対応したルートテーブルを紐付けるのがベストプラクティス。
  • コスト面(NATゲートウェイ自体の稼働費やAZ間転送料金)とのバランスを見る必要はあるものの、本番環境の可用性を担保するためには非常に強力なアプローチになる。

「インフラの仕事は、いつ何時もシステムを止まりにくくすること」。そのための泥臭い工夫や美しい設計思想が、クラウドネットワークのあちこちに隠されています。
一歩ずつ、こうした知識を自分のものにしていけば、自信を持って信頼性の高いシステムを構築できるようになりますよ。それでは、また次回の技術解説でお会いしましょう!SREチームの主筆ライターがお届けしました。

コメント

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