在 Day 17,我們透過 AWS Load Balancer Controller,讓 Kubernetes 的 Service / Ingress 可以自動建立對應的 ALB 或 NLB。雖然流量入口已經打通,但還有一個缺口:DNS 解析。
若每次建立 Ingress / Service,都要手動到 Route53 建立記錄,顯然既麻煩又容易出錯。這就是今天的主角 —— ExternalDNS。
ExternalDNS 是一個 Kubernetes Controller,會自動觀察叢集裡的 Service 和 Ingress,然後在 DNS 提供者(AWS Route53、Cloudflare…等)建立或刪除對應的 DNS record。
舉例:
host: argocd.example.com
的 Ingress。argocd.example.com → NLB/ALB
的 CNAME/A記錄。我們的 DNS 並不是由專案帳號直接管理,而是放在另一個專用的 AWS Account。
因此,這邊我們不會使用 ApplicationSet,而是單純用 Application 在 central cluster 安裝 ExternalDNS。
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: external-dns
namespace: argocd
spec:
project: infra
source:
repoURL: https://kubernetes-sigs.github.io/external-dns
chart: external-dns
targetRevision: 1.14.5
helm:
releaseName: external-dns
valueFiles:
- infra-charts/external-dns/values.yaml
destination:
name: in-cluster
namespace: kube-system
syncPolicy:
syncOptions:
- serverSideApply=true
以下是我們實際使用的 values(精簡版):
serviceAccount:
create: true
name: external-dns
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::DNSACCOUNT00:role/external-dns
rbac:
create: true
interval: 5m
policy: sync
registry: txt
provider: aws
tolerations:
- operator: Exists
extraArgs:
- --annotation-filter=external-dns.alpha.kubernetes.io/exclude notin (true)
resources:
requests:
cpu: 10m
memory: 50Mi
limits:
memory: 50Mi
txtOwnerId: example-internal
txtPrefix: example-internal-edns-
domainFilters:
- example.com
eks.amazonaws.com/role-arn
綁到 DNS 管理帳號的 IAM Role。external-dns.alpha.kubernetes.io/exclude: true
的 Ingress,避免誤加記錄。細節可以看這項 comment。有了前面幾個幫我們打通網路的工具(ingress-nginx / load balancer controller / external-dns)之後,我們終於可以拿 ArgoCD 建立 ingress,並且用 domain name 正正當當的連進去看、不用再使用 port forward 了!
我們只需要在 ArgoCD 的 value file 中加入以下的設定,並再次使用 terraform apply
:
server:
ingress:
enabled: true
ingressClassName: nginx
hosts:
- argocd.example.com
Helm chart 就會自動再生成一個 ingress,內容如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argo-cd-argocd-server
namespace: argocd
spec:
ingressClassName: nginx
rules:
- host: argocd.example.com
http:
paths:
- backend:
service:
name: argo-cd-argocd-server
port:
number: 443
path: /
pathType: Prefix
於是 ExternalDNS 會偵測到多了這個 ingress,並將這個 ingress 對應的 record 更新到 hosted zone 中:
接著打開我們註冊到 A record 中的 ArgoCD URL,就可以看到熟悉的 UI 了:
今天我們安裝了 ExternalDNS,讓 Kubernetes 的 Ingress / Service 自動和 Route53 同步:
到這裡,從 Pod → Service → Ingress → NLB/ALB → DNS 的完整流量鏈路已經打通。
在 Day 19,我們會進一步介紹 Monitoring(Prometheus & Grafana),讓這些基礎設施不只會動,還能被觀察 👀