ExternalDNSについて
ExternalDNSはKubernetesから外部のDNSサービスにServicetype: LoadBalancer
やIngressのIPアドレスのDNSレコードを登録してくれます。
v0.4の段階では次のサービスに対応しています。
このブログの証明書を見てもらえば分かりますが、私はCloudFlareを使ってSSL対応をしており、有償オプション($10/month)でDedicatedな証明書を使用しています。
SANでマルチドメインを登録しまくっています。
Kubernetesでtype: LoadBalancer
なサービスやIngressを作る時にAレコードを毎回CloudFlareに登録していて面倒だと思ってたので、このExternalDNSの仕組みはありがたいのです。
(自分でCloudFlareのAPIを叩く何かを作ろうと思っていました...)
ExternalDNSのデプロイ
まずはExternalDNSのデプロイを使うために、external-dns.yml
を作成します。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: external-dns
namespace: kube-system
spec:
strategy:
type: Recreate
template:
metadata:
labels:
app: external-dns
spec:
containers:
- name: external-dns
image: registry.opensource.zalan.do/teapot/external-dns:v0.4.8
args:
- --source=service
- --source=ingress
- --domain-filter=ik.am # your domain managed by cloud flare
- --provider=cloudflare
- --cloudflare-proxied
env:
- name: CF_API_KEY
valueFrom:
secretKeyRef:
name: cloudflare-secret
key: cloudflare-api-key
- name: CF_API_EMAIL
valueFrom:
secretKeyRef:
name: cloudflare-secret
key: cloudflare-api-email
CF_API_KEY
とCF_API_EMAIL
の内容はcloudflare-secret.yml
に設定しておきます。
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-secret
namespace: kube-system
type: Opaque
data:
cloudflare-api-key: ********** # echo -n <CF_API_KEY> | base64
cloudflare-api-email: ********** # echo -n <CF_API_EMAIL> | base64
これらをデプロイします。
kubectl apply -f cloudflare-secret.yml
kubectl apply -f external-dns.yml
これでExternalDNSのデプロイ完了です。
動作確認
動作確認としてnginx
をデプロイしてCloudFlareと連携できるか試します。次のnginx.yml
を作成します。
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:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
自分はCloudFlareのFull SSLモードを使っているので、Ingress側でもSSLの設定が必要です。Strictモードでなければ、Ingress側は自己証明書でOKです。
kubectl create secret tls tls-secret -n default --cert=public.crt --key=private.key
# public.crtとprivate.keyは自己証明書でOK
Flexibleモードを使えばGCP側でSSLの設定は不要になりますが、CloudFlare <-> GCP間の通信が平文になってしまい、イマイチです。
次にGCPでIngressのstatic ipを発行します。名前はcloudflare-ingress
にします。
gcloud compute addresses create cloudflare-ingress --global
次にIngressの設定を書きます。次のingress.yml
を作成します。ホスト名はCloudFlare管理化のドメインにします。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: demo-ingress
namespace: default
annotations:
kubernetes.io/ingress.global-static-ip-name: cloudflare-ingress
ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- secretName: tls-secret
rules:
- host: nginx.ik.am
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
これをデプロイします。
kubectl apply -f ingress.yml
しばらくすると、CloudFlare側にTXTレコードとAレコードが作成されます。AレコードにはIngressに設定したstatic ipが設定されます。
Audit Logを見るとわかりやすいです。
しばらくするとGKE側のIngressのStatusがOKになり(遅い)、
https://nginx.ik.amにアクセスできるようになります。
Ingressを設定するだけでCloudFlareにAレコードが登録されることを確認できました。運用が少し楽になります。 Let's Encryptでも試してみたいところです。