ハイブリッドクラウドのDNS地獄を脱出せよ:GCP Cloud DNS 転送ゾーンとインバウンドエンドポイントの極意
「オンプレとGCPをVPNで繋いだはいいが、名前解決ができない」。
これは、クラウド移行の現場で最も遭遇する「お約束」のトラブルです。
ping は通るのに、なぜか curl でAPIを叩こうとすると Could not resolve host と冷たく突き放される――。この原因の多くは、DNSの疎通経路が考慮されていないことにあります。今回は、GCPの「Cloud DNS 転送ゾーン」と「インバウンドDNSサーバー」を使いこなし、オンプレミスとクラウドの境界をシームレスに繋ぐネットワーク設計の真髄を解説します。
—
1. なぜ「DNSの分断」が起きるのか?
クラウドネイティブな環境にいると忘れがちですが、DNSは階層構造です。オンプレミスのレガシーな AD や Bind サーバーが管理する corp.example.com を、GCP上の Compute Engine が知る由もありません。
ここで登場するのが、Cloud DNSの2つの機能です。
- 転送ゾーン (Forwarding Zones): GCPからオンプレのDNSサーバーへ問い合わせを「転送」する。
- インバウンド DNS サーバー (Inbound Server Policy): オンプレからGCPのマネージドDNSへ問い合わせを「受け入れる」。
これらを組み合わせることで、双方向の名前解決が可能になります。
—
2. インバウンドDNSサーバー:オンプレからの窓口を開く
オンプレミス環境から *.c.googlevideo.com や、GCP内部のプライベートな *.internal ホスト名を解決したい場合、Cloud DNSの「インバウンドエンドポイント」が必要です。
インバウンドサーバーポリシーを作成すると、指定したVPC内に 169.254.169.254 ではなく、特定のIPアドレス(エンドポイント)が払い出されます。
設定例:gcloud コマンドによる構築
このコマンドを実行すると、指定したサブネット内にDNS専用のプライベートIPが確保されます。
# インバウンドDNSポリシーを作成し、オンプレからのクエリを受け入れる
gcloud dns policies create inbound-policy \
--network=your-vpc-name \
--enable-inbound-forwarding \
--description="オンプレからのDNSクエリを受け入れるためのポリシー"
このポリシーが適用されたVPCのサブネット内には、自動的に「転送先IP」が割り当てられます。オンプレ側のDNSサーバー(BindやWindows Server)で、GCP向けのドメインをこのIPへ転送するように設定してください。
—
3. 転送ゾーン:GCPからオンプレへ「お使い」を頼む
逆に、GCP上のPodやVMが app.internal.corp のようなオンプレのドメインを引くには、「転送ゾーン」を定義します。
Terraformでの宣言的設定例
実務では手動操作は厳禁です。以下のようにTerraformで定義し、オンプレのDNSサーバーIPを明示的に指定します。
resource "google_dns_managed_zone" "onprem-forwarding-zone" {
name = "onprem-zone"
dns_name = "corp.example.com." # オンプレ側のドメイン
description = "オンプレミスのDNSへ転送するゾーン"
visibility = "private"
private_visibility_config {
networks {
network_url = google_compute_network.main.self_link
}
}
forwarding_config {
# オンプレ側で公開しているDNSサーバーのIPを指定
target_name_servers {
ipv4_address = "10.0.5.5"
}
}
}
—
4. 現場のデバッグTips:パケットはどこで消えた?
DNSトラブルは「階層」が多すぎて、どこで失敗しているか切り分けにくいのが厄介です。私はトラブルシューティングの際、必ず以下の手順を踏みます。
Step 1: dig でネームサーバーを直指定する
まず、Cloud DNSが正しく機能しているか、あるいはオンプレ側が応答しているかを確認します。
# GCP上のVMから、直接オンプレのDNSサーバーに問い合わせる
dig @10.0.5.5 app.internal.corp
もしこれで応答がなければ、ネットワーク(Cloud VPNやInterconnect)のFirewall設定で、UDP/53 および TCP/53 がブロックされている可能性が濃厚です。
Step 2: Pythonで疎通確認を行う
アプリケーションコード上でDNS解決が失敗する場合、環境変数の http_proxy や、OSの nsswitch.conf が悪さをしていることがあります。
import socket
def check_dns(hostname):
try:
# システムのDNS設定を使用して名前解決を試みる
ip = socket.gethostbyname(hostname)
print(f"成功: {hostname} -> {ip}")
except socket.gaierror:
print(f"失敗: {hostname} の名前解決ができませんでした")
# 現場での検証用
check_dns("api.internal.corp")
—
SREからの最後のアドバイス
DNSは「動いていて当たり前」のインフラですが、一度壊れるとシステム全体が沈黙します。
1. 疎通確認の自動化: 監視ツールでオンプレ・GCP双方からDNSの疎通確認(ヘルスチェック)を常時実行してください。
2. キャッシュの罠: TTL の値を適切に設定しないと、オンプレ側のIP変更がクラウド側に反映されるまで数時間かかるという悲劇を生みます。
3. 冗長性の確保: 転送先のDNSサーバーは必ず2台以上用意し、Cloud DNSの設定でも両方をリストに含めてください。
ネットワークのトラブルは「見えないものを見る力」が試されます。まずは tcpdump でパケットの行き先を追いかけ、DNSリクエストがどこで迷子になっているかを特定しましょう。あなたのアーキテクチャが、盤石な名前解決の上に成り立つことを願っています。
コメント