在上一篇文章中,我們描述了 Kubernetes 中自訂 DNS 條目的三種不同使用案例
- 為外部名稱建立別名
- 動態地將服務新增到另一個網域,而無需執行另一個伺服器
- 在叢集網域內新增任意條目
在那篇文章中,我們介紹了前兩個案例。在這篇文章中,我們將向您展示如何使用 kubernetes
外掛程式的 fallthrough
選項來滿足第三個案例。
為了了解其運作方式,我們首先需要了解 CoreDNS 如何處理請求。先前在查詢路由中已提到過,但我們將在此處更詳細地介紹。
我們都知道 CoreDNS 會鏈接外掛程式。但這究竟是什麼意思?為了找出答案,我們將剖析一個 Corefile,看看它如何轉換為 CoreDNS 內部結構,並討論查詢如何通過這些內部結構進行路由。
考慮這個 Corefile
coredns.io:5300 {
file /etc/coredns/zones/coredns.io.db
}
example.io:53 {
errors
log
file /etc/coredns/zones/example.io.db
}
example.net:53 {
file /etc/coredns/zones/example.net.db
}
.: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
}
請注意,這裡有兩個不同的埠:5300 和 53。在內部,每個埠都會產生一個 dnsserver.Server
。即使有四個伺服器區塊(段落),我們也只會得到兩個實際的伺服器。CoreDNS 會收集所有與同一埠相關聯的伺服器區塊,並將它們合併到同一個 dnsserver.Server
中。伺服器會將埠上的查詢多工處理,並根據區域將它們傳遞到不同的外掛程式鏈。它會為該區域選擇最匹配的伺服器區塊。如果沒有伺服器區塊匹配,則會傳回 SERVFAIL
。如下圖所示。
因此,任何特定的查詢都會正好通過一個外掛程式鏈。外掛程式的順序是在建置時由 plugin.cfg
檔案決定的,儘管有一些關於在執行時修改的討論。這就是為什麼即使 cache
出現在伺服器區塊的末尾,它也不是外掛程式鏈的末尾。
請注意,在 .:53
伺服器區塊中,我們定義了 health
外掛程式,但它沒有出現在圖表中。這是因為有幾種不同類型外掛程式。「正常」外掛程式會執行請求處理,並出現在外掛程式鏈中。但是,有一些外掛程式只會修改伺服器或伺服器區塊的設定。由於它們沒有任何請求時邏輯,因此不會將它們插入到外掛程式鏈中。一些以這種方式工作的外掛程式是 health
、tls
、startup
、shutdown
和 root
外掛程式。
您可以將執行請求時處理的外掛程式分為兩組:以某種方式操作請求的外掛程式和後端外掛程式。後端外掛程式提供不同的區域和記錄資料來源。etcd
、file
和 kubernetes
外掛程式都是後端的範例。
操作請求但不是後端的外掛程式(也就是說,它們不是區域資料的來源)通常會在執行其邏輯後將查詢傳遞給下一個外掛程式。例如,rewrite
外掛程式會對請求進行變更,然後將其傳遞下去。當從後續外掛程式傳回結果時,它會將問題部分恢復為原始狀態(以便客戶端不會抱怨),但會保留回應並將其傳回客戶端。
任何給定的後端通常都是其區域的最終決定權 - 它要么傳回結果,要么為查詢傳回 NXDOMAIN。但是,有時這不是所需的行為,因此有些外掛程式支援 fallthrough
選項。當啟用 fallthrough
時,外掛程式不會在找不到記錄時傳回 NXDOMAIN,而是會將請求向下傳遞到鏈中。鏈中較後面的後端便有機會處理該請求。
回到我們最初關於 Kubernetes 中三個使用案例的討論,我們現在可以了解如何使用 fallthrough
來滿足第三個使用案例。請回想一下該部落格中的初始 Corefile
.:53 {
errors
log
health
kubernetes cluster.local 10.0.0.0/24
forward . /etc/resolv.conf
cache 30
}
這處理了叢集內標準的 DNS 服務探索。第三個使用案例是在現有的叢集網域中新增任意條目。為此,我們定義另一個處理 cluster.local
區域的後端,並在 kubernetes
外掛程式中設定 fallthrough
選項。對於非常動態的條目,我們可以使用 etcd
外掛程式。但是為了示範起見,使用 file
外掛程式更簡單,這也是我們將要做的。
由於 kubernetes
在 plugin.cfg
中位於 file
之前,因此在 kubernetes
中使用 fallthrough
將導致 file
處理 kubernetes
未處理的任何查詢。這表示我們需要有一個區域檔案作為 ConfigMap 的一部分,就像我們在之前的部落格中處理第二個使用案例一樣。但是,在這種情況下,file
外掛程式不是使用不同的區域 (另一個部落格中的 example.org
) 進行設定,而是設定為使用 cluster.local
網域
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
namespace: kube-system
data:
Corefile: |
.:53 {
errors
log
health
kubernetes cluster.local 10.0.0.0/24 {
fallthrough
}
file /etc/coredns/cluster.db cluster.local
forward . /etc/resolv.conf
cache 30
}
cluster.db: |
cluster.local. IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 2015082541 7200 3600 1209600 3600
something.cluster.local. IN A 10.0.0.1
otherthing.cluster.local. IN CNAME google.com.
請記得將 cluster.db
檔案新增至 Pod 範本的 config-volume
volumes:
- name: config-volume
configMap:
name: coredns
items:
- key: Corefile
path: Corefile
- key: cluster.db
path: cluster.db
最後通知 CoreDNS 正常重新載入(每個執行的 Pod)
$ kubectl -n kube-system exec coredns-461002909-7mp96 -- kill -SIGUSR1 1
現在讓我們試試我們新的 DNS 記錄。
$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools
If you don't see a command prompt, try pressing enter.
/ # host kubernetes
kubernetes.default.svc.cluster.local has address 10.0.0.1
/ # host something
something.cluster.local has address 10.0.0.1
/ # host otherthign
Host otherthign not found: 3(NXDOMAIN)
/ # host otherthing
otherthing.cluster.local is an alias for google.com.
google.com has IPv6 address 2607:f8b0:4005:805::200e
google.com mail is handled by 30 alt2.aspmx.l.google.com.
google.com mail is handled by 50 alt4.aspmx.l.google.com.
google.com mail is handled by 40 alt3.aspmx.l.google.com.
google.com mail is handled by 20 alt1.aspmx.l.google.com.
google.com mail is handled by 10 aspmx.l.google.com.
/ #
我們可以看看,如果我們輸入不正確的名稱,我們仍然會像預期的那樣收到 NXDOMAIN。但是,正確的名稱將會解析為我們區域檔案中的記錄。因此,我們現在有一種方法可以在叢集網域中建立自訂條目。
在標準 CoreDNS 版本中,kubernetes
外掛程式位於 file
和 etcd
之前。這表示它首先有機會處理查詢。如果您希望,您可以重新建置 CoreDNS 以變更該順序 - 如果您想了解如何完成,請查看 Miek 關於如何將外掛程式新增至 CoreDNS 的文章。