ExternalDNSでOCI DNSにDNSレコードを動的に登録してみよう

# はじめに

この記事は、[Oracle Cloud Infrastructure Advent Calender 2024 シリーズ 1 Day17](https://qiita.com/advent-calendar/2024/oci)の記事として書いています。

前回はNGINX Gateway Fabricを利用したGateway APIの利用について書きました。

https://qiita.com/takuya_0301/items/caaebe01716e05e5cd22

今回はその関連として、払い出されたLBのIPと自分が保持するドメインを動的にDNSサーバに登録するというのをやってみます。

# ExternalDNS

k8sにはExternalDNSという仕組みがあります。
この仕組みはk8s上のServiceリソースやIngressリソースを監視しつつDNSレコードを動的に管理できるというものです。
今回はGateway APIを利用してExternalDNSでの動的なDNSレコードの登録をやってみたいと思います。

https://github.com/kubernetes-sigs/external-dns

k8sとしてOKE、DNSサーバとしてOCI DNSを利用します。

# ExternalDNSのデプロイ

今回はOCI DNSを利用するので、[こちら](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/oracle.md)の設定に従います。

今回利用するManifestは以下になります。

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-dns
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - pods
      - nodes
      - namespaces
    verbs:
      - get
      - watch
      - list
  - apiGroups:
      - extensions
      - networking.k8s.io
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - gateway.networking.k8s.io
    resources:
      - gateways
      - httproutes
      - tlsroutes
      - tcproutes
      - udproutes
    verbs:
      - get
      - watch
      - list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-dns-viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
  - kind: ServiceAccount
    name: external-dns
    namespace: kube-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
  namespace: kube-system
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: external-dns
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      serviceAccountName: external-dns
      containers:
        - name: external-dns
          image: registry.k8s.io/external-dns/external-dns:v0.15.0
          args:
            - --source=gateway-httproute
            - --source=ingress
            - --source=service
            - --log-level=debug
            - --provider=oci
            - --policy=create-only
            - --txt-owner-id=my-identifier
            - --oci-zone-scope=
            - --oci-auth-instance-principal
            - --oci-compartment-ocid=ocid1.compartment.oc1..aaamlvfoscnamvmrzgdq
```

コンテナのargsでの以下の設定が注目ポイントです。

```sh
- --source=gateway-httproute
- --source=ingress
- --source=service
```

これはDNSレコードを登録する際の対象となるリソースを示しています。
今回は、前回の記事でも紹介したGateway APIのHTTPRoute、Ingress、Serviceを対象としています。

```sh
- --provider=oci
```

今回はDNSサーバとしてOCI DNSを利用するので、`oci`とします。


```sh
- --oci-auth-instance-principal
- --oci-compartment-ocid=ocid1.compartment.oc1..aaamlvfoscnamvmrzgdq
```

DNSレコードを動的に登録する際の認可の手法を記載します。
`--oci-auth-instance-principal`は[インスタンスプリンシパル](https://docs.oracle.com/ja-jp/iaas/Content/Identity/Tasks/callingservicesfrominstances.htm)を利用した認可を示します。
別の手法としてユーザプリンシパル(APIキー)を利用した認可もあります。
`--oci-compartment-ocid`は対象のDNSゾーンが存在するコンパートメントを示します。

これをデプロイします。

```sh
kubectl get deploy external-dns -n kube-system
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
external-dns   1/1     1            1           61s
```

# HTTPRouteのデプロイ

Gateway APIのHTTPRouteを作成します。

```sh
kubectl get httproute 
NAME   HOSTNAMES                 AGE
cafe   ["gateway.ochacafe.jp"]   29s
ocha   ["gateway.ochacafe.jp"]   29s
```

OCI DNSの画面を見てみます。

最初は以下の状態です。

![CleanShot 2024-12-17 at 21.53.03@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/c13b6696-9678-56e2-3651-3da1c3a74abb.png)

ExternalDNSを利用すると、HTTPRouteをデプロイした後に以下のように更新があります。

![CleanShot 2024-12-17 at 21.54.10@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/924dacd8-8d1d-a66f-d0de-07ffad0cd73a.png)

`リフレッシュ`をクリックすると

![CleanShot 2024-12-17 at 21.55.11@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40392/94845ee5-0960-1a5f-34bc-2c59d92c6ad0.png)

このようにプロビジョニングされたLoadBalancerのIPがAレコードとして登録されていることが確認できます。

# おわりに

ExternalDNSを利用するとDNSサーバへのレコード登録が自動化できます。
これを利用することで、デプロイされたアプリケーション環境構築がより迅速にできるようになりますね!!

# 参考

https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/oracle.md

https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengconfiguringdnsserver.htm

https://blogs.oracle.com/oracle4engineer/post/ja-enviro-isolation-oke-namespaces-externaldns