【実務・中級編】 VPCにおけるDHCPオプションセットのカスタマイズ – クラウドインフラと仮想化ネットワーク実践ガイド

クラウドインフラと仮想化ネットワークの深い森へようこそ。
AWSのVPCを構築し、EC2やEKSクラスターを立ち上げ、「よし、インフラの土台はできた!」と意気込んだのもつかの間、実務では決まって次のような壁にぶつかります。

「社内のオンプレミス環境にある独自DNSサーバーと名前解決を同期させたい」
「マルチテナントなマイクロサービス環境で、独自のドメインサフィックスを自動付与させたい」

VPCを新規作成したときにAWSがデフォルトで用意してくれるAmazonProvidedDNS(VPCのネットワークアドレスに +2 したIPアドレス)は非常に優秀ですが、本番システムの要件が複雑化するにつれて、そのデフォルトの靴では窮屈になってきます。

今回は、AWSのネットワークの裏側でDHCPがどのようにインスタンスの運命を握っているのか、そして実務で即座に使える「DHCPオプションセット」のカスタマイズ術を、現場の泥臭い知見を交えて徹底解説します。

—

1. パケットとRFCの裏側:AWS VPCにおけるDHCPの正体

まず、頭の片隅に入れておかなければならない大前提があります。AWS VPCは、物理的なDHCPサーバーを私たちの視界から完全に隠蔽した、極めて洗練されたソフトウェア定義のネットワーク(SDN)です。

インスタンスがOSを起動し、VPC内のプライベートサブネットに舞い降りた瞬間、何が起きているでしょうか?
OSのネットワークデーモン(dhcpcdやNetworkManagerなど)は、ブロードキャスト(あるいはそれに準ずるリクエスト)を放ち、IPアドレスのリースを要求します。

このとき、ハイパーバイザーのレイヤー(AWSの基盤)がそのリクエストをインターセプトし、裏でこっそりと以下の情報をパケットに載せて返却しています。

  • yiaddr(Your IP Address):割り当てられたプライベートIP
  • Subnet Mask:サブネットマスク
  • Router(Gateway):デフォルトゲートウェイのIP
  • Domain Name Server(DNS):DNSサーバーのIP
  • Domain Name:検索ドメイン(サフィックス)

この「何をクライアントに配るか」のレシピブックこそが、今回フォーカスする「DHCPオプションセット(DHCP Options Set)」です。

デフォルトとカスタムの決定的な違い

VPCを新規作成すると、AWSは自動的にデフォルトのDHCPオプションセットを割り当てます。
リージョンごとに異なりますが、大体以下のような設定になっています。

  • domain-name: us-west-2.compute.internal (リージョン名に依存)
  • domain-name-servers: AmazonProvidedDNS (VPCのベースIP + 2)
  • ntp-servers: (AWS提供のNTPサーバー)

これの何が問題になるかというと、「デフォルトのオプションセットは、AWSが作ったVPC内だけで完結する閉じた世界用の設定であり、あとから変更することができない(イミュータブル)」という点です。独自のDNSサーバー(例えば、Route 53 Resolverのインバウンド・アウトバウンドエンドポイントや、社内のBIND、Consulなど)を指定したい場合は、新しいDHCPオプションセットを自分で作り、VPCにアタッチし直す必要があります。

—

2. 実務で直面する要件とパラメーターの意味

DHCPオプションセットで設定できるパラメーターは、RFC 2132(DHCP Options and BOOTP Vendor Extensions)に準拠しています。実務で触る主要なパラメーターを整理しておきましょう。

| パラメーター名 | 設定値の例 | 実務上のユースケースと注意点 |
| :— | :— | :— |
| domain-name-servers | 10.0.0.2, 1.1.1.1 | インスタンスの/etc/resolv.confに書き込まれるDNS。最大4つまで指定可能。自前でDNSクラスタを組んでいる場合はそのIPを指定。 |
| domain-name | internal.example.com | ホスト名解決の際に自動付与されるドメインサフィックス。例えば app-server というホスト名だけで app-server.internal.example.com を引けるようになる。 |
| ntp-servers | 169.254.169.123 | 時刻同期。基本はAWS提供のタイムサーバーで十分だが、厳密な金融系システムなどで社内NTPに向かせたい場合に指定。 |
| netbios-name-servers | (通常は空) | レガシーなWindows環境(WINS)向け。現代のWeb API設計やLinux主体のクラウドネイティブ環境ではまず使いません。 |

⚠️ 現場のシニアが教える「絶対にハマる罠」

ここで、私が過去のトラブルシューティングで何度も冷や汗をかいた「DNSの罠」を共有します。

domain-name-servers に自社のカスタムDNSサーバーのIP(例: 10.100.0.10)を指定したとします。このとき、そのカスタムDNS側で 「AWSのメタデータサービス(169.254.169.254)」や「インターネット上の外部ドメイン」への名前解決(フォワーディング)が正しく設定されていないと、インスタンスから外部へのAPI通信や、AWSの各サービス(S3やDynamoDBなど)のエンドポイント名前解決が突如として全滅します。

カスタムDNSを挟む場合は、必ず「フォワーダーとしてAmazonProvidedDNS(あるいはPublic DNSである 8.8.8.8 や 1.1.1.1)へ転送するパス」を担保しておくのが鉄則です。

—

3. 実践:AWS CLIとTerraformによる構築コード

では、実際にこのDHCPオプションセットを構築し、VPCに適用するコードを見ていきましょう。手動のマネジメントコンソールポチポチ作業は、インフラの再現性を下げるため極力避けるのがSREの流儀です。

パターンA: Terraformによる宣言的インフラ構築

現代のインフラ管理のデファクトスタンダードであるTerraformでの記述例です。社内DNSとして 10.0.0.10 と 10.0.0.11 を利用し、ドメイン名を hoge.internal に設定するシナリオを想定しています。

# 1. カスタムDHCPオプションセットの定義
resource "aws_vpc_dhcp_options" "custom_dhcp" {
  domain_name          = "hoge.internal"
  domain_name_servers  = ["10.0.0.10", "10.0.0.11"]
  ntp_servers          = ["169.254.169.123"] # AWSのデフォルトNTPを指定
  netbios_node_type    = 2                   # Windowsクライアント向けのブロードキャスト抑制(通常は2)

  tags = {
    Name        = "prod-custom-dhcp-options"
    Environment = "production"
  }
}

# 2. VPC本体の作成(サンプル)
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "prod-vpc"
  }
}

# 3. VPCとDHCPオプションセットの関連付け(ここが重要!)
resource "aws_vpc_dhcp_options_association" "dns_association" {
  vpc_id          = aws_vpc.main.id
  dhcp_options_id = aws_vpc_dhcp_options.custom_dhcp.id
}

パターンB: AWS CLIによる即時適用(検証・アドホック環境用)

手元でサクッと検証したい場合や、CI/CDパイプラインの一部としてシェルスクリプトで制御する場合のAWS CLIコマンドです。

#!/usr/bin/env bash
set -euo pipefail

# 変数の定義
VPC_ID="vpc-0123456789abcdef0"
CUSTOM_DNS="10.0.0.10,10.0.0.11"
DOMAIN_NAME="hoge.internal"

echo "==> 1. 新しいDHCPオプションセットを作成します..."
DHCP_OPTIONS_ID=$(aws ec2 create-dhcp-options \
    --dhcp-configurations "Key=domain-name-servers,Value=${CUSTOM_DNS}" "Key=domain-name,Value=${DOMAIN_NAME}" \
    --query 'DhcpOptions.DhcpOptionsId' \
    --output text)

echo "作成されたDHCPオプションセットID: ${DHCP_OPTIONS_ID}"

echo "==> 2. VPC (${VPC_ID}) にDHCPオプションセットを関連付けます..."
aws ec2 associate-vpc-dhcp-options \
    --vpc-id "${VPC_ID}" \
    --dhcp-options-id "${DHCP_OPTIONS_ID}"

echo "==> 3. 関連付けが完了しました。"

—

4. 適用後のトラップとデバッグ:パケットはどこへ向かうのか?

「Terraformを適用した!よし、インスタンスを再起動しよう!」
ここで一つ重要な事実をお伝えしなければなりません。VPCに新しいDHCPオプションセットをアタッチしても、すでに稼働中のEC2インスタンスは自動的に新しい設定を読み込みません。

DHCPのリース期間(Lease Time)が切れるか、あるいはインスタンス側でネットワークをリフレッシュ(OSの再起動、もしくはDHCPクライアントの再起動)しない限り、古い設定(AmazonProvidedDNS)を使い続けます。

現場で使えるデバッグ・確認コマンド

インスタンスにSSHやSession Managerでログインし、意図した通りにDNSやドメインが設定されているか確認する手順です。

1. /etc/resolv.conf の中身を覗き見する

現代のLinux(UbuntuやAmazon Linux 2023など)では、systemd-resolved が間に入っていることが多いですが、最終的なDNSサーバーが意図したIPに向いているか確認します。

# 現在参照されているDNSサーバーとドメインの確認
resolvectl status
# あるいは従来通りの確認
cat /etc/resolv.conf

出力結果の中に、私たちが指定した 10.0.0.10 が含まれていることを確認してください。

2. 意図したドメインサフィックスで名前解決テスト

nslookup や dig コマンドを使い、短いホスト名(FQDNではない名前)で引いたときに、正しく hoge.internal が補完されて名前解決できるかをテストします。

# 短縮名での名前解決テスト
nslookup my-api-server

# 期待される動作:
# サーバ:   10.0.0.10
# Address:  10.0.0.10#53
#
# 名まえ:   my-api-server.hoge.internal
# Address: 10.0.0.50

もしここで connection timed out や SERVFAIL が返ってきた場合は、インスタンスからカスタムDNSサーバー(10.0.0.10)へのセキュリティグループ(Security Group)やネットワークACL(NACL)のポート 53(TCP/UDP)の疎通がブロックされていないか、パケットキャプチャや nc -zv コマンドで即座にレイヤー4の疎通確認を行いましょう。

—

5. まとめ

AWS VPCにおけるDHCPオプションセットのカスタマイズは、単なる「IPの割り当て設定」ではありません。オンプレミスとクラウドをシームレスに繋ぐハイブリッドアーキテクチャの根幹であり、マイクロサービスの名前解決戦略を左右する重要なインフラの意思決定です。

  • デフォルトのオプションセットは変更できないため、カスタムのセットを新規作成してVPCにアタッチする。
  • カスタムDNSを指定する際は、外部へのフォワーディング(転送設定)を忘れないと同時に、セキュリティグループのポート 53 を確実に空けておく。
  • 適用後はインスタンス側のDHCPリース更新(再起動など)を忘れずに実施する。

この一連のライフサイクルとトラブルシューティングの勘所を押さえておけば、どれほど複雑なネットワーク要件を持つエンタープライズ環境であっても、自信を持ってAWS上のインフラをコントロールできるようになります。

あなたの構築するクラウドインフラが、今日も安定したパケットの奔流に包まれますように。それでは、また次回の現場でお会いしましょう!

コメント

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