IBM Cloud: DNSサービスのCustom Resolver機能

# 1. はじめに
DNSサービスで[Custom Resolver](https://cloud.ibm.com/docs/dns-svcs?topic=dns-svcs-custom-resolver&locale=en)という機能が利用できるようになっていた（2021/07/14現在、ベータです）ので試してみました。

`Custom Resolver`は、簡単に言ってしまえば、DNS forwarderを実現する機能です。オンプレミスのDNSと連携することで、

- オンプレミスから、IBM Cloud上のDNSサービスが提供するDNSレコードの名前解決
- IBM Cloud上のVPCから、オンプレミス上のDNSが提供するDNSレコードの名前解決(DNS forwarding)

の両方が可能になります。



# 2. Custom Resolverの作成
DNSサービスにて、`Custom resolver`を左側のメニューから選択して作成可能です。以下のように指定したSubnetの中に、`resolver location`(オンプレミスなどの外部から参照可能なDNS resolverのIPアドレスでもあり、VPC上のサーバーがresolverとして参照するIPアドレスにもなる）が作成されます。以下の例では、`10.0.0.23`で作成されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/9dade1fb-ab11-0069-3970-642050eb8129.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/295f4882-014c-fe3f-10d5-98e317694daa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/edaafa0c-644d-e767-cbe9-2de04b6603e8.png)

:::note
今回の例ではテスト目的のために、Resolve locationsは１つしか登録していません。本番環境では必ず２つ以上のResolve locationsを登録することを推奨します
:::


# 3. オンプレミス（Direct Link越し）からのDNS Resolverとしてのテスト
今回は、Power Systems Virtual Server(AIX)とVPCをDirect Link 2.0で接続しているので、Power Systems Virtual Server(AIX)をオンプレミス環境と見立てて動作確認をしてみます。ちなみに、この`resolover location`として割り当てられたIPアドレスに対しては、Direct Link経由で現在でもアクセスすることができます。

:::note
`Resolver locations`の設定における`Enabled`/`Disabled`は、Custom Resolverを有効(`Enabled`)にした際に、該当のIPアドレスをDHCPでVPC上のサーバーに配布するかどうかを制御しています。
`Resolver locations`のIPアドレスを直接指定するのであれば、この設定が`Enabled`でも`Disabled`でも該当のIPアドレスを使って名前解決が可能です（必ずしも`Custom resolver`を`Enabled`にする必要がありません）。
逆に、`Resolver locations`のIPアドレスを直接指定しても名前解決をさせないようにするためには、該当の`Resolver locations`を削除する必要があります。
:::


https://www.ibm.com/support/pages/aix-toolbox-linux-applications-downloads-alpha

```txt:AIXにて実行。www.google.comの名前解決
bash-4.3# dig +short www.google.com @8.8.8.8
142.250.217.68
bash-4.3# dig +short www.google.com @10.0.0.23
172.217.24.132
```

```txt:AIXにて実行。ミラーサーバー（ClassicInfrastuctureのPrivateNW内部に存在）の名前解決
bash-4.3# dig +short mirrors.service.networklayer.com @8.8.8.8
10.0.77.54
bash-4.3# dig +short mirrors.service.networklayer.com @10.0.0.23
10.0.77.54
```

```txt:AIXにて実行。NTPサーバー(PrivateNW内部に存在）の名前解決
bash-4.3# dig +short time.adn.networklayer.com  @8.8.8.8
161.26.0.6
bash-4.3# dig +short time.adn.networklayer.com  @10.0.0.23
161.26.0.6
```

ここからがある意味本題。DNS Serviceで指定したレコード（これは、Permitted networksで指定したVPC内部からしか本来は参照できない！）をちゃんと参照できるかどうかの確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/4f46f947-baac-eb67-08d4-04b705f03d89.png)


```txt:AIXにて実行。DNSサービスで定義したDNSレコード(PermittedNetworkで指定したVPCからのみ利用可能）の名前解決
bash-4.3# dig +short www.roksvpc.internal @8.8.8.8
（何も返って来ない）

bash-4.3# dig +short www.roksvpc.internal @10.0.0.23
10.240.0.10
```

# 4. オンプレミス（Direct Link越し）へのDNS Forwardingのテスト
次に、VPC上のVSIから、オンプレに見立てたPower Systems Virtual Server(AIX)上のDNSを利用できるかどうかを検証します。
今回は、`syasuda.local`と言うドメインがオンプレミス上に存在するため、`www.syasuda.local`とか`smtp.syasuda.local`のようなFQDNに対するDNS Queryに対してはオンプレミス側のDNSを参照するように構成します。

- DNS Forwarding rulesの設定。ここで、192.168.50.223はDirect Link越しにアクセス可能なAIXのIPアドレスです。<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/08b25a36-4e7d-6a6c-2024-d2d548774303.png)
- Custom Resolverの有効化（以下のようにEnabledにする）。これにより、VPC上のVSIに対してDHCPでResolver LocationのIPアドレスが割り振られるようになります。<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/28a5b12e-be7f-fc7a-2cef-d28bfa783671.png)

```txt:CustomResolverのStatusがEnabledになっていない時。
# cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
nameserver 161.26.0.7
nameserver 161.26.0.8
```

```txt:CustomResolverのStatusがEnabledになっている時。
# cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
nameserver 10.0.0.23
```


実際に、VPC上のVSIでdigを実行すると、Direct Linkの対抗側にあるAIXには`resolover location`(10.0.0.23)からDNS Queryが届いています。


```txt:VPC上のVSIでdigを実行
# dig +short www.syasuda.local
100.0.0.1
```

```txt:AIX上でのtcpdump。確かにresolverlocationIPからport53に対してDNSQueryが届いている。
bash-4.3# tcpdump -i en1 port 53 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en1, link-type EN10MB (Ethernet), capture size 262144 bytes
11:49:35.736265 IP 10.0.0.23.36731 > 192.168.50.223.53: 7534+ [1au] A? www.syasuda.local. (46)
11:49:35.736661 IP 192.168.50.223.53 > 10.0.0.23.36731: 7534*- 1/1/1 A 100.0.0.1 (85)
```

# 5. Red Hat OpenShift on IBM Cloudのworker nodeへの反映

Red Hat OpenShift on IBM CloudはManagedのOpenShift環境であり、worker nodeに直接ログインすることはできませんが、以下のように`oc debug node` コマンドを使用すると、クラスターの任意のノードでシェルプロンプトを開くことができます。
以下では、Custom Resolver機能を有効化したVPC環境にあるRed Hat OpenShift on IBM Cloud環境で、/etc/resolv.confがResolver LocationのIPアドレスに更新されていることを確認し、そのworker nodeからもDNS forwardingによってオンプレ環境上のDNSサーバーに登録されているDNSレコードが引けることを確認しました。

```
# oc get nodes
NAME        STATUS   ROLES           AGE    VERSION
10.0.0.19   Ready    master,worker   7d5h   v1.20.0+87cc9a4
10.1.0.18   Ready    master,worker   7d5h   v1.20.0+87cc9a4

# oc debug -t node/10.0.0.19
Creating debug namespace/openshift-debug-node-ttfp2 ...
Starting pod/100019-debug ...
To use host binaries, run `chroot /host`
Pod IP: 10.0.0.19
If you don't see a command prompt, try pressing enter.
sh-4.4# chroot /host
sh-4.2# cat /etc/resolv.conf
; generated by /usr/sbin/dhclient-script
nameserver 10.0.0.23
sh-4.2# dig +short www.syasuda.local
100.0.0.1
```


# 6. Red Hat OpenShift on IBM Cloudのコンテナーへの反映

Red Hat OpenShift on IBM CloudのCoreDNSは各ホストの/etc/resolv.confを参照している。

```
# oc get configmap dns-default -n openshift-dns -o yaml |grep forward -A 2 -B 2
        }
        prometheus 127.0.0.1:9153
        forward . /etc/resolv.conf {
            policy sequential
        }
```

と言うので、DNS forwardingもそのまま使えるかと思ったが、、、

```
# oc debug -t deployment/busybox
Starting pod/busybox-debug ...

Pod IP: 172.17.9.225
If you don't see a command prompt, try pressing enter.
/ # nslookup -type=A  www.yahoo.co.jp
Server:		172.21.0.10
Address:	172.21.0.10:53

www.yahoo.co.jp	canonical name = edge12.g.yimg.jp
Name:	edge12.g.yimg.jp
Address: 182.22.25.252

/ # nslookup -type=A  www.syasuda.local
Server:		172.21.0.10
Address:	172.21.0.10:53

** server can't find www.syasuda.local: NXDOMAIN
```

うまくいかない。DNSのPodを確認してみたところ、古いconfigmapを参照し続けているようだ。

```txt:CoreDNSが古い情報を見続けている
# oc get pods -n openshift-dns
NAME                READY   STATUS    RESTARTS   AGE
dns-default-f4sb7   3/3     Running   0          7d10h
dns-default-tg8cf   3/3     Running   0          7d10h

# oc exec -n openshift-dns dns-default-f4sb7 -- cat /etc/resolv.conf
Defaulting container name to dns.
Use 'oc describe pod/dns-default-f4sb7 -n openshift-dns' to see all of the containers in this pod.
nameserver 161.26.0.7
nameserver 161.26.0.8
```

よって、既存のDNSのpodを削除し再作成すると良い。

```
# oc delete pod dns-default-f4sb7 -n openshift-dns
pod "dns-default-f4sb7" deleted
# oc delete pod dns-default-tg8cf -n openshift-dns
pod "dns-default-tg8cf" deleted

# oc get pods -n openshift-dns
NAME                READY   STATUS    RESTARTS   AGE
dns-default-6sjgw   3/3     Running   0          38s
dns-default-jssf7   2/3     Running   0          7s

# oc exec -n openshift-dns dns-default-6sjgw -- cat /etc/resolv.conf
Defaulting container name to dns.
Use 'oc describe pod/dns-default-6sjgw -n openshift-dns' to see all of the containers in this pod.
nameserver 10.0.0.23

```

今度はうまくいった！

```
# oc debug -t deployment/busybox
Starting pod/busybox-debug ...
Pod IP: 172.17.9.229
If you don't see a command prompt, try pressing enter.
/ # nslookup -type=A  www.yahoo.co.jp
Server:		172.21.0.10
Address:	172.21.0.10:53

Non-authoritative answer:
www.yahoo.co.jp	canonical name = edge12.g.yimg.jp
Name:	edge12.g.yimg.jp
Address: 183.79.250.123

/ # nslookup -type=A  www.syasuda.local
Server:		172.21.0.10
Address:	172.21.0.10:53

Name:	www.syasuda.local
Address: 100.0.0.1
```