使用 kubeadm 進行證書管理

特性狀態: Kubernetes v1.15 [穩定]

kubeadm 生成的客戶端證書有效期為 1 年。本頁面介紹瞭如何使用 kubeadm 管理證書續訂。它還涵蓋了與 kubeadm 證書管理相關的其他任務。

Kubernetes 專案建議及時升級到最新的補丁版本,並確保你正在執行受支援的 Kubernetes 次要版本。遵循此建議有助於你保持安全。

準備工作

你應該熟悉 Kubernetes 中的 PKI 證書和要求

你應該熟悉如何將配置檔案傳遞給 kubeadm 命令。

本指南涵蓋了 openssl 命令的使用(如果你選擇這種方法,用於手動證書籤名),但你可以使用你喜歡的工具。

此處的某些步驟使用 sudo 進行管理員訪問。你可以使用任何等效工具。

使用自定義證書

預設情況下,kubeadm 會生成叢集執行所需的所有證書。你可以透過提供自己的證書來覆蓋此行為。

為此,你必須將它們放置在 --cert-dir 標誌或 kubeadm 的 ClusterConfigurationcertificatesDir 欄位指定的任何目錄中。預設情況下,這是 /etc/kubernetes/pki

如果在執行 kubeadm init 之前存在給定的證書和私鑰對,kubeadm 不會覆蓋它們。這意味著你可以,例如,將現有 CA 複製到 /etc/kubernetes/pki/ca.crt/etc/kubernetes/pki/ca.key 中,kubeadm 將使用此 CA 簽署其餘證書。

選擇加密演算法

kubeadm 允許你選擇用於建立公鑰和私鑰的加密演算法。這可以透過使用 kubeadm 配置的 encryptionAlgorithm 欄位來完成。

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
encryptionAlgorithm: <ALGORITHM>

<ALGORITHM> 可以是 RSA-2048(預設)、RSA-3072RSA-4096ECDSA-P256 之一。

選擇證書有效期

kubeadm 允許你選擇 CA 和葉子證書的有效期。這可以透過使用 kubeadm 配置的 certificateValidityPeriodcaCertificateValidityPeriod 欄位來完成。

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
certificateValidityPeriod: 8760h # Default: 365 days × 24 hours = 1 year
caCertificateValidityPeriod: 87600h # Default: 365 days × 24 hours * 10 = 10 years

欄位值遵循 Go 的 time.Duration接受的格式,支援的最長單位是 h(小時)。

外部 CA 模式

也可以只提供 ca.crt 檔案而不提供 ca.key 檔案(這僅適用於根 CA 檔案,不適用於其他證書對)。如果所有其他證書和 kubeconfig 檔案都已就位,kubeadm 會識別此情況並激活“外部 CA”模式。kubeadm 將在磁碟上沒有 CA 金鑰的情況下繼續執行。

相反,使用 --controllers=csrsigner 獨立執行 controller-manager 並指向 CA 證書和金鑰。

在使用外部 CA 模式時,有多種方法可以準備元件憑據。

手動準備元件憑據

PKI 證書和要求包含有關如何手動準備 kubeadm 所需的所有元件憑據的資訊。

本指南涵蓋了 openssl 命令的使用(如果你選擇這種方法,用於手動證書籤名),但你可以使用你喜歡的工具。

透過簽署 kubeadm 生成的 CSR 來準備憑據

kubeadm 可以生成 CSR 檔案,你可以使用 openssl 和你的外部 CA 等工具手動簽署這些檔案。這些 CSR 檔案將包含 kubeadm 部署的元件所需的所有憑據規範。

透過使用 kubeadm phases 自動準備元件憑據

或者,可以使用 kubeadm phase 命令來自動化此過程。

  • 轉到要準備為帶有外部 CA 的 kubeadm 控制平面節點的宿主機。
  • 將外部 CA 檔案 ca.crtca.key 複製到節點的 /etc/kubernetes/pki 中。
  • 準備一個臨時的 kubeadm 配置檔案,命名為 config.yaml,可與 kubeadm init 一起使用。確保此檔案包含證書中可能包含的任何相關的叢集範圍或宿主機特定資訊,例如 ClusterConfiguration.controlPlaneEndpointClusterConfiguration.certSANsInitConfiguration.APIEndpoint
  • 在同一臺宿主機上執行命令 kubeadm init phase kubeconfig all --config config.yamlkubeadm init phase certs all --config config.yaml。這將在 /etc/kubernetes/ 及其 pki 子目錄下生成所有必需的 kubeconfig 檔案和證書。
  • 檢查生成的檔案。刪除 /etc/kubernetes/pki/ca.key,刪除或移動到安全位置的檔案 /etc/kubernetes/super-admin.conf
  • 在將呼叫 kubeadm join 的節點上,也要刪除 /etc/kubernetes/kubelet.conf。此檔案僅在將呼叫 kubeadm init 的第一個節點上需要。
  • 請注意,某些檔案,如 pki/sa.*pki/front-proxy-ca.*pki/etc/ca.* 在控制平面節點之間共享。你可以生成它們一次,然後手動分發到將呼叫 kubeadm join 的節點,或者你可以使用 kubeadm init--upload-certs 功能和 kubeadm join--certificate-key 來自動化此分發。

在所有節點上準備好憑據後,呼叫 kubeadm initkubeadm join,使這些節點加入叢集。kubeadm 將使用 /etc/kubernetes/ 及其 pki 子目錄中現有的 kubeconfig 和證書檔案。

證書過期和管理

你可以使用 check-expiration 子命令檢查證書何時過期

kubeadm certs check-expiration

輸出類似於:

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 Dec 30, 2020 23:36 UTC   364d                                    no
apiserver                  Dec 30, 2020 23:36 UTC   364d            ca                      no
apiserver-etcd-client      Dec 30, 2020 23:36 UTC   364d            etcd-ca                 no
apiserver-kubelet-client   Dec 30, 2020 23:36 UTC   364d            ca                      no
controller-manager.conf    Dec 30, 2020 23:36 UTC   364d                                    no
etcd-healthcheck-client    Dec 30, 2020 23:36 UTC   364d            etcd-ca                 no
etcd-peer                  Dec 30, 2020 23:36 UTC   364d            etcd-ca                 no
etcd-server                Dec 30, 2020 23:36 UTC   364d            etcd-ca                 no
front-proxy-client         Dec 30, 2020 23:36 UTC   364d            front-proxy-ca          no
scheduler.conf             Dec 30, 2020 23:36 UTC   364d                                    no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Dec 28, 2029 23:36 UTC   9y              no
etcd-ca                 Dec 28, 2029 23:36 UTC   9y              no
front-proxy-ca          Dec 28, 2029 23:36 UTC   9y              no

該命令顯示 /etc/kubernetes/pki 資料夾中客戶端證書以及 kubeadm 使用的 kubeconfig 檔案(admin.confcontroller-manager.confscheduler.conf)中嵌入的客戶端證書的到期/剩餘時間。

此外,kubeadm 會告知使用者證書是否由外部管理;在這種情況下,使用者應手動/使用其他工具管理證書續訂。

kubelet.conf 配置檔案未包含在上述列表中,因為 kubeadm 配置 kubelet 以便透過 /var/lib/kubelet/pki 下的可旋轉證書進行自動證書續訂。要修復過期的 kubelet 客戶端證書,請參閱Kubelet 客戶端證書旋轉失敗

自動證書續訂

kubeadm 會在控制平面升級期間續訂所有證書。

此功能旨在解決最簡單的用例;如果你對證書續訂沒有特定要求,並且定期執行 Kubernetes 版本升級(每次升級之間間隔不到 1 年),kubeadm 將負責保持你的叢集最新且相對安全。

如果你對證書續訂有更復雜的要求,你可以透過向 kubeadm upgrade applykubeadm upgrade node 傳遞 --certificate-renewal=false 來選擇退出預設行為。

手動證書續訂

你可以隨時使用 kubeadm certs renew 命令和適當的命令列選項手動續訂證書。如果你執行的是具有複製控制平面的叢集,則此命令需要在所有控制平面節點上執行。

此命令使用儲存在 /etc/kubernetes/pki 中的 CA(或 front-proxy-CA)證書和金鑰執行續訂。

kubeadm certs renew 使用現有證書作為屬性(通用名稱、組織、主題備用名稱)的權威來源,並且不依賴於 kubeadm-config ConfigMap。即便如此,Kubernetes 專案仍建議保持提供的證書和該 ConfigMap 中的相關值同步,以避免任何混淆風險。

執行命令後,你應該重新啟動控制平面 Pod。這是必需的,因為目前並非所有元件和證書都支援動態證書重新載入。靜態 Pod 由本地 kubelet 管理,而不是由 API 伺服器管理,因此不能使用 kubectl 刪除和重新啟動它們。要重新啟動靜態 Pod,你可以暫時將其清單檔案從 /etc/kubernetes/manifests/ 中刪除,並等待 20 秒(參見 KubeletConfiguration 結構中的 fileCheckFrequency 值。如果 Pod 不再位於清單目錄中,kubelet 將終止該 Pod。然後你可以將檔案移回,在另一個 fileCheckFrequency 週期後,kubelet 將重新建立 Pod,並且該元件的證書續訂可以完成。

kubeadm certs renew 可以續訂任何特定證書,或者使用子命令 all,它可以續訂所有證書。

# If you are running cluster with a replicated control plane, this command
# needs to be executed on all the control-plane nodes.
kubeadm certs renew all

複製管理員證書(可選)

使用 kubeadm 構建的叢集通常會將 admin.conf 證書複製到 $HOME/.kube/config 中,如使用 kubeadm 建立叢集中所述。在此類系統上,為了在續訂 admin.conf 後更新 $HOME/.kube/config 的內容,你可以執行以下命令:

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

使用 Kubernetes 證書 API 續訂證書

本節提供了有關如何使用 Kubernetes 證書 API 執行手動證書續訂的更多詳細資訊。

設定簽名器

Kubernetes 證書頒發機構無法立即工作。你可以配置外部簽名者,例如 cert-manager,或者你可以使用內建簽名者。

內建簽名者是 kube-controller-manager 的一部分。

要啟用內建簽名者,你必須傳遞 --cluster-signing-cert-file--cluster-signing-key-file 標誌。

如果你正在建立新叢集,可以使用 kubeadm 配置檔案

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
controllerManager:
  extraArgs:
  - name: "cluster-signing-cert-file"
    value: "/etc/kubernetes/pki/ca.crt"
  - name: "cluster-signing-key-file"
    value: "/etc/kubernetes/pki/ca.key"

建立證書籤名請求 (CSR)

有關使用 Kubernetes API 建立 CSR 的資訊,請參閱建立 CertificateSigningRequest

使用外部 CA 續訂證書

本節提供了有關如何使用外部 CA 執行手動證書續訂的更多詳細資訊。

為了更好地與外部 CA 整合,kubeadm 還可以生成證書籤名請求 (CSR)。CSR 表示向 CA 請求客戶端簽名證書。在 kubeadm 術語中,任何通常由磁碟 CA 簽名的證書都可以作為 CSR 生成。然而,CA 不能作為 CSR 生成。

透過使用證書籤名請求 (CSR) 續訂

可以透過生成新的 CSR 並使用外部 CA 簽署它們來續訂證書。有關使用 kubeadm 生成的 CSR 的更多詳細資訊,請參閱簽署 kubeadm 生成的證書籤名請求 (CSR) 部分。

證書頒發機構 (CA) 輪換

Kubeadm 不支援開箱即用的 CA 證書輪換或替換。

有關手動輪換或替換 CA 的更多資訊,請參見手動輪換 CA 證書

啟用已簽名 kubelet 服務證書

預設情況下,kubeadm 部署的 kubelet 服務證書是自簽名的。這意味著從外部服務(如 metrics-server)到 kubelet 的連線無法透過 TLS 保護。

要在新的 kubeadm 叢集中配置 kubelet 以獲取正確簽名的服務證書,你必須向 kubeadm init 傳遞以下最小配置

apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
serverTLSBootstrap: true

如果你已經建立了叢集,則必須透過以下方式進行調整

  • kube-system 名稱空間中查詢並編輯 kubelet-config-1.34 ConfigMap。在該 ConfigMap 中,kubelet 鍵的值是一個 KubeletConfiguration 文件。編輯 KubeletConfiguration 文件以設定 serverTLSBootstrap: true
  • 在每個節點上,在 /var/lib/kubelet/config.yaml 中新增 serverTLSBootstrap: true 欄位,並使用 systemctl restart kubelet 重新啟動 kubelet。

serverTLSBootstrap: true 欄位將透過從 certificates.k8s.io API 請求 kubelet 服務證書來啟用引導。一個已知的限制是,這些證書的 CSR(證書籤名請求)無法由 kube-controller-manager 中的預設簽名器自動批准 - kubernetes.io/kubelet-serving。這將需要使用者或第三方控制器採取行動。

可以使用以下命令檢視這些 CSR

kubectl get csr
NAME        AGE     SIGNERNAME                        REQUESTOR                      CONDITION
csr-9wvgt   112s    kubernetes.io/kubelet-serving     system:node:worker-1           Pending
csr-lz97v   1m58s   kubernetes.io/kubelet-serving     system:node:control-plane-1    Pending

要批准它們,你可以執行以下操作

kubectl certificate approve <CSR-name>

預設情況下,這些服務證書將在一年後過期。Kubeadm 將 KubeletConfiguration 欄位 rotateCertificates 設定為 true,這意味著在接近過期時,將建立一組新的服務證書 CSR,並且必須批准才能完成輪換。要了解更多資訊,請參見證書輪換

如果你正在尋找自動批准這些 CSR 的解決方案,建議你聯絡你的雲提供商,詢問他們是否有透過帶外機制驗證節點身份的 CSR 簽名器。

可以使用第三方自定義控制器

除非此類控制器不僅驗證 CSR 中的通用名稱,還驗證請求的 IP 和域名,否則它不是一種安全機制。這將防止擁有 kubelet 客戶端證書的惡意行為者建立請求任何 IP 或域名的服務證書的 CSR。

為其他使用者生成 kubeconfig 檔案

在叢集建立期間,kubeadm init 會簽署 super-admin.conf 中的證書,使其具有 Subject: O = system:masters, CN = kubernetes-super-adminsystem:masters 是一個“破窗”超級使用者組,它繞過授權層(例如 RBAC)。admin.conf 檔案也由 kubeadm 在控制平面節點上建立,它包含一個證書,其 Subject: O = kubeadm:cluster-admins, CN = kubernetes-adminkubeadm:cluster-admins 是一個邏輯上屬於 kubeadm 的組。如果你的叢集使用 RBAC(kubeadm 預設),則 kubeadm:cluster-admins 組繫結到 cluster-admin ClusterRole。

你可以使用 kubeadm kubeconfig user 命令為其他使用者生成 kubeconfig 檔案。該命令接受命令列標誌和 kubeadm 配置選項的混合。生成的 kubeconfig 將寫入標準輸出,並且可以使用 kubeadm kubeconfig user ... > somefile.conf 管道傳輸到檔案。

可與 --config 一起使用的示例配置檔案

# example.yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
# Will be used as the target "cluster" in the kubeconfig
clusterName: "kubernetes"
# Will be used as the "server" (IP or DNS name) of this cluster in the kubeconfig
controlPlaneEndpoint: "some-dns-address:6443"
# The cluster CA key and certificate will be loaded from this local directory
certificatesDir: "/etc/kubernetes/pki"

確保這些設定與所需的目標叢集設定匹配。要檢視現有叢集的設定,請使用

kubectl get cm kubeadm-config -n kube-system -o=jsonpath="{.data.ClusterConfiguration}"

以下示例將生成一個 kubeconfig 檔案,其中包含有效期為 24 小時的新使用者 johndoe 的憑據,該使用者屬於 appdevs

kubeadm kubeconfig user --config example.yaml --org appdevs --client-name johndoe --validity-period 24h

以下示例將生成一個 kubeconfig 檔案,其中包含有效期為 1 周的管理員憑據

kubeadm kubeconfig user --config example.yaml --client-name admin --validity-period 168h

簽署 kubeadm 生成的證書籤名請求 (CSR)

你可以使用 kubeadm certs generate-csr 建立證書籤名請求。呼叫此命令將為常規證書生成 .csr / .key 檔案對。對於嵌入在 kubeconfig 檔案中的證書,該命令將生成 .csr / .conf 對,其中金鑰已嵌入在 .conf 檔案中。

CSR 檔案包含 CA 簽署證書所需的所有相關資訊。kubeadm 為其所有證書和 CSR 使用定義明確的規範

預設證書目錄是 /etc/kubernetes/pki,而 kubeconfig 檔案的預設目錄是 /etc/kubernetes。這些預設值可以分別透過 --cert-dir--kubeconfig-dir 標誌覆蓋。

要將自定義選項傳遞給 kubeadm certs generate-csr,請使用 --config 標誌,它接受 kubeadm 配置檔案,類似於 kubeadm init 等命令。任何規範,例如額外的 SAN 和自定義 IP 地址,都必須儲存在同一配置檔案中,並作為 --config 傳遞給所有相關的 kubeadm 命令。

準備 CA 和服務賬戶檔案

在主控制平面節點(將執行 kubeadm init 的節點)上,呼叫以下命令:

sudo kubeadm init phase certs ca
sudo kubeadm init phase certs etcd-ca
sudo kubeadm init phase certs front-proxy-ca
sudo kubeadm init phase certs sa

這將用 kubeadm 控制平面節點所需的所有自簽名 CA 檔案(證書和金鑰)和服務賬戶(公鑰和私鑰)填充 /etc/kubernetes/pki/etc/kubernetes/pki/etcd 資料夾。

對於輔助控制平面節點 (kubeadm join --control-plane),無需呼叫上述命令。根據你設定高可用性叢集的方式,你可能需要手動從主控制平面節點複製相同的檔案,或者使用 kubeadm init 的自動化 --upload-certs 功能。

生成 CSR

kubeadm certs generate-csr 命令為 kubeadm 管理的所有已知證書生成 CSR。命令完成後,你必須手動刪除不需要的 .csr.conf.key 檔案。

kubelet.conf 的注意事項

本節適用於控制平面節點和工作節點。

如果你已從控制平面節點刪除了 ca.key 檔案(外部 CA 模式),則此叢集中的活動 kube-controller-manager 將無法簽署 kubelet 客戶端證書。如果你的設定中不存在用於簽署這些證書的外部方法(例如外部簽名器),你可以手動簽署 kubelet.conf.csr,如本指南所述。

請注意,這還意味著自動kubelet 客戶端證書輪換將被停用。如果是這樣,在證書到期前,你必須生成新的 kubelet.conf.csr,簽署證書,將其嵌入 kubelet.conf 並重新啟動 kubelet。

如果這不適用於你的設定,你可以跳過在輔助控制平面和工作節點(所有呼叫 kubeadm join ... 的節點)上處理 kubelet.conf.csr。這是因為活動的 kube-controller-manager 將負責簽署新的 kubelet 客戶端證書。

控制平面節點

在主(kubeadm init)和輔助(kubeadm join --control-plane)控制平面節點上執行以下命令以生成所有 CSR 檔案

sudo kubeadm certs generate-csr

如果要使用外部 etcd,請遵循使用 kubeadm 的外部 etcd 指南,以瞭解 kubeadm 和 etcd 節點上需要哪些 CSR 檔案。/etc/kubernetes/pki/etcd 下的其他 .csr.key 檔案可以刪除。

根據kubelet.conf 的注意事項中的解釋,保留或刪除 kubelet.confkubelet.conf.csr 檔案。

工作節點

根據kubelet.conf 的注意事項中的解釋,可以選擇呼叫

sudo kubeadm certs generate-csr

並只保留 kubelet.confkubelet.conf.csr 檔案。或者完全跳過工作節點步驟。

簽署所有證書的 CSR

對所有具有 CSR 檔案的節點重複此步驟。

將以下指令碼寫入 /etc/kubernetes 目錄,導航到該目錄並執行指令碼。該指令碼將為 /etc/kubernetes 樹中存在的所有 CSR 檔案生成證書。

#!/bin/bash

# Set certificate expiration time in days
DAYS=365

# Process all CSR files except those for front-proxy and etcd
find ./ -name "*.csr" | grep -v "pki/etcd" | grep -v "front-proxy" | while read -r FILE;
do
    echo "* Processing ${FILE} ..."
    FILE=${FILE%.*} # Trim the extension
    if [ -f "./pki/ca.srl" ]; then
        SERIAL_FLAG="-CAserial ./pki/ca.srl"
    else
        SERIAL_FLAG="-CAcreateserial"
    fi
    openssl x509 -req -days "${DAYS}" -CA ./pki/ca.crt -CAkey ./pki/ca.key ${SERIAL_FLAG} \
        -in "${FILE}.csr" -out "${FILE}.crt"
    sleep 2
done

# Process all etcd CSRs
find ./pki/etcd -name "*.csr" | while read -r FILE;
do
    echo "* Processing ${FILE} ..."
    FILE=${FILE%.*} # Trim the extension
    if [ -f "./pki/etcd/ca.srl" ]; then
        SERIAL_FLAG=-CAserial ./pki/etcd/ca.srl
    else
        SERIAL_FLAG=-CAcreateserial
    fi
    openssl x509 -req -days "${DAYS}" -CA ./pki/etcd/ca.crt -CAkey ./pki/etcd/ca.key ${SERIAL_FLAG} \
        -in "${FILE}.csr" -out "${FILE}.crt"
done

# Process front-proxy CSRs
echo "* Processing ./pki/front-proxy-client.csr ..."
openssl x509 -req -days "${DAYS}" -CA ./pki/front-proxy-ca.crt -CAkey ./pki/front-proxy-ca.key -CAcreateserial \
    -in ./pki/front-proxy-client.csr -out ./pki/front-proxy-client.crt

將證書嵌入 kubeconfig 檔案

對所有具有 CSR 檔案的節點重複此步驟。

將以下指令碼寫入 /etc/kubernetes 目錄,導航到該目錄並執行指令碼。該指令碼將從上一步的 CSR 中獲取為 kubeconfig 檔案簽名的 .crt 檔案,並將其嵌入到 kubeconfig 檔案中。

#!/bin/bash

CLUSTER=kubernetes
find ./ -name "*.conf" | while read -r FILE;
do
    echo "* Processing ${FILE} ..."
    KUBECONFIG="${FILE}" kubectl config set-cluster "${CLUSTER}" --certificate-authority ./pki/ca.crt --embed-certs
    USER=$(KUBECONFIG="${FILE}" kubectl config view -o jsonpath='{.users[0].name}')
    KUBECONFIG="${FILE}" kubectl config set-credentials "${USER}" --client-certificate "${FILE}.crt" --embed-certs
done

執行清理

在所有具有 CSR 檔案的節點上執行此步驟。

將以下指令碼寫入 /etc/kubernetes 目錄,導航到該目錄並執行指令碼。

#!/bin/bash

# Cleanup CSR files
rm -f ./*.csr ./pki/*.csr ./pki/etcd/*.csr # Clean all CSR files

# Cleanup CRT files that were already embedded in kubeconfig files
rm -f ./*.crt

(可選)將 .srl 檔案移動到下一個要處理的節點。

(可選)如果使用外部 CA,請刪除 /etc/kubernetes/pki/ca.key 檔案,如外部 CA 節點部分所述。

kubeadm 節點初始化

一旦 CSR 檔案已簽名並且所需證書已位於要用作節點的宿主機上,你就可以使用 kubeadm initkubeadm join 命令從這些節點建立 Kubernetes 叢集。在 initjoin 期間,kubeadm 會使用宿主機本地檔案系統上 /etc/kubernetes 樹中找到的現有證書、加密金鑰和 kubeconfig 檔案。

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

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

最後修改於 2025 年 8 月 14 日太平洋標準時間上午 12:09:[en] 修復 kubeadm-certs.md 中的拼寫錯誤 (7d0a490efd)