IBM Cloud: VPC からのプライベートな名前解決にDNS Services を使う(GUI編）

#1. はじめに
IBM CloudのVPCからのみ名前解決できるDNS機能があるため、それをGUIから利用してみます。コマンドラインでの設定方法については[こちら](https://qiita.com/khayama/items/93b1fb5b25b69eb2d6a6)で紹介されています。

#2. DNSサービスを注文する

<img width="1271" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/e167c641-e924-351d-bc2d-689702070120.png">
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/a3fe392d-999f-35b9-536d-e76c1c88061e.png">

#3. Zone（ドメイン）を作成する

`Create Zone`を押下してZoneを作成します。
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/fbdb4650-ae70-acde-d130-82ad60e1ee36.png">

ゾーン名（ドメイン名）は、`.local.`というTLDを利用するのは避けましょう。未だに`.local.`を使っている既存システムは多く、確かにIBM CloudのDNSサービスでも動くことは確認しましたが、そもそも推奨されていないのですから・・・
https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E5%90%8D
>内部（プライベート）向けに独自ドメインを利用することは名前衝突を避けるために推奨されない。しかしやむを得ずプライベートTLDを導入する際の指針がRFC 6762で示されている。
    - .local.を利用しない
    - 次のいずれかを利用する: .intranet., .internal., .private., .corp., .home., .lan.

ここでは`roksvpc.internal`というZoneを作成することにします。
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/2ff2cbca-8b60-d4bc-b27b-24abf21ead88.png">


"Permitted Network"タブを選択して、このDNSサービスを利用するVPCを選択します。（Pendingの状態なのはVPCが登録されていないためです）
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/3bc50207-78ae-0f73-c3cb-3b0662e42f92.png">

該当のVPCを選択します。
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/d9d78fc1-0f3b-9e6e-5bd6-525e7733de99.png">

#4. DNSレコードを登録する。

`Add Record`を押下してDNSレコードを作成します。
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/41b81f1a-8140-df8a-627e-9329ab100ea5.png">
ここではwwwというAレコードを作成しています。
<img width="1279" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/2e6c4ab2-ffdc-180d-bc11-c8bf951a94c1.png">




#5. VPC上のVSIから名前解決してみる
(2020/12/7補足)
VPCがpermitted networkに追加された状態でサーバーをプロビジョニングすると、自動的に161.26.0.7と161.26.0.8が使われるように仕様変更されたようです。これにより、`/etc/dhcp/dhclient.conf`を編集して手動でDNSサーバーを変更する作業は不要になりました。既存のサーバーも(約3分間隔で実施される）DHCPの更新タイミングで161.26.0.7と161.26.0.8に変更されます。これにより手動で変更する手順はドキュメントから削除されてしまったようです。代わりに、以下のような文言が追加されています。

> https://cloud.ibm.com/docs/dns-svcs?topic=dns-svcs-managing-permitted-networks
Newly created virtual server instances are automatically configured to use private DNS resolvers (161.26.0.7 and 161.26.0.8). Existing virtual server instances can take up to 3 minutes to be configured to use private DNS resolvers.

なお、だいぶ前にpermitted networkに追加されたVPCではこの機能が有効になっていない可能性があります。その場合は、いったんVPCをpermitted networkから削除して、再度permitted networkに追加しなおしてください。

-----------


上記で選択したVPC上のVSIから、名前解決してみると・・・うまくいきません！

```
# dig SOA +noall +answer roksvpc.internal
（何も返ってこない）

# dig A +noall +answer www.roksvpc.internal
（何も返ってこない）

# cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
nameserver 161.26.0.10
nameserver 161.26.0.11
```

実は、このDNSを利用するためには、`161.26.0.7, 161.26.0.8`というDNSに変更する必要があります。ただし、VPC上のVSIはDHCPで構成されており、再起動などを実施することで再度`161.26.0.10, 161.26.0.11`に上書きされてしまうため、上書きされないように以下のように構成します。
https://cloud.ibm.com/docs/dns-svcs?topic=dns-svcs-updating-dns-resolver#updating-dns-resolver-centos-vpcgen2


```txt:/etc/dhcp/dhclient.conf
supersede domain-search "roksvpc.internal";
supersede domain-name-servers 161.26.0.7, 161.26.0.8;
```

DHCP Clientを再起動します。

```
# dhclient -v -r eth0; dhclient -v eth0
Internet Systems Consortium DHCP Client 4.2.5
Copyright 2004-2013 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/eth0/02:00:04:0e:e6:54
Sending on   LPF/eth0/02:00:04:0e:e6:54
Sending on   Socket/fallback
DHCPRELEASE on eth0 to 10.240.0.1 port 67 (xid=0x6290bb7a)
Internet Systems Consortium DHCP Client 4.2.5
Copyright 2004-2013 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/eth0/02:00:04:0e:e6:54
Sending on   LPF/eth0/02:00:04:0e:e6:54
Sending on   Socket/fallback
DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 8 (xid=0x1a51a69f)
DHCPREQUEST on eth0 to 255.255.255.255 port 67 (xid=0x1a51a69f)
DHCPOFFER from 10.240.0.1
DHCPACK from 10.240.0.1 (xid=0x1a51a69f)
bound to 10.240.0.7 -- renewal in 137 seconds.
```

今度はうまくいきました！

```
# dig SOA +noall +answer roksvpc.internal
roksvpc.internal.	0	IN	SOA	ns1.dns-svcs.cloud.ibm.com. donotcontact.domaindoesnotexist.local. 1306010001 86400 7200 3600000 3600

# dig A +noall +answer www.roksvpc.internal
www.roksvpc.internal.	55	IN	A	10.240.0.10
```

また、ドメイン名を指定せずにホスト名指定でも名前解決できています。

```
# host www.roksvpc.internal
www.roksvpc.internal has address 10.240.0.10
```

#6. Red Hat OpenShift Container on IBM Cloud(VPC)上のPodから名前解決してみる

このVPC上にデプロイされたOpenShiftにログインし、Podから名前解決を試みてみます。
Worker nodeも実装としてはVSIのはずであり、DHCPの更新タイミングで161.26.0.7と161.26.0.8に変更されることにより、PodからもDNS Serviceで登録したレコードに対する名前解決ができるはずです。

```
# oc -it run dns-test --image=busybox --restart=Never --rm
If you don't see a command prompt, try pressing enter.
/ # hostname
dns-test
/ # nslookup -type=A www.roksvpc.internal
Server:		172.21.0.10
Address:	172.21.0.10:53

Name:	www.roksvpc.internal
Address: 10.240.0.10
/ # ping www.roksvpc.internal
PING www.roksvpc.internal (10.240.0.10): 56 data bytes
^C
--- www.roksvpc.internal ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
```