境界を溶かす魔術:GCPグローバルVPCの深淵とパケットが駆け抜ける物理的現実
クラウドネイティブなインフラを設計する際、私たちはしばしば「VPCは単なる仮想空間である」という錯覚に陥ります。しかし、GCPのVPCは、伝統的なネットワークの概念を根底から覆す「分散型ソフトウェア定義ネットワーク(SDN)」の極致です。今回は、単なるドキュメントの焼き直しではない、パケットレベルの挙動と、グローバルVPCが隠蔽する物理的な熱量を掘り下げていきましょう。
1. グローバルVPC:IPアドレスという「論理的幻影」の正体
AWSのVPCが「リージョン固定」であるのに対し、GCPのVPCは「グローバル」です。これは単にコンソールでリージョンを跨げるという意味ではありません。Googleの基盤である Andromeda(SDNスタック)が、地球規模で単一のフラットなL3ネットワークをエミュレートしているのです。
パケットレベルの挙動:カプセル化とルーティング
あるリージョンから別のリージョンへパケットが飛ぶとき、パケットはインターネットに出ることはありません。Googleの専用光ファイバー網である「B4」を通ります。
1. カプセル化: ソースVMから送出されたパケットは、ハイパーバイザー(GoogleのKVMベースのスタック)によって、Google独自のカプセル化プロトコルで包まれます。
2. グローバル・バックボーン: このカプセル化されたパケットは、パブリックIPのルーティングテーブルに頼らず、Googleの内部インフラ上を最短のレイテンシで転送されます。
3. デカプセル化: 到着先リージョンのハイパーバイザーがカプセルを剥がし、宛先VMの仮想NICへ届けます。
ここで重要なのは、「カーネルのルーティングテーブルは、この複雑さを全く知らない」ということです。ip route コマンドを叩いても、単にそのVPCのサブネットが見えるだけ。その背後にある数千キロの物理的移動は、完全にブラックボックス化されています。
2. RTTを極限まで削る:TCPスタックのチューニング
リージョン間通信で最も恐ろしいのは、往復遅延時間(RTT)によるTCPスループットの「頭打ち」です。帯域幅がどれほど太くても、BDP(Bandwidth-Delay Product)がボトルネックになります。
BDP計算とバッファの最適化
リージョン間が20msのRTTで、1Gbpsの帯域を使い切りたい場合、必要なTCPウィンドウサイズは以下の通りです。
1Gbps * 0.020s = 20Mbps つまり、最低でも約2.5MBのバッファが必要です。デフォルト設定のままだと、数msでウィンドウが埋まり、送信側が待機状態になってしまいます。
Linuxカーネルで以下のパラメータをチューニングし、グローバル通信のパイプを広げてください。
# /etc/sysctl.conf に追記して、TCPウィンドウの自動調整機能を拡張する
# 最大バッファを 16MB まで引き上げる
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
# 遅延が支配的な環境では、輻輳制御アルゴリズムを bbr に変更するのが鉄則
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
3. TLSハンドシェイクとセッション再開の極意
リージョン間通信において、TLSハンドシェイクのたびに発生する「3往復のやり取り」は、レイテンシの大きな敵です。
- TLS 1.3の活用: 1-RTTハンドシェイクを強制し、最初のパケットから暗号化通信を開始させます。
- TLS Session Resumption: セッションチケットを利用し、2回目以降の接続を0-RTTに近づけます。
もし内部通信で暗号化が必須であれば、mTLS を実装する際に Sidecar (Istio/Envoy) を利用するケースが多いでしょう。その際、Keep-Alive 設定を徹底し、コネクションプールを使い倒してください。接続を閉じるコストは、思っている以上に高いのです。
4. ネットワーク脆弱性の回避と設計のアンチパターン
グローバルVPCは「どこからでもどこへでも繋がる」という利便性の裏に、大きなリスクを抱えています。
アンチパターン:全開放のファイアウォール
「面倒だから」と 0.0.0.0/0 を許可するのは言語道断です。GCPでは 「タグ」 または 「サービスアカウント」 を用いたマイクロセグメンテーションが必須です。
# サービスアカウントを使用して、特定のインスタンス間のみ通信を許可する推奨例
gcloud compute firewall-rules create allow-internal-web-to-db \
--direction=INGRESS \
--priority=1000 \
--network=my-global-vpc \
--action=ALLOW \
--rules=tcp:5432 \
--source-service-accounts=web-server-sa@project.iam.gserviceaccount.com \
--target-service-accounts=db-server-sa@project.iam.gserviceaccount.com
これにより、IPアドレスが変更されようとも、アイデンティティに基づいた強固なネットワーク境界が維持されます。
最後に:SREとしての視点
グローバルVPCは強力な武器ですが、その「抽象化された快適さ」に甘んじてはいけません。リージョン間の通信には、必ず物理的な距離が伴い、その距離には必ず光の速度という制約が存在します。
トラブルシューティング時には、traceroute や mtr を鵜呑みにせず、パケットがどの論理パスを通り、どのハイパーバイザーを経由しているのかという「SDNの影」を想像してください。ネットワークの深淵を覗き込むとき、初めて本当の意味でクラウドを「制御」できるのです。
次は、Cloud CDN と Global Load Balancing を組み合わせた際の、エッジでのヘッダー圧縮(HPACK)と、クライアントの地理的分布に最適化されたコンテンツ配信戦略についてお話ししましょう。現場からは以上です。
コメント