LoginSignup
1

posted at

updated at

ExternalDNSをさくらのクラウドに対応させたので使ってみる

本稿は、さくらのアドベントカレンダー2022 24日目の投稿です。

さくらインターネットの相馬です。
今回は、さくらのクラウド DNSアプライアンスに対応させたExternalDNSの使い方を紹介させていただきます。

ExternalDNSはDNSゾーンを操作するため、環境に影響が出ないことを保証できません。
実際にお試しになる場合は自己責任でお願いします。

ExternalDNSとは

ExternalDNSは、Kubernetesにおいてサービス公開のために Ingress リソースや Service リソースを作成/更新した際にDNSレコードを動的に設定してくれるアドオンです。

例えば、以下のような Ingress リソースを作成することで、ドメイン名 example.com に対するAレコードを登録することができます。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example
  namespace: example
spec:
  ingressClassName: traefik
  rules:
  - host: "example.com"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: example
            port:
              number: 80

 

現状のExternalDNS(v0.13.1現在)は、DNSプロバイダとしてさくらのクラウドは対応しておりません。
したがって今回、さくらのクラウド DNSアプライアンスをExternalDNSに対応させて使ってみました。

ExternalDNSにおけるプロバイダの開発方法につきましては下記の記事で紹介しておりますのでご興味がありましたら参照してください。

デプロイ

まず、下記マニフェストをKubernetesクラスタに適用し、ネームスペースの作成、RBACの設定を行います。

---
apiVersion: v1
kind: Namespace
metadata:
  name: external-dns
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
  namespace: external-dns
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-dns
rules:
- apiGroups: [""]
  resources: ["services","endpoints","pods"]
  verbs: ["get","watch","list"]
- apiGroups: ["networking.k8s.io"]
  resources: ["ingresses"]
  verbs: ["get","watch","list"]
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["list","watch"]
---
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: external-dns
---

 

次に、さくらのクラウドのAPIキー情報を持った Secret リソースとさくらのクラウドに対応したExternalDNSをデプロイします。
(実際にAPIキーなどの機密情報を保管する際はSealed Secretsといった Secret リソースをセキュアに管理する方法を利用してください。)

Secret リソースにおいて、SAKURACLOUD_ACCESS_TOKEN にはAPIキーのアクセストークンを、SAKURACLOUD_ACCESS_TOKEN_SECRET にはAPIキーのアクセストークンシークレットを指定します。

---
apiVersion: v1
kind: Secret
metadata:
  name: sakuracloud
  namespace: external-dns
type: Opaque
data:
  SAKURACLOUD_ACCESS_TOKEN: "<your sakuracloud access token>"
  SAKURACLOUD_ACCESS_TOKEN_SECRET: "<your sakuracloud access token secret>"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
  namespace: external-dns
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: external-dns
  template:
    metadata:
      labels:
        app: external-dns
    spec:
      serviceAccountName: external-dns
      containers:
      - name: external-dns
        image: sosomasox/external-dns:latest
        args:
        - --source=service
        - --source=ingress
        - --domain-filter=example.com
        - --provider=sakuracloud
        #- --log-level=debug # debug only
        env:
        - name: SAKURACLOUD_ACCESS_TOKEN
          valueFrom:
            secretKeyRef:
              name: sakuracloud
              key: SAKURACLOUD_ACCESS_TOKEN
        - name: SAKURACLOUD_ACCESS_TOKEN_SECRET
          valueFrom:
            secretKeyRef:
              name: sakuracloud
              key: SAKURACLOUD_ACCESS_TOKEN_SECRET
---

 

APIキー作成時には適切なアクセスレベル(作成・削除の権限が必要)を設定する必要があります。
APIキーの作成方法につきましては下記のドキュメントを参照ください。

 

下記はさくらのクラウドに対応したExternalDNSを稼働させるDeployment リソースの spec の部分を抜粋したものです。

spec.containers.args--domain-filter にはさくらのクラウド DNSアプライアンスで作成したDNSゾーンを指定してください。
また、--provider にはDNSプロバイダとしてさくらのクラウドを利用することを表す sakuracloud を指定します。
(ログにおいてデバッグメッセージが不必要な場合は --log-level をコメントアウト、またはその他のログレベルにしてください。)

    spec:
      serviceAccountName: external-dns
      containers:
      - name: external-dns
        image: sosomasox/external-dns:latest
        args:
        - --source=service
        - --source=ingress
        - --domain-filter=example.com
        - --provider=sakuracloud
        - --log-level=debug # debug only
        env:
        - name: SAKURACLOUD_ACCESS_TOKEN
          valueFrom:
            secretKeyRef:
              name: sakuracloud
              key: SAKURACLOUD_ACCESS_TOKEN
        - name: SAKURACLOUD_ACCESS_TOKEN_SECRET
          valueFrom:
            secretKeyRef:
              name: sakuracloud
              key: SAKURACLOUD_ACCESS_TOKEN_SECRET

動作確認

まず、下記マニフェストをKubernetesクラスタに適用し、Nginxのコンテナを稼働させ、Ingress リソースでサービス公開します。
(本環境ではIngressコントローラーとしてtraefikを利用しています。)

---
apiVersion: v1
kind: Namespace
metadata:
  name: test-web
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-web
  namespace: test-web
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: test-web
  template:
    metadata:
      labels:
        app.kubernetes.io/name: test-web
    spec:
      containers:
      - name: test-web
        image: nginx:1.23
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: test-web
  namespace: test-web
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    app.kubernetes.io/name: test-web
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-web
  namespace: test-web
spec:
  ingressClassName: traefik
  rules:
  - host: test.sosomasox.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: test-web
            port:
              number: 80
---

 

次に、Kuberneteクラスタ上にリソースが作成されたことを確認します。

$ kubectl -n test-web get all,ingress
NAME                            READY   STATUS    RESTARTS   AGE
pod/test-web-586cc45d97-njrvw   1/1     Running   0          5s

NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/test-web   ClusterIP   10.96.207.16   <none>        80/TCP    5s

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/test-web   1/1     1            1           5s

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/test-web-586cc45d97   1         1         1       5s

NAME                                 CLASS     HOSTS                ADDRESS        PORTS   AGE
ingress.networking.k8s.io/test-web   traefik   test.sosomasox.com   172.18.255.1   80      5s

 

ExternalDNSによって、Ingress リソースの情報に対応したDNSレコードがさくらのクラウド DNSアプライアンス上に設定されているか、クラウドのコントロールパネルから確認してみます。

↓ちゃんと設定されている!
DNSゾーン.png

また、ExternalDNSのコンテナログにもDNSレコードの作成が行われていることが確認できました。

time="2022-12-22T07:06:07Z" level=debug msg="No endpoints could be generated from service test-web/test-web"
time="2022-12-22T07:06:07Z" level=debug msg="Endpoints generated from ingress: test-web/test-web: [test.sosomasox.com 0 IN A  172.18.255.1 []]"
time="2022-12-22T07:06:07Z" level=debug msg="change.Create: iaas.DNSRecord{Name:\"test\", Type:\"A\", RData:\"172.18.255.1\", TTL:300}"
time="2022-12-22T07:06:07Z" level=debug msg="change.Create: iaas.DNSRecord{Name:\"test\", Type:\"TXT\", RData:\"heritage=external-dns,external-dns/owner=default,external-dns/resource=ingress/test-web/test-web\", TTL:300}"
time="2022-12-22T07:06:07Z" level=debug msg="change.Create: iaas.DNSRecord{Name:\"a-test\", Type:\"TXT\", RData:\"heritage=external-dns,external-dns/owner=default,external-dns/resource=ingress/test-web/test-web\", TTL:300}"

最後に

本稿では、さくらのクラウド DNSアプライアンスに対応させたExternalDNSの使い方を紹介させていただきました。

現状、さくらのクラウドに対応させたExternalDNSは私個人でメンテナンスしております。
もし、さくらのクラウド対応ExternalDNSに需要がありそうでしたら、さくらインターネットでメンテナンスし、Helmチャート化とリポジトリの公開、ひいてはExternalDNSのupstreamへのマージなどできればと思います。

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
What you can do with signing up
1