LoginSignup
11
9

More than 5 years have passed since last update.

AWSハイブリッド構成にてRoute 53 Private Hosted Zoneでサブドメインを管理する

Last updated at Posted at 2018-05-15

前提となる環境

  • オンプレミス環境に既に権威サーバがある(例: example.org)
  • AWS Direct ConnectやVPNでオンプレミス環境とAmazon VPCを接続している

やりたいこと

  • Route 53 Private Hosted Zoneでサブドメインを管理したい(例: sub.example.org)
  • サブドメインをオンプレミス側からでも解決できるようにしたい

課題

  • Route 53 Private Hosted Zoneがサブドメインの委任に対応していない
  • Amazon DNSがVPC専用のため、オンプレミスからのリクエストに直接応答できない

モチベーション

クラスメソッドさんがまとめられたAWSハイブリッド構成のDNS設計レシピ設計レシピ5 : オンプレミスとAWSの権威サーバーを併用する では、上記課題があるためにRoute 53は使わずに、DNSキャッシュサーバと権威サーバをVPC内に構築するという設計パターンが紹介されています。

しかし、APIで色々とコントロールできるRoute 53はやっぱり魅力的なわけです。例えば弊社ではAWS上にKubernetesを構築して開発環境用の各種サーバを運用しているのですが、そうするとDNSレコードの登録をKubernetesへのデプロイと連動させて自動化したい、というモチベーションがありました。

また、バックアップ運用など、耐障害を考慮したDNSサーバを自前で構築・運用したくないというのもモチベーションのひとつです。Route 53のSLAは100%であり魅力的です。

というわけで本記事では、VPC内に権威サーバとして振る舞いつつバックエンドにRoute 53 Private Hosted Zoneを使用するDNSサーバを配置し、上記課題を解決する方式について説明したいと思います。

実現方式

前述のとおり、

  • 権威サーバをVPC内に構築する
  • その権威サーバでは直接サブドメイン管理をせずに、Amazon DNSにリクエストを委譲してRoute 53 Private Hosted Zoneにて名前解決を行う

ということを実現すればよさそうです。今回実現にあたり、CoreDNS に自作プラグイン(Amazon DNS plugin)を追加することで対応しています。構成図としては以下のようになります。

image.png

※BINDなどのよく使われるDNSサーバはフォワーダーとしては設定できますが、権威サーバとして振る舞うように設定ができませんでした。もし設定できる/他のDNSサーバでできるよ、という情報がありましたら是非教えていただきたいです :bow:

CoreDNSとは

CoreDNSについて簡単に説明しておきます。

CoreDNSはGolangで実装されたDNSサーバで、KubernetesのデフォルトDNSとしてkube-dnsの代わりとなることが予定されています

Currently, CoreDNS is Alpha in Kubernetes 1.9. We have a roadmap which will make CoreDNS Beta in version 1.10 and eventually be the default DNS, replacing kube-dns.

CoreDNSの特徴として、プラグインでDNSのリクエスト・レスポンス処理の拡張が簡単に行えるという点があります。

今回作成したAmazon DNS pluginでは、リクエストを受け付けるとVPC内のAmazon DNSに対してそのままリクエストをフォワードし、レスポンスを返す際に権威サーバの情報を付加して返す、ということをやっています。

CoreDNSそのものについては、QiitaにもCoreDNS入門記事がありますのでそちらを参照してみてください。

CoreDNS(+Amazon DNS plugin)の設定

CoreDNSの設定はとてもシンプルです。ゾーンごとに適用したいプラグインの設定を並べる形となります。今回作成したAmazon DNS pluginの設定としては、

  • soa: SOAレコード設定
  • ns: NSレコード設定(複数設定可)
  • nsa: NSレコードで設定したFQDNを解決するためのAレコード設定(複数設定可)

を行うようにしています。例えば、サブドメインとしてsub.example.orgを管理する設定としては、以下のような設定になります。

. {
    amazondns sub.example.org {
        soa "sub.example.org 3600 IN SOA ns.sub.example.org hostmaster.sub.example.org (2018030619 3600 900 1209600 900)"
        ns "sub.example.org 3600 IN NS ns.sub.example.org"
        nsa "ns.sub.example.org 3600 IN A 192.168.0.10"
    }
}

また、ネームサーバが複数台構成としたい場合(例えば、AWSなのでマルチAZ構成でAZ単位にネームサーバを配置したい場合)があるかと思いますが、その場合は下記のように複数設定ができるようにしています。

. {
    amazondns sub.example.org {
        soa "sub.example.org 3600 IN SOA ns1.sub.example.org hostmaster.sub.example.org (2018030619 3600 900 1209600 900)"
        ns "sub.example.org 3600 IN NS ns1.sub.example.org"
        ns "sub.example.org 3600 IN NS ns2.sub.example.org"
        nsa "ns1.sub.example.org 3600 IN A 192.168.0.10"
        nsa "ns2.sub.example.org 3600 IN A 192.168.0.130"
    }
}

動作確認

事前設定

上記CoreDNSの設定でCoreDNSをVPC内で起動しつつ、AWSの環境を

  • Route 53 Private Hosted Zoneをsub.example.orgというFQDNで作成し、VPCにアタッチ
  • 上記ゾーンにtest.sub.example.orgのAレコードを登録
  • ELBを作成し、上記ゾーンにlb.sub.example.orgでELBのCNAMEレコードを登録

のように設定しておきます。

名前解決

CoreDNSを起動しているサーバにて、digコマンドを使って動作を確認してみます。権威サーバとしての挙動を確認したいので、+norecurseをつけています。

test.sub.example.orgのAレコードが返るだけでなく、AUTHORITY SECTIONADDITIONAL SECTIONが合わせて返ってきているところがポイントです。

> dig @localhost test.sub.example.org +norecurse

; <<>> DiG 9.11.1 <<>> @localhost test.sub.example.org +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 28681
;; flags: qr aa ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 3

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 23246de45b4a3601 (echoed)
;; QUESTION SECTION:
;test.sub.example.org.        IN  A

;; ANSWER SECTION:
test.sub.example.org.   3600  IN  A  10.0.0.10

;; AUTHORITY SECTION:
sub.example.org.        3600  IN  NS  ns1.sub.example.org.
sub.example.org.        3600  IN  NS  ns2.sub.example.org.

;; ADDITIONAL SECTION:
ns1.sub.example.org.    3600  IN  A   192.168.0.10
ns2.sub.example.org.    3600  IN  A   192.168.0.130

;; Query time: 12 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Feb 20 15:11:55 JST 2018
;; MSG SIZE  rcvd: 146

NSレコードも確認してみます。こちらはCoreDNSの設定ファイルに記述したNSレコードの設定が静的に返ってきます。

> dig @localhost sub.example.org ns

; <<>> DiG 9.11.1 <<>> @localhost sub.example.org ns +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2719
;; flags: qr aa ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 3

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: c1c3332966dba8fd (echoed)
;; QUESTION SECTION:
;sub.example.org.            IN  NS

;; ANSWER SECTION:
sub.example.org.       3600  IN  NS  ns1.sub.example.org.
sub.example.org.       3600  IN  NS  ns2.sub.example.org.

;; ADDITIONAL SECTION:
ns1.sub.example.org.   3600  IN  A   192.168.0.10
ns2.sub.example.org.   3600  IN  A   192.168.0.130

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Feb 20 15:08:27 JST 2018
;; MSG SIZE  rcvd: 125

最後に、作成しておいたELBのCNAMEレコードを解決してみます。通常、CNAMEレコードが返ってくるところなのですが、Amazon DNS pluginの内部処理でAレコードに敢えて変換して返しています(Route 53のAliasのような挙動になります)。こうするとこで、問い合わせ元がAmazon DNSに到達できない場所、つまりVPC外でも名前解決できるようにしています。

> dig @localhost lb.sub.example.org

; <<>> DiG 9.11.1 <<>> @localhost test.sub.example.org +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63630
;; flags: qr aa ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 3

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 89a840e16b4d3fc7 (echoed)
;; QUESTION SECTION:
;lb.sub.example.org.         IN  A

;; ANSWER SECTION:
lb.sub.example.org.    54    IN  A   10.0.0.16
lb.sub.example.org.    54    IN  A   10.0.0.132

;; AUTHORITY SECTION:
sub.example.org.       3600  IN  NS  ns1.sub.example.org.
sub.example.org.       3600  IN  NS  ns2.sub.example.org.

;; ADDITIONAL SECTION:
ns1.sub.example.org.   3600  IN  A   192.168.0.10
ns2.sub.example.org.   3600  IN  A   192.168.0.130

;; Query time: 11 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Feb 27 11:20:08 JST 2018
;; MSG SIZE  rcvd: 174

上位の委任元へのフォワード設定

CoreDNSの設定に下記のように上位ドメインに対するフォワード設定を追記しておきます。これにはCoreDNSに付属のproxyプラグインを利用しています。こうすることで、VPC内からこのDNSサーバに対して上位ドメインの名前解決がリクエストされた場合は、オンプレミス側のDNSサーバに問い合わせがフォワードされ名前解決が可能になります。

example.org {
    proxy . /etc/resolv.conf
}

/etc/resolv.conf にはオンプレミス側のネームサーバを設定しておきます。

注意点として、VPC内ではデフォルトではAmazon DNSがDNSサーバとして設定されるため、VPC内のDNSクライアント側では明示的にCoreDNSのサーバをDNSサーバとして設定するか、VPCのデフォルトのDNSサーバを設定変更する必要があります。

上位の委任元のDNSサーバの設定

上位のドメイン(例: example.org)を管理しているDNSサーバにはサブドメイン(例: sub.example.org)への委任を示すグルーレコードの登録をお忘れなく。この登録が完了すれば、オンプレ側のネットワークからサブドメイン配下のFQDNの名前解決ができるようになります。

その他考慮点

せっかくRoute 53を利用しても、CoreDNSサーバの障害対策ができていなければSLA100%の意味がありません。今運用している環境では、AZ障害も考慮して、

という構成にしています。また、上記環境の構築をCloudFormationで自動化もしており、

  • cfn-initでEC2起動時にCloudWatch LogsのエージェントのインストールやCoreDNSのインストール・設定させる

ということもしております。これにより、他のVPCにも横展開が容易にできるようにもしています。

まとめ

AWSハイブリッド構成にて、Route 53 Private Hosted Zoneでサブドメインを管理する方式の一つとして、CoreDNSを活用した方式を紹介しました。同じようにオンプレ-AWSのハイブリッド環境でRoute 53を活用したくて悩んでいらっしゃる方の助けになれば幸いです。

参考

11
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
9