Kubernetes 與外部身份驗證系統整合對於企業環境至關重要。本文詳細說明如何使用 OpenID Connect(OIDC)將 KinD 叢集與 Active Directory Federation Services(ADFS)整合,實作根據角色的存取控制(RBAC)和單點登入(SSO)。此方案確保使用者能透過 ADFS 驗證身份後,安全地存取 Kubernetes 叢集資源,包含 Kubernetes Dashboard 和 kubectl 命令列工具。文章涵蓋了 ADFS 作為 OIDC 提供者的設定、Kubernetes API 伺服器的 OIDC 組態、AD 群組與 RBAC 的對映,以及 OpenUnison 的佈署流程,以簡化整合流程並提升安全性。透過 OpenUnison,使用者登入後會在叢集內建立對應的使用者物件,並取得 kubectl 組態和 Dashboard 的存取許可權,同時支援重要的安全機制,例如 refresh token 和 session timeout。
組態 KinD 使用 OpenID Connect
在我們的示例佈署中,我們將使用來自客戶 FooWidgets 的場景。Foowidgets 擁有一個 Kubernetes 叢集,希望透過 OIDC 進行整合。所提出的解決方案需要滿足以下需求:
需求詳解
Kubernetes 必須使用我們的中央身份驗證系統 Active Directory Federation Services。
- 這意味著我們需要將 Kubernetes 組態為使用 Active Directory Federation Services(ADFS)作為 OpenID Connect(OIDC)身份提供者。
我們需要能夠將 Active Directory 群組對映到我們的 RBAC RoleBinding 物件。
- 這要求我們在 Kubernetes 中組態 OIDC 認證,以便將 Active Directory 中的群組資訊對映到 Kubernetes 的 RBAC(根據角色的存取控制)RoleBinding 中。
使用者需要存取 Kubernetes Dashboard。
- 為了滿足此需求,我們需要確保 Kubernetes Dashboard 組態為使用 OIDC 認證,並且使用者可以透過 ADFS 登入。
使用者需要能夠使用 CLI。
- 這意味著
kubectl命令列工具需要組態為使用 OIDC 認證,以便使用者可以安全地存取叢集。
- 這意味著
必須滿足所有企業合規要求。
- 這包括確保身份驗證流程符合企業的安全和合規標準,例如使用多因素身份驗證、適當的許可權控制等。
解決方案概述
為了滿足上述需求,我們將採取以下步驟:
組態 ADFS 為 OIDC 身份提供者:確保 ADFS 可以作為 OIDC 身份提供者,並為 Kubernetes 提供必要的組態引數,如簽發者 URL、使用者端 ID 等。
組態 Kubernetes 使用 OIDC:更新 Kubernetes 組態,使其使用 ADFS 作為 OIDC 身份提供者。這涉及在 Kubernetes API 伺服器組態中指定 OIDC 相關引數。
apiVersion: v1 kind: Config clusters: - name: my-cluster cluster: server: https://your-kubernetes-server.com certificate-authority-data: <base64 encoded CA cert> users: - name: oidc-user user: exec: apiVersion: client.authentication.k8s.io/v1beta1 command: kubectl args: - oidc-login - get-token - --oidc-issuer-url=https://your-adfs-server.com/adfs - --oidc-client-id=kubernetes-client-id # 其他必要的 oidc-login 引數 contexts: - context: cluster: my-cluster user: oidc-user name: oidc-context current-context: oidc-context內容解密:
apiVersion和kind定義了組態檔案的版本和型別。clusters部分定義了 Kubernetes 叢集的資訊,包括 API 伺服器的地址和憑證授權單位(CA)的憑證。users部分定義瞭如何進行身份驗證。在此例中,我們使用了oidc-login外掛來處理 OIDC 認證流程。exec部分指定了用於取得 OIDC 令牌的命令和引數。--oidc-issuer-url和--oidc-client-id是必要的引數,分別指定了 OIDC 簽發者 URL 和使用者端 ID。
對映 Active Directory 群組到 RBAC RoleBinding:建立 Kubernetes 的 RoleBinding 或 ClusterRoleBinding 物件,以將 Active Directory 中的群組對映到 Kubernetes 中的角色。
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: oidc-group-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: Group name: "oidc-group-name" namespace: default內容解密:
apiVersion和kind指定了物件的 API 版本和型別。metadata部分提供了物件的中繼資料,如名稱。roleRef部分定義了要繫結的角色,在此例中是cluster-admin。subjects部分列出了要繫結到角色的實體,在此例中是一個名為oidc-group-name的群組。
組態 Kubernetes Dashboard 使用 OIDC:確保 Kubernetes Dashboard 組態為使用相同的 OIDC 身份提供者,以便使用者可以透過 ADFS 登入。
驗證和測試:完成上述組態後,進行充分的測試以確保所有功能正常運作,包括
kubectl命令列工具和 Kubernetes Dashboard 的存取。
透過遵循上述步驟,FooWidgets 可以成功地將其 Kubernetes 叢集與 ADFS 整合,使用 OIDC 實作安全、合規的身份驗證和授權管理。
將驗證整合到您的叢集
使用Active Directory Federation Services
大多數企業使用微軟的Active Directory來儲存使用者資訊和憑證。根據企業規模的不同,使用者可能分佈在多個網域或林中。如果您的身份提供者(IdP)與微軟的Kerberos環境整合良好,它可能知道如何導航這些不同的系統。然而,大多數非微軟的應用程式(包括大多數身份提供者)並不具備此能力。Active Directory Federation Services(ADFS)是微軟的IdP,支援SAML2和OpenID Connect,並且能夠導航企業實作中的網域和林。在許多大型企業中,這是一種常見的解決方案。
選擇SAML2或OpenID Connect
在使用ADFS時,下一個決定是選擇SAML2還是OpenID Connect。在撰寫本文時,SAML2更容易實作,大多數使用ADFS的企業環境都傾向於使用SAML2。SAML2的另一個好處是,它不需要在叢集和ADFS伺服器之間建立連線;所有重要的資訊都透過使用者的瀏覽器傳輸。這減少了為了讓叢集正常運作而需要在防火牆上設定的規則。
將Active Directory群組對映到RBAC RoleBindings
這在我們開始討論授權時將變得非常重要。這裡需要注意的是,ADFS有能力將使用者的群組成員資格放入SAML斷言中,我們的叢集隨後可以消費這些資訊。
Kubernetes儀錶板存取
儀錶板是快速存取叢集資訊和進行快速更新的有力工具。當正確佈署時,儀錶板不會產生任何安全問題。正確的佈署方式是賦予其零許可權,而是依賴使用者的自身憑證。我們將透過反向代理來實作這一點,它在每次請求中注入使用者的OIDC令牌,儀錶板隨後將在對API伺服器發出呼叫時使用該令牌。使用這種方法,我們將能夠像對待其他網頁應用程式一樣,對儀錶板的存取進行相同的約束。
為什麼不使用kubectl內建代理和埠轉發?
有幾個原因說明為什麼使用kubectl內建代理和埠轉發不是存取儀錶板的好策略。許多企業不會在本機安裝CLI工具,這迫使您使用跳躍主機來存取像Kubernetes這樣的特權系統,這意味著埠轉發將無法運作。即使您可以在本機執行kubectl,在迴環地址(127.0.0.1)上開啟一個埠也意味著系統上的任何東西都可以使用它,而不僅僅是您的瀏覽器。雖然瀏覽器有控制措施來防止您使用惡意指令碼存取迴環地址上的埠,但這並不能阻止您工作站上的其他東西。最後,這只是一個不好的使用者經驗。
Kubernetes CLI存取
大多數開發人員希望能夠存取kubectl和其他依賴於kubectl組態的工具。例如,Visual Studio Code Kubernetes外掛程式不需要任何特殊的組態,它只是使用kubectl內建的組態。大多數企業嚴格限制您可以安裝的二進位制檔案,因此我們希望盡量減少需要安裝的額外工具和外掛程式。
企業合規要求
作為雲原生應用程式並不意味著您可以忽略企業的合規要求。大多數企業都有諸如20分鐘閒置逾時、可能需要對特權存取進行多因素驗證等要求。我們實施的任何解決方案都必須透過所需的控制表格才能上線。此外,不言而喻,所有東西都需要加密(我確實是指所有東西)。
統合所有內容
為了滿足這些要求,我們將使用OpenUnison。它具有與Kubernetes、儀錶板、CLI和SAML2身份提供者(如ADFS)協同工作的預建組態。它也非常快速佈署,因此我們不需要專注於提供者特定的實作細節,而是專注於Kubernetes的組態選項。我們的架構將如下所示:
圖7.2 – 驗證架構
此圖示展示了我們的驗證架構。 圖表翻譯: 圖7.2展示了我們的驗證架構,包括OpenUnison、Kubernetes叢集和SAML2身份提供者之間的互動關係。
對於我們的實作,我們將使用兩個主機名:
- k8s.apps.X-X-X-X.nip.io:存取OpenUnison入口網站,我們將在此啟動登入並取得令牌
- k8sdb.apps.X-X-X-X.nip.io:存取Kubernetes儀錶板
nip.io的作用
nip.io是一個公共DNS服務,它將從嵌入在您的主機名中的IP位址傳回該位址。在實驗室環境中,這非常有用,因為設定DNS可能會很麻煩。在我們的例子中,X-X-X-X是您的Docker主機的IP。
組態 KinD 使用 OpenID Connect
當使用者嘗試存取 https://k8s.apps.X-X-X-X.nip.io/ 時,他們將被重新導向至 ADFS,以收集他們的使用者名稱和密碼(甚至可能需要多因素身份驗證令牌)。ADFS 將產生一個斷言,該斷言將被數位簽署並包含使用者的唯一 ID 以及他們的群組分配。這個斷言與我們之前檢查過的 id_token 類別似,但不是 JSON 格式,而是 XML。
斷言被傳送到使用者的瀏覽器中的一個特殊網頁,該網頁包含一個表單,該表單將自動將斷言提交回 OpenUnison。在此時,OpenUnison 將在 OpenUnison 名稱空間中建立使用者物件以儲存使用者的資訊並建立 OIDC 會話。
早些時候,我們描述了 Kubernetes 沒有使用者物件的事實。Kubernetes 允許您使用自定義資源定義(CRD)擴充套件基本 API。OpenUnison 定義了一個使用者 CRD,以幫助實作高用性並避免需要資料函式庫來儲存狀態。這些使用者物件不能用於 RBAC。
一旦使用者登入 OpenUnison,他們就可以獲得 kubectl 組態以使用 CLI 或使用 Kubernetes 儀錶板(https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/)從瀏覽器存取叢集。一旦使用者準備就緒,他們就可以登出 OpenUnison,這將結束他們的會話並使他們的 refresh_token 無效,使他們無法在再次登入之前使用 kubectl 或儀錶板。如果他們在沒有登出的情況下離開桌子去吃午餐,當他們傳回時,他們的 refresh_token 將已過期,因此在再次登入之前無法與 Kubernetes 互動。
現在我們已經瞭解了使用者如何登入和與 Kubernetes 互動,我們將佈署 OpenUnison 並將其整合到叢集中以進行身份驗證。
佈署 OIDC
我們提供了兩個安裝指令碼來自動化佈署步驟。這些指令碼 install-oidc-step1.sh 和 install-oidc-step2.sh 位於本文的 GitHub 儲存函式庫中的 chapter7 目錄中。
重要注意事項
如果您使用指令碼安裝 OIDC,您必須遵循此過程以成功佈署:
- 執行
./install-oidc-step1.sh指令碼。 - 按照「註冊 SAML2 測試實驗室」部分中的步驟註冊 SAML2 測試實驗室。
- 執行
./install-oidc-step2.sh指令碼以完成 OIDC 佈署。
使用 OpenUnison 將 OIDC 佈署到 Kubernetes 叢集是一個五步驟的過程:
- 佈署儀錶板。
- 佈署 OpenUnison 操作員。
- 建立秘密。
- 建立
values.yaml檔案。 - 佈署圖表。
讓我們一步一步地執行這些步驟。
佈署 OpenUnison
儀錶板是許多使用者流行的功能。它提供了一個快速檢視資源的檢視,而無需使用 kubectl CLI。多年來,它因安全性問題而受到一些負面報導,但正確佈署時,它非常安全。大多數您可能讀到或聽到的故事都來自未正確設定的儀錶板佈署。我們將在第 9 章「保護 Kubernetes 儀錶板」中介紹這個主題。
- 首先,我們將從 https://github.com/kubernetes/dashboard 佈署儀錶板:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml
內容解密:
此命令用於從指定的 URL 下載 Kubernetes 儀錶板的 YAML 組態檔案,並將其應用於目前的 Kubernetes 叢集中。這樣就佈署了 Kubernetes 儀錶板。
namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created
- 接下來,我們需要將包含 OpenUnison 的儲存函式庫新增到我們的 Helm 清單中。要新增 Tremolo 圖表儲存函式庫,請使用
Helm repo add命令:
helm repo add tremolo https://nexus.tremolo.io/repository/Helm/
內容解密:
此命令用於新增 Tremolo Helm 儲存函式庫到本地 Helm 組態中。這樣就可以使用 Helm 從該儲存函式庫安裝圖表。
"tremolo" has been added to your repositories
- 新增後,您需要使用
Helm repo update命令更新儲存函式庫:
helm repo update
內容解密:
此命令用於更新本地 Helm 儲存函式庫的快取,以確保您擁有最新的圖表版本。
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "tremolo" chart repository
Update Complete. Happy Helming!
- 首先,我們要在一個名為
openunison的新名稱空間中佈署 OpenUnison。我們需要在佈署 Helm 圖表之前建立名稱空間:
kubectl create ns openunison
內容解密:
此命令用於在目前的 Kubernetes 叢集中建立一個名為 openunison 的新名稱空間。
namespace/openunison created
- 建立名稱空間後,您可以使用 Helm 將圖表佈署到名稱空間中。要使用 Helm 安裝圖表,請使用
helm install <name> <chart> <options>:
helm install openunison tremolo/openunison-operator --namespace openunison
內容解密:
此命令用於在 openunison 名稱空間中安裝 openunison-operator Helm 圖表。這樣就佈署了 OpenUnison 操作員。
NAME: openunison
LAST DEPLOYED: Fri Apr 17 15:04:50 2020
NAMESPACE: openunison
STATUS: deployed
REVISION: 1
TEST SUITE: None
操作員需要幾分鐘時間來完成佈署。
重要注意事項
操作員是一種由 CoreOS 開創的概念,旨在封裝管理員可能執行的許多工,以便自動化。操作員透過監視特定 CRD 的變化並相應地採取行動來實作。OpenUnison 操作員會監視 OpenUnison 型別的物件並建立所需的任何物件。建立了一個包含 PKCS12 檔案的秘密;Deployment、Service 和 Ingress 物件也被建立。當您對 OpenUnison 物件進行更改時,操作員會根據需要對 Kubernetes 物件進行更新。例如,如果您更改了 OpenUnison 物件中的映像,操作員會更新 Deployment,這會觸發 Kubernetes 推出新的 Pod。對於 SAML,操作員還會監視後設資料,以便在後設資料更改時匯入更新的憑證。