kubernetes-incubator/external-dnsって何?
KubernetesでServiceやIngressなどの作成/更新を検知してDNSレコードを動的に設定してくれるexternal-dnsというプロダクトがkubernetes-incubator配下にあります。
例えば以下のようなIngressを作成するとnginx.example.org
というホスト名に対応するAレコードを作成してくれます。
kind: Ingress metadata: name: nginx annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: nginx.example.org http: paths: - backend: serviceName: nginx servicePort: 80
external-dnsの特徴的な点として、データソース(ServiceやIngressなど)とレコード作成先(プロバイダーと呼ばれている)が分離されており、 それぞれを任意の組み合わせで利用することが可能という点があります。 これにより様々なプラットフォームを統一的な手段でサポートできるようになっています。
データソースとしてはService/Ingressだけでなく、istio-gatewayや独自のCRD(Custom Resource Definitions)などがあり、 レコードの作成先については以下のような様々なプラットフォームがサポートされています。
external-dns v0.5時点で対応しているプロバイダー
- Google CloudDNS
- AWS Route 53
- AWS Service Discovery
- AzureDNS
- CloudFlare
- DigitalOcean
- DNSimple
- Infoblox
- Dyn
- OpenStack Designate
- PowerDNS
- CoreDNS
- Exoscale
- Oracle Cloud Infrastructure DNS
- Linode DNS
- RFC2136
これがさくらのクラウドに対応していませんでしたので今回forkして対応してみました。
当記事ではさくらのクラウドでのexternal-dnsの使い方について紹介します。
(なお今の所はupstreamへのマージは考えてません。使いたいという方が増えたら考えます。)
external-dnsをさくらのクラウドで使う
準備作業
まずはKubernetesクラスターの準備やさくらのクラウドDNSに管理対象のゾーンを登録しておく必要があります。
KubernetesクラスターについてはRancher2セットアップというスタートアップスクリプトが提供されていますのでそちらを利用して準備しておきます。
以下の記事などが参考になるかと思います。
また、さくらのクラウドへのDNSゾーン登録も必要です。
こちらは以下のスライドなどが参考になるかと思います。
www.slideshare.net
sacloud/external-dnsのデプロイ
準備が出来たらexternal-dnsをデプロイします。
manifestは以下のようになります。
apiVersion: v1 kind: ServiceAccount metadata: name: external-dns --- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: name: external-dns rules: - apiGroups: [""] resources: ["services"] verbs: ["get","watch","list"] - apiGroups: [""] resources: ["pods"] verbs: ["get","watch","list"] - apiGroups: ["extensions"] resources: ["ingresses"] verbs: ["get","watch","list"] - apiGroups: [""] resources: ["nodes"] verbs: ["list"] --- apiVersion: rbac.authorization.k8s.io/v1beta1 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: default --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: external-dns spec: strategy: type: Recreate template: metadata: labels: app: external-dns spec: serviceAccountName: external-dns containers: - name: external-dns image: sacloud/external-dns:latest args: - --source=service - --source=ingress - --domain-filter=example.com # (optional, but we highly recommended to set this) limit to only example.com domains; change to match the zone created above. - --provider=sakuracloud env: - name: SAKURACLOUD_ACCESS_TOKEN value: "YOUR_API_KEY" - name: SAKURACLOUD_ACCESS_TOKEN_SECRET value: "YOUR_API_SECRET"
上の方がRBACの設定、Deploymentのcontainersの部分がexternal-dnsのコンテナの定義となっています。
RBACを使わない場合については以下のドキュメントを参照してください
external-dns/sakuracloud.md at master · sacloud/external-dns · GitHub
external-dnsのコンテナ定義部分だけ抜粋
containers: - name: external-dns image: sacloud/external-dns:latest args: - --source=service - --source=ingress - --domain-filter=example.com # (optional, but we highly recommended to set this) limit to only example.com domains; change to match the zone created above. - --provider=sakuracloud env: - name: SAKURACLOUD_ACCESS_TOKEN value: "YOUR_API_KEY" - name: SAKURACLOUD_ACCESS_TOKEN_SECRET value: "YOUR_API_SECRET"
以下の部分は各自で任意の値を設定してください。
--domain-filter
: 操作対象のゾーン(ドメイン)SAKURACLOUD_ACCESS_TOKEN
: さくらのクラウド APIトークンSAKURACLOUD_ACCESS_TOKEN_SECRET
: さくらのクラウド APIシークレット
この例では以下のような指定を行なっています。
動作確認
動作確認のためnginxコンテナをデプロイし、Ingressで外部からアクセスできるようにします。
まずはPodとServiceをデプロイします。
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx spec: template: metadata: labels: app: nginx spec: containers: - image: nginx name: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx spec: selector: app: nginx type: ClusterIP ports: - protocol: TCP port: 80 targetPort: 80
続いてIngressをデプロイします。
ここではFQDNとしてexternal-dns.example.com
を指定しています。
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-example namespace: default spec: rules: - host: external-dns.example.com http: paths: - backend: serviceName: nginx servicePort: 80
しばらく待つと対象のゾーンにAレコードとTXTレコードが追加されているのがコントロールパネルなどで確認できます。 後は指定したFQDNに対してアクセスするとNGINXのデフォルトページが表示されるはずです。
後片付け
Ingressを削除すると対応するDNSレコードも削除されるようになっています。
(この動作はexternal-dnsのオプション--policy
にデフォルトでsync
が指定されているためです)
終わりに
external-dnsを利用することでKubernetes側の操作だけでDNSレコードの登録/変更/破棄が行えます。
頻繁にアプリケーションのデプロイ/DNSレコードの更新を行うけど、
さくらのクラウドのコントロールパネル/APIヘのアクセスは集中管理したい/触れる人を限定したい、といった場合などで便利だと思います。
ぜひご利用ください。
以上です。