Create an ExternalDNS with Bind

2023/10/11閱讀時間約 10 分鐘

因為想要使用FQDN的方式連接到Kubernetes cluster內部的應用服務,加上早已使用Linux Bind為測試環境的主要DNS,希望在滿足以下條件之下實現我的需求:

  • 不另外建立DNS server
  • 外部可以使用FQDN的方式連接到容器應用(ex. nginx)

所以找到了一個老牌的Project: ExternalDNS,但滿多文章都是直接利用CoreDNS來進行名稱解析,但這種方式只能適用於Cluster內部,讓內部服務可以找到彼此,而ExternalDNS用來將服務對外部公開,就可以透過自定義FQDN來存取Kubernetes cluster內部服務,ExternalDNS官網就有提供與各家Provider的做法,而且其實不難,那我們就開始吧!!

那間房子才有我需要的服務呢?

那間房子才有我需要的服務呢?

1. 什麼是ExternalDNS

Source: Official site

Source: Official site

實現將Kubernetes Cluster內的pod, service, ingress等資源註冊到外面dns。讓外部的服務可以透過統一的dns訪問到cluster內的服務。

external-dns支援將domain name註冊到不同的domain service,如aws, linode、coredns,bind-dns等。以下官方github provider頁面找尋你需要串接的dns provider:

外部domain name支援,細節可以到provider目錄確認。


2. 部署

提醒一下,Bind provider需套用rfc2316 rule,可以先將rfc2316所需要的內容準備好,我們會使用到的domain name如下:

  • apps.test.example.poc : Kubernetes cluster內部應用服務使用
  • test.example.poc : 全域domain

PS. 建議如果有Loadbalancer最好,例如MetalLB (之後會再跟大家說明)

# 產生certificates
[master]# tsig-keygen -a hmac-sha256 externaldns
key "externaldns" {
algorithm hmac-sha256;
secret "BL4uv5x5Pd0DWbioNS6BvqG2fWAM/F3ZQcyic2q+SwE=";
};
# 修改named

key "externaldns" {
algorithm hmac-sha256;
secret "BL4uv5x5Pd0DWbioNS6BvqG2fWAM/F3ZQcyic2q+SwE=";
};

zone "test.example.poc" IN {
type master;
file "named.test.example.poc.zone";
allow-transfter {
key "externaldns";
};
update-policy {
grant externaldns zonesub ANY;
};
};
# 建立namespace

[master]# kubectl create externaldns
# 建立clusterrole

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: external-dns
namespace: external-dns
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- pods
- nodes
verbs:
- get
- watch
- list
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- networking.istio.io
resources:
- gateways
- virtualservices
verbs:
- get
- watch
- list
# 建立SA

apiVersion: v1
kind: ServiceAccount
metadata:
name: external-dns
namespace: external-dns
# 建立rolebinding

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: external-dns-viewer
namespace: external-dns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: external-dns
subjects:
- kind: ServiceAccount
name: external-dns
namespace: external-dns
# 建立deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: external-dns
namespace: external-dns
spec:
selector:
matchLabels:
app: external-dns
template:
metadata:
labels:
app: external-dns
spec:
serviceAccountName: external-dns
containers:
- name: external-dns
image: k8s.gcr.io/external-dns/external-dns:v0.7.6
args:
- --registry=txt
- --txt-prefix=external-dns-
- --txt-owner-id=k8s
- --provider=rfc2136
- --rfc2136-host=10.107.88.9
- --rfc2136-port=53
- --rfc2136-zone=test.example.poc
- --rfc2136-tsig-secret=BL4uv5x5Pd0DWbioNS6BvqG2fWAM/F3ZQcyic2q+SwE=
- --rfc2136-tsig-secret-alg=hmac-sha256
- --rfc2136-tsig-keyname=externaldns
- --rfc2136-tsig-axfr
- --source=service
- --source=ingress
- --domain-filter=apps.test.example.poc
- --interval=30s
- --log-level=debug
# 執行以上YAML

[master]# kubectl create -f clusterrole.yaml -n external-dns
[master]# kubectl create -f ac.yaml -n external-dns
[master]# kubectl create -f clusterrolebinding.yaml -n external-dns
[master]# kubectl create -f deployment.yaml -n external-dns
# 測試service/ingress

[master]# kubectl run nginx --image=nginx --port=80
[master]# kubectl expose pod nginx --port=80 --target-port=80 --type=LoadBalancer
[master]# kubectl get svc -n external-dns
[[master]# kubectl annotate service nginx "external-dns.alpha.kubernetes.io/hostname=nginx.apps.test.example.poc."

//確認是否可以解析
[master]# nslookup nginx.apps.test.example.poc 10.107.88.9
raw-image
raw-image

以上就實現在地端的dns服務,ExternalDNS是一個從Kube-DNS所沿伸出來的專門為了外部DNS服務的專案,包含許多知名的平台都有支援。

以正式環境來說,建議從使用的平台角度出發來決定FQDN的解決方案會更符合實際環境的需求。但以小型/LAB使用的規模,ExternalDNS還是一個非常不錯的選項。

之後有時間的話再跟大家分享ExternalDNS的運作原理 :)


參考:


10會員
40內容數
記錄IT社畜的自我學習筆記,如同專題名稱,主要是怕自已忘記自已做過什麼、學到什麼。索性就分享我自已在學習Kubernetes這條路上的各種測試、學習心得。
留言0
查看全部
發表第一個留言支持創作者!