Documentation Index

Fetch the complete documentation index at: https://guide.ncloud-docs.com/llms.txt

Use this file to discover all available pages before exploring further.

External DNS 活用のユースケース

Prev Next

VPC環境で利用できます。

Ncloud Kubernetes Service(NKS)で ExternalDNSを使用して Kubernetesリソースと Global DNSサービスのレコードを同期できます。

使用前に確認

ExternalDNS活用のユースケースを行う前に、次のサポート範囲と準備事項をご確認ください。

項目 サポート範囲
利用環境 VPC
Kubernetes(NKS Add-on) 1.36.2以上
Kubernetes(Helm手動インストール) 1.33以上
ExternalDNS 0.21.0
サポートリソース Service, Ingress, DNSEndpoint
サポートレコードタイプ A, AAAA, CNAME, MX, TXT
認証方式 NKS Node IAM Roleまたは Sub Accountアクセスキー

ExternalDNSが管理するレコードタイプと条件は、次の通りです。

レコードタイプ 管理条件
A, AAAA, CNAME 基本管理対象
MX、直接定義した TXT Helm手動インストールで managedRecordTypesに追加した場合のみ管理(NKS Add-on未対応)
所有権の確認用 TXT registry: txt 設定に応じて自動作成(管理対象タイプとは関係なし)

次の項目を予め準備してください。

  • Ncloud Kubernetes Serviceクラスタ
  • kubectlを使用できる kubeconfig
  • Helm 3(手動インストール時)
  • Global DNSサービスに登録されたドメイン
  • ドメイン照会、レコードの照会/作成/変更/削除、変更事項の適用権限

インストール中に使用する値は、次の通りです。

入力値 説明
<KUBE_CONTEXT> ExternalDNSをインストールする kubeconfig context nks_kr_cluster_example
<DNS_ZONE> Global DNSサービスに登録された管理対象ドメイン example.com
<DNS_BASE_URL> 手動インストールに使用する環境別 Global DNS OpenAPIアドレス https://globaldns.apigw.ntruss.com/dns/v1
<WEBHOOK_IMAGE_TAG> 手動インストールに使用するウェブフックイメージの固定されたリリースタグ v1.0.0
<TXT_OWNER_ID> 手動インストールした ExternalDNSインスタンスを区分する固有値 nks-cluster-a
<INGRESS_CLASS> クラスタで使用する Ingress Class alb
<NODE_LABEL_KEY> Node IAM Roleが関連付けられているノードプールのラベルキー ncloud.com/nks-nodepool
<NODE_LABEL_VALUE> Node IAM Roleが関連付けられているノードプールのラベル値 pool2

可能であれば、クラスタ別に別途の Global DNSドメインや委任したサブドメインを使用します。複数のクラスタが同じドメインを共有する必要がある場合はクラスタごとに固有の <TXT_OWNER_ID>を使用し、同じホスト名を重複管理しないよう構成します。NKS Add-onは、クラスタ UUIDを txtOwnerId デフォルト値として使用します。
以下のコマンドを実行して kubeconfig contextと Ingress Classを確認します。

kubectl --context "<KUBE_CONTEXT>" cluster-info
kubectl --context "<KUBE_CONTEXT>" get ingressclass

Global DNSのドメイン準備

ExternalDNSで管理するドメインを Global DNSサービスに登録します。

例えば、example.comを管理ドメインとして指定すると、app.example.comのようなサブホストのレコードを作成できます。
公開 DNSでレコードを照会するには、ドメイン登録機関に Global DNSのネームサーバ情報を設定する必要があります。

参考

Kubernetesリソースに指定したホスト名が Global DNSの登録ドメインに含まれていない場合は DNSレコードを作成せずに警告ログを残します。

認証情報の準備

ウェブフックプロバイダは、NKS Node IAM Roleと Sub Accountアクセスキーをサポートします。2つの方式がすべて設定されている場合、Sub Accountアクセスキーを先に使用します。

NKS Node IAM Roleを使用する

NKS Node IAM Roleを使用する場合、長期アクセスキーを Kubernetes Secretに保存しなくても構いません。以下の順序に従って、ロールを準備します。

  1. ロール作成を参照して Serverタイプの Sub Accountロールを作成します。
  2. ロールに Global DNSドメインとレコード管理権限を追加します。
  3. ノードプールを作成する場合、当該ロールに Node IAM Roleを選択します。
  4. ExternalDNS Podが当該ノードプールに配置されるように、ノードラベルと taintを確認します。
参考

Node IAM Role設定の詳細については、Node IAM Role 活用のユースケースをご参照ください。

Global DNSの全機能を許可するには NCP_GLOBAL_DNS_MANAGER マネージドポリシーを使用できます。最小権限のユーザー定義ポリシーを使用する場合、次のアクションを選択します。

権限区分 選択するアクション
照会権限 getDomainList, getRecordList
変更権限 createRecord, updateRecord, deleteRecord, applyRecordConfig

Sub Accountは上記のアクションに必要な getDomainDetailgetRecordDetailを関連アクションとして自動追加します。自動的に追加された関連アクションの選択を解除しないでください。getDomainMonitordownloadRecordListcreateDomainuploadZonefiledeleteDomainchangeDNSSECstatusは必要ありません。

詳細は Global DNS の権限管理をご参照ください。

Sub Accountアクセスキーを使用する

Sub Accountアクセスキーを使用する場合、ExternalDNS Podが実行される名前空間に認証情報が含まれた Secretを作成します。
NKS Add-onは kube-system 名前空間にインストールされます。既存のクラスタに Add-onをインストールする場合、以下のコマンドを実行して Secretを予め作成します。

kubectl --context "<KUBE_CONTEXT>" --namespace kube-system \
  create secret generic ncloud-credentials \
  --from-literal=access-key="<NCLOUD_ACCESS_KEY>" \
  --from-literal=secret-key="<NCLOUD_SECRET_KEY>"

Add-on設定の credentials.secretNamencloud-credentialsを入力します。

クラスタ作成と同時に ExternalDNS Add-onをインストールする場合には、credentials.secretNameを先に入力できます。クラスタ作成が完了した後、kube-system 名前空間に Secretを作成し、以下のコマンドを実行して ExternalDNS Deploymentを再開してください。

kubectl --context "<KUBE_CONTEXT>" --namespace kube-system \
  rollout restart deployment/external-dns
kubectl --context "<KUBE_CONTEXT>" --namespace kube-system \
  rollout status deployment/external-dns --timeout=5m

Sub Accountアクセスキーを使用するには、Add-on設定の credentials.secretNameSecret名を入力します。Node IAM Roleを使用するには、値を空にします。同じ名前の Secretでアクセスキーを変更した場合には、ExternalDNS Deploymentを再起動することで、変更された値が適用されます。

Helmで手動インストールする場合、以下のコマンドを実行して external-dns 名前空間と Secretを作成します。

kubectl --context "<KUBE_CONTEXT>" create namespace external-dns
kubectl --context "<KUBE_CONTEXT>" --namespace external-dns \
  create secret generic ncloud-credentials \
  --from-literal=access-key="<NCLOUD_ACCESS_KEY>" \
  --from-literal=secret-key="<NCLOUD_SECRET_KEY>"

ExternalDNSのインストール

ExternalDNSは、NKS Add-onまたは Helmでインストールできます。

インストール方式 値設定 管理方式 推奨状況
NKS Add-on NKSが一部の値を自動的に組み込み、ユーザーは Add-onが提供する設定項目のみ入力 NKSで構成とバージョンを自動管理 NKSでサポートする設定範囲で運用する場合
Helm手動インストール ExternalDNS Helmチャートの全体値をユーザーが直接設定 インストール、アップグレード、削除をユーザーが直接管理 Add-onで提供しない値を設定する必要がある場合
参考

2つのインストール方式のうち、1つのみ選択します。同じクラスタに Add-onと Helmリリースを一緒にインストールすると、DNSレコードの所有権が競合することがあります。

NKS Add-onを利用したインストール

NKS Add-on機能で ExternalDNSを選択してインストールします。Add-onは ExternalDNSコンテナ、NAVERクラウドプラットフォーム用のウェブフックプロバイダ、DNSEndpoint CRD、サポートソースの serviceingresscrdに必要な RBACを一緒にインストールします。

Add-onはクラスタ UUIDと利用環境に応じた Global DNS OpenAPIアドレスなどの一部の値を自動的に組み込みます。ユーザーは Add-onが提供する設定項目のみ入力し、NKSが Add-onの構成とバージョンを自動的に管理します。Add-onが提供していない値を変更する必要がある場合、Helmを利用した手動インストールを行います。

主要 Add-on設定は次の通りです。

設定 デフォルト値 説明
domainFilter 空の値 管理する Global DNSドメイン。空の値の場合、使用中の認証情報で照会できる全ドメインが管理対象
sources service, ingress, crd DNSレコードを作成する Kubernetesリソースタイプ
policy upsert-only レコード変更ポリシー。syncupsert-onlycreate-onlyの中から選択
annotationFilter 空の値 指定したアノテーション条件と一致するリソースのみ処理
labelFilter 空の値 指定したラベル条件と一致するリソースのみ処理
txtPrefix _edns. 所有権 TXTレコード名のプレフィックス
txtSuffix 空の値 所有権 TXTレコード名のサフィックス
txtOwnerId クラスタ UUID ExternalDNSインスタンスの所有者識別子
logLevel info ログレベル
credentials.secretName 空の値 kube-system 名前空間の Sub Accountアクセスキー Secret の名前。Node IAM Role使用時に入力しない
scheduling.nodeSelector 空の値 Node IAM Roleが接続されたノードプールを選択
scheduling.extraTolerations 空の値 当該ノードプールの taint許可設定
参考

設定時に次の事項をご参照ください。

  • 運用環境では意図しないドメインが管理範囲に含まれないよう、管理するドメインを domainFilterに指定することをお勧めします。
  • Node IAM Roleを使用する場合、ロールが接続されたノードプールの scheduling.nodeSelectorと必要な scheduling.extraTolerationsを入力します。
  • Kubernetesリソースを削除する時、DNSレコードも一緒に削除するには、policysyncとして設定します。デフォルト値 upsert-onlyは、リソースを削除しても DNSレコードを維持します。
  • txtOwnerIdを入力しないと、クラスタ UUIDが使用されます。既存の ExternalDNSから移行する場合のみ、既存の所有者値を入力します。
  • txtPrefixtxtSuffixは、同時に設定できません。運用中に値を変更すると、既存の所有権 TXTレコードが残ることがあるため、インストール後には変更しないでください。
  • NKSが利用環境に適した Global DNS OpenAPIアドレスを自動的に設定するため、Add-onをインストールする時、dnsBaseUrlを入力しなくても構いません。
  • Add-onインストールステータスが正常に表示されたら、Service DNSレコード作成から行います。

Helmを利用した手動インストール

ExternalDNS Add-onを使用できない、またはユーザー定義設定を使用する必要がある場合、ExternalDNS公式 Helmチャートで手動インストールできます。手動インストールでは、インストール、値の変更、アップグレード、削除をユーザーが直接管理します。ExternalDNSコンテナと NAVERクラウドプラットフォーム用のウェブフックプロバイダは、1つの Podにリリースされます。

Node IAM Roleを使用する場合、以下のコマンドを実行して名前空間を作成します。

kubectl --context "<KUBE_CONTEXT>" create namespace external-dns

以下のコマンドを実行して ExternalDNS Helmストレージを追加します。

helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
helm repo update

手動インストールでは、利用環境に適した Global DNS OpenAPIアドレスを直接設定する必要があります。

利用環境 <DNS_BASE_URL>
個人/法人向け https://globaldns.apigw.ntruss.com/dns/v1
公共官公庁向け https://globaldns.apigw.gov-ntruss.com/dns/v1
金融 https://globaldns.apigw.fin-ntruss.com/dns/v1

次の内容をコピーして external-dns-values.yaml ファイルで保存します。
<DNS_ZONE><DNS_BASE_URL><TXT_OWNER_ID><WEBHOOK_IMAGE_TAG>は、準備した値に変更します。

image:
  tag: v0.21.0
sources:
  - service
  - ingress
  - crd
registry: txt
policy: sync
logLevel: info
txtPrefix: "_edns."
txtOwnerId: "<TXT_OWNER_ID>"
domainFilters:
  - "<DNS_ZONE>"
extraArgs:
  - --webhook-provider-read-timeout=90s
terminationGracePeriodSeconds: 120
provider:
  name: webhook
  webhook:
    image:
      repository: nks.kr.ncr.ntruss.com/nks/external-dns-navercloud-webhook
      tag: "<WEBHOOK_IMAGE_TAG>"
    env:
      - name: DOMAIN_FILTER
        value: "<DNS_ZONE>"
      - name: NCLOUD_DNS_BASE_URL
        value: "<DNS_BASE_URL>"
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    readinessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 3
      periodSeconds: 5
参考
  • このユースケースでは、sourcesserviceingresscrdに設定します。手動インストールでは、使用目的に応じてリソースタイプを追加・削除できます。
  • crdを使用する場合、ExternalDNS Helmチャートに含まれた DNSEndpoint CRDをインストール対象から削除しないでください。

手動インストールで MX レコードと Kubernetesリソースから直接定義した TXT レコードを管理するには、external-dns-values.yamlに次の値を追加します。

managedRecordTypes:
  - A
  - AAAA
  - CNAME
  - MX
  - TXT

txtPrefixは CNAMEレコードと所有権 TXTレコードの名前競合を防止します。txtOwnerIdは複数の ExternalDNSインスタンスが同じレコードを変更しないよう所有者を区分します。
Sub Accountアクセスキーを使用する場合、provider.webhook.envを次のように設定します。

    env:
      - name: DOMAIN_FILTER
        value: "<DNS_ZONE>"
      - name: NCLOUD_DNS_BASE_URL
        value: "<DNS_BASE_URL>"
      - name: NCLOUD_ACCESS_KEY
        valueFrom:
          secretKeyRef:
            name: ncloud-credentials
            key: access-key
      - name: NCLOUD_SECRET_KEY
        valueFrom:
          secretKeyRef:
            name: ncloud-credentials
            key: secret-key

以下のコマンドを実行して ExternalDNSをインストールします。

helm upgrade --install external-dns external-dns/external-dns \
  --kube-context "<KUBE_CONTEXT>" \
  --namespace external-dns \
  --version 1.21.1 \
  --values external-dns-values.yaml

Helmチャートをインストールする時、DNSEndpoint CRDも一緒にインストールされます。--skip-crds オプションを使用しないでください。
以下のコマンドを実行して ExternalDNSと CRDのステータスを確認します。

kubectl --context "<KUBE_CONTEXT>" --namespace external-dns \
  rollout status deployment/external-dns --timeout=5m
kubectl --context "<KUBE_CONTEXT>" --namespace external-dns get pod
kubectl --context "<KUBE_CONTEXT>" get crd dnsendpoints.externaldns.k8s.io

以下のコマンドを実行して ExternalDNSコンテナとウェブフックコンテナのログを確認します。

kubectl --context "<KUBE_CONTEXT>" --namespace external-dns \
  logs deployment/external-dns --all-containers=true --tail=100

ウェブフックプロバイダが使用中の認証方式は、ログで次の値で確認できます。

  • provider=ServerRoleProvider: NKS Node IAM Roleを使用する
  • provider=EnvProvider: Sub Accountアクセスキーを使用する

Service DNSレコード作成

LoadBalancer タイプの Serviceに ExternalDNSアノテーションを追加すると、Serviceの外部アドレスを示す DNSレコードを作成できます。
ユースケースリソースは external-dns 名前空間に作成します。当該名前空間がない場合、以下のコマンドを実行して作成します。

kubectl --context "<KUBE_CONTEXT>" create namespace external-dns

次の内容をコピーして external-dns-service.yaml ファイルで保存します。<SERVICE_HOSTNAME><DNS_ZONE>のサブホスト名に変更します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns-nginx
  namespace: external-dns
spec:
  replicas: 1
  selector:
    matchLabels:
      app: external-dns-nginx
  template:
    metadata:
      labels:
        app: external-dns-nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.27-alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: external-dns-nginx
  namespace: external-dns
  annotations:
    external-dns.alpha.kubernetes.io/hostname: "<SERVICE_HOSTNAME>"
    external-dns.alpha.kubernetes.io/ttl: "300"
spec:
  type: LoadBalancer
  selector:
    app: external-dns-nginx
  ports:
    - port: 80
      targetPort: 80

以下のコマンドを実行して Deploymentと Serviceを作成し、外部アドレスの割り当てステータスを確認します。

kubectl --context "<KUBE_CONTEXT>" apply -f external-dns-service.yaml
kubectl --context "<KUBE_CONTEXT>" --namespace external-dns \
  get service external-dns-nginx

次の同期が完了したら、Global DNSメニューで <SERVICE_HOSTNAME>のレコードと所有権 TXTレコードが作成されたか確認します。ExternalDNSは基本的に1分ごとに同期します。Load Balancer作成には数分以上かかることがあります。

Ingress DNSレコード作成

Ingress Controllerが Ingressに割り当てた外部アドレスと Ingressに指定したホスト名を利用して DNSレコードを作成できます。Ingress Controllerインストールと Ingress作成方法は ALB Ingress Controller 活用のユースケースをご参照ください。

次の内容をコピーして external-dns-ingress.yaml ファイルで保存します。<INGRESS_HOSTNAME><DNS_ZONE>のサブホスト名に変更します。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: external-dns-ingress
  namespace: external-dns
  annotations:
    external-dns.alpha.kubernetes.io/ttl: "300"
spec:
  ingressClassName: "<INGRESS_CLASS>"
  rules:
    - host: "<INGRESS_HOSTNAME>"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: external-dns-nginx
                port:
                  number: 80

以下のコマンドを実行して Ingressを作成し、外部アドレスの割り当てステータスを確認します。

kubectl --context "<KUBE_CONTEXT>" apply -f external-dns-ingress.yaml
kubectl --context "<KUBE_CONTEXT>" --namespace external-dns \
  get ingress external-dns-ingress

次の同期が完了したら、Global DNSメニューで <INGRESS_HOSTNAME>のレコードと所有権 TXTレコードが作成されたか確認します。
Ingress Controllerが IPアドレスを提供すると、A または AAAAレコードが作成されます。ホスト名を指定すると CNAME レコードが作成されます。

DNSEndpointで DNSレコード作成

DNSEndpointを使用すると、Serviceまたは Ingressと関係なく DNSレコードを直接定義できます。
次の内容をコピーして external-dns-crd.yaml ファイルで保存します。

<CRD_HOSTNAME><IP_ADDRESS>は、使用するホスト名と IPアドレスに変更します。

apiVersion: externaldns.k8s.io/v1alpha1
kind: DNSEndpoint
metadata:
  name: external-dns-crd
  namespace: external-dns
spec:
  endpoints:
    - dnsName: "<CRD_HOSTNAME>"
      recordTTL: 300
      recordType: A
      targets:
        - "<IP_ADDRESS>"

以下のコマンドを実行して DNSEndpointを作成し、作成有無を確認します。

kubectl --context "<KUBE_CONTEXT>" apply -f external-dns-crd.yaml
kubectl --context "<KUBE_CONTEXT>" --namespace external-dns \
  get dnsendpoint external-dns-crd

次の同期が完了したら、Global DNSメニューで <CRD_HOSTNAME>A レコードと所有権 TXTレコードが作成されたか確認します。

DNSレコード削除

このユースケースでは、policy: syncを使用するために Kubernetesリソースを削除すると、ExternalDNSが管理対象 DNSレコードと所有権 TXTレコードを削除します。
以下のコマンドを実行してユースケースリソースを削除します。

kubectl --context "<KUBE_CONTEXT>" delete -f external-dns-crd.yaml
kubectl --context "<KUBE_CONTEXT>" delete -f external-dns-ingress.yaml
kubectl --context "<KUBE_CONTEXT>" delete -f external-dns-service.yaml

次の同期が完了したら、Global DNSメニューで DNSレコードと所有権 TXTレコードが削除されたか確認します。
ExternalDNSをこれ以上使用しない場合、インストール方式に応じて削除します。

  • NKS Add-on: NKSの Add-on管理画面で ExternalDNS Add-onを削除
  • Helm手動インストール: 以下のコマンドを実行して Helmリリースを削除
helm uninstall external-dns \
  --kube-context "<KUBE_CONTEXT>" \
  --namespace external-dns

Helmリリースを削除しても DNSEndpoint CRDは削除されません。CRDがこれ以上必要でない場合、使用中の DNSEndpointがないか確認してから別途削除します。
Helm手動インストールで Sub Accountアクセスキーを使用した場合、当該 Secretを他のワークロードで使用していないか確認した後、以下のコマンドを実行して削除します。

kubectl --context "<KUBE_CONTEXT>" --namespace external-dns \
  delete secret ncloud-credentials

Add-onで Sub Accountアクセスキーを使用した場合、当該 Secretを他のワークロードで使用していないか確認してから削除します。

注意

Kubernetesリソースを削除する前に ExternalDNSを削除すると、DNSレコードを自動的にクリーンアップできません。policyupsert-onlyに設定した場合にも DNSレコードが維持されるため、Global DNSサービスから直接削除する必要があります。

制限事項

ExternalDNSと NAVERクラウドプラットフォーム用のウェブフックプロバイダを使用する時、次の制限事項をご確認ください。

  • Global DNSサービスに登録されていないドメインのホスト名はスキップします。
  • Add-onで domainFilterを設定、または Helm手動インストールで domainFiltersDOMAIN_FILTERを設定すると、指定したドメインのみ管理します。
  • Global DNSでネームサーバに反映しなかった変更事項が残っている場合、ExternalDNSは当該ドメインのレコードを変更しません。[設定適用] > [リリース] ボタンを順に選択して変更事項を反映、または [変更事項キャンセル] ボタンを選択して戻すと次の同期から再処理されます。
  • ウェブフックプロバイダが実行中の場合、Global DNSコンソールで同じドメインのレコードを直接変更しないでください。
  • SOANS 基本レコードは管理しません。