Kubernetes 使用kubeadm進(jìn)行證書管理

2022-06-02 10:24 更新

使用 kubeadm 進(jìn)行證書管理

FEATURE STATE: Kubernetes v1.15 [stable]

由 kubeadm 生成的客戶端證書在 1 年后到期。 本頁說明如何使用 kubeadm 管理證書續(xù)訂,同時也涵蓋其他與 kubeadm 證書管理相關(guān)的說明。

在開始之前

你應(yīng)該熟悉 Kubernetes 中的 PKI 證書和要求

使用自定義的證書

默認(rèn)情況下,kubeadm 會生成運(yùn)行一個集群所需的全部證書。 你可以通過提供你自己的證書來改變這個行為策略。

如果要這樣做,你必須將證書文件放置在通過 ?--cert-dir? 命令行參數(shù)或者 kubeadm 配置中的 ?certificatesDir ?配置項(xiàng)指明的目錄中。默認(rèn)的值是 ?/etc/kubernetes/pki?。

如果在運(yùn)行 ?kubeadm init? 之前存在給定的證書和私鑰對,kubeadm 將不會重寫它們。 例如,這意味著你可以將現(xiàn)有的 CA 復(fù)制到 ?/etc/kubernetes/pki/ca.crt? 和 ?/etc/kubernetes/pki/ca.key? 中,而 kubeadm 將使用此 CA 對其余證書進(jìn)行簽名。

外部 CA 模式

只提供了 ?ca.crt? 文件但是不提供 ?ca.key? 文件也是可以的 (這只對 CA 根證書可用,其它證書不可用)。 如果所有的其它證書和 kubeconfig 文件已就緒,kubeadm 檢測到滿足以上條件就會激活 "外部 CA" 模式。kubeadm 將會在沒有 CA 密鑰文件的情況下繼續(xù)執(zhí)行。

否則,kubeadm 將獨(dú)立運(yùn)行 controller-manager,附加一個 ?--controllers=csrsigner? 的參數(shù),并且指明 CA 證書和密鑰。

PKI 證書和要求包括集群使用外部 CA 的設(shè)置指南。

檢查證書是否過期

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

kubeadm certs check-expiration

輸出類似于以下內(nèi)容:

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(?admin.conf?、?controller-manager.conf? 和 ?scheduler.conf?) 使用的 KUBECONFIG 文件中嵌入的客戶端證書的到期時間/剩余時間。

另外,kubeadm 會通知用戶證書是否由外部管理; 在這種情況下,用戶應(yīng)該小心的手動/使用其他工具來管理證書更新。

Warning: ?kubeadm ?不能管理由外部 CA 簽名的證書

Note: 上面的列表中沒有包含 ?kubelet.conf?,因?yàn)?nbsp;kubeadm 將 kubelet 配置為 自動更新證書。 輪換的證書位于目錄 ?/var/lib/kubelet/pki?。

Warning:
在通過 ?kubeadm init? 創(chuàng)建的節(jié)點(diǎn)上,在 kubeadm 1.17 版本之前有一個 缺陷,該缺陷 使得你必須手動修改 ?kubelet.conf? 文件的內(nèi)容。 ?kubeadm init? 操作結(jié)束之后,你必須更新 ?kubelet.conf? 文件 將 ?client-certificate-data? 和 ?client-key-data? 改為如下所示的內(nèi)容 以便使用輪換后的 kubelet 客戶端證書:
client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
client-key: /var/lib/kubelet/pki/kubelet-client-current.pem

自動更新證書

kubeadm 會在控制面 升級 的時候更新所有證書。

這個功能旨在解決最簡單的用例;如果你對此類證書的更新沒有特殊要求, 并且定期執(zhí)行 Kubernetes 版本升級(每次升級之間的間隔時間少于 1 年), 則 kubeadm 將確保你的集群保持最新狀態(tài)并保持合理的安全性。

Note: 最佳的做法是經(jīng)常升級集群以確保安全。

如果你對證書更新有更復(fù)雜的需求,則可通過將 ?--certificate-renewal=false? 傳遞給 ?kubeadm upgrade apply? 或者 ?kubeadm upgrade node?,從而選擇不采用默認(rèn)行為。

Warning: kubeadm 在 1.17 版本之前有一個缺陷, 該缺陷導(dǎo)致 ?kubeadm update node? 執(zhí)行時 ?--certificate-renewal? 的默認(rèn)值被設(shè)置為 ?false?。 在這種情況下,你需要顯式地設(shè)置 ?--certificate-renewal=true?。

手動更新證書

你能隨時通過 ?kubeadm certs renew? 命令手動更新你的證書。

此命令用 CA(或者 front-proxy-CA )證書和存儲在 ?/etc/kubernetes/pki? 中的密鑰執(zhí)行更新。

執(zhí)行完此命令之后你需要重啟控制面 Pods。因?yàn)閯討B(tài)證書重載目前還不被所有組件和證書支持,所有這項(xiàng)操作是必須的。 靜態(tài) Pods 是被本地 kubelet 而不是 API Server 管理, 所以 kubectl 不能用來刪除或重啟他們。 要重啟靜態(tài) Pod 你可以臨時將清單文件從 ?/etc/kubernetes/manifests/? 移除并等待 20 秒。 如果 Pod 不在清單目錄里,kubelet 將會終止它。 在另一個 ?fileCheckFrequency ?周期之后你可以將文件移回去,為了組件可以完成 kubelet 將重新創(chuàng)建 Pod 和證書更新。

Warning: 如果你運(yùn)行了一個 HA 集群,這個命令需要在所有控制面板節(jié)點(diǎn)上執(zhí)行。

Note: ?certs renew? 使用現(xiàn)有的證書作為屬性(Common Name、Organization、SAN 等)的權(quán)威來源, 而不是 kubeadm-config ConfigMap。強(qiáng)烈建議使它們保持同步。

?kubeadm certs renew? 提供以下選項(xiàng):

Kubernetes 證書通常在一年后到期。

  • ?--csr-only? 可用于經(jīng)過一個外部 CA 生成的證書簽名請求來更新證書(無需實(shí)際替換更新證書)。
  • 可以更新單個證書而不是全部證書。

用 Kubernetes 證書 API 更新證書

本節(jié)提供有關(guān)如何使用 Kubernetes 證書 API 執(zhí)行手動證書更新的更多詳細(xì)信息。

Caution: 這些是針對需要將其組織的證書基礎(chǔ)結(jié)構(gòu)集成到 kubeadm 構(gòu)建的集群中的用戶的高級主題。 如果默認(rèn)的 kubeadm 配置滿足了你的需求,則應(yīng)讓 kubeadm 管理證書。

設(shè)置一個簽名者(Signer)

Kubernetes 證書頒發(fā)機(jī)構(gòu)不是開箱即用。你可以配置外部簽名者,例如 cert-manager, 也可以使用內(nèi)置簽名者。 內(nèi)置簽名者是 ?kube-controller-manager? 的一部分。 要激活內(nèi)置簽名者,請傳遞 ?--cluster-signing-cert-file? 和 ?--cluster-signing-key-file? 參數(shù)。

如果你正在創(chuàng)建一個新的集群,你可以使用 kubeadm 的 配置文件。

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

通過外部 CA 更新證書

本節(jié)提供有關(guān)如何使用外部 CA 執(zhí)行手動更新證書的更多詳細(xì)信息。

為了更好的與外部 CA 集成,kubeadm 還可以生成證書簽名請求(CSR)。 CSR 表示向 CA 請求客戶的簽名證書。 在 kubeadm 術(shù)語中,通常由磁盤 CA 簽名的任何證書都可以作為 CSR 生成。但是,CA 不能作為 CSR 生成。

創(chuàng)建證書簽名請求 (CSR)

你可以通過 ?kubeadm certs renew --csr-only? 命令創(chuàng)建證書簽名請求。

CSR 和隨附的私鑰都在輸出中給出。 你可以傳入一個帶有 ?--csr-dir? 的目錄,將 CRS 輸出到指定位置。 如果未指定 ?--csr-dir?,則使用默認(rèn)證書目錄(?/etc/kubernetes/pki?)。

證書可以通過 ?kubeadm certs renew --csr-only? 來續(xù)訂。 和 ?kubeadm init? 一樣,可以使用 ?--csr-dir? 標(biāo)志指定一個輸出目錄。

CSR 簽署證書后,必須將證書和私鑰復(fù)制到 PKI 目錄(默認(rèn)情況下為 ?/etc/kubernetes/pki?)。

CSR 中包含一個證書的名字,域和 IP,但是未指定用法。 頒發(fā)證書時,CA 有責(zé)任指定正確的證書用法

使用首選方法對證書簽名后,必須將證書和私鑰復(fù)制到 PKI 目錄(默認(rèn)為 ?/etc/kubernetes/pki? )。

證書機(jī)構(gòu)(CA)輪換

kubeadm 并不直接支持對 CA 證書的輪換或者替換。

啟用已簽名的 kubelet 服務(wù)證書

默認(rèn)情況下,kubeadm 所部署的 kubelet 服務(wù)證書是自簽名(Self-Signed)。 這意味著從 metrics-server 這類外部服務(wù)發(fā)起向 kubelet 的鏈接時無法使用 TLS 來完成保護(hù)。

要在新的 kubeadm 集群中配置 kubelet 以使用被正確簽名的服務(wù)證書, 你必須向 ?kubeadm init? 傳遞如下最小配置數(shù)據(jù):

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

如果你已經(jīng)創(chuàng)建了集群,你必須通過執(zhí)行下面的操作來完成適配:

  • 找到 ?kube-system? 名字空間中名為 ?kubelet-config-1.24? 的 ConfigMap 并編輯之。 在該 ConfigMap 中,?kubelet ?鍵下面有一個 KubeletConfiguration 文檔作為其取值。編輯該 KubeletConfiguration 文檔以設(shè)置 ?serverTLSBootstrap: true?。
  • 在每個節(jié)點(diǎn)上,在 ?/var/lib/kubelet/config.yaml? 文件中添加 ?serverTLSBootstrap: true? 字段,并使用 ?systemctl restart kubelet? 來重啟 kubelet。

字段 ?serverTLSBootstrap ?將允許啟動引導(dǎo) kubelet 的服務(wù)證書,方式 是從 ?certificates.k8s.io? API 處讀取。這種方式的一種局限在于這些 證書的 CSR(證書簽名請求)不能被 kube-controller-manager 中默認(rèn)的 簽名組件 ?kubernetes.io/kubelet-serving? 批準(zhǔn)。需要用戶或者第三方控制器來執(zhí)行此操作。

可以使用下面的命令來查看 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

你可以執(zhí)行下面的操作來批準(zhǔn)這些請求:

kubectl certificate approve <CSR-名稱>

默認(rèn)情況下,這些服務(wù)證書上會在一年后過期。 kubeadm 將 ?KubeletConfiguration ?的 ?rotateCertificates ?字段設(shè)置為 ?true?;這意味著證書快要過期時,會生成一組針對服務(wù)證書的新的 CSR,而 這些 CSR 也要被批準(zhǔn)才能完成證書輪換。

如果你在尋找一種能夠自動批準(zhǔn)這些 CSR 的解決方案,建議你與你的云提供商 聯(lián)系,詢問他們是否有 CSR 簽名組件,用來以帶外(out-of-band)的方式檢查 節(jié)點(diǎn)的標(biāo)識符。

也可以使用第三方定制的控制器:

除非既能夠驗(yàn)證 CSR 中的 CommonName,也能檢查請求的 IP 和域名, 這類控制器還算不得安全的機(jī)制。 只有完成徹底的檢查,才有可能避免有惡意的、能夠訪問 kubelet 客戶端證書的第三方 為任何 IP 或域名請求服務(wù)證書。

為其他用戶生成 kubeconfig 文件 

在集群創(chuàng)建過程中,kubeadm 對 ?admin.conf? 中的證書進(jìn)行簽名時,將其配置為 ?Subject: O = system:masters, CN = kubernetes-admin?。 ?system:masters? 是一個例外的超級用戶組,可以繞過鑒權(quán)層(例如 RBAC)。 強(qiáng)烈建議不要將 ?admin.conf ?文件與任何人共享。

你要使用 ?kubeadm kubeconfig user? 命令為其他用戶生成 kubeconfig 文件,這個命令支持命令行參數(shù)和 kubeadm 配置結(jié)構(gòu)。 以上命令會將 kubeconfig 打印到終端上,也可以使用 ?kubeadm kubeconfig user ... > somefile.conf? 輸出到一個文件中。

如下 kubeadm 可以在 ?--config? 后加的配置文件示例:

# example.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
# kubernetes 將作為 kubeconfig 中集群名稱
clusterName: "kubernetes"
# some-dns-address:6443 將作為集群 kubeconfig 文件中服務(wù)地址(IP 或者 DNS 名稱)
controlPlaneEndpoint: "some-dns-address:6443"
# 從本地掛載集群的 CA 秘鑰和 CA 證書
certificatesDir: "/etc/kubernetes/pki"

確保這些設(shè)置與所需的目標(biāo)集群設(shè)置相匹配??梢允褂靡韵旅畈榭船F(xiàn)有集群的設(shè)置:

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

以下示例將為在 ?appdevs ?組的 ?johndoe ?用戶創(chuàng)建一個有效期為 24 小時的 kubeconfig 文件:

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

以下示例將為管理員創(chuàng)建一個有效期有一周的 kubeconfig 文件:

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


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號