パブリックサブネットという属性は存在しない
一言でいうと
サブネットに「パブリック」という設定は存在しません。ルートテーブルに、インターネットゲートウェイへ向かうデフォルト経路があればパブリックで、なければプライベートです。それがすべてです。
なぜ必要なのか
「パブリックサブネットに入れたのに、インターネットにつながりません」という質問に答えるには、この事実を知っている必要があります。名前をpublic-subnet-aと付けても、パブリックにはなりません。
インスタンスがインターネットに出るには、4つがすべて揃っている必要があります。
- サブネットのルートテーブルに
0.0.0.0/0 → igw-xxxがある - インスタンスにグローバルIPが付いている
- セキュリティグループのアウトバウンドが許可している
- ネットワークACLが、インバウンド・アウトバウンドの両方を許可している
1つでも欠ければだめです。そして、症状がすべて「つながらない」で同じなので、順番に確認する習慣が必要です。
標準的な3層配置
VPC 10.0.0.0/16
├─ 퍼블릭 서브넷 10.0.0.0/24, 10.0.1.0/24 (AZ-a, AZ-b)
│ └ 로드밸런서, NAT 게이트웨이, 배스천
├─ 앱 서브넷 10.0.16.0/20, 10.0.32.0/20
│ └ 애플리케이션 서버 — 공인 IP 없음
└─ 데이터 서브넷 10.0.48.0/24, 10.0.49.0/24
└ DB — 인터넷으로 나가는 경로 자체가 없음
原則は1つです。インターネットから直接届くものを最小限に。ロードバランサーだけを前に置いて、残りはすべて後ろに隠します。
サブネットの大きさを変えているのも、意図的です。パブリックには数個しか入らず、アプリ層はオートスケーリングで大きく増えます。
AZごとにサブネットを別々に作る理由
サブネットは1つのAZの中にだけ存在します。複数のAZにまたがれません。そのため、マルチAZ構成にするには、層ごとにAZの数だけサブネットが必要です。3層 × 2AZ = サブネット6つが最小です。
ルートテーブルの読み方
목적지 대상
10.0.0.0/16 local ← VPC 내부. 지울 수 없다
0.0.0.0/0 igw-abc123 ← 나머지 전부 인터넷으로
最も具体的な経路が勝ちます(longest prefix match)。10.0.0.0/16は/16なので0.0.0.0/0より具体的であり、VPC内部の通信はインターネットに出ていきません。このルールを知っていれば、オンプレミス接続がなぜそう動作するのかも説明できます。
プライベートサブネットのアウトバウンド
DBはインターネットに公開されてはいけませんが、パッケージの更新は受け取る必要があります。そのためNATゲートウェイを使います。
프라이빗 라우팅 테이블
0.0.0.0/0 → nat-xyz (퍼블릭 서브넷에 있는 NAT)
NATは出ていくものだけを許可します。外から先に接続を始めることはできません。この非対称性が、プライベートサブネットの核心です。
注意: NATゲートウェイには、時間あたりの料金 + 処理データの料金がかかります。プライベートサブネットから大容量を絶えずダウンロードすると、ここでコストが大きくかさみます。次のコースで、改めて扱います。
つながらないときに見る順序
1. 보안그룹 — 가장 흔하다. 인바운드 규칙 확인
2. 라우팅 테이블 — 그 목적지로 가는 경로가 있나
3. NACL — 서브넷 수준. 아웃바운드도 확인(상태 비저장이라 양방향 필요)
4. 공인 IP — 퍼블릭 접근이면 붙어 있나
5. 대상 자체 — 프로세스가 그 포트에서 듣고 있나
この順序で見ると、ほとんどが3段階以内に原因が見つかります。
アドレス範囲を決めるときの、元に戻しにくい決定
サブネットの分割は、あとから直すのが非常に難しいです。VPCのアドレス範囲は、作ったあとに縮小できず、サブネットは、中にリソースがあると削除できません。最初の30分で決めたことが、何年も続きます。
他者のアドレス範囲と重なると、そのときから迂回のコストがかかります。社内のアドレス範囲、別のチームのVPC、買収した会社のネットワーク、VPNでつなぐ協力会社。いつかつなぐ必要のある相手と重なると、ピアリングもVPNもできません。RFC 1918は広いので、よくある場所を避けます。10.0.0.0/16と192.168.0.0/24は、誰もが最初に選ぶアドレス範囲です。
サブネットは大きく取ります。IPはタダで、不足は高くつきます。/24(約250個)で始めて、Podごとに1つIPを使うコンテナネットワークをつなぐ瞬間に、底をつきます。クラウドがサブネットごとに5個を予約していくことも、計算に入れます。
| 用途 | 推奨 | 理由 |
|---|---|---|
| VPC | /16 |
あとから広げることはできますが、面倒です |
| パブリックサブネット | /24 |
ロードバランサーとNATくらいしか入りません |
| プライベートサブネット | /20以上 |
Podやタスクがアドレスを消費します |
| データサブネット | /24 |
インスタンス数が少ないです |
AZごとに分けますが、規則的に分けます。第3オクテットをAZとして使うように決めておけば、アドレスだけを見てどこかがわかります。規則がないと、数か月後にルートテーブルを読むたびに、ドキュメントを探すことになります。
つながらないときに見る順序は、いつも同じです。下に行くほどまれです。
- セキュリティグループ: 状態を記憶するので、戻りの道は開けなくてもよいです
- ネットワークACL: 状態を記憶しないので、応答用のエフェメラルポート範囲も開ける必要があります
- ルートテーブル: そのサブネットに、宛先へ行く経路があるか
- 対象の状態: そのポートを実際に待ち受けているか
- 対象側のOSのファイアウォール
1つ目と2つ目を混同することが、最もよくある事故です。ACLでインバウンドだけを開けて、アウトバウンドの1024-65535を開けないと、リクエストは入るのに、応答が出ていけません。症状が「つながったりつながらなかったりする」と現れるので、原因を見つけにくくなります。
現場での姿
- 名前が
public-subnet-aなのにインターネットにつながりません。ルートテーブルにIGWへ向かうデフォルト経路がありませんでした。名前には何の効力もありません。 - ロードバランサーを1つのサブネットにだけ付けて、マルチAZだと信じていました。サブネットは1つのAZにしか存在しないので、その構成は単一AZでした。
- プライベートサブネットでパッケージの更新ができません。NATは作ってありましたが、そのサブネットが別のルートテーブルに関連付けられていました。
- DBをパブリックサブネットに置いてセキュリティグループだけで防いでいたところ、ルール1行を間違えて開けた日に、そのまま公開されました。層を分けることは、ミス1つが事故にならないようにする仕組みです。
次に見ること
セキュリティグループとNACL。名前は似ていますが、動作方式が根本的に違います。