コンテナ化アプリケーションをクラスターにデプロイする際、クラスター内サービス名に加えて、外部ドメイン名の解決も必要になる場合があります。Container Service for Kubernetes (ACK) では、CustomDNSConfig カスタムリソース (CR) を作成することで、マネージド CoreDNS の DNS 動作をカスタマイズできます。これにより、特定のドメインを上流 DNS サーバーにルーティングしたり、ホスト名を静的 IP アドレスにマップしたり、すべてのクエリに対するデフォルトリゾルバーをオーバーライドしたりできます。
概要
ACK のマネージド CoreDNS は、CustomDNSConfig カスタムリソース定義 (CRD) を networking.alibabacloud.com/v1beta1 API グループ内でクラスター範囲で公開しています。この default CR を作成または更新すると、コントローラーがその内容を CoreDNS の ConfigMap(Corefile)に反映し、ライブ再読み込みをトリガーします。Pod の再起動は不要です。
CustomDNSConfig CRD はクラスター範囲であり、インスタンス名は default のみです。この設計により、クラスターごとに単一の権威ある DNS 構成が保証され、複数の構成間の競合が防止されます。構成を更新するには、新しい CR を作成するのではなく、既存の CR に変更を適用してください。
仕組み:
CustomDNSConfig CR(default)
↓ コントローラーによる反映
CoreDNS ConfigMap(Corefile)
↓ CoreDNS の再読み込み(約 20 秒)
ライブ DNS 解決が更新される
CR テンプレート
以下の例は、すべてのサポート対象フィールドおよびプレースホルダー値を含む CustomDNSConfig CR の完全な構造を示しています:
apiVersion: networking.alibabacloud.com/v1beta1
kind: CustomDNSConfig
metadata:
name: default
namespace: default
spec:
zones:
- name: example.com
forward:
protocolStrategy: ""
transportConfig: {}
upstreams:
- xxx.xxx.xxx.xxx # IP アドレス
- xxx.xxx.xxx.xxx:53 # IP:ポート
hosts:
- hostName: "a.example.com"
ipAddress: xxx.xxx.xxx.xxx
CR フィールドリファレンス
以下の表は、CustomDNSConfig CR の各フィールドについて説明しています:
-
spec.zones[].name: 文字列型、必須、デフォルト値は"."。DNS ゾーン名です。完全修飾ドメイン名 (FQDN) である必要があります。特殊ゾーン"."はすべてのクエリに一致し、デフォルトリゾルバーを表します。 -
spec.zones[].forward.upstreams: 文字列配列型、任意。上流 DNS サーバーのアドレスです。形式はIPまたはIP:PORTです。IPv4 のみをサポートします。ゾーンあたり最大 15 アドレスまで指定可能です。未設定の場合、Alibaba Cloud DNS PrivateZone が使用されます。 -
spec.zones[].forward.protocolStrategy: 文字列型、任意、デフォルト値は""。トランスポートプロトコルです。""の場合 UDP を使用し、tcpの場合 TCP を強制します。 -
spec.zones[].forward.transportConfig: オブジェクト型、任意、デフォルト値は{}。TLS トランスポート構成です。変更できません。 -
spec.zones[].hosts[].hostName: 文字列型、必須。静的にマップするホスト名です。DNS の命名規則に準拠している必要があります。 -
spec.zones[].hosts[].ipAddress: 文字列型、必須。ホスト名に対応する IPv4 アドレスです。
ゾーンの概念: ゾーンは DNS 名前空間を定義します。example.com を指定すると、example.com およびすべてのサブドメイン(例: api.example.com)に一致します。特殊ゾーン "." はすべてのクエリに一致し、デフォルトリゾルバーを表します。
forward プラグイン は、指定されたゾーンのクエリを上流 DNS サーバーにルーティングします。オンプレミス DNS や他のクラウド DNS サービスでホストされている非公開ドメインに使用します。
hosts プラグイン は、上流サーバーへのクエリを行わず、静的なホスト名から IP アドレスへのマッピングを提供します。少数の固定ホスト名のオーバーライドが必要な場合に使用します。
前提条件
-
マネージド CoreDNS プラグインがバージョン 1.9.3.20 以降でインストール済みであること。詳細については、「サービスディスカバリー DNS」をご参照ください。
-
kubectl クライアントがクラスターに接続されています。詳細については、「クラスターの kubeconfig ファイルを取得し、kubectl を使用してクラスターに接続する」をご参照ください。
制限事項
-
CustomDNSConfigCR は 1 つしか作成できず、名前は必ずdefaultでなければなりません。他の名前で CR を作成した場合、その phase はNotSupportedに設定され、構成は無視されます。 -
upstreamsフィールドは IPv4 アドレスのみをサポートします(形式:IPまたはIP:PORT)。ゾーンあたり最大 15 アドレスまで指定可能です。 -
ipAddressフィールドは、hostsエントリ内で IPv4 アドレスのみをサポートします。 -
transportConfigフィールドは変更できません。
シナリオ 1: カスタムゾーンの設定
このシナリオでは、特定のドメインのクエリを上流 DNS サーバーにルーティングするか、ドメイン内のホスト名を静的 IP アドレスにマップします。
以下の例では、2 つのカスタムゾーンを設定します:
-
example.com— すべてのクエリをアップストリーム DNS サーバ100.100.2.136および100.100.2.138にルーティングします。(これはデフォルトの内部 DNS 名前解決サービスのアドレスです。詳細については、「エンドポイント」をご参照ください。) -
foo.com—a.foo.comおよびb.foo.comを静的 IP アドレスにマップします(hostsプラグインを使用)。
手順 1: CR マニフェストの作成
以下の内容で default.yaml というファイルを作成します:
apiVersion: networking.alibabacloud.com/v1beta1
kind: CustomDNSConfig
metadata:
name: default # 名前は必ず "default" でなければなりません
spec:
zones:
- name: example.com
forward:
upstreams:
- 100.100.2.136 # example.com の上流 DNS サーバーとして 100.100.2.136 および 100.100.2.138 を設定します。
- 100.100.2.138
- name: foo.com
hosts:
- hostName: "a.foo.com" # foo.com ゾーン内で a.foo.com および b.foo.com のカスタム静的 IP アドレスを設定します。
ipAddress: 192.168.0.251
- hostName: "b.foo.com"
ipAddress: 192.168.0.252
100.100.2.136 および 100.100.2.138 は、システムによって割り当てられたデフォルトの内部 DNS 名前解決サービスアドレスです。詳細については、「エンドポイント」をご参照ください。
手順 2: マニフェストの適用
kubectl apply -f default.yaml
手順 3: Corefile の生成確認
kubectl get customdnsconfig default -o yaml | grep corefile -A 35 -B 1
期待される出力:
status:
corefile: |
example.com:53 {
prometheus :9153
forward . 100.100.2.136 100.100.2.138 {
policy random
prefer_udp
}
...
}
foo.com:53 {
prometheus :9153
hosts {
192.168.0.251 a.foo.com
192.168.0.252 b.foo.com
fallthrough
}
forward . /etc/resolv.conf {
policy random
prefer_udp
}
...
}
...
--
corefileHash: 41f7be21cf3022c305091665ed33b1e5
lastTransitionTime: "2024-09-13T09:07:37Z"
phase: GenerateSuccess
phase: GenerateSuccess のステータスは、CR が受理され、Corefile が正常に生成されたことを確認します。
手順 4: DNS 解決の確認
構成の再読み込み後(約 20 秒)、テスト Pod を実行して DNS クエリが正しく解決されることを確認します:
# example.com が上流 DNS サーバー経由で解決されることを確認
kubectl run -it --rm dns-test --image=busybox:1.28 --restart=Never -- nslookup example.com
# foo.com の静的ホストマッピングが機能することを確認
kubectl run -it --rm dns-test --image=busybox:1.28 --restart=Never -- nslookup a.foo.com
nslookup の出力には、設定したアドレス(192.168.0.251 は a.foo.com、192.168.0.252 は b.foo.com)が表示されるはずです。
1 つのホスト名を複数の IP アドレスにマップできます。例:
hosts:
- hostName: "a.example.com"
ipAddress: 10.0.0.123
- hostName: "a.example.com"
ipAddress: 10.0.0.124
シナリオ 2: デフォルトゾーン構成の変更
このシナリオでは、クラスター全体のすべてのクエリに対する上流 DNS サーバーを変更します。つまり、組み込みのデフォルトリゾルバーゾーン(".")をオーバーライドします。
spec.zones はカスタムゾーンを構成します。spec.zones と name: "." を併用することで、すべてのクラスタークエリを処理するデフォルトゾーンの上流サーバーをオーバーライドできます。
手順 1: CR マニフェストの作成
以下の内容で default.yaml というファイルを作成します:
apiVersion: networking.alibabacloud.com/v1beta1
kind: CustomDNSConfig
metadata:
name: default # 名前は必ず "default" でなければなりません
spec:
zones:
- name: .
forward:
upstreams:
- 100.100.2.136 # デフォルトゾーン "." の上流 DNS サーバーとして 100.100.2.136 および 100.100.2.138 を設定します。
- 100.100.2.138
手順 2: マニフェストの適用
kubectl apply -f default.yaml
手順 3: Corefile の生成確認
kubectl get customdnsconfig default -o yaml | grep corefile -A 35 -B 1
期待される出力:
status:
corefile: |
.:53 {
errors
health {
lameduck 20s
}
ready
kubeapi {
kubeconfig /etc/kubernetes/config/managed-coredns.conf
}
k8s_event {
level error warning
}
...
prometheus :9153
forward . 100.100.2.136 100.100.2.138 {
policy random
prefer_udp
}
...
}
corefileHash: 847bf69cc4c97cee965945f45d17c661
lastTransitionTime: "2024-09-13T09:54:22Z"
phase: GenerateSuccess
phase: GenerateSuccess のステータスは、デフォルトゾーン構成が正常に更新されたことを確認します。
手順 4: DNS 解決の確認
構成の再読み込み後(約 20 秒)、テスト Pod を実行して外部クエリが設定された上流サーバー経由でルーティングされることを確認します:
kubectl run -it --rm dns-test --image=busybox:1.28 --restart=Never -- nslookup kubernetes.default.svc.cluster.local
CustomDNSConfig CR を作成または変更すると、CoreDNS が構成の再読み込みを実行し、約 20 秒かかります。再読み込みの持続時間は、lameduck 値を Corefile で変更することで調整できます。デフォルト値は 20 秒です。
トラブルシューティング
default 以外の名前で作成された CR が NotSupported と表示される
クラスターあたり CustomDNSConfig CR は 1 つしか作成できず、名前は必ず default でなければなりません。異なる名前で CR を作成した場合、コントローラーはその phase を NotSupported に設定し、構成を無視します。
以下の例でこの動作を示します。
手順 1: test.yaml というファイルを作成し、デフォルト以外の CR 名を指定します。
apiVersion: networking.alibabacloud.com/v1beta1
kind: CustomDNSConfig
metadata:
name: test ## CustomDNSConfig CR は default のみ作成できます。
spec:
zones:
- name: example.com
forward:
upstreams:
- 100.100.2.138
- name: foo.com
hosts:
- hostName: "ah.foo.com"
ipAddress: 1.1.xx.251
- hostName: "aha.foo.com"
ipAddress: 1.1.xx.252
手順 2: マニフェストの適用
kubectl apply -f test.yaml
手順 3: すべての CustomDNSConfig CR のステータスを確認
kubectl get customdnsconfig
期待される出力:
NAME PHASE VERSION AGE
default GenerateSuccess 847bf69cc4c97cee96xxxxxxxxxxx 89m
test NotSupported 9s
test CR は NotSupported と表示され、default のみが受理されることを確認します。この問題を修正するには、誤った名前の CR を削除し、代わりに default CR に構成を適用します:
kubectl delete customdnsconfig test
kubectl apply -f default.yaml
イベント情報
カスタム CoreDNS コントローラーは、イベント情報を default 名前空間に同期します。これらのイベントを使用して、構成の正常な同期を確認したり、障害の診断を行ったりできます。
以下のコマンドを実行してイベントを表示します:
kubectl get events
期待される出力:
LAST SEEN TYPE REASON OBJECT MESSAGE
45m Normal CustomDNSConfigSyncOk customdnsconfig/default custom dns config sync to coredns configmap success
以下の表は、イベントタイプについて説明しています:
-
Normal/CustomDNSConfigSyncOk: CR が正常に CoreDNS の ConfigMap に反映されました。追加の操作は不要です。 -
NotSupported: CR の名前がdefaultではありません。構成は拒否されました。CR を削除し、name: defaultで再適用してください。
変更の伝播中に CR のステータスをリアルタイムで監視するには:
kubectl get customdnsconfig default -w