M Sections/2.Backgrounds.tex => Sections/2.Backgrounds.tex +1 -1
@@ 68,7 68,7 @@ Kubernetes 主要透過兩個機制達成使用者的存取控制,其一是 RB
Kubernetes 內建許多 admission controllers,其中一些用來實做基本功能並預設啟用,如資源配額的部份邏輯。另外也有些預設停用的 admission controllers,提供給管理者進行平台加固或者調整行為使用。
-對於內建的 admission controllers 不敷使用的場合,Kubernetes 提供兩個機制讓管理者進一步自訂邏輯:webhooks 與 Common Expression Language (簡稱 CEL)。Webhooks 透過呼叫管理者提供的 HTTP API 達成,支援 mutating 與 validating,可以透過任何能架設 HTTP API 的語言編寫,在生態系上已經有多個框架可以協助開發,例如:Open Policy Agent 與 Kyverno 等。CEL 為一結構資料處理語言,常用以使軟體功能可程式化,Kubernetes 將其導入作為延伸 kube-apiserver 邏輯的手段。以 Kubernetes 1.31 而言,目前只有 validating 進入穩定狀態,對 mutating 的支援仍在測試階段 (alpha)。相對於 webhooks,使用 CEL 可以直接在 kube-apiserver 上執行邏輯,省略了呼叫 HTTP API 的網路溝通,減少造成的延遲影響與管理負擔,但能夠進行的操作受限於 Kubernetes 對其執行環境提供的函式庫。
+對於內建的 admission controllers 不敷使用的場合,Kubernetes 提供兩個機制讓管理者進一步自訂邏輯:webhooks 與 Common Expression Language\cite{cel} (簡稱 CEL)。Webhooks 透過呼叫管理者提供的 HTTP API 達成,支援 mutating 與 validating,可以透過任何能架設 HTTP API 的語言編寫,在生態系上已經有多個框架可以協助開發,例如:Open Policy Agent 與 Kyverno 等。CEL 為一結構資料處理語言,常用以使軟體功能可程式化,Kubernetes 將其導入作為延伸 kube-apiserver 邏輯的手段。以 Kubernetes 1.31 而言,目前只有 validating 進入穩定狀態,對 mutating 的支援仍在測試階段 (alpha)。相對於 webhooks,使用 CEL 可以直接在 kube-apiserver 上執行邏輯,省略了呼叫 HTTP API 的網路溝通,減少造成的延遲影響與管理負擔,但能夠進行的操作受限於 Kubernetes 對其執行環境提供的函式庫。
\section{Helm}
M Sections/4.Architecture.tex => Sections/4.Architecture.tex +45 -48
@@ 99,7 99,7 @@ Kubernetes 中容器 images 的下載策略(\verb|imagePullPolicy| 欄位)
\section{權限開通實做}
\label{sec:provisioner}
-使用者權限開通的主要流程為:建立一個 Namespace,增加 admission controllers 政策相關標記,對其設定配額,最終調整 RBAC 授予使用者此 Namespace 下的權限。為了將其自動化,我們規劃為拓展 Kubernetes API,使用自訂 resource 種類進行實做,此種類稱為 User。使用者登入網頁界面時會自動嘗試創立代表自身的 User,若已存在代表已開通完成不須另外動作。面對新創立的 User,我們撰寫的 controller 會實行上述的開通流程。
+使用者權限開通的主要流程為:建立一個 Namespace,增加 admission controllers 政策相關標記,對其設定資源配額,最終調整 RBAC 授予使用者此 Namespace 下的權限。為了將其自動化,我們規劃為拓展 Kubernetes API,使用自訂 resource 種類進行實做,此種類稱為 User。使用者登入網頁界面時會自動嘗試創立代表自身的 User,若已存在代表已開通完成不須另外動作,而面對新創立的 User,我們撰寫的 controller 會實行上述的開通流程。
\begin{figure}[htb]
\centering
@@ 107,58 107,57 @@ Kubernetes 中容器 images 的下載策略(\verb|imagePullPolicy| 欄位)
\caption{權限開通自訂 resource 種類 User spec 範例}
\end{figure}
-每個使用者會創立一個與其系計中帳號名稱相同的 User,其中 \verb|spec| 的 \verb|profile| 欄位帶有其身份組資訊,由網頁界面自動判斷填入。身份組影響對齊開放配額的大小。對於創立代表自身 User 所需的權限,我們透過 RBAC 允許所有使用者創立 User,再透過 admission control 將其限制名稱必須與身份相同。分兩階段設計有助於簡化 RBAC 實做,使 RBAC 實做上不須枚舉使用者名稱一一事先對應,同時也減少叢集上相關設定的 resources 個數,有助於減少管理上的負擔。對於 \verb|profile| 欄位的真實性,我們一樣透過 admission control 與身份資訊比對。
+每個使用者會創立一個與其系計中帳號名稱相同的 User,其中 \verb|spec| 的 \verb|profile| 欄位帶有身份組資訊,影響資源配額的大小,由網頁界面自動判斷填入。對於創立代表自身 User 所需的權限,我們透過 RBAC 允許所有使用者創立 User,再透過 admission control 將其限制名稱必須與身份相同。兩階段的設計有助於簡化 RBAC 實做,使 RBAC 實做上不須枚舉使用者名稱一一事先對應,同時也大幅降低叢集上相關設定的 resources 個數,有助於減少管理上的負擔。對於 \verb|profile| 欄位的真實性,我們一樣透過 admission control 與身份資訊比對證實。
-實際上以 \verb|profile| 欄位而言,還有一個可行的方法,即是以 mutating admission control 層由叢集端判斷寫入,而不用仰賴網頁界面邏輯。這個方式目前有個缺點:admission control 邏輯我們希望透過 CEL 實做,而以 CEL 實做 mutating 雖然已有相關機制,現今仍未進入穩定狀態。另外,透過網頁界面預填也使得 admission control 層只須實做 validating,相對於 mutating,validating 因不能修改 resource 內容,較為單純且有平行化處理的空間,在效能與管理上皆有些許優勢。
+就 \verb|profile| 欄位而言,還有另一個可行的方法,即是以 mutating admission control 由叢集端判斷寫入,而不仰賴網頁界面邏輯。這個方式目前有個缺點:admission control 邏輯我們希望透過 CEL 實做,而以 CEL 實做 mutating 雖然已有相關機制,現今仍未進入穩定狀態。另外,透過網頁界面預填也使得 admission control 層只須實做 validating,相對於 mutating,validating 因不能修改 resource 內容,較為單純且有平行化處理的空間,在效能與管理上皆有些許優勢。
-對於管理需求,我們在 admission control 實做保留了彈性,若操作者為管理者即不加以限制。管理者可以自行創立代表他人的 User,為其修改身份組,提供人工處理政策上例外的空間。另外,由 User 所產生的每個 resource 皆會採用 Kubernetes 的 \verb|ownerReferences| 機制。\verb|ownerReferences| 表現了一個 resource 被一個 owner resource 所管轄,當 owner resource 被刪除時,Kubernetes 的回收機制也會一併刪除此 resource。在我們的場景,由於使用者的資料皆為於個人專屬的 Namespace 底下,而 User 又為此 Namespace 的 owner resource,於是當使用者行為極端異常,管理者需要對其制裁時,只須刪除其 User 變可以徹底清除此使用者的所作所為。
+對於管理需求,我們在 admission control 實做保留了彈性,若操作者為管理者即不加以限制。管理者可以自行創立代表他人的 User,為其修改身份組,提供人工處理政策上例外的空間。另外,由 User 所產生的每個 resource 皆會採用 Kubernetes 的 \verb|ownerReferences| 機制。\verb|ownerReferences| 表現了一個 resource 被一個 owner resource 所管轄,當 owner resource 被刪除時,Kubernetes 的回收機制也會一併刪除此 resource。在我們的場景,由於使用者的資料皆為於個人專屬的 Namespace 底下,而 User 又為此 Namespace 的 owner resource,於是當使用者行為極端異常,管理者需要對其制裁時,只須刪除其 User 便可徹底清除此使用者的所作所為。
-在實做方面,User 種類的定義以及 controller 邏輯採取 kubebuilder 框架實做。kubebuilder 採用 Go 程式語言,以及 \verb|sig.k8s.io/controller-runtime| 函式庫開發,提供由 Go 語言的資料結構定義輔以註解擴充,搭配程式碼生成技術實現 Kubernetes resource 種類的定義,並且提供實做 controller 時所需的監控 resources 變更等基本邏輯。另外,\verb|sig.k8s.io/controller-runtime| 亦具備 \verb|envtest| 測試框架,自動化運行 kube-apiserver 等元件,在不需要架設完整叢集的前提下,提供 controller 較為完整的測試環境。
+在實做方面,User 種類的定義以及 controller 邏輯採用 Kubebuilder\cite{kubebuilder} 框架撰寫。Kubebuilder 採用 Go 程式語言與 \verb|sig.k8s.io/controller-runtime| 函式庫開發,由 Go 語言的資料結構定義輔以註解補充,搭配程式碼生成技術實現 Kubernetes resource 種類的定義,並且提供實做 controller 時所需的監控 resources 變更等基本邏輯。另外,\verb|sig.k8s.io/controller-runtime| 亦具備 \verb|envtest| 測試框架,自動化運行 kube-apiserver 等元件,在不需要架設完整叢集的前提下,提供 controller 較為完整的測試環境。
\subsection{Namespace}
為了避免命名與叢集上既有、負責叢集本身運行的 Namespaces 衝突,我們將使用者的 Namespace 命名為 \verb|u-| 前綴加上系計中帳號名稱(即相關 User resource 的名稱)。
-在創立 Namespace 時,根據個別的 admission controllers 設計,需要在 \verb|labels| 或 \verb|annotations| 上加註政策。\verb|labels| 與 \verb|annotations| 皆是 Kubernetes resources 共通的 key-value 標記,常用以輔助管理辨識,或是以較高的彈性提供次要的功能,其中 \verb|labels| 在透過 Kubernetes API 列舉時可以用來作為條件過濾 resources,但同時能夠儲存的內容也具有相關限制。需要設定的有 \ref{sec:PodSecurity} PodSecurity、\ref{sec:PodTolerationRestriction} PodTolerationRestriction 與 \ref{sec:CEL} 以 CEL 實做的域名使用權管控。為了方便管理者透過過濾進行清查,域名管控我們設計以 \verb|labels| 設定白名單,一個域名一條 label。平台預設開放如帳號名稱加上 \verb|.u.cloud.cs.nycu.edu.tw| 後綴的域名供使用者使用。
+在創立 Namespace 時,根據個別的 admission controllers 設計,需要在 \verb|labels| 或 \verb|annotations| 上加註政策。\verb|labels| 與 \verb|annotations| 皆是 Kubernetes resources 共通的 key-value 標記欄位,常用於輔助管理辨識,或是以較高的修改彈性提供次要的功能,其中 \verb|labels| 在透過 Kubernetes API 列舉 resources 時可作為條件過濾,因此也常用於 resources 間的關聯建立,但能夠儲存的內容也具有相關限制。需要設定政策的有 \ref{sec:PodSecurity} \verb|PodSecurity|、\ref{sec:PodTolerationRestriction} \verb|PodTolerationRestriction| 與 \ref{sec:CEL} 以 CEL 實做的域名使用權管控。為了方便管理者透過過濾進行清查,域名管控我們設計以 \verb|labels| 設定白名單,一個域名一條 label。平台預設開放如帳號名稱加上 \verb|.u.cloud.cs.nycu.edu.tw| 後綴\footnote{平台有預先配置 *.u.cloud.cs.nycu.edu.tw 的 wildcard 域名紀錄與 TLS 憑證。}的域名供使用者使用。
Namespace 上 \verb|u-| 以及平台提供域名中 \verb|u.| 的命名切分設計使得平台可以進一步擴充,除了以使用者為單位以外,未來可以增加其他種類的命名切分,提供以如實驗室或課程為單位的服務。
\subsection{ResourceQuota}
-ResourceQuota 是 Kubernetes 的一個 resource 種類,用來實做單一 Namespace 下的資源配額,其運作邏輯大致分兩大塊:admission controller 與一般的 controller。ResourceQuota 的 admission controller 屬於 validating,負責在創立或更新 resource 時推算其資源用量的變化值,並且拒絕用量會超出配額的請求。一般的 controller 端則是以更為全面的觀點,監控整體 resources 的變更,並且統計資源用量總額。
+ResourceQuota 是 Kubernetes 的一個 resource 種類,用來實做單一 Namespace 下的資源配額,其運作邏輯大致分兩大塊:admission controller 與一般的 controller。ResourceQuota 的 admission controller 屬於 validating,負責在創立或更新 resource 時推算其資源用量的變化值,並且拒絕用量將超出配額的請求。一般的 controller 端則是以更為全面的觀點,監控整體 resources 的變更,並且統計資源用量總額。
ResourceQuota 所能管控的資源大致有兩種:運算資源以及 resources 的數量。運算資源具有量值,例如部屬容器時設定的 CPU 或者記憶體用量限制,以及 PersistentVolumeClaim (PVC)\footnote{PVC: Resource 種類,表示儲存空間請求,需自動或手動與 PersistentVolume(PV,分配實體)耦合。} 中的儲存用量請求。Resources 的數量則是滿足特定條件的 resources 的個數,例如正在運行的 Pods。
-除了使用 ResourceQuota 來限制運算資源用量,我們運用其中部份特定條件來限制 resource 內容,最為代表性的是 Service。Service 作為具備負載均衡的網路存取點,根據其 \verb|spec| 的 \verb|type| 欄位,主要又分為 \verb|ClusterIP|、\verb|NodePort|、\verb|LoadBalancer| 三大類別。\verb|ClusterIP| 為最單純、最常見的叢集內部存取點,\verb|NodePort| 額外在每個節點宿主端的網路環境提供存取點,\verb|LoadBalancer| 則是進一步串接叢集外部的負載均衡器。由於在我們的叢集規劃下,節點架設於內部網路,使用者無法直接存取節點,\verb|NodePort| 對使用者來說並無用途,同時 \verb|NodePort| 使用叢集本身的有限網路資源,不適合對使用者開放。\verb|LoadBalancer| 則是需佔用外部負載均衡器的 IP 位址分配池,其大小非常有限,也不適合開放給使用者。ResourceQuota 正有根據類別分開統計 Service 數量的邏輯,我們利用此特性,設置相關配額為零,防止使用者使用 \verb|NodePort| 與 \verb|LoadBalancer|。
+除了使用 ResourceQuota 來限制運算資源用量,我們運用個數特定條件邏輯來限制 resource 內容,其中最為代表性的是 Service。Service 作為具備負載均衡的網路存取點,根據其 \verb|spec| 的 \verb|type| 欄位,主要又分為 \verb|ClusterIP|、\verb|NodePort|、\verb|LoadBalancer| 三大型別。\verb|ClusterIP| 為最基本、最常見的叢集內部存取點,\verb|NodePort| 額外在每個節點宿主端的網路環境提供存取點,\verb|LoadBalancer| 則是進一步串接叢集外部的負載均衡器。在我們的叢集規劃下,節點架設於內部網路,使用者無法直接存取節點,\verb|NodePort| 對使用者來說並無用途,同時 \verb|NodePort| 使用節點的有限網路資源,不適合對使用者開放。\verb|LoadBalancer| 則是需佔用外部負載均衡器的 IP 位址分配池,其大小非常有限,也不適合開放給使用者。ResourceQuota 正有根據型別分開統計 Service 數量的邏輯,我們利用此特性,設置對應配額為零,防止使用者使用 \verb|NodePort| 與 \verb|LoadBalancer|。
-除了運算資源,以及上述針對 resource 內容的管控,我們也對所有使用者能夠創立的 resource 種類進行總量限制,避免濫用。在其限額設計上,我們仍盡量保持讓使用者可以在運算資源限制合理地自由運用。
+除了運算資源,以及上述針對 resource 內容的管控,我們也對所有使用者能夠創立的 resource 種類進行總量限制,避免濫用。對其限額設計,我們仍盡量保持讓使用者可以在運算資源限制內合理地自由運用。
\subsection{LimitRange}
-在有使用 ResourceQuota 限制總運算資源用量的情況,所有的 Pods 必須設定容器的相關資源限制。這點十分容易影響使用者體驗,資源限制在 API 上並非必填,以 Kubernetes 通常經由高層次 resources (如 Deployment)去控管 Pods 的方式,如果在高層次 resources 中的 Pod 模板並未填寫資源限制,創立當下並沒有影響,而是在相關 controller 創立 Pod 時才發生錯誤,對使用者來說較難除錯。另外,部份常用代為呼叫 API 的手段如 \verb|kubectl create deployment| 也沒有途徑可以填寫限制。
+在使用 ResourceQuota 限制總運算資源用量的情境,所有 Pods 必須設定容器的相關資源限制。這點十分容易影響使用者體驗,資源限制在 API 上並非必填,以 Kubernetes 通常經由高層次 resources (如 Deployment)去控管 Pods 的方式,如果在高層次 resources 中的 Pod 模板並未填寫資源限制,創立當下並不受限制,而是在相關 controller 創立 Pod 時才發生錯誤,對使用者來說較難除錯。另外,部份常用代為呼叫 API 的手段如 \verb|kubectl create deployment| 也沒有途徑可以填寫限制。
-對於這個場景,我們可以使用 LimitRange resource 種類。LimitRange 透過 LimitRanger admission controller 限制使用者能夠填寫的資源限制大小範圍,同時也能夠在未填寫的狀況下套用預設值協助補足。LimitRange 如同 ResourceQuota,以單一 Namespace 為作用範圍。我們使用 LimitRange 實做資源限制預設值,以提昇使用者體驗。
+面對這個場景,我們使用 LimitRange resource 種類。LimitRange 透過 \verb|LimitRanger| admission controller 限制使用者能夠填寫的資源限制大小範圍,同時也能夠在未填寫的狀況下套用預設值協助補足。LimitRange 如同 ResourceQuota,以單一 Namespace 為作用範圍。我們使用 LimitRange 實做資源限制的欄位預設值,以提昇使用者體驗。
\subsection{測試}
-由於權限開通過程較為複雜,並且牽涉多個 admission control 安全性相關設定,因此這方面的測試顯得相當重要。\verb|envtest| 提供的環境涵蓋 kube-apiserver,足以讓我們測試 admission control 的行為,我們用其來實做測試,以整體的行為作為測試目標,例如開通後,使用者應能在其 Namespace 下創立 Pods,但不能帶有關閉隔離措施的設定等。同樣測試流程我們也進一步重複利用,將 \verb|envtest| 抽離,提供可以直接對真實叢集進行的行為測試。
+由於權限開通過程較為複雜,並且牽涉多個 admission control 安全性相關設定,因此這方面的測試顯得相當重要。\verb|envtest| 提供的環境涵蓋 kube-apiserver,足以讓我們測試 admission control 的行為,我們用其實做整合測試,以整體的行為作為測試目標,例如開通後,使用者應能在其 Namespace 下創立 Pods,但不能帶有關閉隔離措施的設定等。同樣測試流程我們也進一步重複利用,將 \verb|envtest| 抽離,提供可以直接對真實叢集測試的變種,適用於完整部屬後的驗證場合。
-相對於一般用途的 Kubernetes 叢集,CSKloud 也需要額外進行如啟用特定 admission controller 等設定,對此我們也撰寫叢集設定驗證測試,確保相關功能有被啟用,且其設定有經過儲存,以避免安裝上的人為疏失。
+相對於一般用途的 Kubernetes 叢集,CSKloud 也需要額外進行如啟用特定 admission controller 等設定。高層次的行為測試雖然可以直觀地撰寫,對於失敗的除錯卻需要對系統有相當深入的認知。對此,我們也撰寫叢集設定驗證測試,確保相關功能有被啟用,且其設定有經過儲存,以底層的角度防止安裝上的人為疏失。
\section{網頁界面實做}
-進一步對網頁界面的需求分析,可以將網頁界面切分為兩大塊:支援 Helm 的通用 Kubernetes 網頁型客戶端,以及 CSKloud 特定的部份,包含權限開通元件的整合以及 CSKloud 平台面向使用者的文件等。其中 Kubernetes 客戶端很容易的就可以利用於其他場景,我們採取 open core 的策略,將其 Kubernetes 客戶端開放原始碼,以 MIT 授權條款\footnote{MIT license: 一個在網頁技術場域廣受歡迎的寬鬆型開放原始碼條款。}釋出,命名為 Sparkles\footnote{Sparkles 釋出於 \url{https://github.com/xdavidwu/sparkles} 。},回饋於社會,使得非平台使用者也能受益,同時可以也利用開放原始碼社群的力量來茁壯平台的發展。
+進一步對網頁界面的需求分析,可以將網頁界面切分為兩大塊:支援 Helm 的通用 Kubernetes 網頁型客戶端,以及 CSKloud 特定的部份,包含權限開通元件的整合以及 CSKloud 平台面向使用者的文件等。其中 Kubernetes 客戶端很容易的就可以利用於其他場景,我們採取 open-core 的策略,將其開放原始碼,以 MIT 授權條款\footnote{MIT license: 一個在網頁技術場域廣受歡迎的寬鬆型開放原始碼條款。}釋出,命名為 Sparkles\footnote{Sparkles 釋出於 \url{https://github.com/xdavidwu/sparkles} 。},回饋於社會,使得非平台使用者也能受益,同時也利用開放原始碼社群的力量來茁壯平台的發展。
-\begin{figure}[htb]
+\begin{figure}[thb]
\centering
\includegraphics{assets/sparkles-and-web.png}
\caption{CSKloud v3 網頁界面與 Sparkles 關係示意圖}
\end{figure}
-% TODO 可以加一坨 webpage ref :p
-網頁界面採用 Vue.js 框架,以 TypeScript 語言\footnote{TypeScript: 一個轉譯為 JavaScript 的語言,比起 JavaScript 多了型別標示以利開發。}撰寫,使用 Vuetify 做為元件庫。Vuetify 的元件設計採用基於 Google 提出的 Material Design 設計語彙,同時 Kubernetes 也是由 Google 發跡的,在些許程度上,選擇 Vuetify 帶給了 Kubernetes 使用者更契合的親切感。由於界面希望帶有在容器內執行指令的功能,所需的終端機傳統上採用黑底白字配色,為避免其元件顯得突兀,整體界面亦採暗色系設計。在流行上,近期資訊界生產力相關的網頁服務也有逐漸導入暗色系設計的趨勢。
+網頁界面採用 Vue.js\cite{vue} 框架,以 TypeScript 語言\footnote{TypeScript: 一個轉譯為 JavaScript 的語言,比起 JavaScript 多了型別標示以利開發。}撰寫,使用 Vuetify 做為元件庫。Vuetify 的元件設計採用基於 Google 提出的 Material Design 設計語彙,同時 Kubernetes 也是由 Google 發跡的,在些許程度上,選擇 Vuetify 帶給了 Kubernetes 使用者更契合的親切感。由於界面希望帶有在容器內執行指令的功能,所需的終端機傳統上採用黑底白字配色,為避免其元件顯得突兀,整體界面亦採暗色系設計。在流行上,近期資訊界生產力相關的網頁服務也有逐漸導入暗色系設計的趨勢。
-對於 Kubernetes API 的操作,我們採用由 Kubernetes 提供的 OpenAPI\footnote{OpenAPI: 一種用於描述 RESTful API 行為的框架。} 定義檔,透過 openapi-generator\footnote{openapi-generator: 由 OpenAPI 定義檔產生適用於各種不同語言的函式庫的工具。} 自動產生的函式庫輔助開發。在網頁的各個功能,我們皆有採用 Kubernetes 的 watch 機制達到資料的即時更新。Kubernetes 的 watch 是一個特有的 HTTP API 呼叫方法,透過維持長期不中斷的 HTTP response,藉由 HTTP 的 chunked transfer\footnote{Chunked transfer: 一個將內容分塊傳送的 HTTP 編碼機制,常用於串流等持續產生資料的場合。} 編碼,即時的將一個 resources 列表的內容更新以新增、移除、修改 resource 等事件傳出,並且每個事件帶有一個版本號,如果 HTTP 通訊意外中止,客戶端可以透過這個版本號代表對目前 resources 列表的認知,向 Kubernetes 重發一個 watch 呼叫獲取由該版本後的變更。這個機制也廣泛運用在 Kubernetes 元件內部的溝通。
+對於 Kubernetes API 的操作,我們採用由 Kubernetes 提供的 OpenAPI\footnote{OpenAPI: 一種用於描述 RESTful API 行為的框架。} 定義檔,透過 openapi-generator\footnote{openapi-generator: 由 OpenAPI 定義檔產生適用於各種不同語言的函式庫的工具。} 自動產生的函式庫輔助開發。在網頁的各個功能,我們皆有採用 Kubernetes 的 watch 機制達到資料的即時更新。Kubernetes 的 watch 是一個特有的 HTTP API 呼叫方法,透過維持長期不中斷的 HTTP response,藉由 HTTP 的 chunked transfer\footnote{Chunked transfer: 一個將內容分塊傳送的 HTTP 編碼機制,常用於串流等持續產生資料的場合。} 編碼,即時的將一個 resources 列表的內容更新以新增、移除、修改 resource 等事件傳出,並且每個事件帶有一個版本號,如果 HTTP 通訊意外中止,客戶端可以透過這個版本號代表目前對 resources 列表的認知,向 Kubernetes 重發一個 watch 呼叫獲取由該版本後的變更。這個機制也廣泛運用在 Kubernetes 元件內部的溝通。
\begin{figure}[htb]
\centering
@@ 166,7 165,7 @@ ResourceQuota 所能管控的資源大致有兩種:運算資源以及 resource
\caption{CSKloud v3 網頁界面導覽設計}
\end{figure}
-網頁界面設計以單一 Kubernetes Namespace 為主軸,符合 CSKloud 對使用者提供獨立 Namespace 使用的場景。網頁的導覽透過頁面左方的導覽列達成,由此存取各個子功能,並且顯示目前所操作的 namespace。在 Sparkles 上,Namespace 可由可搜尋的下拉式選單選擇,在 CSKloud 上,則是固定為使用者對應的 Namespace 而停用選單,保留在界面上是為了往後開發出使用者群組功能後,切換至群組所對應的 Namespace 使用。
+網頁界面設計以單一 Kubernetes Namespace 為主軸,符合 CSKloud 對使用者提供獨立 Namespace 的場景。網頁的導覽透過頁面左方的導覽列達成,由此存取各個子功能,並且顯示目前所操作的 Namespace。在 Sparkles 上,Namespace 可由可搜尋的下拉式選單選擇,在 CSKloud 上,則是固定為使用者對應的 Namespace 而停用選單,保留在界面上是為了往後開發出使用者以外的服務單位時,切換對應的 Namespace 使用。
\subsection{Pods 頁面與 Web Terminal 功能實做}
\label{sec:web-terminal}
@@ 186,7 185,7 @@ ResourceQuota 所能管控的資源大致有兩種:運算資源以及 resource
Pods 作為 Kubernetes 中的重要角色之一,表示叢集上運行的容器組合,我們特別為其提供了特製一覽頁面,也展示了網頁在資料呈現與互動上的顯著優於 kubectl 的 CLI 界面。網頁界面可以很容易的繪製較複雜的表格結構,也可以透過顏色幫助使用者快速的分辨異同。同時也能夠在資料上進一步的提供互動,例如點擊容器的 image 連結會導向至相關的資訊頁面,也可以針對項目顯示功能按鈕。
-在容器的功能按鈕中,有瀏覽容器的運行紀錄 (log) 以及在容器中動態執行指令的功能。執行指令需要有雙向的即時資料流來傳送輸入與輸出,在這方面 Kubernetes 提供兩個解決方案:SPDY 與 WebSocket。SPDY 是 Google 早期提出的協定,用來改善 HTTP 1.x 的效能,如今在 HTTP 的場域已經被為廣泛的 HTTP/2 取代,Kubernetes 則是持續利用其雙向即時傳輸的功能。WebSocket 是特別設計在網頁場景提供雙向即時資料流的協定,並且連線由 HTTP 請求觸發進行進一步的協定轉移,對於 HTTP 既有的代理生態有一定的相容性而被廣泛採納。Kubernetes 原先以 SPDY 為主,因長期發展考量逐步轉換為 WebSocket。因為瀏覽器支援因素,我們採用 WebSocket 進行實做。
+在容器的功能按鈕中,有瀏覽容器的運行紀錄 (log) 以及在容器中動態執行指令的功能。執行指令需要有雙向的即時資料流來傳送輸入與輸出,在這方面 Kubernetes 提供兩個解決方案:SPDY 與 WebSocket。SPDY 是 Google 早期提出的協定,用來改善 HTTP 1.x 的效能,如今在 HTTP 的場域已經被為廣泛的 HTTP/2 取代,Kubernetes 則是持續利用其雙向即時傳輸的功能。WebSocket\cite{fette2011websocket} 是特別設計在網頁場景提供雙向即時資料流的協定,並且連線由 HTTP 請求觸發進行進一步的協定轉移,對於 HTTP 既有的代理生態有一定的相容性而被廣泛採納。Kubernetes 原先以 SPDY 為主,因長期發展考量逐步轉換為 WebSocket。因為瀏覽器支援因素,我們採用 WebSocket 進行實做。
% 或許可以來個架構圖, 沒有很重要但文字偏抽象, 要避免牽扯到前面都沒提的 kubernetes components
有了雙向的資料流,我們還需要一個終端機模擬器負責進一步的處理,與叢集上的 pty\footnote{pty: Unix-like 系統常見的元件,主要負責處理文字行編輯、訊號快捷鍵(如 Ctrl+C)等。} 溝通。終端機模擬器繪製整個文字界面,並且處理 pty 輸出中的控制訊息,達到文字界面的顏色與游標位置等的控制。這部份我們使用既有的 Xterm.js 開源函式庫達成。
@@ 194,11 193,11 @@ Pods 作為 Kubernetes 中的重要角色之一,表示叢集上運行的容器
\subsection{Helm 頁面與 Helm 功能實做}
\label{sec:helm}
-對於 Helm 功能,我們希望保持 SPA 架構將部份邏輯推往瀏覽器端在運行成本上優勢,規劃在瀏覽器內實做。起初我們將 Helm 的函式庫直接透過 WebAssembly 包裝,並提供其以指令操作為切分單位的函式接口與 TypeScript 串接,但我們發現以此方式實做效能不佳,於列出已安裝的 Helm Release 等基本操作在低資料量下已產生足以影響使用者體驗的延遲。
+對於 Helm 功能,我們希望保持 SPA 架構中,將部份邏輯推往瀏覽器端在運行成本上的優勢,規劃將其在瀏覽器內實做。起初我們將 Helm 的函式庫直接透過 WebAssembly 包裝,並提供其以指令操作為切分單位的函式接口與 TypeScript 串接,但我們發現以此方式實做效能不佳,於列出已安裝的 Helm Releases 等基本操作,在低資料量下已產生足以影響使用者體驗的延遲。
-Helm Release 一般的儲存格式需要經過 Base64\footnote{Base64: 一個編碼格式,可將任何形式資料轉為文字表示。} 與 gzip\footnote{gzip: 一個被廣泛利用的資料壓縮演算法。} 等操作,如果將 Helm Release 的解讀透過 WebAssembly 處理,在不經調整的情況下呼叫的會是來自 Go 語言基本函式庫編譯成 WebAssembly 的 Base64 與 gzip 實做。WebAssembly 雖然設計上已經較為接近硬體,但仍是虛擬機架構,在運算上仍然有額外負擔。而 Base64 與 gzip 作為常用的算法,瀏覽器本身有提供高效能的實做。另外將資料傳送進出 WebAssembly 環境也有一定的執行成本。
+Helm Release 預設的 Secret 儲存方式需要經過 Base64\footnote{Base64: 一個編碼格式,可將任何形式資料轉為文字表示。} 與 gzip\footnote{gzip: 一個被廣泛利用的資料壓縮演算法。} 等操作,如果將 Helm Release 的解讀透過 WebAssembly 處理,在不經調整的情況下,呼叫的是來自 Go 語言基本函式庫的 Base64 與 gzip 實做。WebAssembly 雖然設計上已經較為接近硬體,但仍是虛擬機架構,在運算上仍然有額外負擔。而 Base64 與 gzip 作為常用的算法,瀏覽器本身有提供高效能的實做,卻未被利用。另外將資料傳送進出 WebAssembly 環境也有一定的執行成本。
-面對這個情景,我們面臨兩個可能的解法:抽換 Go 語言基本函式庫相關演算法改為呼叫瀏覽器的實做,或者將容易影響使用者體驗的區塊以 TypeScript 重新實做。抽換的方法仍然無法避免資料傳輸的負擔。而分析 Helm 架構可發現,除了模板引擎因為基於 Go 基本函式庫的模板框架,其設計容易牽涉語言特性而不易重新實做外,剩餘的區塊皆為一般的資料處理與 Kubernetes API 的串接。其中需要模板引擎的操作只有安裝、升級等使用者會預期需要時間的情景,不包含對使用者體驗影響重大的列出 Helm Release。綜上考量,我們將 Helm 模板引擎外的部份由 TypeScript 重新實做。
+關於這個情景,我們面臨兩個可能的解法:抽換相關演算法改為呼叫瀏覽器的實做,或者將容易影響使用者體驗的區塊以 TypeScript 重新實做。抽換的方法不但無法避免資料傳輸的負擔,反而會增加傳送的次數,不甚理想。而分析 Helm 架構可發現,除了模板引擎因基於 Go 基本函式庫的模板框架,設計容易牽涉語言特性而不易重新實做外,剩餘的區塊皆為一般的資料處理與 Kubernetes API 的串接。其中需要模板引擎的操作只有安裝、升級等使用者傾向預期需要時間的情景,不包含對使用者體驗影響重大的列出 Helm Releases。綜上考量,我們將 Helm 模板引擎外的部份抽離,由 TypeScript 重新實做。
\begin{figure}[htb]
\centering
@@ 206,7 205,9 @@ Helm Release 一般的儲存格式需要經過 Base64\footnote{Base64: 一個編
\caption{CSKloud v3 網頁界面實做 Helm 原理示意圖}
\end{figure}
-除此之外,瀏覽器執行程式碼的方式主要為單執行緒,不論 JavaScript 或 WebAssembly 邏輯皆是在與畫面繪製相同的執行緒執行,唯 JavaScript 語言上具有異步 IO 的特性,使得一般負擔主要在 IO 與事件處理的網頁程式碼具備可接受的效能。但我們的場景不同,Helm 的模板引擎運算量較多,在執行時容易拖累到畫面繪製,造成卡頓。對此,我們進一步採用 WebWorker 技術。WebWorker 提供一個較侷限的執行環境,但在獨立的執行緒運行,可以避面上述影響繪製的窘境,使用上開發者需自行處理 WebWorker 與瀏覽器的一般執行緒間的溝通。我們將安裝、升級、回滾、解除安裝的耗時的操作,包含 WebAssembly 的使用,在 WebWorker 環境下實做以改善使用者體驗。
+除此之外,瀏覽器執行程式碼的方式主要為單執行緒,不論 JavaScript 或 WebAssembly 邏輯皆是在與畫面繪製相同的執行緒執行,唯 JavaScript 語言上具有異步 IO 相關設計,使得一般負擔主要在 IO 與事件處理的網頁程式碼具備可接受的效能。但我們的場景不同,Helm 的模板引擎運算量較多,在執行時容易拖累到畫面繪製,造成卡頓。對此,我們進一步採用 Web Workers 技術。Web Workers 提供一個較侷限的執行環境,但在獨立的執行緒運行,可以避面上述影響繪製的窘境,使用上開發者需自行處理 Web Workers 與瀏覽器一般執行緒間的溝通。我們將安裝、升級、回滾、解除安裝的耗時的操作,包含 WebAssembly 的使用,在 Web Workers 環境下實做以改善使用者體驗。
+
+在安裝的部份,由於我們是在瀏覽器內實做,能存取的 HTTP 服務受到對端的跨域政策影響。除非對端主動的表示允許,瀏覽器會限制網頁邏輯對其他域名服務的存取,作為增強安全性的一個手段。由於 Helm 傳統上並非在瀏覽器環境執行,Helm Repositories 大多不會特別放寬跨域政策,因此我們無法直接使用市面上大多數的 Helm Repositories。針對 CSKloud 的場景,因為可以預期部份 Charts 會受到平台加固等策略影響而無法安裝,我們採用自行架設 Helm Repositories,並只納入批量測試成功安裝的 Helm Charts,目前共提供 32 個來自 Bitnami 的 Helm Charts。
\begin{figure}[htb]
\centering
@@ 216,18 217,18 @@ Helm Release 一般的儲存格式需要經過 Base64\footnote{Base64: 一個編
\begin{figure}[htb]
\centering
- \begin{subfigure}{0.5\textwidth}
+ \begin{subfigure}{0.49\textwidth}
\centering
\includegraphics[width=\textwidth]{assets/web-helm-install-repo.png}
\caption{選擇 Helm Chart}
\end{subfigure}%
~
- \begin{subfigure}{0.5\textwidth}
+ \begin{subfigure}{0.49\textwidth}
\centering
\includegraphics[width=\textwidth]{assets/web-helm-install-values.png}
\caption{填寫 Helm Values}
\end{subfigure}
- \begin{subfigure}{0.5\textwidth}
+ \begin{subfigure}{0.49\textwidth}
\centering
\includegraphics[width=\textwidth]{assets/web-helm-install-name.png}
\caption{命名 Helm Release}
@@ 235,11 236,9 @@ Helm Release 一般的儲存格式需要經過 Base64\footnote{Base64: 一個編
\caption{CSKloud v3 網頁界面 Helm Releases 安裝流程}
\end{figure}
-界面上以 Helm Releases 表格呈現為主,可以展開觀看版本歷史,在每個項目旁有解除安裝、回滾、更新等按鈕,解除安裝會保留歷史,仍然可以將其裝回,也可以選擇刪除歷史。在畫面的右下角則是有浮動式的按鈕,可以觸發安裝新 Helm Release 的流程。
+界面上以 Helm Releases 表格呈現為主,可以展開觀看版本歷史,在每個項目旁有解除安裝、回滾、更新等按鈕,解除安裝會保留歷史,仍然可以將其裝回,也可以事後刪除歷史。畫面的右下角則是有浮動式的按鈕,可以觸發安裝新 Helm Release 的流程。
-在安裝的部份,由於我們是在瀏覽器內實做,能存取的 HTTP 服務受到對端的跨域政策影響。除非對端主動的表示允許,瀏覽器預設會限制網頁邏輯對其他域名服務的存取,作為增強安全性的一個手段。由於 Helm 傳統上並非在瀏覽器環境執行,Helm Repositories 大多不會特別放寬跨域政策,因此我們無法直接使用市面上大多數的 Helm Repositories。針對 CSKloud 的場景,因為可以預期部份 Charts 會因為平台加固等策略影響無法安裝,我們採用自行架設 Helm Repositories,並且只納入批量測試過可以安裝的 Helm Charts,目前共提供 32 個來自 Bitnami 的 Helm Charts。
-
-對於安裝的流程,在按下浮動式按鈕後,會跳出對話框進行三個步驟。第一是選擇要安裝的 Helm Chart,由一個可搜尋的列表選取。第二是填入 Helm Values,如同 Helm CLI 以 YAML\footnote{YAML: 一個資料標記語言,在 Kubernetes 生態系頗為常用,尤其是用來表達 Kubernetes resources。} 的形式填入,這裡界面上提供三個頁簽,一是填 Helm Values 的編輯器,二是顯示來自 Helm Chart 的 README 檔案,通常會在此提供常用選項的說明,三是 Helm Chart 內的 Helm Values 預設值檔案,慣例在此以註解的形式完整地對選項欄位說明。以 CSKloud 的場景,在編輯器上,會自動帶入針對 CSKloud 的第二層預設值,這個預設值來自測試安裝時所帶入的參數,調整如資源配額用量等選項,以確保在平台的限制下得以安裝,使用者也可以進一步進行修改。最後的步驟則是為此 Helm Release 命名,界面會自動預設一個隨機的名字。
+對於安裝的流程,按下浮動式按鈕後,會跳出對話框進行三個步驟:第一步是選擇要安裝的 Helm Chart,由一個可搜尋的列表選取。第二步是填入 Helm Values,如同 Helm CLI 以 YAML\footnote{YAML: 一個資料標記語言,在 Kubernetes 生態系頗為常用,尤其是用來表達 Kubernetes resources。} 的形式填入,界面上提供三個頁簽,一是填寫 Helm Values 的編輯器,二是來自 Helm Chart 的 README 檔案,通常會在此提供常用選項的說明,三是 Helm Chart 內的 Helm Values 預設值檔案,慣例在此以註解的形式完整地對選項欄位說明。以 CSKloud 的場景,編輯器會自動帶入針對 CSKloud 的第二層預設值,這個預設值來自測試安裝時所帶入的參數,調整如資源配額用量等選項,以確保在平台的限制下得以安裝,使用者也可以進一步進行修改。最後的步驟則是為此 Helm Release 命名,界面會自動預設一個隨機的名字。
調整 Helm Values 的編輯器採用 CodeMirror 開源編輯器專案,除了 YAML 的基本語法高亮以外,我們採用 codemirror-json-schema 擴充元件提供進一步的資料驗證、欄位說明與名稱自動補全。codemirror-json-schema 收取 JSON Schema 作為欄位定義,JSON Schema 是一個描述 JSON\footnote{JSON: 資料標記語言,與 YAML 的模型類似,語法較為容易以程式解析。} 資料的定義框架,但由於大多數 YAML 應用場景描述的資料也都可以由 JSON 的形式表達,也常用來描述 YAML 資料。部份 Helm Chart 會提供對其 Helm Values 的 JSON Schema 定義檔。
@@ 247,43 246,43 @@ Helm Release 一般的儲存格式需要經過 Base64\footnote{Base64: 一個編
\begin{figure}[htb]
\centering
- \includegraphics[width=0.75\textwidth]{assets/web-quotas.png}
+ \includegraphics[width=0.7\textwidth]{assets/web-quotas.png}
\caption{CSKloud v3 網頁界面 Quotas 頁面}
\end{figure}
此頁面針對平台透過 ResourceQuota 對 Namespace 下實行的資源配額進行視覺化,使用圓餅圖顯示每個取用單位(如 Pod 下的一個容器)在相關資源(如記憶體)允許配額下所佔用的比例。使用者可以透過將游標移動到圓餅區塊上,查看取用單位的名稱以及佔用量,方便使用者了解何處取用最多。在總取用比例高到一定程度時,會改以黃色或紅色顯示提醒使用者注意。
-在實做上,由於 ResourceQuota 只帶有配額與佔用總量資訊,須以程式邏輯另外獲取相關取用單位資訊才能自行判斷細項。另外,圓餅圖的繪製透過 Chart.js 開源函式庫實做。
+在實做上,由於 ResourceQuota 只帶有配額與佔用總量資訊,須以程式邏輯額外列舉相關 resources,解析取用單位資訊以判斷細項。另外,圓餅圖的繪製透過 Chart.js 開源函式庫實做。
\subsection{Tokens 管理}
\label{sec:tokens-mgmt}
-CSKloud 開放使用者直接存取 API,並且提供 kubectl 連線設定檔。因為叢集本身使用 OIDC 驗證方式,客戶端需要有相關 OIDC 流程邏輯,在網頁界面我們可以直接實做,而對於 kubectl 的場景,我們則是使用 kubelogin 擴充程式,在 kubectl 發出 Kubernetes API 請求時,kubelogin 會檢查是否持有有效的 token,並且在有必要時執行 OIDC 流程。OIDC 需要透過瀏覽器進行網頁登入,導致這個驗證方式雖然在使用者的互動使用時可行且較為安全,在自動化場景卻相當不方便。
+CSKloud 開放使用者直接存取 Kubernetes API,並且提供 kubectl 連線設定檔。因為叢集本身使用 OIDC 驗證方式,客戶端需要有相關 OIDC 流程邏輯,在網頁界面我們可以直接實做,而對於 kubectl 的場景,我們則是使用 kubelogin 擴充程式,在 kubectl 發出 Kubernetes API 請求時,kubelogin 會檢查當下是否持有有效的 token,在有必要時執行 OIDC 流程。OIDC 需要透過瀏覽器進行網頁登入,導致這個驗證方式雖然在使用者的互動使用時可行且較為安全,在自動化場景卻相當不方便。
-對此,我們採用 ServiceAccount tokens 彌補對自動化場景的不足。Tokens 管理頁面幫助使用者設定一個具有當下 Namespace 權限的 ServiceAccount,再經由此 ServiceAccount,簽發綁定 Secret 的 token。使用者在簽發 token 時需指定效期,並且可以紀錄相關的用途筆記,存放在對應的 Secret 內。這些 Secrets 使得網頁界面可以紀錄簽發的 tokens,同時作為撤銷 tokens 的手段。
+對此,我們採用 ServiceAccount tokens 彌補對自動化場景的不足。Tokens 管理頁面幫助使用者設定一個具有當下 Namespace 權限的 ServiceAccount,再經由此 ServiceAccount 簽發指定效期、綁定 Secret 的 token。使用者可以紀錄相關的用途筆記,存放在對應的 Secret 內。這些 Secrets 使得網頁界面可以紀錄追蹤簽發的 tokens,同時作為撤銷 tokens 的手段。
\subsection{Resource Explorer}
\begin{figure}[htb]
\centering
- \begin{subfigure}{0.5\textwidth}
+ \begin{subfigure}{0.49\textwidth}
\centering
\includegraphics[width=\textwidth]{assets/web-resources-list.png}
\caption{Resources 列表}
\end{subfigure}%
~
- \begin{subfigure}{0.5\textwidth}
+ \begin{subfigure}{0.49\textwidth}
\centering
\includegraphics[width=\textwidth]{assets/web-resources-single.png}
\caption{單一 resource 檢視}
\end{subfigure}
- \begin{subfigure}{0.5\textwidth}
+ \begin{subfigure}{0.49\textwidth}
\centering
\includegraphics[width=\textwidth]{assets/web-resources-single-menu.png}
\caption{單一 resource 檢視功能表}
\end{subfigure}%
~
- \begin{subfigure}{0.5\textwidth}
+ \begin{subfigure}{0.49\textwidth}
\centering
\includegraphics[width=\textwidth]{assets/web-resources-single-new.png}
\caption{創立 resource 的模板預填}
@@ 291,24 290,22 @@ CSKloud 開放使用者直接存取 API,並且提供 kubectl 連線設定檔
\caption{CSKloud v3 網頁界面 Resource Explorer 頁面}
\end{figure}
-Resource Explorer 提供對 Kubernetes resource 的基本列出、創立、編輯、刪除的功能,作為使用者與 Kubernetes 互動中最基礎的功能。這個頁面採用 Kubernetes API discovery 機制,在運行時會從 Kubernetes API 查詢所有支援的 resource 種類,未來如果隨著 Kubernetes 演進而有所增減,這個頁面不須經過修改可以直接沿用。
+Resource Explorer 提供對 Kubernetes resource 列舉、創立、編輯、刪除的操作界面,作為使用者與 Kubernetes 互動中最基礎的功能。這個頁面採用 Kubernetes API discovery 機制,在運行時會查詢叢集所有支援的 resource 種類,未來如果隨著 Kubernetes 演進而對種類有所增減,這個頁面不須經過修改可以直接沿用。
-在列表的部份,這個頁面採用 Kubernetes API 本身的製表功能,可以對 resources 產出基本的概要,kubectl 的表格呈現亦是採用此機制。使用者可以將游標移動到表格欄位名稱上方,透過提示框了解欄位意義,也可以點擊針對欄位排序。右下方的浮動按鈕可以撰寫新的 resource,點擊表格列則是查看對應的 resource 的完整內容,以 YAML 的形式呈現。在單一 resource 完整呈現中右下方的浮動按鈕功能列表,也有編輯與刪除等功能。
+這個頁面採用 Kubernetes API 本身的製表功能,可以對 resources 產出基本的概要,kubectl 的表格呈現亦是基於此機制。使用者可以將游標移動到表格欄位名稱上方,透過提示框了解欄位意義,也可以點擊針對欄位排序。右下方的浮動按鈕可以撰寫新的 resource,點擊表格列則是查看對應的 resource 的完整內容,以 YAML 的形式呈現。在單一 resource 完整呈現中右下方的浮動按鈕功能列表,也有編輯與刪除等功能。
-在 YAML 檢視與編輯的方面,則與 \ref{sec:helm} Helm 頁面功能相似,基於 CodeMirror,並且一樣有基於 JSON Schema 的資料驗證、欄位提示與名稱補全。這裡的欄位定義則是來自於 Kubernetes API 的 OpenAPI 定義檔。Kubernetes 具有 OpenAPI Discovery 功能,可以從 API 獲取定義檔,如同 API Discovery,這樣的機制使得網頁不須修改,即可適用於未來的 Kubernetes 版本。
+在 YAML 檢視與編輯的方面,則與 \ref{sec:helm} Helm 頁面功能相似,採用 CodeMirror,並且一樣有基於 JSON Schema 的資料驗證、欄位提示與名稱補全。這裡的欄位定義則是來自於 Kubernetes API 的 OpenAPI 定義檔,由相關 API endpoint 的定義萃取轉換而成。Kubernetes 具有 OpenAPI Discovery 功能,可以從 API 獲取定義檔,如同 API Discovery,這樣的機制使得網頁不須修改,即可適用於未來的 Kubernetes 版本。
-在創立新 resource 時,網頁會針對目前選擇的 resource 種類,預先填好必填或者常用的欄位,也會取好一個暫定名稱。預填欄位較為難以進行自動判斷,因此採用人工逐一事先設計的方式。如果未先設計,仍會自動預填 Kubernetes resource 共通的 \verb|apiVersion|、\verb|kind|、\verb|metadata| 欄位。
+創立新 resource 時,網頁會針對目前選擇的 resource 種類,預先填好必填或者常用的欄位,也會取好一個暫定名稱。預填欄位較為難以進行動態判斷,因此採用人工逐一事先設計的方式。如果選定的種類未先設計模板,仍會自動預填 Kubernetes resource 共通的 \verb|apiVersion|、\verb|kind|、\verb|metadata| 欄位。
-這個頁面功能可以涵蓋 Kubernetes 上的大多數操作,但仍然有限制,主要為並不支援 subresources。Subresources 為單一一個 resource 實例下的額外 API endpoints,使 Kubernetes 得以跳脫基本 resource 讀寫操作的框架,並且不具有固定的形式,其中較為代表的有:Pod 的 log subresource,用以查看 Pod 下容器的運行紀錄;Pod 的 exec subresources,用以在 Pod 下容器執行指令;ServiceAccount 的 tokens subresource,用以簽發 tokens。由於 subresources 的形式、用途皆不固定,我們無法直接提供通用的操作界面,而是經由如 \ref{sec:web-terminal} Pod 頁面等,針對不同場景另外實做。
+這個頁面功能可以涵蓋 Kubernetes 上的大多數操作,但仍然有限制,主要為不支援 subresources。Subresources 為單一 resource 實例下的額外 API endpoints,使 Kubernetes 得以跳脫 resource 讀寫操作的框架,並且不具有固定的形式,其中較為代表的有:Pod 的 log subresource,用以查看 Pod 下容器的運行紀錄;Pod 的 exec subresources,用以在 Pod 下容器執行指令;ServiceAccount 的 tokens subresource,用以簽發 tokens。由於 subresources 的形式、用途皆不固定,我們無法直接提供通用的操作界面,而是經由如 \ref{sec:web-terminal} Pod 頁面等,針對不同場景另外實做。
\subsection{kubectl shell 功能}
-隨著 Kubernetes 的更迭,即使我們盡力擴增網頁界面對應的功能,難免還是會有跟不上的時候。即使是現在,雖然我們已經實做了通用型的 Resource Explorer,仍然有少數 Kubernetes 功能無法直接透過網頁界面使用。對此,我們提供一個逃生口 (escape hatch):在網頁界面直接使用 kubectl 指令。雖然使用者可以自行安裝設定 kubectl,在網頁界面直接提供這個功能還是有免安裝、隨時帶著走的優勢。
+隨著 Kubernetes 的更迭,即使我們盡力擴增網頁界面對應的功能,難免還是會有跟不上的時候。就算是現在,雖然我們已經實做了通用型的 Resource Explorer,仍然有少數 Kubernetes 功能無法直接透過網頁界面使用。對此,我們提供一個逃生口 (escape hatch):在網頁界面直接使用 kubectl 指令。雖然使用者可以自行安裝設定 kubectl,在網頁界面直接提供這個功能還是有免安裝、隨時帶著走的優勢。
實做這個功能有兩個可行方向:使用 WebAssembly 將 kubectl 移植到瀏覽器,或者在叢集內執行 kubectl。前者實際上除了移植 kubectl 指令外,還需提供一個 shell 環境以便使用,在需將環境內各種工具一一移植的前提下,容易產生缺漏使用者想要的項目的窘境,開發成本相當高,於是我們選擇了後者。
-kubectl shell 頁面類似於 \ref{sec:tokens-mgmt} Tokens 管理頁面,都會先產生一個具有當下 Namespace 權限的 ServiceAccount,但取用的方式不同。接著會採用 Kubernetes 設計上將 ServiceAccount 對 Pod 做的特殊整合,創立一個使用該 ServiceAccount 的 Pod 時,Kubernetes 會自動簽發綁定此 Pod 的 token,並且將 token 與相關連線資訊放置至 Pod 內容器的檔案系統中。容器內具備的 kubectl 指令會自動採用檔案系統內的這些資訊進行連線。再來只須重複利用 \ref{sec:web-terminal} 所述的虛擬終端機連線機制,便可以讓使用者操作容器內的 kubectl 指令。
+kubectl shell 頁面類似於 \ref{sec:tokens-mgmt} Tokens 管理頁面,都會先產生一個具有當下 Namespace 權限的 ServiceAccount,但取用的方式不同。接著會採用 Kubernetes 設計上將 ServiceAccount 對 Pod 做的特殊整合,創立一個使用該 ServiceAccount 的 Pod 時,叢集會自動簽發綁定此 Pod 的 token,並將 token 與相關連線資訊放置於 Pod 內容器的檔案系統中。容器內具備的 kubectl 指令會自動採用這些資訊進行連線。再來只須重複利用 \ref{sec:web-terminal} 所述的虛擬終端機連線機制,便可讓使用者操作容器內的 kubectl 指令。
這個方式雖然因為在叢集內執行容器,會佔用到使用者的資源配額,但實際此場景預期的資源使用極小,對於使用者權益的影響不大。運作機制主要又是基於其他既有的功能做組合,實際開發成本極低,卻十分有效。圖 \ref{fig:kubectl-get-pods} 即是來自於此功能。
-
-\subsection{Node Metrics 視覺化}
M assets/kubectl-pods.png => assets/kubectl-pods.png +0 -0
M assets/provisioner-user-spec.png => assets/provisioner-user-spec.png +0 -0
M assets/web-helm-install-name.png => assets/web-helm-install-name.png +0 -0
M assets/web-helm-install-repo.png => assets/web-helm-install-repo.png +0 -0
M assets/web-helm-install-values.png => assets/web-helm-install-values.png +0 -0
M assets/web-helm-list.png => assets/web-helm-list.png +0 -0
M assets/web-pods.png => assets/web-pods.png +0 -0
M ref.bib => ref.bib +36 -5
@@ 3,7 3,6 @@
author = {周詳},
year = {2021},
month = {January},
- % TODO available where?
school = {國立交通大學},
type = {Master's thesis},
}
@@ 13,13 12,15 @@
author = {李宗緯},
year = {2022},
month = {August},
- % TODO available where?
school = {國立陽明交通大學},
type = {Master's thesis},
}
+% XXX quotes missing on online/electornic in IEEEtran
+% TODO dot position, urldate
+
@online{kubernetes,
- title = {{Kubernetes}},
+ title = {``{Kubernetes}''},
author = {{The Kubernetes Authors}},
year = {2024},
url = {https://kubernetes.io/},
@@ 27,7 28,7 @@
}
@online{helm,
- title = {{Helm}},
+ title = {``{Helm}''},
author = {{Helm Authors}},
year = {2024},
url = {https://helm.sh/},
@@ 35,9 36,39 @@
}
@inproceedings{haas2017bringing,
- title = {Bringing the web up to speed with WebAssembly},
+ title = {Bringing the web up to speed with {WebAssembly}},
author = {Haas, Andreas and Rossberg, Andreas and Schuff, Derek L and Titzer, Ben L and Holman, Michael and Gohman, Dan and Wagner, Luke and Zakai, Alon and Bastien, JF},
booktitle = {Proceedings of the 38th ACM SIGPLAN Conference on Programming Language Design and Implementation},
pages = {185--200},
year = {2017},
}
+
+@online{cel,
+ title = {``{CEL}''},
+ author = {{Google LLC}},
+ year = {2024},
+ url = {https://cel.dev/},
+ urldate = {2024-09-24},
+}
+
+@online{kubebuilder,
+ title = {``{Introduction} - The {Kubebuilder} Book''},
+ author = {{The Kubernetes Authors}},
+ year = {2024},
+ url = {https://book.kubebuilder.io/introduction},
+ urldate = {2024-09-23},
+}
+
+@online{vue,
+ title = {``{Vue.js} - The Progressive {JavaScript} Framework''},
+ author = {Evan You},
+ year = {2024},
+ url = {https://vuejs.org/},
+ urldate = {2024-09-23},
+}
+
+@techreport{fette2011websocket,
+ title = {The websocket protocol},
+ author = {Fette, Ian and Melnikov, Alexey},
+ year = {2011},
+}