本記事は Google Cloud Platform その1 Advent Calendar 2018 - Qiita の4日目の記事です。
GCPといえば、BigQueryとかSpannerとかGKEとかの話が多いですが、ネットワーク関連のアップデートもしばしばあります。
少々前になりますが、GCPサービスの Cloud DNS がプライベートDNSゾーンに対応しましたので早速試してみました。
今回はgcloudコマンドで作成していきます。バージョンが 222.0.0
以上である必要があるためアップデートしておいてください。
$ gcloud components update
今回は以下のようなDNSレコードを設定してみます *1
DNS 名 | タイプ | TTL(秒) | データ |
---|---|---|---|
test-instance.example.com. | A | 60 | 10.0.0.6 |
test-instance2.example.com. | CNAME | 60 | test-instance.example.com. |
test-outdomain.example.com. | CNAME | 60 | foo.example.net. |
プライベートゾーンの作成
$ gcloud beta dns managed-zones create "my-new-zone" \ --dns-name="example.com" \ --description="exaple" \ --networks="default" \ --visibility=private
レコードの追加
# トランザクションの開始 $ gcloud dns record-sets transaction start \ --zone=my-new-zone # Aレコードの追加 $ gcloud dns record-sets transaction add 10.0.0.6 \ --type=A \ --name=test-instance.example.com. \ --ttl=60 \ --zone=my-new-zone # CNAMEレコードの追加 $ gcloud dns record-sets transaction add test-instance.example.com. \ --type=CNAME \ --name=test-instance2.example.com. \ --ttl=60 \ --zone=my-new-zone $ gcloud dns record-sets transaction add test-outdomain.example.com. \ --type=CNAME \ --name=foo.example.net. \ --ttl=60 \ --zone=my-new-zone # トランザクションの実行(適用) $ gcloud dns record-sets transaction execute \ --zone=my-new-zone
トランザクションを開始すると、ローカルに以下のような transaction.yaml
というファイルが生成され、transaction add
や transaction remove
するとYAMLファイルが編集されます。このファイルを直接編集してDNSレコードの追加・削除・変更を行なうこともできます。
transaction execute
を実行すると transaction.yaml
の内容がCloud DNSに反映されます。
$ cat transaction.yaml --- additions: - kind: dns#resourceRecordSet name: example.com. rrdatas: - ns-gcp-private.googledomains.com. cloud-dns-hostmaster.google.com. 2 21600 3600 259200 300 ttl: 21600 type: SOA deletions: - kind: dns#resourceRecordSet name: example.com. rrdatas: - ns-gcp-private.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 259200 300 ttl: 21600 type: SOA
追加したらGCEインスタンスに入って名前解決ができるか確認します。
$ dig test-instance.example.com ; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> test-instance.example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 145 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;test-instance.example.com. IN A ;; ANSWER SECTION: test-instance.example.com. 60 IN A 10.0.0.6 ;; Query time: 3 msec ;; SERVER: 169.254.169.254#53(169.254.169.254) ;; WHEN: 月 10月 29 10:51:45 UTC 2018 ;; MSG SIZE rcvd: 80 $ dig test-instance2.example.com ; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> test-instance2.example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17272 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;test-instance2.example.com. IN A ;; ANSWER SECTION: test-instance2.example.com. 60 IN CNAME test-instance.example.com. test-instance.example.com. 60 IN A 10.0.0.6 ;; Query time: 3 msec ;; SERVER: 169.254.169.254#53(169.254.169.254) ;; WHEN: 木 11月 01 10:20:56 UTC 2018 ;; MSG SIZE rcvd: 109
もちろん、VPCネットワーク外では名前解決ができません。
$ dig test-instance.example.com ; <<>> DiG 9.10.6 <<>> test-instance.example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 9921 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4000 ;; QUESTION SECTION: ;test-instance.example.com. IN A ;; AUTHORITY SECTION: example.com. 893 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2018100708 7200 3600 1209600 3600 ;; Query time: 62 msec ;; SERVER: 10.33.3.10#53(10.33.3.10) ;; WHEN: Thu Nov 01 19:13:01 JST 2018 ;; MSG SIZE rcvd: 111
外部ドメインのCNAMEレコードで名前解決ができない問題
先程設定したCNAMEレコードの test-outdomain.example.com
ですが名前を引くと以下のようにIPアドレスが返ってきません。この foo.example.net
はAレコードでIPアドレスが正引きできるものとします。
$ dig test-outdomain.example.com ; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> test-outdomain.example.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16587 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;test-outdomain.example.com. IN A ;; ANSWER SECTION: test-outdomain.example.com. 60 IN CNAME foo.example.net. # IPアドレスが返ってこない ;; Query time: 64 msec ;; SERVER: 169.254.169.254#53(169.254.169.254) ;; WHEN: Tue Nov 13 07:41:58 UTC 2018 ;; MSG SIZE rcvd: 142
サポートに問い合わせたところ、現時点でバグであり今後改善される予定とのことです。
サーバ内でDNSフォワーダを設定して内部DNSに向けるようにすれば、回避が可能です。これについては別の記事で詳しく取り上げていきたいと思います。
まとめ
Cloud DNSのプライベートDNSゾーンを設定してみました。一部バグがありますが、名前解決がVPCネットワーク内に閉じることができるため、外部に情報公開したくないドメインを設定できたり、アプリケーション側でサービスの利用などに使うことができますね。
試していませんが、複数VPCネットワークに紐付けができるので、ピアリングや共有VPCにすることで、プライベートDNSゾーンも共有しあってますます便利になるのではないかと思っています。
参考
*1:NS、SOAはゾーン作成時に自動生成されるため、表記上は省略しています