如同我們在先前的文章中所述,CoreDNS 可以用來取代 Kube-DNS,在 Kubernetes 叢集中進行服務探索。由於 CoreDNS 具有彈性的架構,因此可以實現一些有趣的應用案例。在這篇部落格中,我們將展示如何解決一個常見的問題 - 為您的服務建立自訂 DNS 條目。
這裡有幾種不同的可能性
- 為外部名稱建立別名
- 將服務動態新增至另一個網域,而無需執行其他伺服器
- 在叢集網域內新增任意條目
CoreDNS 可以解決所有這些應用案例。讓我們先從第一個開始,這很常見。在這種情況下,您希望能夠為給定的服務使用相同的名稱,無論您是在叢集內部還是外部存取它。例如,當使用繫結到該名稱的 TLS 憑證時,這會很有幫助。
假設我們有一個服務 foo.default.svc.cluster.local
,外部用戶端可以使用 foo.example.com
存取。也就是說,當在叢集外部查詢時,foo.example.com
將解析為負載平衡器的 VIP - 服務的外部 IP 位址。在叢集內部,它將解析為相同的內容,因此在內部使用此名稱將導致流量迴路 - 流量會離開叢集,然後透過外部 IP 返回。相反地,我們希望它解析為內部的 ClusterIP,以避免迴路。
為了在 CoreDNS 中執行此操作,我們使用 rewrite
外掛程式。這個外掛程式可以在查詢被發送到將要回答它的任何後端之前修改查詢。回想一下我們在上一篇部落格中使用的 Corefile
(CoreDNS 設定檔)
.:53 {
errors
log
health
kubernetes cluster.local 10.0.0.0/24
forward . /etc/resolv.conf
cache 30
}
為了獲得我們想要的行為,我們只需要新增一個重寫規則,將 foo.example.com
對應到 foo.default.svc.cluster.local
.:53 {
errors
log
health
rewrite name foo.example.com foo.default.svc.cluster.local
kubernetes cluster.local 10.0.0.0/24
forward . /etc/resolv.conf
cache 30
}
一旦我們透過 kubectl edit
或 kubectl apply
將其新增到 ConfigMap
後,我們必須讓 CoreDNS 知道 Corefile
已變更。您可以傳送 SIGUSR1
給它,告訴它以優雅的方式重新載入 - 也就是說,不會遺失服務
$ kubectl exec -n kube-system coredns-980047985-g2748 -- kill -SIGUSR1 1
執行我們的測試 pod,我們可以看到這個方法有效
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host foo
foo.default.svc.cluster.local has address 10.0.0.72
/ # host foo.example.com
foo.example.com has address 10.0.0.72
/ # host bar.example.com
Host bar.example.com not found: 3(NXDOMAIN)
/ #
這就是解決第一個問題的全部方法。
第二個問題也很容易解決。在這裡,我們只想從不同於叢集網域的區域提供 DNS 條目。由於 CoreDNS 是一個通用 DNS 伺服器,因此除了 kubernetes
外掛程式之外,還有許多其他方法可以提供區域。為了簡單起見,我們將使用 file
外掛程式以及另一個 ConfigMap
條目來滿足此應用案例。但是,您可以使用 etcd
外掛程式將服務直接儲存在 etcd 執行個體中,或者使用 auto
外掛程式來管理一組區域 (與 git-sync 一起使用時非常棒)。
為了建立新的區域,我們需要修改我們一直用來在 pod 中建立其他檔案的 coredns.yaml
。為此,我們必須編輯 ConfigMap
,方法是在 Corefile
中新增 file
行,並為區域檔案新增另一個鍵 example.db
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
log
health
rewrite name foo.example.com foo.default.svc.cluster.local
kubernetes cluster.local 10.0.0.0/24
file /etc/coredns/example.db example.org
forward . /etc/resolv.conf
cache 30
}
example.db: |
; example.org test file
example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600
example.org. IN NS b.iana-servers.net.
example.org. IN NS a.iana-servers.net.
example.org. IN A 127.0.0.1
a.b.c.w.example.org. IN TXT "Not a wildcard"
cname.example.org. IN CNAME www.example.net.
service.example.org. IN SRV 8080 10 10 example.org.
我們也需要編輯 Pod
範本規格的 volumes
區段
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
- key: example.db
path: example.db
一旦我們使用 kubectl apply -f
應用此設定,由於磁碟區中新增了檔案,將會建立一個新的 CoreDNS pod。稍後對檔案的變更不需要新的 pod,只需像我們之前所做的那樣優雅地重新啟動即可。讓我們看一下
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host foo
foo.default.svc.cluster.local has address 10.0.0.72
/ # host foo.example.com
foo.example.com has address 10.0.0.72
/ # host example.org
example.org has address 127.0.0.1
/ #
完美!我們現在可以編輯該 ConfigMap
並傳送 SIGUSR1
,隨時將條目新增至 example.org
。當然,如前所述,我們也可以使用 etcd
後端,避免修改 ConfigMap
和傳送訊號的麻煩。
這將我們帶到最後一個問題。可以使用 kubernetes
外掛程式中新增的 fallthrough
支援來解決該問題。此功能已在最近發布的 CoreDNS 007 版本中新增 - 我們將很快發表另一篇部落格來展示如何使用它。