M Sections/4.Architecture.tex => Sections/4.Architecture.tex +20 -7
@@ 49,9 49,9 @@ CSKloud 達成一代願景中的開放使用者直接存取 Kubernetes API,使
\begin{onehalfspacing}
\begin{itemize}
- \item PodSecurity
- \item PodTolerationRestriction
- \item AlwaysPullImages
+ \item \verb|PodSecurity|
+ \item \verb|PodTolerationRestriction|
+ \item \verb|AlwaysPullImages|
\end{itemize}
\end{onehalfspacing}
@@ 61,23 61,36 @@ CSKloud 達成一代願景中的開放使用者直接存取 Kubernetes API,使
即使並未關閉任何預設的隔離機制,對於一般的工作負載,我們也應遵循最小權限原則,例如以非 root 的身份執行等,針對容器內的執行身份,在 Pod 內也可以進行設定。另外,Kubernetes 除了傳統容器隔離技術外,也支援進一步設定其餘的安全與 mandatory access control (MAC)\footnote{MAC: 針對特定行程的操作與其目標(如讀寫特定檔案、使用特定網路資源)進行限制的機制。} 機制,例如 seccomp、SELinux、AppArmor 等。
-面對如此多元的安全性相關設定,以及其產生的無數組合,我們需要一個標準評判 Pod 的安全性。Kubernetes 提出了 Pod Security Standards,並且將可能的設定分為三個政策層級:privileged、baseline 與 restricted。Privileged 可以放寬隔離機制,baseline 包含未特別指定任何設定的場景,restricted 則是進一步要求提升安全性設定。對於執行這些政策檢查,Kubernetes 提供了 PodSecurity admission controller。
+面對如此多元的安全性相關設定,以及其產生的無數組合,我們需要一個標準評判 Pod 的安全性。Kubernetes 提出了 Pod Security Standards,並且將可能的設定分為三個政策層級:privileged、baseline 與 restricted。Privileged 可以放寬隔離機制,baseline 包含未特別指定任何設定的場景,restricted 則是進一步要求提升安全性設定。對於執行這些政策檢查,Kubernetes 提供了 \verb|PodSecurity| admission controller。
-大多數政策類型的 admission controllers,包含 PodSecurity,設計上皆能夠以 Namespace 為單位設定政策,為了確保平台安全性,我們針對使用者的 namespaces 實施 restricted 政策。
+大多數政策類型的 admission controllers,包含 \verb|PodSecurity|,設計上皆能夠以 Namespace 為單位設定政策,為了確保平台安全性,我們針對使用者的 namespaces 實施 restricted 政策。
\subsection{PodTolerationRestriction}
+\label{sec:PodTolerationRestriction}
在典型的 Kubernetes 叢集規劃下,節點分為兩大類:control plane 與 worker nodes。Control plane 負責運行叢集本身的元件,例如 kube-apiserver 與各式 controllers 等;而 worker nodes 負責運行一般的工作負載。Control plane 的元件通常也是以容器的形式部屬,而其節點也會納入叢集本身的管轄下,然而我們不希望 control plane 節點運行一般工作負載,避免影響到叢集控制邏輯的運行。Kubernetes 提供 taints 機制,用來標示 Node 的屬性,以及屬性應帶來的效果。以這個場景為例,我們標示這個 Node 為 control plane 並且不允許納入排程。此外,taints 機制同時也拿來自動標記異常的節點,例如節點資源即將耗盡的場景,並且藉此調整排程機制,優先使用其他節點。
與 taints 相對,Pod 可以設定 tolerations 來抑制 taints 的效果。例如在擴充 Kubernetes API 的場景,我們需要部屬實做自訂 resource 種類邏輯的 controller,這個 controller 屬於叢集控制邏輯的一部分,我們會希望規劃在 control plane 運行。在部屬此 controller 時,我們便會設定前述 taints 相對的 tolerations 解除限制,並且搭配其他排程設定強制排程至 control plane。
-為了避免一般使用者濫用這個機制,我們採用 PodTolerationRestriction 來限制使用者能填寫的 tolerations。PodTolerationRestriction 可以針對 Namespace 設定其中 Pods 可使用的 tolerations 白名單,我們將其限制為只允許系統內部會預設填入的項目。
+為了避免一般使用者濫用這個機制,我們採用 \verb|PodTolerationRestriction| 來限制使用者能填寫的 tolerations。\verb|PodTolerationRestriction| 可以針對 Namespace 設定其中 Pods 可使用的 tolerations 白名單,我們將其限制為只允許系統內部會預設填入的項目。
\subsection{AlwaysPullImages}
在 Kubernetes 下,容器 images 的下載策略(\verb|imagePullPolicy| 欄位)有三種:\verb|Always|、\verb|IfNotPresent| 與 \verb|Never|。\verb|Always| 在啟動容器之前總是會檢查容器的 image 的更新,若有更新即重新下載;\verb|IfNotPresent| 是當節點上尚未有該 image 時才會下載;\verb|Never| 則是不主動下載,仰賴節點上的存放狀況。在容器結束執行後,Kubernetes 並不會主動刪除 image 資料,而是只有在儲存空間有壓力時才會刪除,藉此減少下載 image 的負擔。
-在容器生態下,images 主要可分為公開存取以及私人的兩種。下載公開存取的 images 不須經過身份驗證,而私人的 images 則是需要。由於 \verb|IfNotPresent| 與 \verb|Never| 在節點已經存有指定 image 時,不會進行任何更新檢查,因此也不需進行身份驗證,如此在共用叢集的狀況下,便形成了一個可能用來存取他人遺留在節點上的私人 images 的途徑。對此,我們採用 AlwaysPullImages 將下載策略一律複寫為 \verb|Always|。
+在容器生態下,images 主要可分為公開存取以及私人的兩種。下載公開存取的 images 不須經過身份驗證,而私人的 images 則是需要。由於 \verb|IfNotPresent| 與 \verb|Never| 在節點已經存有指定 image 時,不會進行任何更新檢查,因此也不需進行身份驗證,如此在共用叢集的狀況下,便形成了一個可能用來存取他人遺留在節點上的私人 images 的途徑。對此,我們採用 \verb|AlwaysPullImages| 將下載策略一律複寫為 \verb|Always|。
+
+\subsection{CEL}
+
+對於防止使用者在 control plane 上運行容器,\ref{sec:PodTolerationRestriction} \verb|PodTolerationRestriction| 仍然不足。預設在 control plane 上的 taint 只有防止排程,使用者實際上可以繞過排程直接指定節點。一個解決方法是修改 control plane 上的 taint,改為防止執行而非單純防止排程,但由於這個 taint 由 Kubernetes 安裝工具提供,實際上已被廣泛使用,修改容易造成管理上的負擔,若欠缺注意更有可能造成部屬叢集元件時意外安排到 worker nodes 上,間接影響叢集服務品質。於是我們採取另外撰寫邏輯,防止使用者繞過排程。這同時也有附加的優勢:使用者提交的工作負載一律會經過平台的排程機制,使資源的充分、平均利用更有保障。
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=\textwidth]{assets/code-pod-policy.png}
+ \caption{以 CEL 防止使用者繞過排程機制}
+\end{figure}
+
+% TODO explain
\section{權限開通實做}
A assets/code-pod-policy.png => assets/code-pod-policy.png +0 -0