服務與 Pod 的 DNS

您的工作負載可以使用 DNS 探索叢集中的服務;此頁面說明其運作方式。

Kubernetes 為服務與 Pod 建立 DNS 記錄。您可以使用一致的 DNS 名稱而非 IP 位址來聯絡服務。

Kubernetes 發布關於 Pod 與服務的資訊,這些資訊用於程式設計 DNS。Kubelet 設定 Pod 的 DNS,以便執行中的容器可以使用名稱而非 IP 查詢服務。

在叢集中定義的服務會被指派 DNS 名稱。預設情況下,用戶端 Pod 的 DNS 搜尋清單包含 Pod 自己的命名空間與叢集的預設網域。

服務的命名空間

DNS 查詢可能會根據發出查詢的 Pod 的命名空間傳回不同的結果。未指定命名空間的 DNS 查詢僅限於 Pod 的命名空間。透過在 DNS 查詢中指定其他命名空間來存取其他命名空間中的服務。

例如,考量在 test 命名空間中的 Pod。data 服務位於 prod 命名空間中。

data 的查詢不會傳回任何結果,因為它使用 Pod 的 test 命名空間。

data.prod 的查詢會傳回預期的結果,因為它指定了命名空間。

DNS 查詢可以使用 Pod 的 /etc/resolv.conf 進行擴充。Kubelet 為每個 Pod 設定此檔案。例如,僅對 data 的查詢可能會擴充為 data.test.svc.cluster.localsearch 選項的值用於擴充查詢。若要深入瞭解 DNS 查詢,請參閱 resolv.conf 手冊頁面。

nameserver 10.32.0.10
search <namespace>.svc.cluster.local svc.cluster.local cluster.local
options ndots:5

總之,test 命名空間中的 Pod 可以成功解析 data.proddata.prod.svc.cluster.local

DNS 記錄

哪些物件取得 DNS 記錄?

  1. 服務
  2. Pod

以下章節詳細說明支援的 DNS 記錄類型與支援的版面配置。任何其他版面配置或名稱或碰巧可運作的查詢都被視為實作細節,並且可能會在沒有警告的情況下變更。如需最新的規格,請參閱 Kubernetes 基於 DNS 的服務發現

服務

A/AAAA 記錄

「一般」(非 Headless)服務會被指派 DNS A 及/或 AAAA 記錄,取決於服務的 IP 系列或系列,名稱格式為 my-svc.my-namespace.svc.cluster-domain.example。這會解析為服務的叢集 IP。

Headless 服務(沒有叢集 IP)服務也會被指派 DNS A 及/或 AAAA 記錄,名稱格式為 my-svc.my-namespace.svc.cluster-domain.example。與一般服務不同,這會解析為服務所選取的所有 Pod 的 IP 集合。用戶端預期會使用該集合,否則會從該集合中使用標準的循環配置資源選擇。

SRV 記錄

SRV 記錄是為屬於一般或 Headless 服務的具名連接埠建立的。對於每個具名連接埠,SRV 記錄的格式為 _port-name._port-protocol.my-svc.my-namespace.svc.cluster-domain.example。對於一般服務,這會解析為連接埠號碼與網域名稱:my-svc.my-namespace.svc.cluster-domain.example。對於 Headless 服務,這會解析為多個答案,每個答案對應一個支援服務的 Pod,並包含連接埠號碼與 Pod 的網域名稱,格式為 hostname.my-svc.my-namespace.svc.cluster-domain.example

Pod

A/AAAA 記錄

DNS 規格實作之前,Kube-DNS 版本具有以下 DNS 解析

pod-ipv4-address.my-namespace.pod.cluster-domain.example.

例如,如果 default 命名空間中的 Pod 的 IP 位址為 172.17.0.3,並且您叢集的網域名稱為 cluster.local,則 Pod 的 DNS 名稱為

172-17-0-3.default.pod.cluster.local.

服務公開的任何 Pod 都有以下可用的 DNS 解析

pod-ipv4-address.service-name.my-namespace.svc.cluster-domain.example.

Pod 的 hostname 與 subdomain 欄位

目前,當 Pod 建立時,其主機名稱(從 Pod 內部觀察到的)是 Pod 的 metadata.name 值。

Pod 規格具有選用的 hostname 欄位,可用於指定不同的主機名稱。指定時,它優先於 Pod 的名稱,成為 Pod 的主機名稱(再次,從 Pod 內部觀察到的)。例如,給定一個 spec.hostname 設定為 "my-host" 的 Pod,該 Pod 將會將其主機名稱設定為 "my-host"

Pod 規格也具有選用的 subdomain 欄位,可用於指示 Pod 是命名空間子群組的一部分。例如,在 "my-namespace" 命名空間中,spec.hostname 設定為 "foo",且 spec.subdomain 設定為 "bar" 的 Pod,其主機名稱將設定為 "foo",而其完整網域名稱 (FQDN) 將設定為 "foo.bar.my-namespace.svc.cluster.local"(再次,從 Pod 內部觀察到的)。

如果與 Pod 在相同命名空間中存在與子網域名稱相同的 Headless 服務,則叢集的 DNS 伺服器也會傳回 Pod 完整限定主機名稱的 A 及/或 AAAA 記錄。

範例

apiVersion: v1
kind: Service
metadata:
  name: busybox-subdomain
spec:
  selector:
    name: busybox
  clusterIP: None
  ports:
  - name: foo # name is not required for single-port Services
    port: 1234
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox1
  labels:
    name: busybox
spec:
  hostname: busybox-1
  subdomain: busybox-subdomain
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    name: busybox
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox2
  labels:
    name: busybox
spec:
  hostname: busybox-2
  subdomain: busybox-subdomain
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    name: busybox

給定上述服務 "busybox-subdomain" 與將 spec.subdomain 設定為 "busybox-subdomain" 的 Pod,第一個 Pod 會將自己的 FQDN 視為 "busybox-1.busybox-subdomain.my-namespace.svc.cluster-domain.example"。DNS 在該名稱提供 A 及/或 AAAA 記錄,指向 Pod 的 IP。Pod "busybox1" 與 "busybox2" 都會有自己的位址記錄。

EndpointSlice 可以指定任何端點位址的 DNS 主機名稱,以及其 IP。

Pod 的 setHostnameAsFQDN 欄位

功能狀態: Kubernetes v1.22 [stable]

當 Pod 組態為具有完整網域名稱 (FQDN) 時,其主機名稱是簡短主機名稱。例如,如果您有一個完整網域名稱 busybox-1.busybox-subdomain.my-namespace.svc.cluster-domain.example 的 Pod,則預設情況下,該 Pod 內部的 hostname 命令會傳回 busybox-1,而 hostname --fqdn 命令會傳回 FQDN。

當您在 Pod 規格中設定 setHostnameAsFQDN: true 時,kubelet 會將 Pod 的 FQDN 寫入該 Pod 命名空間的主機名稱。在這種情況下,hostnamehostname --fqdn 都會傳回 Pod 的 FQDN。

Pod 的 DNS 原則

DNS 原則可以在每個 Pod 的基礎上設定。目前 Kubernetes 支援以下 Pod 特定的 DNS 原則。這些原則在 Pod 規格的 dnsPolicy 欄位中指定。

  • "Default":Pod 從 Pod 執行的節點繼承名稱解析組態。請參閱相關討論以取得更多詳細資訊。
  • "ClusterFirst":任何與已設定的叢集網域後綴(例如 "www.kubernetes.io")不符的 DNS 查詢,都會由 DNS 伺服器轉發到上游名稱伺服器。叢集管理員可能已設定額外的存根網域和上游 DNS 伺服器。請參閱相關討論以取得關於在這些情況下如何處理 DNS 查詢的詳細資訊。
  • "ClusterFirstWithHostNet":對於使用 hostNetwork 執行的 Pod,您應該明確地將其 DNS 原則設定為 "ClusterFirstWithHostNet"。否則,使用 hostNetwork 和 "ClusterFirst" 執行的 Pod 將會退回 "Default" 原則的行為。
    • 注意:Windows 不支援此功能。請參閱下方的 DNS 與 Windows 以取得詳細資訊
  • "None":它允許 Pod 忽略來自 Kubernetes 環境的 DNS 設定。所有 DNS 設定都應使用 Pod 規格中的 dnsConfig 欄位提供。請參閱下方 Pod 的 DNS 組態 子章節。

以下範例顯示一個 DNS 原則設定為 "ClusterFirstWithHostNet" 的 Pod,因為它已將 hostNetwork 設定為 true

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  namespace: default
spec:
  containers:
  - image: busybox:1.28
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
    name: busybox
  restartPolicy: Always
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet

Pod 的 DNS 組態

FEATURE STATE: Kubernetes v1.14 [stable]

Pod 的 DNS 組態允許使用者更精細地控制 Pod 的 DNS 設定。

dnsConfig 欄位是選用的,它可以與任何 dnsPolicy 設定搭配使用。但是,當 Pod 的 dnsPolicy 設定為 "None" 時,則必須指定 dnsConfig 欄位。

以下是使用者可以在 dnsConfig 欄位中指定的屬性

  • nameservers:將用作 Pod 的 DNS 伺服器的 IP 位址清單。最多可以指定 3 個 IP 位址。當 Pod 的 dnsPolicy 設定為 "None" 時,此清單必須包含至少一個 IP 位址,否則此屬性為選用。列出的伺服器將與從指定的 DNS 原則產生的基本名稱伺服器合併,並移除重複的位址。
  • searches:用於 Pod 中主機名稱查詢的 DNS 搜尋網域清單。此屬性為選用。指定後,提供的清單將合併到從選定的 DNS 原則產生的基本搜尋網域名稱中。重複的網域名稱會被移除。Kubernetes 允許最多 32 個搜尋網域。
  • options:一個選用物件清單,其中每個物件可能具有 name 屬性(必要)和 value 屬性(選用)。此屬性中的內容將合併到從指定的 DNS 原則產生的選項中。重複的項目會被移除。

以下是具有自訂 DNS 設定的 Pod 範例

apiVersion: v1
kind: Pod
metadata:
  namespace: default
  name: dns-example
spec:
  containers:
    - name: test
      image: nginx
  dnsPolicy: "None"
  dnsConfig:
    nameservers:
      - 192.0.2.1 # this is an example
    searches:
      - ns1.svc.cluster-domain.example
      - my.dns.search.suffix
    options:
      - name: ndots
        value: "2"
      - name: edns0

當上述 Pod 建立時,容器 test 會在其 /etc/resolv.conf 檔案中取得以下內容

nameserver 192.0.2.1
search ns1.svc.cluster-domain.example my.dns.search.suffix
options ndots:2 edns0

對於 IPv6 設定,應如下設定搜尋路徑和名稱伺服器

kubectl exec -it dns-example -- cat /etc/resolv.conf

輸出結果類似於此

nameserver 2001:db8:30::a
search default.svc.cluster-domain.example svc.cluster-domain.example cluster-domain.example
options ndots:5

DNS 搜尋網域列表限制

FEATURE STATE: Kubernetes 1.28 [stable]

Kubernetes 本身不限制 DNS 組態,除非搜尋網域列表的長度超過 32 個,或所有搜尋網域的總長度超過 2048 個字元。此限制分別適用於節點的解析器組態檔、Pod 的 DNS 組態和合併的 DNS 組態。

Windows 節點上的 DNS 解析

  • 在 Windows 節點上執行的 Pod 不支援 ClusterFirstWithHostNet。Windows 將所有帶有 . 的名稱視為 FQDN,並跳過 FQDN 解析。
  • 在 Windows 上,可以使用多個 DNS 解析器。由於它們的行為略有不同,因此建議使用 Resolve-DNSName PowerShell Cmdlet 進行名稱查詢解析。
  • 在 Linux 上,您有一個 DNS 後綴列表,在完全合格名稱解析失敗後使用。在 Windows 上,您只能有一個 DNS 後綴,即與該 Pod 命名空間關聯的 DNS 後綴(例如:mydns.svc.cluster.local)。Windows 可以解析 FQDN、服務或可以使用此單一後綴解析的網路名稱。例如,在 default 命名空間中產生的 Pod 將具有 DNS 後綴 default.svc.cluster.local。在 Windows Pod 內部,您可以解析 kubernetes.default.svc.cluster.localkubernetes,但不能解析部分合格的名稱 (kubernetes.defaultkubernetes.default.svc)。

下一步

有關管理 DNS 組態的指南,請查看設定 DNS 服務