ExternalDNSを使ってKubernetesからDNSレコードを登録する
ExternalDNSは公開されたIngressやServiceを見ていい感じにDNSレコードを登録してくれるやつです。
たとえば、以下のようなIngressを公開することで、 myservice.foo.org
のホスト名に対するAレコードを登録することができます。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-myservicea
spec:
rules:
- host: myservice.foo.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myservicea
port:
number: 80
ingressClassName: nginx
さまざまなクラウドプロバイダーに対応しているのでとても便利。
(v0.10.2時点で対応しているクラウドプロバイダー)
- Google Cloud DNS
- AWS Route 53
- AWS Cloud Map
- AzureDNS
- BlueCat
- CloudFlare
- RcodeZero
- DigitalOcean
- Hetzner
- DNSimple
- Infoblox
- Dyn
- OpenStack Designate
- PowerDNS
- CoreDNS
- Exoscale
- Oracle Cloud Infrastructure DNS
- Linode DNS
- RFC2136
- NS1
- TransIP
- VinylDNS
- Vultr
- OVH
- Scaleway
- Akamai Edge DNS
- GoDaddy
- Gandi
- UKFast SafeDNS
今回はIngressで公開したホスト名に対するDNSレコードをAWS Route53に登録していこうと思います。
external-dnsをデプロイする
今回はHelmを使ってexternal-dnsをクラスターにデプロイしていきます。
external-dnsリポジトリをHelmに追加
$ helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
chartをインストールする際の設定をvalues.yamlとして書き起こしています。
serviceAccount:
create: true
sources:
- ingress
policy: sync
registry: txt
txtOwnerId: rnakamine
env:
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
key: aws_access_key_id
name: external-dns
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
key: aws_secret_access_key
name: external-dns
設定の詳細は以下の通りです。
Parameter | Description |
---|---|
serviceAccount.create | 新しいサービスアカウントを作成する |
sources | 監視されるKubernetesリソース |
policy | DNSレコードがKubernetesとプロバイダー間でどのように同期されるか。sync, upsert-only |
registry | レジストリタイプ。txt, noop |
txtOwnerId | TXTレジストリの識別子 |
env | external-dnsのコンテナの環境変数。SecretとConfigMapも使える。 |
今回はKuberenetes Clusterを別のクラウドプロバイダーで構築しているため、Route53へのアクセスは専用のIAM Userを作成して、そのCredencialsをSecretとして登録しています。(他に良い方法があれば....)
Route53を操作するIAM Policyは以下のように設定しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/*"
]
},
{
"Effect": "Allow",
"Action": [
"route53:ListHostedZones",
"route53:ListResourceRecordSets"
],
"Resource": [
"*"
]
}
]
}
chartのインストール
上記で作成した values.yaml
を指定しつつhelmコマンドでchartをインストールします。
$ helm upgrade --install external-dns external-dns/external-dns -f values.yaml --namespace external-dns
DNSレコードを追加する
Deployment, Serviceの作成
まずはIngressで公開するServiceとDeploymentを以下のように作成。今回はnginxのコンテナを使ってリクエストを受け付けるようにしました。
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample
spec:
replicas: 1
selector:
matchLabels:
app: sample
template:
metadata:
labels:
app: sample
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: blog
spec:
selector:
app: blog
ports:
- name: http
protocol: TCP
port: 80
Ingressの作成
次にIngressを作成し、rnakamine.com
というホスト名をRoute53に登録するようにします。今回はIngressコントローラーに NGINX Ingress Controller を使用しています。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: sample
spec:
ingressClassName: nginx
rules:
- host: rnakamine.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: sample
port:
number: 80
これらをKubernetes上にapplyするとExternalDNSにより rnakamine.com
のAレコードがRoute53に登録され、上記で作成したnginxのコンテナが入ったPodにアクセスすることができるようになります。
まとめ
ExternalDNSはを使うことでKubernetes上のServiceリソースやIngressリソースを監視しつつDNSレコードを動的に管理できるようになるのでかなり便利です。
Discussion