本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

CoreDNS 正式成為 Kubernetes 叢集 DNS

編者按:此文章是關於 Kubernetes 1.11 新功能的一系列深度文章之一

引言

在 Kubernetes 1.11 中,CoreDNS 已達到通用可用性 (GA),可作為 kube-dns 外掛的替代方案,用於基於 DNS 的服務發現。這意味著 CoreDNS 將在即將釋出的各種安裝工具版本中作為選項提供。事實上,kubeadm 團隊選擇將其作為 Kubernetes 1.11 預設選項。

基於 DNS 的服務發現長期以來一直是 Kubernetes 的一部分,透過 kube-dns 叢集外掛實現。這通常執行良好,但其實現的可靠性、靈活性和安全性存在一些問題。

CoreDNS 是一個通用型權威 DNS 伺服器,它提供與 Kubernetes 向後相容且可擴充套件的整合。它解決了 kube-dns 存在的問題,並提供了許多獨特功能,可以解決更廣泛的用例。

在本文中,您將瞭解 kube-dns 和 CoreDNS 之間實現上的差異,以及 CoreDNS 提供的一些實用擴充套件。

實現差異

在 kube-dns 中,一個 Pod 中使用了多個容器:`kubedns`、`dnsmasq` 和 `sidecar`。`kubedns` 容器監控 Kubernetes API 並根據 Kubernetes DNS 規範提供 DNS 記錄,`dnsmasq` 提供快取和存根域支援,`sidecar` 提供指標和健康檢查。

這種設定導致了一些長期存在的問題。例如,`dnsmasq` 中的安全漏洞曾導致 Kubernetes 在過去需要釋出安全補丁。此外,由於 `dnsmasq` 處理存根域,而 `kubedns` 處理外部服務,因此您不能在外部服務中使用存根域,這極大地限制了該功能(參見 dns#131)。

在 CoreDNS 中,所有這些功能都在一個用 Go 編寫的程序中完成,該程序執行在一個單獨的容器中。啟用的不同外掛複製(並增強)了 kube-dns 中的功能。

配置 CoreDNS

在 kube-dns 中,您可以透過修改 ConfigMap 來更改服務發現的行為。這允許新增諸如提供存根域、修改上游名稱伺服器和啟用聯邦等功能。

在 CoreDNS 中,您也可以類似地修改 CoreDNS Corefile 的 ConfigMap,以更改服務發現的工作方式。此 Corefile 配置提供了比 kube-dns 更多的選項,因為它 CoreDNS 用於配置所有功能的 主要配置檔案,甚至那些與 Kubernetes 無關的功能。

當使用 `kubeadm` 從 kube-dns 升級到 CoreDNS 時,您現有的 ConfigMap 將用於為您生成自定義的 Corefile,包括存根域、聯邦和上游名稱伺服器的所有配置。有關更多詳細資訊,請參閱使用 CoreDNS 進行服務發現

錯誤修復和增強

kube-dns 存在一些未解決的問題,這些問題已在 CoreDNS 中解決,無論是在預設配置中還是透過一些自定義配置。

指標

預設 CoreDNS 配置的功能行為與 kube-dns 相同。但是,您需要注意的一個區別是,釋出的指標不同。在 kube-dns 中,您會獲得 `dnsmasq` 和 `kubedns` (skydns) 的單獨指標。在 CoreDNS 中,由於它是一個單獨的程序,因此有一組完全不同的指標。您可以在 CoreDNS Prometheus 外掛頁面上找到有關這些指標的更多詳細資訊。

一些特殊功能

標準 CoreDNS Kubernetes 配置旨在與之前的 kube-dns 行為向後相容。但透過一些配置更改,CoreDNS 可以讓您修改叢集中 DNS 服務發現的工作方式。其中許多功能仍然符合 Kubernetes DNS 規範;它們增強了功能,但保持了向後相容。由於 CoreDNS 不僅僅是為 Kubernetes 而生,而是一個通用 DNS 伺服器,因此您可以做很多超出該規範的事情。

Pod 驗證模式

在 kube-dns 中,Pod 名稱記錄是“偽造的”。也就是說,任何“a-b-c-d.namespace.pod.cluster.local”查詢都會返回 IP 地址“a.b.c.d”。在某些情況下,這可能會削弱 TLS 提供的身份保障。因此,CoreDNS 提供了一種“Pods Verified”模式,僅當指定名稱空間中存在具有該 IP 地址的 Pod 時才返回 IP 地址。

基於 Pod 名稱的端點名稱

在 kube-dns 中,當使用無頭服務時,您可以使用 SRV 請求來獲取服務的所有端點列表

dnstools# host -t srv headless
headless.default.svc.cluster.local has SRV record 10 33 0 6234396237313665.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 10 33 0 6662363165353239.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 10 33 0 6338633437303230.headless.default.svc.cluster.local.
dnstools#

然而,端點 DNS 名稱(實際上)是隨機的。在 CoreDNS 中,預設情況下,您會獲得基於端點 IP 地址的端點 DNS 名稱

dnstools# host -t srv headless
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-14.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-18.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-4.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-9.headless.default.svc.cluster.local.

對於某些應用程式,需要使用 Pod 名稱而不是 Pod IP 地址(例如,參見 kubernetes#47992coredns#1190)。要在 CoreDNS 中啟用此功能,您可以在 Corefile 中指定“endpoint_pod_names”選項,這將導致以下結果

dnstools# host -t srv headless
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-qv84p.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-zc8lx.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-q7lf2.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-566rt.headless.default.svc.cluster.local.

自動路徑

CoreDNS 還具有一項特殊功能,可提高外部名稱 DNS 請求的延遲。在 Kubernetes 中,Pod 的 DNS 搜尋路徑指定了一個很長的字尾列表。這允許在請求叢集中的服務時使用短名稱,例如,上面的“headless”,而不是“headless.default.svc.cluster.local”。然而,當請求外部名稱(例如“infoblox.com”)時,客戶端會發出幾個無效的 DNS 查詢,每次都需要客戶端與 kube-dns 之間進行往返通訊(實際上是先到 `dnsmasq`,然後到 `kubedns`,因為停用了負快取

  • infoblox.com.default.svc.cluster.local -> NXDOMAIN
  • infoblox.com.svc.cluster.local -> NXDOMAIN
  • infoblox.com.cluster.local -> NXDOMAIN
  • infoblox.com.your-internal-domain.com -> NXDOMAIN
  • infoblox.com -> 返回有效記錄

在 CoreDNS 中,可以啟用一個名為 autopath 的可選功能,它將導致此搜尋路徑在伺服器**內部**被跟蹤。也就是說,CoreDNS 將根據源 IP 地址判斷客戶端 Pod 所在的名稱空間,並遍歷此搜尋列表,直到獲得有效答案。由於前三個查詢在 CoreDNS 內部自行解決,因此它消除了客戶端和伺服器之間的所有來回通訊,從而降低了延遲。

其他一些 Kubernetes 特有功能

在 CoreDNS 中,您可以使用標準 DNS 區域傳輸來匯出整個 DNS 記錄集。這對於除錯服務以及將叢集區域匯入其他 DNS 伺服器非常有用。

您還可以按名稱空間或標籤選擇器進行過濾。這允許您執行僅提供與過濾器匹配的記錄的特定 CoreDNS 例項,從而僅透過 DNS 公開有限的服務集。

可擴充套件性

除了上述功能外,CoreDNS 易於擴充套件。可以構建包含您自己功能的自定義 CoreDNS 版本。例如,此功能已被用於擴充套件 CoreDNS,透過 unbound 外掛進行遞迴解析,透過 pdsql 外掛直接從資料庫提供記錄,以及允許多個 CoreDNS 例項透過 redisc 外掛共享公共的二級快取。

CoreDNS 網站的外部外掛頁面上還添加了許多其他有趣的擴充套件。其中一個對 Kubernetes 和 Istio 使用者來說非常有趣的是 kubernetai 外掛,它允許單個 CoreDNS 例項連線到多個 Kubernetes 叢集,並在所有叢集中提供服務發現。

接下來呢?

CoreDNS 是一個獨立的專案,因此正在開發許多與 Kubernetes 不直接相關的功能。然而,其中許多功能將在 Kubernetes 中得到應用。例如,即將與策略引擎整合,將允許 CoreDNS 在請求無頭服務時做出智慧選擇,返回哪個端點。這可以用於將流量路由到本地 Pod,或路由到響應更快的 Pod。許多其他功能正在開發中,當然,作為一個開源專案,我們歡迎您提出並貢獻自己的功能!

上面描述的功能和差異只是一些例子。您可以用 CoreDNS 做更多的事情。您可以在 CoreDNS 部落格上找到更多資訊。

參與 CoreDNS

CoreDNS 是一個孵化中的 CNCF 專案。

我們在 Slack(和 GitHub)上最活躍。

更多資源可以在以下網站找到