驗證 IPv4/IPv6 雙棧

本文件介紹瞭如何驗證已啟用 IPv4/IPv6 雙協議棧的 Kubernetes 叢集。

準備工作

  • 提供商對雙協議棧網路的支援(雲提供商或其他提供商必須能夠為 Kubernetes 節點提供具有可路由的 IPv4/IPv6 網路介面)
  • 支援雙協議棧網路的網路外掛
  • 已啟用雙協議棧的叢集
你的 Kubernetes 伺服器版本必須是 v1.23 或更高版本。

要檢查版本,請輸入 kubectl version

驗證地址

驗證節點地址

每個雙協議棧節點都應分配一個 IPv4 塊和一個 IPv6 塊。透過執行以下命令來驗證是否配置了 IPv4/IPv6 Pod 地址範圍。將示例節點名稱替換為你叢集中有效的雙協議棧節點。在此示例中,節點名稱為 k8s-linuxpool1-34450317-0

kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .spec.podCIDRs}}{{printf "%s\n" .}}{{end}}'
10.244.1.0/24
2001:db8::/64

應該分配一個 IPv4 塊和一個 IPv6 塊。

驗證節點是否檢測到 IPv4 和 IPv6 介面。將節點名稱替換為叢集中有效的節點。在此示例中,節點名稱為 k8s-linuxpool1-34450317-0

kubectl get nodes k8s-linuxpool1-34450317-0 -o go-template --template='{{range .status.addresses}}{{printf "%s: %s\n" .type .address}}{{end}}'
Hostname: k8s-linuxpool1-34450317-0
InternalIP: 10.0.0.5
InternalIP: 2001:db8:10::5

驗證 Pod 地址

驗證 Pod 是否已分配 IPv4 和 IPv6 地址。將 Pod 名稱替換為你叢集中有效的 Pod。在此示例中,Pod 名稱為 pod01

kubectl get pods pod01 -o go-template --template='{{range .status.podIPs}}{{printf "%s\n" .ip}}{{end}}'
10.244.1.4
2001:db8::4

你還可以透過 Downward API 使用 status.podIPs 欄位路徑驗證 Pod IP。以下程式碼片段演示瞭如何透過名為 MY_POD_IPS 的環境變數在容器中暴露 Pod IP。

        env:
        - name: MY_POD_IPS
          valueFrom:
            fieldRef:
              fieldPath: status.podIPs

以下命令列印容器內 MY_POD_IPS 環境變數的值。該值是一個逗號分隔的列表,對應於 Pod 的 IPv4 和 IPv6 地址。

kubectl exec -it pod01 -- set | grep MY_POD_IPS
MY_POD_IPS=10.244.1.4,2001:db8::4

Pod 的 IP 地址也將寫入容器內的 /etc/hosts。以下命令在雙協議棧 Pod 上執行 cat /etc/hosts。從輸出中,你可以驗證 Pod 的 IPv4 和 IPv6 IP 地址。

kubectl exec -it pod01 -- cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
fe00::0    ip6-mcastprefix
fe00::1    ip6-allnodes
fe00::2    ip6-allrouters
10.244.1.4    pod01
2001:db8::4    pod01

驗證服務

建立以下未明確定義 .spec.ipFamilyPolicy 的 Service。Kubernetes 將從第一個配置的 service-cluster-ip-range 為 Service 分配一個叢集 IP,並將 .spec.ipFamilyPolicy 設定為 SingleStack

apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    app.kubernetes.io/name: MyApp
spec:
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80

使用 kubectl 檢視 Service 的 YAML。

kubectl get svc my-service -o yaml

該 Service 的 .spec.ipFamilyPolicy 設定為 SingleStack.spec.clusterIP 設定為從 kube-controller-manager 上透過 --service-cluster-ip-range 標誌設定的第一個配置範圍中的 IPv4 地址。

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: default
spec:
  clusterIP: 10.0.217.164
  clusterIPs:
  - 10.0.217.164
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 80
    protocol: TCP
    targetPort: 9376
  selector:
    app.kubernetes.io/name: MyApp
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

建立以下 Service,其中明確定義 IPv6 作為 .spec.ipFamilies 陣列的第一個元素。Kubernetes 將從配置的 service-cluster-ip-range 中的 IPv6 範圍為 Service 分配一個叢集 IP,並將 .spec.ipFamilyPolicy 設定為 SingleStack

apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    app.kubernetes.io/name: MyApp
spec:
  ipFamilies:
  - IPv6
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80

使用 kubectl 檢視 Service 的 YAML。

kubectl get svc my-service -o yaml

該 Service 的 .spec.ipFamilyPolicy 設定為 SingleStack.spec.clusterIP 設定為從 kube-controller-manager 上透過 --service-cluster-ip-range 標誌設定的 IPv6 範圍中的 IPv6 地址。

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: MyApp
  name: my-service
spec:
  clusterIP: 2001:db8:fd00::5118
  clusterIPs:
  - 2001:db8:fd00::5118
  ipFamilies:
  - IPv6
  ipFamilyPolicy: SingleStack
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app.kubernetes.io/name: MyApp
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

建立以下 Service,其中在 .spec.ipFamilyPolicy 中明確定義 PreferDualStack。Kubernetes 將分配 IPv4 和 IPv6 地址(因為此叢集已啟用雙協議棧),並根據 .spec.ipFamilies 陣列中第一個元素的地址族從 .spec.ClusterIPs 列表中選擇 .spec.ClusterIP

apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    app.kubernetes.io/name: MyApp
spec:
  ipFamilyPolicy: PreferDualStack
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80

使用 kubectl describe 驗證 Service 是否從 IPv4 和 IPv6 地址塊獲取叢集 IP。然後,你可以透過 IP 和埠驗證對服務的訪問。

kubectl describe svc -l app.kubernetes.io/name=MyApp
Name:              my-service
Namespace:         default
Labels:            app.kubernetes.io/name=MyApp
Annotations:       <none>
Selector:          app.kubernetes.io/name=MyApp
Type:              ClusterIP
IP Family Policy:  PreferDualStack
IP Families:       IPv4,IPv6
IP:                10.0.216.242
IPs:               10.0.216.242,2001:db8:fd00::af55
Port:              <unset>  80/TCP
TargetPort:        9376/TCP
Endpoints:         <none>
Session Affinity:  None
Events:            <none>

建立雙協議棧負載均衡 Service

如果雲提供商支援配置啟用 IPv6 的外部負載均衡器,則建立以下 Service,其中在 .spec.ipFamilyPolicy 中設定 PreferDualStack,將 IPv6 作為 .spec.ipFamilies 陣列的第一個元素,並將 type 欄位設定為 LoadBalancer

apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    app.kubernetes.io/name: MyApp
spec:
  ipFamilyPolicy: PreferDualStack
  ipFamilies:
  - IPv6
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: MyApp
  ports:
    - protocol: TCP
      port: 80

檢查服務

kubectl get svc -l app.kubernetes.io/name=MyApp

驗證 Service 是否從 IPv6 地址塊收到 CLUSTER-IP 地址以及 EXTERNAL-IP。然後,你可以透過 IP 和埠驗證對服務的訪問。

NAME         TYPE           CLUSTER-IP            EXTERNAL-IP        PORT(S)        AGE
my-service   LoadBalancer   2001:db8:fd00::7ebc   2603:1030:805::5   80:30790/TCP   35s
上次修改於 2025 年 1 月 23 日太平洋標準時間上午 9:50:調整兩個網路任務:validate-dual-stack 和 extend-service-ip-ranges (00c294a18a)