驗證 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 fieldPath 驗證 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 的服務。Kubernetes 將從第一個設定的 service-cluster-ip-range 指派服務的叢集 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 以檢視服務的 YAML。

kubectl get svc my-service -o yaml

服務的 .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: {}

建立下列明確定義 IPv6 作為 .spec.ipFamilies 中第一個陣列元素的服務。Kubernetes 將從設定的 IPv6 範圍 service-cluster-ip-range 指派服務的叢集 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 以檢視服務的 YAML。

kubectl get svc my-service -o yaml

服務的 .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 和埠對 Service 的存取。

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.spec.ipFamilies 陣列的第一個元素為 IPv6,且 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

檢查 Service

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

驗證 Service 從 IPv6 位址區塊接收 CLUSTER-IP 位址以及 EXTERNAL-IP。然後,您可以驗證透過 IP 和埠對 Service 的存取。

NAME         TYPE           CLUSTER-IP            EXTERNAL-IP        PORT(S)        AGE
my-service   LoadBalancer   2001:db8:fd00::7ebc   2603:1030:805::5   80:30790/TCP   35s
上次修改時間:2023 年 8 月 24 日下午 6:38 PST:使用 code_sample 簡碼取代 code 簡碼 (e8b136c3b3)