在Kubernetes叢集中,Pod訪問Service或叢集外的服務時使用的是網域名稱,但是網域名稱需要被解析為IP地址才可訪問。DNS(Domain Name System)就用於這個情境,它儲存了名稱與IP地址的對應關係。通過本文,您可瞭解DNS的基礎知識、ACK中的DNS組件以及DNS配置。
DNS網域名稱解析原理
雖然互連網裝置通過IP地址互相通訊,但是網域名稱本身包含了語義,比起IP地址更容易記憶。因此,絕大多數情況下,用戶端會通過網域名稱發起請求。下圖展示了用戶端向example.com發送請求時的流程:
伺服器向DNS伺服器註冊自身的IP地址與網域名稱,DNS伺服器會儲存對應的記錄。
用戶端向DNS伺服器詢問example.com對應的IP地址。
DNS伺服器根據儲存的記錄將IP返回給用戶端。
用戶端使用IP地址訪問目標伺服器。
叢集視角的網域名稱分類
叢集內網域名稱:叢集內Service的網域名稱,僅在叢集內有效。推薦相關業務使用完整網域名稱(
<service-name>.<namespace>.svc.<cluster-domain>)格式進行訪問。使用短網域名稱(<service-name>)會導致過多無效DNS查詢,增加解析耗時。cluster-domain在叢集建立時自訂配置,預設為
cluster.local。叢集外網域名稱:包含VPC內網域名稱,公網網域名稱。解析這些網域名稱時,CoreDNS需要從上遊DNS伺服器擷取解析結果。上遊DNS預設為內網網域名稱解析(PrivateZone)服務,IP地址100.100.2.136和100.100.2.138。
叢集中的DNS組件
在ACK託管叢集中,有兩個負責DNS的組件,CoreDNS與NodeLocal DNSCache。在您瞭解它們的作用之前,請您閱讀下方的內容,瞭解叢集中DNS的基礎知識。
CoreDNS非託管版
CoreDNS是Kubernetes叢集中負責DNS解析的組件,能夠支援解析叢集內部自訂服務網域名稱和叢集外部網域名稱。CoreDNS專案由CNCF託管。關於CoreDNS的更多資訊,請參見CoreDNS: DNS and Service Discovery。
與開源Kubernetes標準相同,ACK叢集預設安裝CoreDNS作為DNS伺服器。CoreDNS以Deployment的方式部署在了叢集的kube-system命名空間下。kube-dns則是CoreDNS所屬的ClusterIP類型的Service。CoreDNS的配置方法,請參見CoreDNS配置說明。
下面的樣本中,處於default命名空間的Pod嘗試訪問database-svc,經歷了以下流程:
Pod查看
/etc/resolv.conf設定檔,確定了DNS伺服器的IP為172.0.XX.XX,這是kube-dns的ClusterIP。樣本設定檔內容如下。nameserver 172.0.XX.XX # 定義DNS伺服器的IP地址。 search default.svc.cluster.local svc.cluster.local cluster.local # 設定網域名稱的尋找尾碼規則,尋找配置越多,說明網域名稱解析尋找匹配次數越多。 options ndots:5 # 定義網域名稱解析設定檔選項,支援多個KV值。Pod向kube-dns發起DNS查詢,它會以
search中的值作為尾碼發起查詢,即依次嘗試查詢:database-svc.default.svc.cluster.local(與Pod同一命名空間的Service)database-svc.svc.cluster.local(其他命名空間的Service)database-svc.cluster.local(叢集範圍內的網域名稱)database-svc(叢集外網域名稱)
CoreDNS Pod返回結果,對應的IP為172.4.XX.XX。
Pod使用此IP訪問目標服務
database-svc。如果請求的是叢集外網域名稱,例如VPC網域名稱、公網網域名稱等,CoreDNS Pod將向上遊DNS服務發起查詢。
重要請勿修改節點DNS Server配置,因為CoreDNS預設繼承所在節點的上遊DNS服務地址。
CoreDNS的配置儲存於kube-system命名空間中的
coredns配置項 。預設配置中的forward指向/etc/resolv.conf,表示需要向上遊DNS服務查詢時,使用CoreDNS容器/etc/resolv.conf中儲存的DNS Server地址,而CoreDNS的/etc/resolv.conf預設與所在節點的/etc/resolv.conf相同,節點預設儲存的DNS Server地址為100.100.2.136和100.100.2.138。如果修改節點的DNS Server配置,會導致CoreDNS使用錯誤的上遊DNS服務地址,導致解析失敗或結果不符合預期。.:53 { ... forward . /etc/resolv.conf { prefer_udp } ... }
CoreDNS託管版
CoreDNS託管版的工作原理與非託管CoreDNS相同,但由ACK託管。CoreDNS託管版不佔用叢集資源,也無需您自行營運,同時會按照負載自動執行Auto Scaling,CoreDNS託管版的效能說明請參見CoreDNS託管版效能說明。
ACK智能託管模式支援CoreDNS託管版。如需使用ACK智能託管模式,請參見建立ACK託管叢集(智能託管模式)。
NodeLocal DNSCache
NodeLocal DNSCache會在每個Worker節點配置DNS緩衝,可以降低CoreDNS的壓力,提升叢集DNS的穩定性和可用性。 我們總是建議您在叢集下安裝該組件,提升DNS 解析的穩定性。您可參見使用NodeLocal DNSCache組件安裝並使用組件。
下面的樣本中,在安裝了NodeLocal DNSCache且給default命名空間打上node-local-dns-injection: "enabled"標籤後,處於default命名空間的Pod嘗試訪問database-svc,經歷了以下流程:
Pod會首先查看所在節點的DNS緩衝。
根據節點DNS緩衝是否命中,此時會分為兩種情況:
快取命中,即節點DNS緩衝中有
database-svc記錄,則緩衝返回結果,Pod使用結果訪問服務。緩衝未命中,即節點DNS緩衝中沒有
database-svc記錄,則仍舊通過CoreDNS擷取結果。從CoreDNS擷取的結果將同步到節點DNS緩衝以便後續使用。
叢集DNS配置
叢集中的DNS配置可分為下列三個維度,它們分別作用於不同的範圍。
叢集配置(全域)
ClusterDomain是每個節點的kubelet配置,但是在整個叢集內所有節點的kubelet中都應保持一致,否則會出現網路錯誤。
ClusterDomainClusterDomain是叢集本地頂級網域名稱,即叢集中所有Service完整網域名稱的預設尾碼,預設為
cluster.local。ClusterDomain配置通常用於區分叢集內網路與叢集外網路。在建立叢集時,您可對ClusterDomain自訂,請注意不要與您常用的外部網域名稱重合。
節點配置
resolveConfresolveConf指定節點上 DNS 設定檔的路徑。當 Pod 的dnsPolicy為Default時,kubelet 會將resolveConf指定的檔案(預設/etc/resolv.conf)複製到 Pod 的/etc/resolv.conf中。
Pod配置
每個Pod都有兩個配置:
dnsPolicy及dnsConfig,您可通過它們為Pod自訂DNS策略。dnsPolicy定義Pod的DNS解析策略,dnsConfig 用於自訂 DNS 伺服器和搜尋域。請參見DNS策略配置和網域名稱解析說明,瞭解如何結合情境使用dnsPolicy與dnsConfig。