ExternalDNSを使用してDigitalOceanKubernetesからDNSレコードを自動的に管理する方法

提供:Dev Guides
移動先:案内検索

著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。

序章

ウェブアプリをKubernetesにデプロイする場合、通常は Services とIngressesを使用して、目的のドメインのクラスターを超えてアプリを公開します。 これには、入力だけでなく、プロバイダーでDNSレコードも手動で構成することが含まれます。これは、時間がかかり、エラーが発生しやすいプロセスになる可能性があります。 アプリケーションが複雑になるにつれて、これは障害になる可能性があります。 外部IPが変更された場合は、それに応じてDNSレコードを更新する必要があります。

これを克服するために、 Kubernetes sig-network team は、Kubernetesクラスター内から外部DNSレコードを自動的に管理する目的でExternalDNSを作成しました。 デプロイされると、ExternalDNSはバックグラウンドで動作し、追加の構成はほとんど必要ありません。 ServiceまたはIngressが作成または変更されるたびに、ExternalDNSはレコードをすぐに更新します。

このチュートリアルでは、Helmを介して DigitalOcean Kubernetes クラスターにExternalDNSをインストールし、DNSプロバイダーとしてDigitalOceanを使用するように構成します。 次に、Ingressを使用してサンプルWebアプリをデプロイし、ExternalDNSを使用してドメイン名を指定します。 最終的には、サービスとイングレスの両方に自動化されたDNSレコード管理システムが導入されます。

前提条件

  • 接続がkubectlデフォルトとして構成されたDigitalOceanKubernetesクラスター。 kubectlを構成する方法の説明は、クラスターを作成するときのクラスターへの接続ステップの下に表示されます。 DigitalOceanでKubernetesクラスタを作成するには、 KubernetesQuickstartをお読みください。
  • ローカルマシンにインストールされているHelm3パッケージマネージャー。 Helm 3 PackageManagerチュートリアルを使用してKubernetesクラスターにソフトウェアをインストールする方法のステップ1を完了します。
  • IngressリソースでExternalDNSを使用するために、Helmを使用してクラスターにインストールされたNginxIngressController。 これを行うには、Helmを使用してDigitalOceanKubernetesでNginxIngressを設定する方法に従ってください。 手順2の手順に従って、publishServiceプロパティをtrueに設定する必要があります。
  • 読み取りおよび書き込み権限を持つDigitalOceanAPIキー(パーソナルアクセストークン)。 作成するには、パーソナルアクセストークンの作成方法にアクセスしてください。
  • 完全に登録されたドメイン名。 このチュートリアルでは、全体を通してecho.your_domainを使用します。 Namecheap でドメイン名を購入するか、 Freenom で無料でドメイン名を取得するか、選択したドメイン登録事業者を使用できます。

ステップ1—Helmを使用したExternalDNSのインストール

このセクションでは、Helmを使用して外部DNSをクラスターにインストールし、DigitalOceanDNSサービスと連携するように構成します。

ExternalDNS Helmチャートのデフォルト設定の一部を上書きするには、インストール中にHelmに渡すvalues.yamlファイルを作成する必要があります。 前提条件でクラスターへのアクセスに使用するマシンで、次のコマンドを実行してファイルを作成します。

nano externaldns-values.yaml

次の行を追加します。

externaldns-values.yaml

provider: digitalocean

digitalocean:
  apiToken: your_api_token

interval: "1m"

policy: sync # or upsert-only

# domainFilters: [ 'your_domain' ]

最初のブロックでは、DNSサービスプロバイダーをDigitalOceanに設定します。 次に、次のブロックで、your_api_tokenを置き換えてDigitalOceanAPIトークンを定義します。

次の行は、ExternalDNSがIngressesおよびServicesへの変更をポーリングする間隔を設定します。 これを低い値に設定すると、DNSへの変更をより速く伝播できます。デフォルト値は1分です。

policy設定は、ExternalDNSがDNSレコードのみを挿入するか(upsert-only)、必要に応じてそれらを作成および削除するか(sync)を決定します。 幸い、バージョン0.3以降、ExternalDNSは、作成したドメインに関する情報を格納する付随する TXT レコードを作成することで所有権の概念をサポートし、アクションの範囲を作成したドメインのみに制限します。

domainFiltersパラメーターは、ExternalDNSが管理できるドメインを制限するために使用されます。 コメントを外して、文字列配列の形式でドメインを入力できますが、これは必須ではありません。

編集が終了したら、ファイルを保存して閉じます。

ExternalDNS Helmチャートは、Bitnamiチャートライブラリの一部です。 次のコマンドを実行して、Helmインストールに追加します。

helm repo add bitnami https://charts.bitnami.com/bitnami

次に、Helmのキャッシュを更新して、その内容をダウンロードします。

helm repo update

最後に、以下を実行して、ExternalDNSをクラスターにインストールします。

helm install external-dns bitnami/external-dns -f externaldns-values.yaml

出力は次のようになります。

OutputNAME: external-dns
LAST DEPLOYED: ...
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
** Please be patient while the chart is being deployed **

To verify that external-dns has started, run:

  kubectl --namespace=default get pods -l "app.kubernetes.io/name=external-dns,app.kubernetes.io/instance=external-dns"

次のコマンドを実行して、ExternalDNSの作成を確認できます。

kubectl --namespace=default get pods -l "app.kubernetes.io/name=external-dns,app.kubernetes.io/instance=external-dns"
OutputNAME                            READY   STATUS    RESTARTS   AGE
external-dns-56c85ff66b-2vm88   1/1     Running   0          24s

KubernetesクラスターにExternalDNSをインストールしました。 次に、サンプルのWebアプリをデプロイし、Nginx Ingressを使用して公開し、ExternalDNSがドメイン名を適切なロードバランサーに自動的にポイントするようにします。

ステップ2—サンプルWebアプリのデプロイと公開

このセクションでは、Ingressを使用して公開するために、ダミーのWebアプリをクラスターにデプロイします。 次に、DNSレコードを自動的に構成するようにExternalDNSを設定します。 最終的に、ドメインのDNSレコードが入力のロードバランサーを指すようになります。

デプロイするダミーのWebアプリは、Hashicorpのhttp-echoです。 これは、指定したメッセージをエコーバックするメモリ内Webサーバーです。 Kubernetesマニフェストをecho.yamlという名前のファイルに保存します。 それを作成し、編集のために開きます。

nano echo.yaml

次の行をファイルに追加します。

echo.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: "echo.your_domain"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: echo
            port:
              number: 80
---
apiVersion: v1
kind: Service
metadata:
  name: echo
spec:
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
spec:
  selector:
    matchLabels:
      app: echo
  replicas: 3
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echo
        image: hashicorp/http-echo
        args:
        - "-text=Echo!"
        ports:
        - containerPort: 5678

この構成では、デプロイメント、イングレス、およびサービスを定義します。 デプロイメントは、http-echoアプリの3つのレプリカで構成され、カスタムメッセージ(Echo!)が渡されます。 サービスは、ポート80を介してデプロイメント内のポッドにアクセスできるように定義されています。 Ingressは、ドメインでサービスを公開するように構成されています。

echo.your_domainをドメインに置き換えてから、ファイルを保存して閉じます。

これで、ドメインのDNSレコードを手動で構成する必要はありません。 設定をKubernetesに適用するとすぐに、ExternalDNSが自動的にこれを行います。

構成を適用するには、次のコマンドを実行します。

kubectl create -f echo.yaml

次の出力が表示されます。

Outputingress.extensions/echo-ingress created
service/echo created
deployment.apps/echo created

ExternalDNSが変更に気づき、適切なDNSレコードを作成するまで、少し待つ必要があります。 ヘルムチャートのinterval設定は、DNSレコードの作成を待機する必要がある時間の長さを管理します。 externaldns-values.yamlでは、間隔の長さはデフォルトで1分に設定されています。

DigitalOceanコントロールパネルにアクセスして、AおよびTXTレコードを見つけることができます。

指定された時間間隔が経過するか、コントロールパネルでレコードを見つけたら、curlを使用してドメインにアクセスします。

curl echo.your_domain

次の出力が表示されます。

OutputEcho!

このメッセージは、ExternalDNSを構成し、NginxIngressControllerのロードバランサーを指すために必要なDNSレコードを作成したことを確認します。 エラーメッセージが表示された場合は、しばらくお待ちください。 または、Echo!を受け取るブラウザからドメインにアクセスしてみてください。

Ingressを使用してサンプルアプリをデプロイすることにより、ExternalDNSをテストしました。 DigitalOceanコントロールパネルで新しいDNSレコードを確認することもできます。 次のステップでは、ドメイン名でサービスを公開します。

ステップ3—(オプション)サービスを使用してアプリを公開する

このオプションのセクションでは、Ingressesの代わりにExternalDNSでサービスを使用します。 ExternalDNSを使用すると、さまざまなKubernetesリソースをDNSサーバーで利用できるようにすることができます。 サービスの使用は、この代替リソースの構成が変更されたIngressesと同様のプロセスです。

注:この手順を実行すると、作成したDNSレコードが削除されます。


echo.yamlに含まれるサービスをカスタマイズするため、echo-ingressは不要になります。 次のコマンドを使用して削除します。

kubectl delete ing echo-ingress

出力は次のようになります。

Outputingress.extensions/echo-ingress deleted

ExternalDNSは、前の手順で作成した既存のDNSレコードを削除します。 手順の残りの部分では、以前に使用したものと同じドメインを使用できます。

次に、echo.yamlファイルを開いて編集します。

nano echo.yaml

ファイルの内容を次の行に置き換えます。

echo.yaml

apiVersion: v1
kind: Service
metadata:
  name: echo
  annotations:
    external-dns.alpha.kubernetes.io/hostname: echo.your_domain
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
spec:
  selector:
    matchLabels:
      app: echo
  replicas: 3
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echo
        image: hashicorp/http-echo
        args:
        - "-text=Echo!"
        ports:
        - containerPort: 5678

以前のセットアップのファイルからIngressを削除し、サービスタイプをLoadBalancerに変更しました。 さらに、ExternalDNSのドメイン名を指定するアノテーションを追加しました。

次のコマンドを実行して、変更をクラスターに適用します。

kubectl apply -f echo.yaml

出力は次のようになります。

Output...
service/echo configured
deployment.apps/echo configured

次のコマンドを実行して、サービスのロードバランサーが使用可能になることを確認できます。

kubectl get svc echo -w
OutputNAME   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
echo   LoadBalancer   10.245.81.235   <pending>     80:31814/TCP   8s
...

前の手順と同様に、DNSレコードが作成されて伝達されるまでしばらく待つ必要があります。 それが完了したら、curl指定したドメイン:

curl echo.your_domain

出力は前のステップと同じになります。

OutputEcho!

エラーが発生した場合は、もう少し待つか、別のドメインを試すことができます。 DNSレコードはクライアントシステムにキャッシュされるため、変更が実際に反映されるまでに長い時間がかかる場合があります。

この手順では、サービス(LoadBalancerタイプ)を作成し、ExternalDNSを使用してドメイン名を指定しました。

結論

ExternalDNSはバックグラウンドでサイレントに動作し、摩擦のないエクスペリエンスを提供します。 Kubernetesクラスタは、ドメインに関する信頼できる唯一の情報源になりました。 DNSレコードを手動で更新する必要はもうありません。

ExternalDNSの真の力は、継続的デリバリーシステムからテスト環境を作成するときに明らかになります。 Kubernetesクラスタにこのようなシステムをセットアップする場合は、 DigitalOceanKubernetesでSpinnakerを使用してCDパイプラインをセットアップする方法にアクセスしてください。