服務和 Pod 的 DNS

你的工作負載可以使用 DNS 在叢集中發現 Services;本頁將解釋其工作原理。

Kubernetes 為 Services 和 Pod 建立 DNS 記錄。你可以使用一致的 DNS 名稱而不是 IP 地址來訪問 Services。

Kubernetes 釋出有關 Pods 和 Services 的資訊,這些資訊用於對 DNS 進行程式設計。kubelet 配置 Pod 的 DNS,以便執行中的容器可以透過名稱而不是 IP 查詢 Services。

在叢集中定義的 Services 會被分配 DNS 名稱。預設情況下,客戶端 Pod 的 DNS 搜尋列表包括 Pod 自己的名稱空間和叢集的預設域。

Services 的名稱空間

DNS 查詢可能會根據發出查詢的 Pod 的名稱空間返回不同的結果。未指定名稱空間的 DNS 查詢僅限於 Pod 的名稱空間。透過在 DNS 查詢中指定名稱空間來訪問其他名稱空間中的 Services。

例如,考慮一個在 `test` 名稱空間中的 Pod。一個 `data` Service 位於 `prod` 名稱空間中。

對 `data` 的查詢不返回任何結果,因為它使用了 Pod 的 `test` 名稱空間。

對 `data.prod` 的查詢返回預期結果,因為它指定了名稱空間。

DNS 查詢可以使用 Pod 的 `/etc/resolv.conf` 進行擴充套件。kubelet 為每個 Pod 配置此檔案。例如,對 `data` 的查詢可能會擴充套件為 `data.test.svc.cluster.local`。`search` 選項的值用於擴充套件查詢。要了解有關 DNS 查詢的更多資訊,請參閱`resolv.conf` 手冊頁

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

總而言之,位於 *test* 名稱空間中的 Pod 可以成功解析 `data.prod` 或 `data.prod.svc.cluster.local`。

DNS 記錄

哪些物件會獲得 DNS 記錄?

  1. 服務
  2. Pod

以下各節詳細介紹了支援的 DNS 記錄型別和佈局。任何其他可能有效的佈局、名稱或查詢都被視為實現細節,並可能在不通知的情況下更改。有關最新規範,請參閱基於 Kubernetes DNS 的服務發現

服務

A/AAAA 記錄

“普通”(非 Headless)Services 會根據 Service 的 IP 族為其分配 DNS A 和/或 AAAA 記錄,名稱格式為 `my-svc.my-namespace.svc.cluster-domain.example`。這會解析為 Service 的叢集 IP。

Headless Services(沒有叢集 IP)也會被分配 DNS A 和/或 AAAA 記錄,名稱格式為 `my-svc.my-namespace.svc.cluster-domain.example`。與普通 Service 不同,它會解析為 Service 選擇的所有 Pod 的 IP 地址集。客戶端預計會使用該集合,或者從該集合中進行標準輪詢選擇。

SRV 記錄

為作為普通或 Headless Service 的一部分的命名埠建立 SRV 記錄。

  • 對於每個命名埠,SRV 記錄的格式為 `_port-name._port-protocol.my-svc.my-namespace.svc.cluster-domain.example`。
  • 對於常規 Service,這會解析為埠號和域名:`my-svc.my-namespace.svc.cluster-domain.example`。
  • 對於 Headless Service,這會解析為多個答案,每個支援 Service 的 Pod 一個,幷包含埠號和 Pod 的域名,格式為 `hostname.my-svc.my-namespace.svc.cluster-domain.example`。

Pod

A/AAAA 記錄

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

<pod-IPv4-address>.<namespace>.pod.<cluster-domain>

例如,如果 `default` 名稱空間中的 Pod 的 IP 地址為 172.17.0.3,並且叢集的域名是 `cluster.local`,則該 Pod 具有 DNS 名稱

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

一些叢集 DNS 機制,例如 CoreDNS,也為以下內容提供 `A` 記錄

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

例如,如果 `cafe` 名稱空間中的 Pod 的 IP 地址為 172.17.0.3,是名為 `barista` 的 Service 的端點,並且叢集的域名是 `cluster.local`,則該 Pod 將具有此服務作用域的 DNS `A` 記錄。

172-17-0-3.barista.cafe.svc.cluster.local

Pod 的主機名和子域名欄位

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

Pod Spec 具有可選的 `hostname` 欄位,可用於指定不同的主機名。當指定時,它優先於 Pod 的名稱作為 Pod 的主機名(再次強調,從 Pod 內部觀察)。例如,給定一個 `spec.hostname` 設定為 `"my-host"` 的 Pod,該 Pod 的主機名將被設定為 `"my-host"`。

Pod spec 還有一個可選的 `subdomain` 欄位,用於指示 Pod 是名稱空間子組的一部分。例如,一個 `spec.hostname` 設定為 `"foo"`,`spec.subdomain` 設定為 `"bar"`,在名稱空間 `"my-namespace"` 中的 Pod,其主機名將設定為 `"foo"`,其完全限定域名 (FQDN) 將設定為 `"foo.bar.my-namespace.svc.cluster.local"`(再次強調,從 Pod 內部觀察)。

如果與 Pod 處於相同名稱空間中存在一個 Headless Service,且其名稱與子域名相同,則叢集的 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

給定上述 Service `"busybox-subdomain"` 和將 `spec.subdomain` 設定為 `"busybox-subdomain"` 的 Pods,第一個 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) 時,其主機名是短主機名。例如,如果你有一個 FQDN 為 `busybox-1.busybox-subdomain.my-namespace.svc.cluster-domain.example` 的 Pod,那麼預設情況下,該 Pod 內部的 `hostname` 命令會返回 `busybox-1`,而 `hostname --fqdn` 命令會返回 FQDN。

當你在 Pod Spec 中設定 `setHostnameAsFQDN: true` 時,kubelet 將 Pod 的 FQDN 寫入該 Pod 名稱空間的主機名。在這種情況下,`hostname` 和 `hostname --fqdn` 都返回 Pod 的 FQDN。

Pod 的 DNS 策略

DNS 策略可以按每個 Pod 進行設定。目前 Kubernetes 支援以下 Pod 特定的 DNS 策略。這些策略在 Pod Spec 的 `dnsPolicy` 欄位中指定。

  • “`Default`”:Pod 從其執行節點繼承名稱解析配置。有關更多詳細資訊,請參閱相關討論

  • “`ClusterFirst`”:任何不匹配已配置的叢集域字尾的 DNS 查詢,例如“`www.kubernetes.io`”,都由 DNS 伺服器轉發到上游名稱伺服器。叢集管理員可能配置了額外的 stub 域和上游 DNS 伺服器。有關在這些情況下如何處理 DNS 查詢的詳細資訊,請參閱相關討論

  • “`ClusterFirstWithHostNet`”:對於使用 hostNetwork 執行的 Pod,應將其 DNS 策略明確設定為 “`ClusterFirstWithHostNet`”。否則,使用 hostNetwork 和 “`ClusterFirst`” 執行的 Pod 將回退到 “`Default`” 策略的行為。

  • “`None`”:它允許 Pod 忽略 Kubernetes 環境中的 DNS 設定。所有 DNS 設定都應使用 Pod Spec 中的 `dnsConfig` 欄位提供。請參閱下面的Pod 的 DNS 配置子節。

下面的示例顯示了一個 Pod,其 DNS 策略設定為 “`ClusterFirstWithHostNet`”,因為它的 `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 配置

功能狀態:`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 搜尋域列表限制

功能狀態:`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、Services 或可以透過此單一字尾解析的網路名稱。例如,在 `default` 名稱空間中生成的 Pod 將具有 DNS 字尾 `default.svc.cluster.local`。在 Windows Pod 內部,你可以解析 `kubernetes.default.svc.cluster.local` 和 `kubernetes`,但不能解析部分限定的名稱(`kubernetes.default` 或 `kubernetes.default.svc`)。

下一步

有關管理 DNS 配置的指導,請檢視配置 DNS 服務

上次修改時間:2025 年 7 月 29 日上午 9:29 PST:新增 HostnameOverride 功能門控的文件 (9e0fdab8b3)