保護叢集
本文件涵蓋了與保護叢集免受意外或惡意訪問相關的主題,並提供了關於整體安全性的建議。
準備工作
你需要擁有一個 Kubernetes 叢集,並且 kubectl 命令列工具已配置為與你的叢集通訊。建議你在至少有兩個非控制平面主機節點的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用這些 Kubernetes 遊樂場之一
要檢查版本,請輸入
kubectl version
。
控制對 Kubernetes API 的訪問
由於 Kubernetes 完全由 API 驅動,因此控制和限制誰可以訪問叢集以及他們被允許執行哪些操作是第一道防線。
對所有 API 流量使用傳輸層安全 (TLS)
Kubernetes 期望叢集中的所有 API 通訊預設都使用 TLS 加密,並且大多數安裝方法都會允許建立必要的證書並分發給叢集元件。請注意,某些元件和安裝方法可能會透過 HTTP 啟用本地埠,管理員應熟悉每個元件的設定以識別潛在的不安全流量。
API 認證
在安裝叢集時,為 API 伺服器選擇一種與常見訪問模式匹配的認證機制。例如,小型、單使用者叢集可能希望使用簡單的證書或靜態 Bearer token 方式。大型叢集可能希望整合現有的 OIDC 或 LDAP 伺服器,以允許使用者細分為組。
所有 API 客戶端都必須經過認證,即使是基礎設施的一部分,如節點、代理、排程器和卷外掛。這些客戶端通常是服務賬號或使用 x509 客戶端證書,它們在叢集啟動時自動建立或作為叢集安裝的一部分進行設定。
請查閱認證參考文件獲取更多資訊。
API 授權
一旦經過認證,每個 API 呼叫也期望透過授權檢查。Kubernetes 提供了一個整合的基於角色的訪問控制 (RBAC) 元件,該元件將傳入的使用者或組與一組繫結到角色的許可權進行匹配。這些許可權將動詞(get、create、delete)與資源(pods、services、nodes)結合起來,並且可以是名稱空間範圍或叢集範圍的。提供了一組開箱即用的角色,這些角色根據客戶端可能希望執行的操作,提供了合理的預設職責分離。建議你結合使用節點和RBAC授權器,以及NodeRestriction准入外掛。
與認證一樣,簡單而廣泛的角色可能適用於小型叢集,但隨著更多使用者與叢集互動,可能需要將團隊分成不同的名稱空間,並使用更受限制的角色。
在授權方面,瞭解一個物件的更新如何導致其他地方的操作非常重要。例如,使用者可能無法直接建立 Pod,但允許他們建立代表他們建立 Pod 的 Deployment 將允許他們間接建立這些 Pod。同樣,從 API 中刪除一個節點將導致排程到該節點的 Pod 被終止並在其他節點上重新建立。開箱即用的角色在靈活性和常見用例之間取得了平衡,但應仔細審查更受限制的角色,以防止意外的許可權提升。如果開箱即用的角色不滿足你的需求,你可以為你的用例定製角色。
請查閱授權參考部分獲取更多資訊。
控制對 Kubelet 的訪問
Kubelet 暴露 HTTPS 端點,這些端點對節點和容器擁有強大的控制權。預設情況下,Kubelet 允許對該 API 進行未認證訪問。
生產叢集應啟用 Kubelet 認證和授權。
請查閱Kubelet 認證/授權參考獲取更多資訊。
在執行時控制工作負載或使用者的能力
Kubernetes 中的授權有意地保持高級別,側重於資源的粗粒度操作。更強大的控制措施以策略的形式存在,透過用例來限制這些物件如何作用於叢集本身和其他資源。
限制叢集上的資源使用
資源配額限制了分配給名稱空間的資源數量或容量。這通常用於限制名稱空間可以分配的 CPU、記憶體或持久磁碟量,但也可以控制每個名稱空間中存在的 Pod、Service 或 Volume 的數量。
限制範圍限制了上述某些資源的最大或最小大小,以防止使用者請求記憶體等常用保留資源的不合理高或低值,或者在未指定預設值時提供預設限制。
控制容器以哪些許可權執行
Pod 定義包含一個安全上下文,它允許 Pod 請求以特定 Linux 使用者身份(如 root)在節點上執行的訪問許可權,請求執行特權或訪問主機網路的訪問許可權,以及其他控制措施,否則這些控制措施將允許 Pod 在託管節點上不受限制地執行。
你可以配置Pod 安全准入,以在名稱空間中強制使用特定的Pod 安全標準,或檢測違規行為。
通常,大多數應用程式工作負載需要對主機資源進行有限的訪問,以便它們可以作為 root 程序(uid 0)成功執行,而無需訪問主機資訊。但是,考慮到與 root 使用者相關的特權,你應該編寫應用程式容器以非 root 使用者身份執行。同樣,希望防止客戶端應用程式逃離其容器的管理員應應用基線或受限Pod 安全標準。
阻止容器載入不需要的核心模組
在某些情況下,例如當連線了硬體或掛載了檔案系統時,Linux 核心會自動從磁碟載入核心模組。對於 Kubernetes 來說,即使是非特權程序也可以透過建立適當型別的 socket 導致某些與網路協議相關的核心模組被載入。這可能允許攻擊者利用管理員認為未使用的核心模組中的安全漏洞。
要防止特定模組自動載入,你可以將其從節點中解除安裝,或新增規則來阻止它們。在大多數 Linux 發行版上,你可以透過建立檔案(例如 /etc/modprobe.d/kubernetes-blacklist.conf
)幷包含以下內容來實現
# DCCP is unlikely to be needed, has had multiple serious
# vulnerabilities, and is not well-maintained.
blacklist dccp
# SCTP is not used in most Kubernetes clusters, and has also had
# vulnerabilities in the past.
blacklist sctp
要更通用地阻止模組載入,可以使用 Linux 安全模組(如 SELinux)完全拒絕容器的 module_request
許可權,從而阻止核心在任何情況下為容器載入模組。(Pod 仍然能夠使用手動載入的模組,或核心代表某些更高許可權程序載入的模組。)
限制網路訪問
名稱空間的網路策略允許應用程式作者限制其他名稱空間中的哪些 Pod 可以訪問其名稱空間中的 Pod 和埠。許多受支援的 Kubernetes 網路提供商現在都遵守網路策略。
配額和限制範圍也可以用於控制使用者是否可以請求節點埠或負載均衡服務,這在許多叢集中可以控制這些使用者應用程式是否在叢集外部可見。
可能還有其他保護措施,根據外掛或環境來控制網路規則,例如每節點防火牆、物理隔離叢集節點以防止交叉通訊,或高階網路策略。
限制雲元資料 API 訪問
雲平臺(AWS、Azure、GCE 等)通常會在本地向例項公開元資料服務。預設情況下,這些 API 可由在例項上執行的 Pod 訪問,並且可以包含該節點的雲憑據或 kubelet 憑據等預置資料。這些憑據可用於在叢集內或同一賬戶下的其他雲服務中進行許可權提升。
在雲平臺上執行 Kubernetes 時,限制授予例項憑據的許可權,使用網路策略限制 Pod 對元資料 API 的訪問,並避免使用預置資料來傳遞 Secret。
控制 Pod 可以訪問哪些節點
預設情況下,對 Pod 可以在哪些節點上執行沒有限制。Kubernetes 為終端使用者提供了一套豐富的策略來控制 Pod 在節點上的放置以及基於汙點的 Pod 放置和驅逐。對於許多叢集來說,使用這些策略來分離工作負載可以是一種作者採用或透過工具強制執行的約定。
作為管理員,可以使用 Beta 版准入外掛 PodNodeSelector
來強制名稱空間中的 Pod 預設或要求特定的節點選擇器,如果終端使用者無法修改名稱空間,這可以強烈限制特定工作負載中所有 Pod 的放置位置。
保護叢集元件免受入侵
本節介紹了一些用於保護叢集免受入侵的常見模式。
限制對 etcd 的訪問
對 API 的 etcd 後端的寫入許可權等同於獲得整個叢集的 root 許可權,而讀取許可權可以快速用於許可權提升。管理員應該始終使用從 API 伺服器到 etcd 伺服器的強憑據,例如透過 TLS 客戶端證書進行相互認證,並且通常建議將 etcd 伺服器隔離在防火牆後面,只有 API 伺服器才能訪問。
注意
允許叢集中的其他元件以讀寫訪問整個鍵空間的方式訪問主 etcd 例項,等同於授予 cluster-admin 許可權。強烈建議為非主元件使用單獨的 etcd 例項,或者使用 etcd ACLs 限制對鍵空間子集的讀寫訪問。啟用審計日誌
審計日誌是一個 Beta 功能,它記錄 API 執行的操作,以便在發生入侵時進行後續分析。建議啟用審計日誌並將審計檔案存檔到安全伺服器上。
限制對 Alpha 或 Beta 功能的訪問
Alpha 和 Beta Kubernetes 功能處於積極開發中,可能存在導致安全漏洞的限制或錯誤。在評估 Alpha 或 Beta 功能可能提供的價值時,始終要權衡其對安全狀況的潛在風險。如有疑問,請停用你不使用的功能。
頻繁輪換基礎設施憑證
秘密或憑證的生命週期越短,攻擊者利用該憑證就越困難。設定較短的證書生命週期並自動化其輪換。使用可以控制頒發令牌可用時長的認證提供商,並在可能的情況下使用較短的生命週期。如果你在外部整合中使用服務賬號令牌,請計劃頻繁輪換這些令牌。例如,一旦引導階段完成,用於設定節點的引導令牌應該被撤銷或移除其授權。
在啟用第三方整合之前進行審查
許多 Kubernetes 第三方整合可能會改變叢集的安全配置檔案。在啟用整合時,始終在授予其訪問許可權之前審查擴充套件請求的許可權。例如,許多安全整合可能會請求檢視叢集中所有 Secret 的許可權,這實際上使該元件成為叢集管理員。如有疑問,請儘可能將整合限制為在單個名稱空間中執行。
如果建立 Pod 的元件能夠在像 kube-system
這樣的名稱空間中建立 Pod,它們也可能擁有意想不到的強大能力,因為這些 Pod 可以獲得服務賬號 Secret 的訪問許可權,或者在這些服務賬號被授予寬鬆的PodSecurityPolicies訪問許可權時以提升的許可權執行。
如果你使用Pod 安全准入並允許任何元件在允許特權 Pod 的名稱空間中建立 Pod,這些 Pod 可能會逃離其容器並使用這種擴大的訪問許可權來提升其特權。
你不應允許不受信任的元件在任何系統名稱空間(名稱以 kube-
開頭的名稱空間)或任何允許許可權提升的名稱空間中建立 Pod。
對靜態資料進行加密
通常,etcd 資料庫將包含透過 Kubernetes API 可訪問的任何資訊,並可能使攻擊者對叢集的狀態獲得重要可見性。始終使用經過充分審查的備份和加密解決方案來加密備份,並考慮在可能的情況下使用全盤加密。
Kubernetes 支援可選的靜態加密,用於 Kubernetes API 中的資訊。這可以確保當 Kubernetes 儲存物件資料(例如,Secret
或 ConfigMap
物件)時,API 伺服器會寫入物件的加密表示。這種加密意味著即使有人訪問了 etcd 備份資料也無法檢視這些物件的內容。在 Kubernetes 1.34 中,你還可以加密自定義資源;CustomResourceDefinitions 中定義的擴充套件 API 的靜態加密是作為 v1.26 版本的一部分新增到 Kubernetes 中的。
接收安全更新警報和報告漏洞
加入 kubernetes-announce 組以獲取安全公告的電子郵件。有關如何報告漏洞的更多資訊,請參閱安全報告頁面。
下一步
- 有關 Kubernetes 安全指南的更多資訊,請參閱安全清單。
- Seccomp 節點參考