Kubernetes 配置聚合層

2022-06-17 09:35 更新

配置聚合層

配置聚合層 可以允許 Kubernetes apiserver 使用其它 API 擴(kuò)展,這些 API 不是核心 Kubernetes API 的一部分。

在開(kāi)始之前

你必須擁有一個(gè) Kubernetes 的集群,同時(shí)你的 Kubernetes 集群必須帶有 kubectl 命令行工具。 建議在至少有兩個(gè)節(jié)點(diǎn)的集群上運(yùn)行本教程,且這些節(jié)點(diǎn)不作為控制平面主機(jī)。 如果你還沒(méi)有集群,你可以通過(guò) Minikube 構(gòu)建一個(gè)你自己的集群,或者你可以使用下面任意一個(gè) Kubernetes 工具構(gòu)建:

要獲知版本信息,請(qǐng)輸入 ?kubectl version?。

說(shuō)明: 要使聚合層在你的環(huán)境中正常工作以支持代理服務(wù)器和擴(kuò)展 apiserver 之間的相互 TLS 身份驗(yàn)證, 需要滿(mǎn)足一些設(shè)置要求。Kubernetes 和 kube-apiserver 具有多個(gè) CA, 因此請(qǐng)確保代理是由聚合層 CA 簽名的,而不是由 Kubernetes 通用 CA 簽名的。

注意: 對(duì)不同的客戶(hù)端類(lèi)型重復(fù)使用相同的 CA 會(huì)對(duì)集群的功能產(chǎn)生負(fù)面影響。

身份認(rèn)證流程

與自定義資源定義(CRD)不同,除標(biāo)準(zhǔn)的 Kubernetes apiserver 外,Aggregation API 還涉及另一個(gè)服務(wù)器:擴(kuò)展 apiserver。 Kubernetes apiserver 將需要與你的擴(kuò)展 apiserver 通信,并且你的擴(kuò)展 apiserver 也需要與 Kubernetes apiserver 通信。 為了確保此通信的安全,Kubernetes apiserver 使用 x509 證書(shū)向擴(kuò)展 apiserver 認(rèn)證。

本節(jié)介紹身份認(rèn)證和鑒權(quán)流程的工作方式以及如何配置它們。

大致流程如下:

  1. Kubernetes apiserver:對(duì)發(fā)出請(qǐng)求的用戶(hù)身份認(rèn)證,并對(duì)請(qǐng)求的 API 路徑執(zhí)行鑒權(quán)。
  2. Kubernetes apiserver:將請(qǐng)求轉(zhuǎn)發(fā)到擴(kuò)展 apiserver
  3. 擴(kuò)展 apiserver:認(rèn)證來(lái)自 Kubernetes apiserver 的請(qǐng)求
  4. 擴(kuò)展 apiserver:對(duì)來(lái)自原始用戶(hù)的請(qǐng)求鑒權(quán)
  5. 擴(kuò)展 apiserver:執(zhí)行

本節(jié)的其余部分詳細(xì)描述了這些步驟。

該流程可以在下圖中看到。


以上泳道的來(lái)源可以在本文檔的源碼中找到。

Kubernetes Apiserver 認(rèn)證和授權(quán)

由擴(kuò)展 apiserver 服務(wù)的對(duì) API 路徑的請(qǐng)求以與所有 API 請(qǐng)求相同的方式開(kāi)始: 與 Kubernetes apiserver 的通信。該路徑已通過(guò)擴(kuò)展 apiserver 在 Kubernetes apiserver 中注冊(cè)。

用戶(hù)與 Kubernetes apiserver 通信,請(qǐng)求訪(fǎng)問(wèn)路徑。 Kubernetes apiserver 使用它的標(biāo)準(zhǔn)認(rèn)證和授權(quán)配置來(lái)對(duì)用戶(hù)認(rèn)證,以及對(duì)特定路徑的鑒權(quán)。

到目前為止,所有內(nèi)容都是標(biāo)準(zhǔn)的 Kubernetes API 請(qǐng)求,認(rèn)證與鑒權(quán)。

Kubernetes apiserver 現(xiàn)在準(zhǔn)備將請(qǐng)求發(fā)送到擴(kuò)展 apiserver。

Kubernetes Apiserver 代理請(qǐng)求 

Kubernetes apiserver 現(xiàn)在將請(qǐng)求發(fā)送或代理到注冊(cè)以處理該請(qǐng)求的擴(kuò)展 apiserver。 為此,它需要了解幾件事:

  1. Kubernetes apiserver 應(yīng)該如何向擴(kuò)展 apiserver 認(rèn)證,以通知擴(kuò)展 apiserver 通過(guò)網(wǎng)絡(luò)發(fā)出的請(qǐng)求來(lái)自有效的 Kubernetes apiserver?
  2. Kubernetes apiserver 應(yīng)該如何通知擴(kuò)展 apiserver 原始請(qǐng)求 已通過(guò)認(rèn)證的用戶(hù)名和組?

為提供這兩條信息,你必須使用若干標(biāo)志來(lái)配置 Kubernetes apiserver。

Kubernetes Apiserver 客戶(hù)端認(rèn)證

Kubernetes apiserver 通過(guò) TLS 連接到擴(kuò)展 apiserver,并使用客戶(hù)端證書(shū)認(rèn)證。 你必須在啟動(dòng)時(shí)使用提供的標(biāo)志向 Kubernetes apiserver 提供以下內(nèi)容:

  • 通過(guò) ?--proxy-client-key-file? 指定私鑰文件
  • 通過(guò) ?--proxy-client-cert-file? 簽名的客戶(hù)端證書(shū)文件
  • 通過(guò) ?--requestheader-client-ca-file? 簽署客戶(hù)端證書(shū)文件的 CA 證書(shū)
  • 通過(guò) ?--requestheader-allowed-names? 在簽署的客戶(hù)證書(shū)中有效的公用名(CN)

Kubernetes apiserver 將使用由 ?--proxy-client-*-file? 指示的文件來(lái)驗(yàn)證擴(kuò)展 apiserver。 為了使合規(guī)的擴(kuò)展 apiserver 能夠?qū)⒃撜?qǐng)求視為有效,必須滿(mǎn)足以下條件:

  1. 連接必須使用由 CA 簽署的客戶(hù)端證書(shū),該證書(shū)的證書(shū)位于 ?--requestheader-client-ca-file? 中。
  2. 連接必須使用客戶(hù)端證書(shū),該客戶(hù)端證書(shū)的 CN 是 ?--requestheader-allowed-names? 中列出的證書(shū)之一。

說(shuō)明: 你可以將此選項(xiàng)設(shè)置為空白,即為?--requestheader-allowed-names?。 這將向擴(kuò)展 apiserver 指示任何 CN 是可接受的。

使用這些選項(xiàng)啟動(dòng)時(shí),Kubernetes apiserver 將:

  1. 使用它們向擴(kuò)展 apiserver 認(rèn)證。
  2. 在 ?kube-system? 命名空間中 創(chuàng)建一個(gè)名為 ?extension-apiserver-authentication? 的 ConfigMap, 它將在其中放置 CA 證書(shū)和允許的 CN。 反過(guò)來(lái),擴(kuò)展 apiserver 可以檢索這些內(nèi)容以驗(yàn)證請(qǐng)求。

請(qǐng)注意,Kubernetes apiserver 使用相同的客戶(hù)端證書(shū)對(duì)所有擴(kuò)展 apiserver 認(rèn)證。 它不會(huì)為每個(gè)擴(kuò)展 apiserver 創(chuàng)建一個(gè)客戶(hù)端證書(shū),而是創(chuàng)建一個(gè)證書(shū)作為 Kubernetes apiserver 認(rèn)證。所有擴(kuò)展 apiserver 請(qǐng)求都重復(fù)使用相同的請(qǐng)求。

原始請(qǐng)求用戶(hù)名和組

當(dāng) Kubernetes apiserver 將請(qǐng)求代理到擴(kuò)展 apiserver 時(shí), 它將向擴(kuò)展 apiserver 通知原始請(qǐng)求已成功通過(guò)其驗(yàn)證的用戶(hù)名和組。 它在其代理請(qǐng)求的 HTTP 頭部中提供這些。你必須將要使用的標(biāo)頭名稱(chēng)告知 Kubernetes apiserver。

  • 通過(guò)?--requestheader-username-headers? 標(biāo)明用來(lái)保存用戶(hù)名的頭部
  • 通過(guò)?--requestheader-group-headers? 標(biāo)明用來(lái)保存 group 的頭部
  • 通過(guò)?--requestheader-extra-headers-prefix? 標(biāo)明用來(lái)保存拓展信息前綴的頭部

這些頭部名稱(chēng)也放置在 ?extension-apiserver-authentication? ConfigMap 中, 因此擴(kuò)展 apiserver 可以檢索和使用它們。

擴(kuò)展 Apiserver 認(rèn)證

擴(kuò)展 apiserver 在收到來(lái)自 Kubernetes apiserver 的代理請(qǐng)求后, 必須驗(yàn)證該請(qǐng)求確實(shí)確實(shí)來(lái)自有效的身份驗(yàn)證代理, 該認(rèn)證代理由 Kubernetes apiserver 履行。擴(kuò)展 apiserver 通過(guò)以下方式對(duì)其認(rèn)證:

  1. 如上所述,從?kube-system?中的 configmap 中檢索以下內(nèi)容:
    • 客戶(hù)端 CA 證書(shū)
    • 允許名稱(chēng)(CN)列表
    • 用戶(hù)名,組和其他信息的頭部
  2. 使用以下證書(shū)檢查 TLS 連接是否已通過(guò)認(rèn)證:
    • 由其證書(shū)與檢索到的 CA 證書(shū)匹配的 CA 簽名。
    • 在允許的 CN 列表中有一個(gè) CN,除非列表為空,在這種情況下允許所有 CN。
    • 從適當(dāng)?shù)念^部中提取用戶(hù)名和組

如果以上均通過(guò),則該請(qǐng)求是來(lái)自合法認(rèn)證代理(在本例中為 Kubernetes apiserver) 的有效代理請(qǐng)求。

請(qǐng)注意,擴(kuò)展 apiserver 實(shí)現(xiàn)負(fù)責(zé)提供上述內(nèi)容。 默認(rèn)情況下,許多擴(kuò)展 apiserver 實(shí)現(xiàn)利用 ?k8s.io/apiserver/? 軟件包來(lái)做到這一點(diǎn)。 也有一些實(shí)現(xiàn)可能支持使用命令行選項(xiàng)來(lái)覆蓋這些配置。

為了具有檢索 configmap 的權(quán)限,擴(kuò)展 apiserver 需要適當(dāng)?shù)慕巧?nbsp;在 ?kube-system? 名字空間中有一個(gè)默認(rèn)角色 ?extension-apiserver-authentication-reader? 可用于設(shè)置。

擴(kuò)展 Apiserver 對(duì)請(qǐng)求鑒權(quán)

擴(kuò)展 apiserver 現(xiàn)在可以驗(yàn)證從標(biāo)頭檢索的?user/group?是否有權(quán)執(zhí)行給定請(qǐng)求。 通過(guò)向 Kubernetes apiserver 發(fā)送標(biāo)準(zhǔn) ?SubjectAccessReview ?請(qǐng)求來(lái)實(shí)現(xiàn)。

為了使擴(kuò)展 apiserver 本身被鑒權(quán)可以向 Kubernetes apiserver 提交 SubjectAccessReview 請(qǐng)求, 它需要正確的權(quán)限。 Kubernetes 包含一個(gè)具有相應(yīng)權(quán)限的名為 ?system:auth-delegator? 的默認(rèn) ?ClusterRole?, 可以將其授予擴(kuò)展 apiserver 的服務(wù)帳戶(hù)。

擴(kuò)展 Apiserver 執(zhí)行

如果 ?SubjectAccessReview ?通過(guò),則擴(kuò)展 apiserver 執(zhí)行請(qǐng)求。

啟用 Kubernetes Apiserver 標(biāo)志 

通過(guò)以下 kube-apiserver 標(biāo)志啟用聚合層。 你的服務(wù)提供商可能已經(jīng)為你完成了這些工作:

    --requestheader-client-ca-file=<path to aggregator CA cert>
    --requestheader-allowed-names=front-proxy-client
    --requestheader-extra-headers-prefix=X-Remote-Extra-
    --requestheader-group-headers=X-Remote-Group
    --requestheader-username-headers=X-Remote-User
    --proxy-client-cert-file=<path to aggregator proxy cert>
    --proxy-client-key-file=<path to aggregator proxy key>

CA-重用和沖突 

Kubernetes apiserver 有兩個(gè)客戶(hù)端 CA 選項(xiàng):

  • ?--client-ca-file ?
  • ?--requestheader-client-ca-file ?

這些功能中的每個(gè)功能都是獨(dú)立的;如果使用不正確,可能彼此沖突。

  • ?--client-ca-file?:當(dāng)請(qǐng)求到達(dá) Kubernetes apiserver 時(shí),如果啟用了此選項(xiàng), 則 Kubernetes apiserver 會(huì)檢查請(qǐng)求的證書(shū)。 如果它是由 ?--client-ca-file? 引用的文件中的 CA 證書(shū)之一簽名的, 并且用戶(hù)是公用名?CN=?的值,而組是組織O= 的取值,則該請(qǐng)求被視為合法請(qǐng)求。
  • ?--requestheader-client-ca-file?:當(dāng)請(qǐng)求到達(dá) Kubernetes apiserver 時(shí), 如果啟用此選項(xiàng),則 Kubernetes apiserver 會(huì)檢查請(qǐng)求的證書(shū)。 如果它是由文件引用中的 --requestheader-client-ca-file 所簽署的 CA 證書(shū)之一簽名的, 則該請(qǐng)求將被視為潛在的合法請(qǐng)求。 然后,Kubernetes apiserver 檢查通用名稱(chēng) ?CN=? 是否是 ?--requestheader-allowed-names? 提供的列表中的名稱(chēng)之一。 如果名稱(chēng)允許,則請(qǐng)求被批準(zhǔn);如果不是,則請(qǐng)求被拒絕。

如果同時(shí)提供了 ?--client-ca-file? 和 ?--requestheader-client-ca-file?, 則首先檢查 ?--requestheader-client-ca-file? CA,然后再檢查?--client-ca-file?。 通常,這些選項(xiàng)中的每一個(gè)都使用不同的 CA(根 CA 或中間 CA)。 常規(guī)客戶(hù)端請(qǐng)求與 ?--client-ca-file? 相匹配,而聚合請(qǐng)求要與 ?--requestheader-client-ca-file? 相匹配。 但是,如果兩者都使用同一個(gè) CA,則通常會(huì)通過(guò) ?--client-ca-file? 傳遞的客戶(hù)端請(qǐng)求將失敗,因?yàn)?nbsp;CA 將與 ?--requestheader-client-ca-file? 中的 CA 匹配,但是通用名稱(chēng) ?CN=? 將不匹配 ?--requestheader-allowed-names? 中可接受的通用名稱(chēng)之一。 這可能導(dǎo)致你的 kubelet 和其他控制平面組件以及最終用戶(hù)無(wú)法向 Kubernetes apiserver 認(rèn)證。

因此,請(qǐng)對(duì)用于控制平面組件和最終用戶(hù)鑒權(quán)的 ?--client-ca-file? 選項(xiàng)和 用于聚合 apiserver 鑒權(quán)的 ?--requestheader-client-ca-file? 選項(xiàng)使用 不同的 CA 證書(shū)。

警告: 除非你了解風(fēng)險(xiǎn)和保護(hù) CA 用法的機(jī)制,否則 不要 重用在不同上下文中使用的 CA。

如果你未在運(yùn)行 API 服務(wù)器的主機(jī)上運(yùn)行 kube-proxy,則必須確保使用以下 ?kube-apiserver? 標(biāo)志啟用系統(tǒng):

--enable-aggregator-routing=true

注冊(cè) APIService 對(duì)象

你可以動(dòng)態(tài)配置將哪些客戶(hù)端請(qǐng)求代理到擴(kuò)展 apiserver。以下是注冊(cè)示例:

apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  name: <注釋對(duì)象名稱(chēng)>
spec:
  group: <擴(kuò)展 Apiserver 的 API 組名>
  version: <擴(kuò)展 Apiserver 的 API 版本>
  groupPriorityMinimum: <APIService 對(duì)應(yīng)組的優(yōu)先級(jí), 參考 API 文檔>
  versionPriority: <版本在組中的優(yōu)先排序, 參考 API 文檔>
  service:
    namespace: <拓展 Apiserver 服務(wù)的名字空間>
    name: <拓展 Apiserver 服務(wù)的名稱(chēng)>
  caBundle: <PEM 編碼的 CA 證書(shū),用于對(duì) Webhook 服務(wù)器的證書(shū)簽名>

APIService 對(duì)象的名稱(chēng)必須是合法的 路徑片段名稱(chēng)。

調(diào)用擴(kuò)展 apiserver

一旦 Kubernetes apiserver 確定應(yīng)將請(qǐng)求發(fā)送到擴(kuò)展 apiserver, 它需要知道如何調(diào)用它。

?service ?部分是對(duì)擴(kuò)展 apiserver 的服務(wù)的引用。 服務(wù)的名字空間和名字是必需的。端口是可選的,默認(rèn)為 443。 路徑配置是可選的,默認(rèn)為 ?/?。

下面是為可在端口 ?1234 ?上調(diào)用的擴(kuò)展 apiserver 的配置示例 服務(wù)位于子路徑 ?/my-path? 下,并針對(duì) ServerName ?my-service-name.my-service-namespace.svc? 使用自定義的 CA 包來(lái)驗(yàn)證 TLS 連接 使用自定義 CA 捆綁包的?my-service-name.my-service-namespace.svc?。

apiVersion: apiregistration.k8s.io/v1
kind: APIService
...
spec:
  ...
  service:
    namespace: my-service-namespace
    name: my-service-name
    port: 1234
  caBundle: "Ci0tLS0tQk...<base64-encoded PEM bundle>...tLS0K"
...


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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)