Kubernetes 的 etcd 叢集操作

etcd 是一個一致且高可用的鍵值儲存,用作 Kubernetes 所有叢集資料的後端儲存。

如果你的 Kubernetes 叢集使用 etcd 作為其後端儲存,請確保你有一個數據備份計劃。

你可以在 etcd 官方文件中找到關於 etcd 的深入資訊。

準備工作

在按照本頁的步驟部署、管理、備份或恢復 etcd 之前,你需要了解操作 etcd 叢集的典型預期。更多上下文請參考 etcd 文件

關鍵細節包括:

  • 生產環境中推薦的 etcd 最低版本是 `3.4.22+` 和 `3.5.6+`。

  • etcd 是一個基於領導者的分散式系統。確保領導者及時向所有追隨者定期傳送心跳以保持叢集穩定。

  • 你應該以奇數個成員執行 etcd 叢集。

  • 儘量確保沒有資源匱乏發生。

    叢集的效能和穩定性對網路和磁碟 I/O 敏感。任何資源匱乏都可能導致心跳超時,從而導致叢集不穩定。不穩定的 etcd 表示沒有選出領導者。在這種情況下,叢集無法對其當前狀態進行任何更改,這意味著無法排程新的 Pod。

etcd 的資源要求

在資源有限的情況下操作 etcd 僅適用於測試目的。對於生產部署,需要高階硬體配置。在生產環境中部署 etcd 之前,請參閱 資源要求參考

保持 etcd 叢集穩定對於 Kubernetes 叢集的穩定性至關重要。因此,請在專用機器或隔離環境中執行 etcd 叢集,以保證資源要求

工具

根據你正在處理的具體結果,你將需要 `etcdctl` 工具或 `etcdutl` 工具(你可能需要兩者)。

理解 etcdctl 和 etcdutl

`etcdctl` 和 `etcdutl` 是用於與 etcd 叢集互動的命令列工具,但它們有不同的用途:

  • `etcdctl`:這是用於透過網路與 etcd 互動的主要命令列客戶端。它用於日常操作,例如管理鍵值、管理叢集、檢查健康狀況等。

  • `etcdutl`:這是一個管理實用程式,旨在直接操作 etcd 資料檔案,包括在 etcd 版本之間遷移資料、碎片整理資料庫、恢復快照以及驗證資料一致性。對於網路操作,應使用 `etcdctl`。

有關 `etcdutl` 的更多資訊,你可以參考 etcd 恢復文件

啟動 etcd 叢集

本節介紹啟動單節點和多節點 etcd 叢集。

本指南假設已經安裝了 `etcd`。

單節點 etcd 叢集

僅將單節點 etcd 叢集用於測試目的。

  1. 執行以下命令:

    etcd --listen-client-urls=http://$PRIVATE_IP:2379 \
       --advertise-client-urls=http://$PRIVATE_IP:2379
    
  2. 使用標誌 `--etcd-servers=$PRIVATE_IP:2379` 啟動 Kubernetes API 伺服器。

    確保 `PRIVATE_IP` 設定為你的 etcd 客戶端 IP。

多節點 etcd 叢集

為了耐用性和高可用性,生產環境中應將 etcd 作為多節點叢集執行並定期備份。生產環境中建議使用五成員叢集。有關更多資訊,請參閱 FAQ 文件

由於你使用的是 Kubernetes,你可以選擇將 etcd 作為容器在一個或多個 Pod 中執行。`kubeadm` 工具預設設定 etcd 靜態 Pod,或者你可以部署一個單獨的叢集並指示 kubeadm 使用該 etcd 叢集作為控制平面的後端儲存。

你可以透過靜態成員資訊或動態發現來配置 etcd 叢集。有關叢集的更多資訊,請參閱 etcd 叢集文件

舉例來說,考慮一個具有以下客戶端 URL 的五成員 etcd 叢集:`http://$IP1:2379`、`http://$IP2:2379`、`http://$IP3:2379`、`http://$IP4:2379` 和 `http://$IP5:2379`。要啟動 Kubernetes API 伺服器:

  1. 執行以下命令:

    etcd --listen-client-urls=http://$IP1:2379,http://$IP2:2379,http://$IP3:2379,http://$IP4:2379,http://$IP5:2379 --advertise-client-urls=http://$IP1:2379,http://$IP2:2379,http://$IP3:2379,http://$IP4:2379,http://$IP5:2379
    
  2. 使用標誌 `--etcd-servers=$IP1:2379,$IP2:2379,$IP3:2379,$IP4:2379,$IP5:2379` 啟動 Kubernetes API 伺服器。

    確保 `IP` 變數設定為你的客戶端 IP 地址。

帶負載均衡器的多節點 etcd 叢集

要執行負載均衡的 etcd 叢集:

  1. 設定 etcd 叢集。
  2. 在 etcd 叢集前配置負載均衡器。例如,讓負載均衡器的地址為 `$LB`。
  3. 使用標誌 `--etcd-servers=$LB:2379` 啟動 Kubernetes API 伺服器。

保護 etcd 叢集

訪問 etcd 等同於叢集中的 root 許可權,因此理想情況下只有 API 伺服器才能訪問它。考慮到資料的敏感性,建議僅向需要訪問 etcd 叢集的節點授予許可權。

要保護 etcd,可以設定防火牆規則或使用 etcd 提供的安全功能。etcd 安全功能依賴於 x509 公鑰基礎設施 (PKI)。首先,透過生成金鑰和證書對來建立安全的通訊通道。例如,使用金鑰對 `peer.key` 和 `peer.cert` 來保護 etcd 成員之間的通訊,使用 `client.key` 和 `client.cert` 來保護 etcd 及其客戶端之間的通訊。請參閱 etcd 專案提供的示例指令碼以生成客戶端認證的金鑰對和 CA 檔案。

保護通訊

要配置 etcd 以進行安全的對等通訊,請指定標誌 `--peer-key-file=peer.key` 和 `--peer-cert-file=peer.cert`,並使用 HTTPS 作為 URL 模式。

同樣,要配置 etcd 以進行安全的客戶端通訊,請指定標誌 `--key=k8sclient.key` 和 `--cert=k8sclient.cert`,並使用 HTTPS 作為 URL 模式。以下是使用安全通訊的客戶端命令示例:

ETCDCTL_API=3 etcdctl --endpoints 10.2.0.9:2379 \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  member list

限制 etcd 叢集的訪問

配置安全通訊後,使用 TLS 認證將 etcd 叢集的訪問許可權限制為僅 Kubernetes API 伺服器。

例如,考慮由 CA `etcd.ca` 信任的金鑰對 `k8sclient.key` 和 `k8sclient.cert`。當 etcd 使用 `--client-cert-auth` 和 TLS 配置時,它透過系統 CA 或由 `--trusted-ca-file` 標誌傳遞的 CA 來驗證客戶端的證書。指定標誌 `--client-cert-auth=true` 和 `--trusted-ca-file=etcd.ca` 將限制對具有證書 `k8sclient.cert` 的客戶端的訪問。

一旦 etcd 配置正確,只有具有有效證書的客戶端才能訪問它。要授予 Kubernetes API 伺服器訪問許可權,請使用標誌 `--etcd-certfile=k8sclient.cert`、`--etcd-keyfile=k8sclient.key` 和 `--etcd-cafile=ca.cert` 配置它們。

替換失敗的 etcd 成員

etcd 叢集透過容忍少量成員故障來實現高可用性。但是,為了提高叢集的整體健康狀況,請立即替換失敗的成員。當多個成員失敗時,請逐個替換它們。替換失敗的成員涉及兩個步驟:移除失敗的成員和新增新成員。

儘管 etcd 內部保留了唯一的成員 ID,但建議為每個成員使用唯一的名稱以避免人為錯誤。例如,考慮一個三成員 etcd 叢集。讓 URL 分別為 `member1=http://10.0.0.1`、`member2=http://10.0.0.2` 和 `member3=http://10.0.0.3`。當 `member1` 失敗時,用 `member4=http://10.0.0.4` 替換它。

  1. 獲取失敗的 `member1` 的成員 ID

    etcdctl --endpoints=http://10.0.0.2,http://10.0.0.3 member list
    

    顯示以下訊息:

    8211f1d0f64f3269, started, member1, http://10.0.0.1:2380, http://10.0.0.1:2379
    91bc3c398fb3c146, started, member2, http://10.0.0.2:2380, http://10.0.0.2:2379
    fd422379fda50e48, started, member3, http://10.0.0.3:2380, http://10.0.0.3:2379
    
  2. 執行以下任一操作:

    1. 如果每個 Kubernetes API 伺服器都配置為與所有 etcd 成員通訊,請從 `--etcd-servers` 標誌中移除失敗的成員,然後重新啟動每個 Kubernetes API 伺服器。
    2. 如果每個 Kubernetes API 伺服器與單個 etcd 成員通訊,則停止與失敗的 etcd 通訊的 Kubernetes API 伺服器。
  3. 在損壞的節點上停止 etcd 伺服器。除了 Kubernetes API 伺服器之外,其他客戶端也可能導致 etcd 流量,最好停止所有流量以防止寫入資料目錄。

  4. 移除失敗的成員

    etcdctl member remove 8211f1d0f64f3269
    

    顯示以下訊息:

    Removed member 8211f1d0f64f3269 from cluster
    
  5. 新增新成員

    etcdctl member add member4 --peer-urls=http://10.0.0.4:2380
    

    顯示以下訊息:

    Member 2be1eb8f84b7f63e added to cluster ef37ad9dc622a7c4
    
  6. 在 IP 為 `10.0.0.4` 的機器上啟動新新增的成員

    export ETCD_NAME="member4"
    export ETCD_INITIAL_CLUSTER="member2=http://10.0.0.2:2380,member3=http://10.0.0.3:2380,member4=http://10.0.0.4:2380"
    export ETCD_INITIAL_CLUSTER_STATE=existing
    etcd [flags]
    
  7. 執行以下任一操作:

    1. 如果每個 Kubernetes API 伺服器都配置為與所有 etcd 成員通訊,請將新新增的成員新增到 `--etcd-servers` 標誌中,然後重新啟動每個 Kubernetes API 伺服器。
    2. 如果每個 Kubernetes API 伺服器與單個 etcd 成員通訊,請啟動在步驟 2 中停止的 Kubernetes API 伺服器。然後配置 Kubernetes API 伺服器客戶端再次將請求路由到停止的 Kubernetes API 伺服器。這通常可以透過配置負載均衡器來完成。

有關叢集重新配置的更多資訊,請參閱 etcd 重新配置文件

備份 etcd 叢集

所有 Kubernetes 物件都儲存在 etcd 中。定期備份 etcd 叢集資料對於在災難場景下(例如丟失所有控制平面節點)恢復 Kubernetes 叢集非常重要。快照檔案包含所有 Kubernetes 狀態和關鍵資訊。為了保證敏感的 Kubernetes 資料安全,請加密快照檔案。

備份 etcd 叢集可以透過兩種方式完成:etcd 內建快照和卷快照。

內建快照

etcd 支援內建快照。快照可以透過 `etcdctl snapshot save` 命令從活動成員建立,也可以透過從 etcd 資料目錄(當前未被 etcd 程序使用)複製 `member/snap/db` 檔案來建立。建立快照不會影響成員的效能。

以下是建立由 `$ENDPOINT` 提供的鍵空間快照到檔案 `snapshot.db` 的示例:

ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshot.db

驗證快照

以下示例展示了使用 `etcdutl` 工具驗證快照:

etcdutl --write-out=table snapshot status snapshot.db 

這應該生成與下面提供的示例相似的輸出:

+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| fe01cf57 |       10 |          7 | 2.1 MB     |
+----------+----------+------------+------------+

以下示例展示了使用 `etcdctl` 工具驗證快照:

export ETCDCTL_API=3
etcdctl --write-out=table snapshot status snapshot.db

這應該生成與下面提供的示例相似的輸出:

Deprecated: Use `etcdutl snapshot status` instead.

+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| fe01cf57 |       10 |          7 | 2.1 MB     |
+----------+----------+------------+------------+

卷快照

如果 etcd 執行在支援備份的儲存捲上,例如 Amazon Elastic Block Store,可以透過建立儲存卷的快照來備份 etcd 資料。

使用 etcdctl 選項進行快照

我們還可以使用 etcdctl 提供的各種選項來建立快照。例如:

ETCDCTL_API=3 etcdctl -h 

將列出 etcdctl 可用的各種選項。例如,你可以透過指定端點、證書和金鑰來建立快照,如下所示:

ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=<trusted-ca-file> --cert=<cert-file> --key=<key-file> \
  snapshot save <backup-file-location>

其中 `trusted-ca-file`、`cert-file` 和 `key-file` 可以從 etcd Pod 的描述中獲取。

擴充套件 etcd 叢集

擴充套件 etcd 叢集會以犧牲效能為代價來提高可用性。擴充套件並不會提高叢集效能或能力。一般規則是不要對 etcd 叢集進行擴充套件或縮減。不要為 etcd 叢集配置任何自動擴縮組。強烈建議在任何官方支援的規模下,為生產 Kubernetes 叢集始終執行一個靜態的五成員 etcd 叢集。

當需要更高的可靠性時,合理的擴充套件是將三成員叢集升級到五成員叢集。有關如何將成員新增到現有叢集的資訊,請參閱 etcd 重新配置文件

恢復 etcd 叢集

etcd 支援從 主要.次要 版本 etcd 程序拍攝的快照進行恢復。也支援從不同補丁版本的 etcd 恢復。恢復操作用於恢復失敗叢集的資料。

在開始恢復操作之前,必須存在快照檔案。它既可以是先前備份操作的快照檔案,也可以是剩餘的 資料目錄

使用 `etcdutl` 恢復叢集時,使用 `--data-dir` 選項指定叢集應恢復到的資料夾:

etcdutl --data-dir <data-dir-location> snapshot restore snapshot.db

其中 `<data-dir-location>` 是在恢復過程中將建立的目錄。

以下示例展示了使用 `etcdctl` 工具進行恢復操作:

export ETCDCTL_API=3
etcdctl --data-dir <data-dir-location> snapshot restore snapshot.db

如果 `<data-dir-location>` 與之前的資料夾相同,請在恢復叢集之前刪除它並停止 etcd 程序。否則,在恢復後更改 etcd 配置並重新啟動 etcd 程序,使其使用新的資料目錄:首先將 `/etc/kubernetes/manifests/etcd.yaml` 中 `name: etcd-data` 的 `volumes.hostPath.path` 更改為 `<data-dir-location>`,然後執行 `kubectl -n kube-system delete pod <name-of-etcd-pod>` 或 `systemctl restart kubelet.service`(或兩者)。

有關從快照檔案恢復叢集的更多資訊和示例,請參閱 etcd 災難恢復文件

如果恢復後的叢集的訪問 URL 與之前的叢集不同,則必須相應地重新配置 Kubernetes API 伺服器。在這種情況下,請使用標誌 `--etcd-servers=$NEW_ETCD_CLUSTER` 替換標誌 `--etcd-servers=$OLD_ETCD_CLUSTER` 重新啟動 Kubernetes API 伺服器。將 `$NEW_ETCD_CLUSTER` 和 `$OLD_ETCD_CLUSTER` 替換為相應的 IP 地址。如果在 etcd 叢集前面使用了負載均衡器,你可能需要更新負載均衡器。

如果大多數 etcd 成員永久失敗,etcd 叢集將被視為失敗。在這種情況下,Kubernetes 無法對其當前狀態進行任何更改。儘管已排程的 Pod 可能會繼續執行,但無法排程新的 Pod。在這種情況下,恢復 etcd 叢集並可能重新配置 Kubernetes API 伺服器以解決問題。

升級 etcd 叢集

有關 etcd 升級的詳細資訊,請參閱 etcd 升級 文件。

維護 etcd 叢集

有關 etcd 維護的更多詳細資訊,請參閱 etcd 維護 文件。

叢集碎片整理

碎片整理是一項昂貴的操作,因此應儘可能少地執行。另一方面,也需要確保任何 etcd 成員都不會超過儲存配額。Kubernetes 專案建議在執行碎片整理時,使用 etcd-defrag 等工具。

你還可以將碎片整理工具作為 Kubernetes CronJob 執行,以確保定期進行碎片整理。有關詳細資訊,請參閱 `etcd-defrag-cronjob.yaml`

本頁面上的專案引用了提供 Kubernetes 所需功能的第三方產品或專案。Kubernetes 專案作者不對這些第三方產品或專案負責。有關更多詳細資訊,請參閱 CNCF 網站指南

在提議新增額外第三方連結的更改之前,你應該閱讀內容指南

最後修改於 2025 年 1 月 23 日下午 4:39 PST:docs: etcdctl 標誌 (87ceff5dd5)