M Sections/4.Architecture.tex => Sections/4.Architecture.tex +19 -1
@@ 54,7 54,7 @@ CSKloud 達成一代願景中的開放使用者直接存取 Kubernetes API,使
\end{figure}
% TODO 可以加一坨 webpage ref :p
-網頁界面採用 Vue.js 框架,以 TypeScript 語言撰寫,使用 Vuetify 做為元件庫。Vuetify 的元件設計採用基於 Google 提出的 Material Design 設計語彙,同時 Kubernetes 也是由 Google 發跡的,在些許程度上,選擇 Vuetify 帶給了 Kubernetes 使用者更契合的親切感。由於界面希望帶有在容器內執行指令的功能,所需的終端機傳統上採用黑底白字配色,為避免其元件顯得突兀,整體界面亦採暗色系設計。在流行上,近期資訊界生產力相關的網頁服務也有逐漸導入暗色系設計的趨勢。
+網頁界面採用 Vue.js 框架,以 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 元件內部的溝通。
@@ 84,10 84,28 @@ Pods 作為 Kubernetes 中的重要角色之一,表示叢集上運行的容器
在容器的功能按鈕中,有瀏覽容器的運行紀錄 (log) 以及在容器中動態執行指令的功能。執行指令需要有雙向的即時資料流來傳送輸入與輸出,在這方面 Kubernetes 提供兩個解決方案:SPDY 與 WebSocket。SPDY 是 Google 早期提出的協定,用來改善 HTTP 1.x 的效能,如今在 HTTP 的場域已經被為廣泛的 HTTP/2 取代,Kubernetes 則是持續利用其雙向即時傳輸的功能。WebSocket 是特別設計在網頁場景提供雙向即時資料流的協定,並且連線由 HTTP 請求觸發進行進一步的協定轉移,對於 HTTP 既有的代理生態有一定的相容性而被廣泛採納。Kubernetes 原先以 SPDY 為主,因長期發展考量逐步轉換為 WebSocket。因為瀏覽器支援因素,我們採用 WebSocket 進行實做。
+% 或許可以來個架構圖, 沒有很重要但文字偏抽象, 要避免牽扯到前面都沒提的 kubernetes components
有了雙向的資料流,我們還需要一個終端機模擬器負責進一步的處理,與叢集上的 pty\footnote{pty: Unix-like 系統常見的元件,主要負責處理文字行編輯、訊號快捷鍵(如 Ctrl+C)等。} 溝通。終端機模擬器繪製整個文字界面,並且處理 pty 輸出中的控制訊息,達到文字界面的顏色與游標位置等的控制。這部份我們使用既有的 Xterm.js 開源函式庫達成。
\subsection{Helm 頁面與 Helm 功能實做}
+% TODO 圖
+
+對於 Helm 功能,我們希望保持 SPA 架構將部份邏輯推往瀏覽器端在運行成本上優勢,規劃在瀏覽器內實做。起初我們將 Helm 的函式庫直接透過 WebAssembly 包裝,並提供其以指令操作為切分單位的函式接口與 TypeScript 串接,但我們發現以此方式實做效能不佳,於列出已安裝的 Helm Release 等基本操作在低資料量下已產生足以影響使用者體驗的延遲。
+
+Helm Release 一般的儲存格式需要經過 Base64\footnote{Base64: 一個編碼格式,可將任何形式資料轉為文字表示。} 與 gzip\footnote{gzip: 一個被廣泛利用的資料壓縮演算法。} 等操作,如果將 Helm Release 的解讀透過 WebAssembly 處理,在不經調整的情況下呼叫的會是來自 Go 語言基本函式庫編譯成 WebAssembly 的 Base64 與 gzip 實做。WebAssembly 雖然設計上已經較為接近硬體,但仍是虛擬機架構,在運算上仍然有額外負擔。而 Base64 與 gzip 作為常用的算法,瀏覽器本身有提供高效能的實做。另外將資料傳送進出 WebAssembly 環境也有一定的執行成本。
+
+面對這個情景,我們面臨兩個可能的解法:抽換 Go 語言基本函式庫相關演算法改為呼叫瀏覽器的實做,或者將容易影響使用者體驗的區塊以 TypeScript 重新實做。抽換的方法仍然無法避免資料傳輸的負擔。而分析 Helm 架構可發現,除了模板引擎因為基於 Go 基本函式庫的模板框架,其設計容易牽涉語言特性而不易重新實做外,剩餘的區塊皆為一般的資料處理與 Kubernetes API 的串接。其中需要模板引擎的操作只有安裝、升級等使用者會預期需要時間的情景,不包含對使用者體驗影響重大的列出 Helm Release。綜上考量,我們將 Helm 模板引擎外的部份由 TypeScript 重新實做。
+
+% TODO 可能差異不是很明顯
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=\textwidth]{assets/web-helm-impl.png}
+ \caption{CSKloud V3 網頁界面實做 Helm 原理示意圖}
+\end{figure}
+
+除此之外,瀏覽器執行程式碼的方式主要為單執行緒,不論 JavaScript 或 WebAssembly 邏輯皆是在與畫面繪製相同的執行緒執行,唯 JavaScript 語言上具有異步 IO 的特性,使得一般負擔主要在 IO 與事件處理的網頁程式碼具備可接受的效能。但我們的場景不同,Helm 的模板引擎運算量較多,在執行時容易拖累到畫面繪製,造成卡頓。對此,我們進一步採用 WebWorker 技術。WebWorker 提供一個較侷限的執行環境,但在獨立的執行緒運行,可以避面上述影響繪製的窘境,使用上開發者需自行處理 WebWorker 與瀏覽器的一般執行緒間的溝通。我們將安裝、升級、回滾、解除安裝的耗時的操作,包含 WebAssembly 的使用,在 WebWorker 環境下實做以改善使用者體驗。
+
\subsection{Quota 視覺化頁面}
\subsection{Tokens 管理頁面}
A assets/web-helm-impl.png => assets/web-helm-impl.png +0 -0