跳至主要内容

儲存網路

Harvester 使用 Longhorn 為虛擬機器和 Pod 提供區塊裝置卷冊 (block device volumes)。如果您希望將 Longhorn 的複寫流量從 mgmt(內建的叢集網路)或其他全叢集工作負載中隔離出來,您可以使用專用的儲存網路來獲得更好的網路頻寬與效能。

如需更多資訊,請參閱 Longhorn 儲存網路。

備註
  • 請避免直接設定 Longhorn 設定,因為這可能會導致非預期或不想要的系統行為。

先決條件​

在開始設定儲存網路之前,請確保滿足以下要求:

  • 網路交換器已正確設定,並已指派專用的 VLAN ID 給儲存網路。

  • 叢集網路 (Cluster network) 和 VLAN 網路 已正確設定。請確保這兩個網路涵蓋所有節點且可存取。

  • 儲存網路的 IP 範圍需具備以下特性:

    • 使用 IPv4 CIDR 格式。

    • 不與 Kubernetes 叢集網路衝突或重疊。

      以下為保留位址:10.42.0.0/16、10.43.0.0/16、10.52.0.0/16 和 10.53.0.0/16。

    • 滿足叢集的需求。

      所需的 IP 位址數量使用以下公式計算:所需 IP 數量 = (節點數量 * 2) + (磁碟數量 * 2) + 欲下載或上傳的映像檔數量

      範例:如果一個叢集有五個節點,每個節點有兩個磁碟,並且要同時上傳十個映像檔,則 IP 範圍應大於或等於 /26(計算方式:(5 x 2) + (5 x 2) + 10 = 30)。

    • 排除 Longhorn Pod 和儲存網路不可使用的 IP 位址,例如保留給 RWX 卷冊、閘道器 (gateway) 和其他元件的位址。

  • Whereabouts CNI 已正確安裝。

    您可以使用指令 kubectl get crd ippools.whereabouts.cni.cncf.io 檢查叢集中是否存在 ippools.whereabouts.cni.cncf.io CRD。

    如果回傳空字串,請使用以下指令新增 此目錄 中的 CRD:

    kubectl apply -f https://raw.githubusercontent.com/harvester/harvester/v1.1.0/deploy/charts/harvester/dependency_charts/whereabouts/crds/whereabouts.cni.cncf.io_ippools.yaml

    kubectl apply -f https://raw.githubusercontent.com/harvester/harvester/v1.1.0/deploy/charts/harvester/dependency_charts/whereabouts/crds/whereabouts.cni.cncf.io_overlappingrangeipreservations.yaml
    備註

    在某些 升級情境 中,Whereabouts CNI 可能未被正確安裝。

  • 所有虛擬機器已停止。

    您可以使用指令 kubectl get -A vmi 檢查虛擬機器的狀態,該指令應回傳空字串。

    警告

    Harvester 會向透過 Harvester UI 停止的虛擬機器發送優雅關機 (graceful shutdown) 訊號。然而,工作負載會被中斷並保持不可用狀態,直到您確認儲存網路設定已成功套用並手動啟動虛擬機器為止。

  • 所有掛接 Longhorn 卷冊的 Pod 已停止。

  • 所有進行中的映像檔上傳和下載皆已完成或刪除。

Longhorn 複寫流量路由​

Longhorn 複寫流量的路由取決於虛擬機器 VLAN 流量與 Longhorn 儲存網路是否共用相同的實體介面,或使用不同的實體介面。

  • 相同的實體介面:在以下範例中,eth2 和 eth3 同時用於虛擬機器 VLAN 流量和 Longhorn 儲存網路。紅線表示 Longhorn 透過 eth3 發送複寫流量。

    storagenetwork-same.png

    備註

    您必須將 eth2 和 eth3 納入叢集網路和 VLAN 網路的設定中。

  • 不同的實體介面:在以下範例中,eth2 和 eth3 用於虛擬機器 VLAN 流量,而 eth4 和 eth5 用於 Longhorn 儲存網路。紅線表示 Longhorn 透過 eth4 發送複寫流量。

    storagenetwork-diff.png

    備註

    您必須將 eth4 和 eth5 納入叢集網路和 VLAN 網路的設定中。

storage-network 設定​

storage-network 設定允許您在需要隔離時,設定用於隔離叢集內儲存流量的網路。

您可以使用 UI 或 CLI 啟用 和 停用 儲存網路。啟用此設定時,您必須透過設定特定欄位來建構 Multus NetworkAttachmentDefinition CRD。

一旦套用 storage-network 設定,將發生以下情況:

  • Harvester 會停止所有與 Longhorn 卷冊、Prometheus、Grafana、Alertmanager 和 VM Import Controller 相關的 Pod。
  • Harvester 會建立一個新的 NetworkAttachmentDefinition 並更新 Longhorn 儲存網路設定。
  • Longhorn 會重新啟動所有 instance-manager 和 backing-image-manager Pod 以套用新的網路設定。

設定步驟​

提示

強烈建議使用 Harvester UI 來配置 storage-network 設定。

啟用儲存網路​

  1. 前往 Advanced > Settings > storage-network。

storage-network-enabled.png

  1. 選擇 Enabled。

  2. 設定 VLAN ID、Cluster Network、IP Range 和 Exclude 欄位以建構 Multus NetworkAttachmentDefinition CRD。

  3. 點擊 Save。

停用儲存網路​

  1. 前往 Advanced > Settings > storage-network。

storage-network-disabled.png

  1. 選擇 Disabled。

  2. 點擊 Save。

一旦儲存網路被停用,Longhorn 將開始使用 Pod 網路進行與儲存相關的操作。

變更儲存網路的 MTU​

請參閱 變更已掛接儲存網路之網路設定的 MTU。

設定後步驟 (Post-Configuration Steps)​

important

Harvester 不會自動啟動虛擬機器。您必須確保設定正確並成功套用,然後在必要時手動啟動虛擬機器。

  1. 使用以下指令驗證 storage-network 設定的狀態是否為 True 且類型為 configured:

    kubectl get settings.harvesterhci.io storage-network -o yaml

    範例:

    apiVersion: harvesterhci.io/v1beta1
    kind: Setting
    metadata:
    annotations:
    storage-network.settings.harvesterhci.io/hash: da39a3ee5e6b4b0d3255bfef95601890afd80709
    storage-network.settings.harvesterhci.io/net-attach-def: ""
    storage-network.settings.harvesterhci.io/old-net-attach-def: ""
    creationTimestamp: "2022-10-13T06:36:39Z"
    generation: 51
    name: storage-network
    resourceVersion: "154638"
    uid: 2233ad63-ee52-45f6-a79c-147e48fc88db
    status:
    conditions:
    - lastUpdateTime: "2022-10-13T13:05:17Z"
    reason: Completed
    status: "True"
    type: configured
  2. 驗證 Longhorn Pod(instance-manager 和 backing-image-manager)是否已就緒,且其網路已正確設定。

    您可以使用以下指令檢查每個 Pod:

    kubectl -n longhorn-system describe pod <pod-name>

    類似以下的錯誤表示儲存網路已耗盡其可用的 IP 位址。您必須使用足夠的 IP 範圍重新配置儲存網路。

    Events:
    Type Reason Age From Message
    ---- ------ ---- ---- -------
    ....

    Warning FailedCreatePodSandBox 2m58s kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for
    sandbox "04e9bc160c4f1da612e2bb52dadc86702817ac557e641a3b07b7c4a340c9fc48": plugin type="multus" name="multus-cni-network" failed (add): [longhorn-system/backing-image-ds-default-image-lxq7r/7d6995ee-60a6-4f67-b9ea-246a73a4df54:storagenetwork-sdfg8]: error adding container to network "storagenetwork-sdfg8": error at storage engine: Could not allocate IP in range: ip: 172.16.0.1 / - 172.16.0.6 / range: net.IPNet{IP:net.IP{0xac, 0x10, 0x0, 0x0}, Mask:net.IPMask{0xff,0xff, 0xff, 0xf8}}
    ....
    備註

    如果儲存網路已耗盡其可用的 IP 位址,您在上傳或下載映像檔時可能會遇到類似的錯誤。您必須刪除受影響的映像檔,並使用足夠的 IP 範圍重新配置儲存網路。

  3. 驗證 k8s.v1.cni.cncf.io/network-status 註解中是否存在名為 lhnet1 的介面。此介面的 IP 位址必須位於指定的 IP 範圍內。

    您可以使用以下指令取得 Longhorn instance-manager Pod 的清單:

    kubectl get pods -n longhorn-system -l longhorn.io/component=instance-manager -o yaml

    範例:

    apiVersion: v1
    kind: Pod
    metadata:
    annotations:
    cni.projectcalico.org/containerID: 2518b0696f6635896645b5546417447843e14208525d3c19d7ec6d7296cc13cd
    cni.projectcalico.org/podIP: 10.52.2.122/32
    cni.projectcalico.org/podIPs: 10.52.2.122/32
    k8s.v1.cni.cncf.io/network-status: |-
    [{
    "name": "k8s-pod-network",
    "ips": [
    "10.52.2.122"
    ],
    "default": true,
    "dns": {}
    },{
    "name": "harvester-system/storagenetwork-95bj4",
    "interface": "lhnet1",
    "ips": [
    "192.168.0.3"
    ],
    "mac": "2e:51:e6:31:96:40",
    "dns": {}
    }]
    k8s.v1.cni.cncf.io/networks: '[{"namespace": "harvester-system", "name": "storagenetwork-95bj4",
    "interface": "lhnet1"}]'
    kubernetes.io/psp: global-unrestricted-psp
    longhorn.io/last-applied-tolerations: '[{"key":"kubevirt.io/drain","operator":"Exists","effect":"NoSchedule"}]'

    Omitted...
  4. 測試 Longhorn Pod 之間的通訊。

    儲存網路專用於 Longhorn Pod 之間的內部通訊,以實現高效能和可靠性。然而,儲存網路仍依賴 外部網路基礎設施 進行連線(類似於 虛擬機器 VLAN 網路 的運作方式)。當外部網路未連線或未正確設定時,您可能會遇到以下問題:

    • 新建立的虛擬機器卡在 Not-Ready 狀態。

    • longhorn-manager Pod 日誌包含錯誤訊息。

      範例:

      longhorn-manager-j6dhh/longhorn-manager.log:2024-03-20T16:25:24.662251001Z time="2024-03-20T16:25:24Z" level=error msg="Failed rebuilding of replica 10.0.16.26:10000" controller=longhorn-engine engine=pvc-0a151c59-ffa9-4938-9c86-59ebb296bc88-e-c2a7fe77 error="proxyServer=10.52.6.33:8501 destination=10.0.16.23:10000: failed to add replica tcp://10.0.16.26:10000 for volume: rpc error: code = Unknown desc = failed to get replica 10.0.16.26:10000: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = \"transport: Error while dialing dial tcp 10.0.16.26:10000: connect: no route to host\"" node=oml-harvester-9 volume=pvc-0a151c59-ffa9-4938-9c86-59ebb296bc88

    若要測試 Longhorn Pod 之間的通訊,請執行以下步驟:

    1. 取得在上一步驟中識別出的每個 Longhorn Instance Manager Pod(每個節點一個)的儲存網路 IP。

    範例:

    instance-manager-43f1624d14076e1d95cd72371f0316e2
    storage network IP: 10.0.16.8

    instance-manager-ba38771e483008ce61249acf9948322f
    storage network IP: 10.0.16.14
    1. 登入這些 Pod。

    當您執行指令 ip addr 時,輸出應包含與 Pod 註解中相同的 IP。在以下範例中,一個 IP 用於 Pod 網路,另一個用於儲存網路。

    範例:

    $ kubectl exec -i -t -n longhorn-system instance-manager-ba38771e483008ce61249acf9948322f -- /bin/sh

    $ ip addr
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    ...
    3: eth0@if2277: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default // pod network link
    link/ether 0e:7c:d6:77:44:72 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.52.6.146/32 scope global eth0
    ...
    4: lhnet1@if2278: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default // storage network link, note the MTU value
    link/ether fe:92:4f:fb:dd:20 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.0.16.14/20 brd 10.0.31.255 scope global lhnet1
    ...

    $ ip route
    default via 169.254.1.1 dev eth0
    10.0.16.0/20 dev lhnet1 proto kernel scope link src 10.0.16.14
    169.254.1.1 dev eth0 scope link
    備註

    儲存網路連結始終會繼承已掛接 叢集網路 的 MTU 值,無論 設定的 MTU 值 為何。

    1. 在一個 Pod 中啟動簡單的 HTTP 伺服器。

    您必須明確將此 HTTP 伺服器綁定到儲存網路 IP。

    範例:

    $ python3 -m http.server 8000 --bind 10.0.16.14 (替換為您的 Pod 儲存網路 IP)
    1. 在另一個 Pod 中測試 HTTP 伺服器。

    範例:

    From instance-manager-43f1624d14076e1d95cd72371f0316e2 (IP 10.0.16.8)

    $ curl http://10.0.16.14:8000

    當儲存網路運作正常時,curl 指令會回傳 HTTP 伺服器上的檔案清單。

    1. (選用) 疑難排解問題。

    儲存網路可能會因為外部網路問題而發生故障,例如:

    • 與儲存網路相關聯的實體 NIC(安裝在 Harvester 節點上)未新增至外部交換器中的相同 VLAN。
    • 外部交換器未正確連線和設定。

一旦確認設定無誤,您可以在必要時手動啟動虛擬機器。

最佳實務​

  • 在為儲存網路設定 IP 範圍 時,請確保分配的 IP 位址能夠滿足叢集的未來需求。這一點很重要,因為當儲存網路設定完成後,若新增節點至叢集或新增更多磁碟至節點,且所需 IP 數量超過已分配的 IP 時,Longhorn Pod(instance-manager 和 backing-image-manager)將停止運作。解決此問題需要使用正確的 IP 範圍重新配置儲存網路。

    Longhorn Pod 使用儲存網路的方式如下:

    • instance-manager Pod:Longhorn Instance Manager 元件已在 Longhorn v1.5.0 中合併。每個節點需要一個 IP 位址。在升級期間,這些 Pod 的舊版本和新版本會同時存在,舊版本會在升級完成後刪除。

    • backing-image-ds Pod:這些 Pod 處理 backing image 資料來源的即時上傳和下載,並在映像檔上傳和下載完成後移除。

    • backing-image-manager Pod:每個磁碟需要一個 IP 位址。在升級期間,這些 Pod 的舊版本和新版本會同時存在,舊版本會在升級完成後刪除。

  • 將儲存網路設定在非 mgmt 的叢集網路上,以確保 Longhorn 複寫流量與 Kubernetes 控制平面流量完全隔離。使用 mgmt 是可能的,但不建議,因為會對控制平面網路效能產生負面影響(資源和頻寬爭用)。僅在您的叢集有 NIC 相關限制且無法完全隔離流量時才使用 mgmt。