~xdavidwu/cskloudv3-thesis

f71aadbbc2ce775fdf7380b2b25a08c2e077a802 — Pinghao Wu 2 months ago fbc2ddf
revisit Introduction, Backgrounds, RelatedWorks
M Sections/1.Introduction.tex => Sections/1.Introduction.tex +7 -7
@@ 5,24 5,24 @@

\section{研究動機}

在大專院校,尤其是資訊相關科系,對於架設網頁的需求相當常見。在陽明交大資工系,我們觀察到實驗室與教授個人普遍皆有架站需求,並且每個單位使用的架站技術皆有所差異。有些單位為了方便管理自己的網頁服務,將網頁架設於放置在系上代管機房的個人伺服器上,卻常因實驗室內部交接因素等,久而久之疏於管理。同時,這類型的網頁服務通常負載極低,四散在各個個人伺服器的場景對於用電以及機房空間管理也相當不理想。對於架設網站需求,如果能夠達到集中管理,在環境、資源運用與資訊安全等方面皆可預期有相當的好處。
在大專院校,尤其是資訊相關科系,對於架設網頁的需求相當常見。在陽明交大資工系,我們觀察到實驗室與教授個人普遍皆有架站需求,並且每個單位使用的架站技術皆有所差異。有些單位為了方便管理自己的網頁服務,將網頁架設於放置在系上代管機房的個人伺服器上,卻常因實驗室內部交接不確實等因素,久而久之疏於管理。同時此類網頁服務通常負載極低,四散在個人伺服器的情景對於用電與機房空間管理相當不理想。針對架設網站的需求,如果能夠達到集中管理,在環境、資源運用與資訊安全等方面皆可預期有相當的好處。

對於大量網站的集中管理,常見的方案依據平台對於網站性質的彈性,由低到高大致可以分為以下類別:
關於大量網站的集中管理,常見的方案依據平台對於網站性質的彈性,由低到高大致可分為以下類別:

\begin{onehalfspacing}
\begin{itemize}
    \item 靜態內容網頁代管
    \item 特定內容管理系統(如: WordPress, Drupal 等)代管
    \item 特定後端語言(如: PHP 等)代管
    \item 特定內容管理系統(如 WordPress、Drupal)代管
    \item 特定後端語言(如 PHP)代管
\end{itemize}
\end{onehalfspacing}

然而考量到資工系系上網頁技術的多元廣泛,以上的形式皆不足以滿足需求。其中若以特定內容管理系統或後端語言提供服務,在整個資工系的規模下,面對內容管理系統或語言本身的更迭,難免需要對特定使用者提供特定版本,以利使用者逐步進行版本更新,在管理上負擔特別大。
然而考量到資工系系上網頁技術的多元廣泛,以上的形式皆不足以滿足需求。其中若以特定內容管理系統或後端語言提供服務,在整個資工系的規模下,面對系統或語言本身的更迭,難免需要對部份使用者提供特定版本,以利使用者逐步進行版本更新,在管理與系統設計上負擔特別大。

我們希望提供的平台可以支援各種網頁技術,達成對程式語言的中立 (language-neutral),其中尤其是直譯式語言 (interpreted language) 因在開發迭代速度上的優勢,在網頁後端特為流行。考量到對直譯式語言在執行期間需要直譯器,普遍對於環境要求較高,以容器或是虛擬機為形式提供服務最為自然。為了避開虛擬機的額外運算負擔,我們選擇相對輕量且在資源分配上較有彈性的容器技術作為平台的基本提供形式。
我們希望提供的平台可以支援各種網頁技術,達成對程式語言的中立 (language-neutral),其中尤其是直譯式語言 (interpreted language) 因在開發迭代速度上的優勢,在網頁後端特為流行。考量到直譯式語言在執行期間需要直譯器,普遍對於環境要求較高,以容器或是虛擬機為形式提供服務最為自然。為了避開虛擬機的額外運算負擔,我們選擇相對輕量且在資源分配上較有彈性的容器技術作為平台的基本提供形式。

綜上所述,我們需要一個網頁代管平台,除了一般平台常見的配額等管理機制外,我們希望以容器作為使用者部屬網頁的基本方式。透過此平台,我們可以集中管理系上四散的網頁服務,提高資源運用效率。另外,以容器作為形式也使得平台本身具備往其他需求發展的可行性,雖設計上以架設網頁服務為主要需求,實質上可以規劃為通用型雲端運算平台。

\section{研究目標}

對於容器的大量部屬,目前最廣泛最通用的技術為 Kubernetes。我們希望以 Kubernetes-as-a-Service 的型式,提供代管的 Kubernetes 平台,讓使用者能夠直接透過標準的 Kubernetes API 進行操作。平台將針對系上的大量多人使用需求規劃,並且雖著重於網頁服務的架設,同時也保留 Kubernetes 本身的通用性,可以作為通用的雲端運算平台使用。對於不熟悉 Kubernetes 的使用者,我們也應提供友善的網頁界面,使其也能利用平台達成一般網頁的架設。
對於容器的大量部屬,目前最廣泛、最通用的管理技術為 Kubernetes。我們希望以 Kubernetes-as-a-Service 的型式,提供代管的 Kubernetes 平台,讓使用者能夠直接透過標準的 Kubernetes API 進行操作。平台將針對系上的大規模使用場景規劃,並且雖著重於網頁服務的架設,同時也保留 Kubernetes 本身的通用性,可以作為通用的雲端運算平台使用。對於不熟悉 Kubernetes 的使用者,我們也應提供友善的網頁界面,使其也能利用平台達成一般網頁的架設。

M Sections/2.Backgrounds.tex => Sections/2.Backgrounds.tex +37 -26
@@ 5,16 5,16 @@

\section{Kubernetes}

Kubernetes (簡稱 K8s)為一容器編排 (orchestration) 系統,其主要任務為將容器委派至叢集節點上執行。為了對網路服務容器達到理想的編排,Kubernetes 也帶有負載均衡、高可用性及自動擴展等網路功能,因此可以將 Kubernetes 視為高度可擴展、可靠的網路程式平台。
Kubernetes\cite{kubernetes} (簡稱 K8s)為一容器編排 (orchestration) 系統,其主要任務為將容器排程至叢集節點上執行。為了對網路服務容器達到理想的編排,Kubernetes 也帶有負載均衡、高可用性及自動擴展等網路應用常見功能,因此亦可將 Kubernetes 視為高度可擴展、可靠的網路程式平台。

\subsection{Kubernetes 架構}

Kubernetes 提供 RESTful API 做為主要控制手段,以 resources 作為對操作意圖的描述以及結果,將系統操作以非同步的形式建模為對 resources 進行讀寫,並且將系統大致切成兩大部份:負責提供 API 與 resources 資料存儲的 API 伺服器 kube-apiserver,以及實際實做 resources 所代表的操作的 controllers。典型的操作流程大致如下:
Kubernetes 提供 RESTful API 做為主要控制手段,以 resources 代表操作意圖及其結果,將系統操作以非同步的形式建模為對 resources 進行讀寫,並且將系統大致切成兩大部份:負責提供 API 與 resources 資料存儲的 API 伺服器 kube-apiserver,以及實際實做 resources 所代表的操作的 controllers。典型的運作流程大致如下:

\begin{onehalfspacing}
\begin{enumerate}
    \item 使用者建立一 resource,並在其 \verb|spec| 欄位描述需要的系統狀態
    \item kube-apiserver 通知相關 controller 有新的 resource 創立
    \item 使用者建立一 resource,並在其 \verb|spec| 欄位描述期望的系統狀態
    \item kube-apiserver 通知相關 controller 新的 resource 創立事件
    \item controller 根據 \verb|spec| 欄位進行操作,嘗試滿足 \verb|spec|,並將結果存入 \verb|status| 欄位
    \item kube-apiserver 通知使用者 resource 有所變更
    \item 使用者透過更新後的 \verb|status| 欄位得知操作結果


@@ 24,46 24,57 @@ Kubernetes 提供 RESTful API 做為主要控制手段,以 resources 作為對
\begin{figure}[htb]
    \centering
    \includegraphics[width=\textwidth]{assets/kubernetes.png}
    \caption{Kubernetes 操作模型簡易示意圖}
    \caption{Kubernetes 運作模型簡易示意圖}
\end{figure}

\noindent 這個架構使得 Kubernetes 在功能面上極易擴展,只須對 kube-apiserver 註冊一個新的 resource 種類,並且實做相關 controller 邏輯,便可以擴展 Kubernetes API。kube-apiserver 除了資料存儲以外,也包含了基本的資料驗證、身份驗證以及相關授權機制,使得 controller 能夠更專注於達成 resource 邏輯的實做,進一步減少擴展開發者的負擔。同時在 resource 本身的設計上,通常也會盡量使描述的操作是可以被重複執行的 (idempotent),令 controller 不須額外維護內部狀態 (stateless),簡化 controller 的部屬管理以及提高 controller 的容錯性,使整體系統更為易用且可靠。
此架構使得 Kubernetes 在功能面上極易擴展,只須對 kube-apiserver 註冊一個新的 resource 種類,並且實做相關 controller 邏輯,便可以擴展 Kubernetes API。kube-apiserver 除了資料存儲以外,也包含了基本的資料驗證、身份驗證以及相關授權機制,使得 controller 能夠更專注於達成 resource 邏輯的實做,減少擴展開發者的負擔。同時在 resource 本身的設計上,也會盡量使描述的操作是可被重複執行的 (idempotent),令 controller 不須額外維護內部狀態 (stateless),簡化 controller 的部屬管理以及提高容錯空間,使整體系統更為易用且可靠。

% maybe a subsection here if it grows

Kubernetes resources 的種類帶給 resources 既定的語意和格式,例如:Pod 代表一組可以互通部份設定的容器、Service 代表網路上具備負載均衡的一個存取點、Node 代表叢集中的一個節點等。其中種類又分為兩大類型:namespaced 與 cluster-scoped。Namespaced 代表此種類在 API 上受到 Namespace 分隔,在不同的 Namespace 下,各個 resources 無法相互關聯,通常用於描述賦予叢集的工作 (workload),Pod 與 Service 即為此類:Service 可以關聯到多個 Pod 提供實際服務內容,但在設計上不允許 Service 取用其他 Namespace 下的 Pod。Cluster-scoped 的種類則不受 Namespace 管轄,屬於整個叢集,常見於描述叢集本體的設定,Node 與 Namespace 本身即為此類。在使用慣例上,Namespace 用以切分不同的應用,使得無關的應用在部屬設定上不會互相衝突影響,但須注意 Namespace 僅只限制 resources 能夠描述的相互關係,並不代表會對實際運行的容器或網路進行隔離加固。
Kubernetes resources 的種類形成了既定的語意和格式,例如:Pod 代表一組可以互通部份設定的容器、Service 代表網路上具備負載均衡的一個存取點、Node 代表叢集中的一個節點等。Resource 種類又分為兩大類型:namespaced 與 cluster-scoped。Namespaced 代表此種類在 API 上受到 Namespace 分隔,於不同的 Namespace 下,各個 resources 無法相互關聯,通常用於描述賦予叢集的工作負載 (workload),Pod 與 Service 即為此類:Service 可以關聯到多個 Pods 提供實際服務內容,但設計上並不允許 Service 取用其他 Namespace 下的 Pod。Cluster-scoped 的種類則不受 Namespace 管轄,屬於整個叢集,常見於描述叢集本體的配置,Node 與 Namespace 本身即為此類。以使用慣例而言,Namespace 用以切分不同的應用,使得無關的應用在部屬設定上不會互相衝突影響,但須注意 Namespace 僅只限制 API 上能夠描述的相互關係,並不代表會對實際運行的容器或網路環境進行隔離加固。

\subsection{Kubernetes 身份驗證}

Kubernetes 的身份驗證策略採用完全以驗證手段提供身份資訊的方式,包含身份名稱以及所在的群組等。Kubernetes 原則上並不存放身份對應的資料,這樣的設計使得伺服器負擔減少,同時有架構單純、易於除錯等優勢,但根據手段不同,可能會使得修改相關資訊(如修改所在的群組)變得不便。其中面向使用者的驗證手段主要有:X.509 憑證、authenticating proxy、static tokens、webhook tokens、ServiceAccount tokens 與 OpenID Connect tokens。
Kubernetes 提供多個身份驗證手段,可搭配混合使用,在設計上盡量單獨以驗證手段提供完整身份資訊,包含身份名稱以及所在的群組等,叢集本身以不存放身份對應的資料為原則。這樣的設計使得伺服器負擔減少,同時具有架構單純、易於除錯等優勢,但根據手段不同,可能會使得更動身份資訊(如修改所在的群組)顯得不便。常見的驗證手段主要有:X.509 憑證、authenticating proxy、static tokens、webhook tokens、ServiceAccount tokens 與 OpenID Connect tokens。

Kubernetes 中的 X.509 憑證即為 TLS 客戶端憑證 (client certificate),在 TLS 的驗證模型下,除了伺服器端需要提供憑證確保伺服器端的真實性以外,客戶端也可以提供憑證,使伺服器端得以驗證客戶端的身份。此機制近期又以 mutual TLS (mTLS) 的名稱流行,強調雙方都可以驗證彼此的身份。Kubernetes 將身份名稱與所在群組存放在客戶端憑證的 Subject 屬性內,並且要求憑證來自特定(通常直接由叢集管理)的簽發單位 (certificate authority, CA),藉此確保資訊的真實性。雖然 X.509 標準有定義憑證的撤銷機制,但目前 Kubernetes 並沒有相關實做,導致只能利用簽發短期限的憑證,達到金鑰洩漏的減災,同樣原因也使得這個方法不易修改群組資訊。由於客戶端憑證較不方便使用,尤其需要透過頻繁換發短期限憑證達到安全性,相關自動化成本較高,除了叢集內部元件的身份驗證外,較不常用於使用者端,多見於非正式環境,或是另外嚴謹保存作為管理者的備用手段。
Kubernetes 中的 X.509 憑證即為 TLS 客戶端憑證 (client certificate),在 TLS 的驗證模型下,除了伺服器端需要提供憑證證明本身的真實性以外,客戶端也可以提供憑證,使伺服器端得以驗證客戶端的身份。此機制近期又以 mutual TLS (mTLS) 的名稱流行,強調雙方都可以驗證彼此的身份。Kubernetes 將身份名稱與所在群組存放在客戶端憑證的 Subject 屬性內,並且要求憑證來自特定的簽發單位 (certificate authority, CA),通常直接由叢集管理,藉此確保資訊的真實性。雖然 X.509 標準有定義憑證的撤銷機制,但目前 Kubernetes 並沒有相關實做,導致只能利用簽發短效期的憑證,達到金鑰洩漏場景的減災。缺乏撤銷機制也使得這個驗證方法不易修改身份資訊。由於客戶端憑證較不方便使用,尤其需要透過頻繁換發短效期憑證達到安全性,相關自動化成本較高,除了叢集內部元件的身份驗證外,較不常用於使用者端,多見於非正式環境,或是另外嚴謹保存作為管理者的備用手段。

Authenticating proxy 透過在 Kubernetes API 之前加一層 proxy 伺服器進行驗證邏輯。Proxy 在將請求轉發給 Kubernetes API 時會加上相關 HTTP headers 以表明使用者身份,而 proxy 本身對使用者的認證方式並沒有限制。這個方法等同於將驗證邏輯直接抽出另外自行實做,開發成本較高,並且需自行注意如撤銷等機制的是否完善。
Authenticating proxy 透過在 Kubernetes API 之前加一層代理伺服器進行驗證邏輯。在將請求轉發給 Kubernetes API 時,代理伺服器會加上約定的 HTTP headers 以表達使用者身份。對於代理伺服器驗證使用者的方式並沒有限制。這個方法等同於將驗證邏輯直接抽出另外自行實做,相當富有彈性,但開發成本較高,並且需自行注意撤銷等機制是否完善。

其餘的手段皆是透過 token 進行身份驗證,但 token 本身有所不同。Static tokens 是在 Kubernetes 本身預先設定好一個 token 對應使用者名稱、所在群組的清單,token 本身通常採用一個隨機的字串。由於目前實做上更動這份清單需要重新啟動 kube-apiserver,這個方法較少人採用。Webhook tokens 則是透過管理者提供的 HTTPS API 去將 token 對應到相關資訊,比 static tokens 來的有彈性,可以動態更動不須重啟 kube-apiserver。
其餘的手段皆是透過 token 進行身份驗證,但 token 本身有所不同。Static tokens 是在 Kubernetes 本身預先設定好一個 token 對應身份資訊的清單,token 本身通常採用一個隨機的字串。由於目前更動這份清單需要重新啟動 kube-apiserver,這個方法較少叢集採用。Webhook tokens 則是透過管理者提供的 HTTP API 將 token 對應到身份資訊,比 static tokens 來的有彈性,可以動態更動而不須重啟 kube-apiserver。

ServiceAccount tokens 與 OpenID Connect tokens 則都是 JSON Web Token (JWT),一個有經過簽章的 token 格式,裡面包含身份資訊與使用期限等,Kubernetes 透過驗證簽章來確保他的真實性。ServiceAccount 是一個 resources 種類,代表一個身份,但不支援群組,由此可以簽發 ServiceAccount tokens,刪除 ServiceAccount resources 可以撤銷全部由其發出的 tokens。簽發 ServiceAccount tokens 時也可以進一步綁定 Secrets\footnote{Secret: Resources 種類,提供資料儲存,本身並不帶有任何功能。} 或 Pods,使用時會額外檢查這些 resources 是否存在,達成以 token 為單位的撤銷。由於可以透過 Kubernetes API 管理,ServiceAccount tokens 常用於自動化場景,也常用於 controllers 元件。由於 ServiceAccount tokens 採用標準的 JWT 格式,透過簽章即可確認真偽,也有自 Kubernetes 存取外部系統時,供外部系統驗證的應用。
ServiceAccount tokens 與 OpenID Connect tokens 則都是採用 JSON Web Token (JWT),一個有經過簽章的 token 格式,裡面包含身份資訊與效期等,Kubernetes 透過驗證簽章來確保真實性。ServiceAccount 是一個 resource 種類,代表一個身份,但不支援群組,由其可以簽發 ServiceAccount tokens。刪除 ServiceAccount resources 可以撤銷全部由其發出的 tokens,簽發 token 時也可以進一步綁定 Secrets\footnote{Secret: Resource 種類,提供資料儲存,本身並不帶有任何功能。} 或 Pods,使用當下會額外檢查這些 resources 是否存在,達成以 token 為單位的撤銷。由於可以透過 Kubernetes API 管理,ServiceAccount tokens 常用於自動化場景,也常用於 controllers 元件。因為 ServiceAccount tokens 採用標準的 JWT 格式,透過簽章即可確認真偽,也有自 Kubernetes 存取外部系統時,供外部系統驗證來源的應用。

OpenID Connect (OIDC) 則是一個基於 OAuth 框架衍生的身份驗證協定,常用於網頁應用場景,由中心化的伺服器進行驗證,將身份資訊授予其他應用使用,並且可以讓使用者管理對應用存取身份資料的授權。Kubernetes 本身並不實做 OIDC 協定,而是利用驗證流程 OIDC 伺服器所簽發的 JWT (\verb|id_token|) 進行驗證,並預期由客戶端處理 OIDC 協定相關操作。由於可以跟現有 OIDC server 整合,實做容易且使用者不須額外的註冊流程,常用於使用者的互動存取。
OpenID Connect (OIDC) 則是一個基於 OAuth 框架衍生的身份驗證協定,廣泛運用於網頁應用場景,由中心化的伺服器進行驗證,將身份資訊授予其他應用使用,並且可以讓使用者管理對應用存取身份資料的授權。Kubernetes 本身並不實做 OIDC 協定,而是利用此機制下,OIDC 伺服器所簽發的 JWT(在協定上以 \verb|id_token| 稱呼)進行驗證,並預期由客戶端處理 OIDC 協定流程。由於可以跟現有 OIDC 伺服器整合,實做容易且不須額外的使用者註冊流程,常用於使用者的互動存取。

% 可能弄個對 revocation 和 expiration support 的比較表, 但大概要想辦法加上 renew 好不好實施(?) 去 justify 在 expiration 可以壓很短的情況下有沒有 revocation 還好
\begin{table}[htb]
    \centering
    \caption{Kubernetes 驗證機制彙整}
    \begin{tabular}{l || c | c | c | l}
        & 效期 & 撤銷 & 管理、開發成本 & 典型場景 \\
        \hline\hline
        X.509 憑證 & 有 & 無 & 中 & 叢集內部、測試環境 \\ \hline
        Authenticating proxy & 自行實做 & 自行實做 & 高 & 需深入客製化時 \\ \hline
        Static tokens & 無 & 有 & 中 & 小型規模叢集 \\ \hline
        Webhook tokens & 自行實做 & 自行實做 & 高 & 需客製化時 \\ \hline
        ServiceAccount tokens & 有 & 有 & 低 & 工作負載、自動化 \\ \hline
        OpenID Connect tokens & 有 & 無 & 低 & 使用者互動存取 \\
    \end{tabular}
\end{table}

\subsection{Kubernetes 存取控制}

Kubernetes 主要透過兩個機制達成使用者的存取控制,其一是 RBAC (Role-based access control)。RBAC 可以根據 resources 的種類、所在的 Namespace 或是特定的 resource 實例授予使用者對其進行操作的權力,包含創立、刪除、更新、獲取、列舉等,不同類型的操作可以分別授予。
Kubernetes 主要透過兩個機制達成使用者的存取控制,其一是 RBAC (Role-based access control)。RBAC 可以根據 resources 的種類、所在的 Namespace 或是特定的 resource 實例授予使用者對其進行各種操作的權力,包含創立、刪除、更新、獲取、列舉等,不同類型的操作可以分別授予。

另一個機制為 admission control,在 RBAC 後執行,可以根據被創立或更新的 resources 內容進行控制。實做該邏輯的 admission controllers 主要又分為 mutating 與 validating 兩種。Mutating admission controllers 可以修改 resources 內容,常用於對 resources spec 中的特定欄位賦予預設值。以 mutating admission controllers 賦予預設值的方法,比起在實做 resources 的 controller 定義預設行為,以使用者的立場更為明確,使用者可以觀察創建或修改後的 resource 內容得知其行為,對於平台提供者,也可以透過這個機制實做平台特定的預設值。Validating admission controllers 則無法修改 resources 內容,只能做出允許或拒絕操作的決策,為了能夠驗證最終的 resources 內容,編排在 mutating admission controllers 後執行,常用於執行特定設定上的政策。由於 Kubernetes 功能上的廣泛,不適合將每個功能都規劃成獨立的 resources 種類,用 RBAC 針對 resources 種類進行存取控制有時會顯得不足,admission control 便補足了這方面的彈性。
另一個機制為 admission control,在 RBAC 後執行,可以根據被創立或更新的 resource 內容進行管控。實做控制邏輯的 admission controllers 主要又分為 mutating 與 validating 兩種。Mutating admission controllers 可以修改 resources 內容,常用於對 resource \verb|spec| 中的特定欄位賦予預設值。以 mutating admission controllers 賦予預設值的方法,比起在實做 resources 的 controller 定義預設行為,以使用者的角度更為明確,使用者可以觀察最終儲存的 resource 內容得知其行為,對於平台提供者,透過這個機制實做平台特定的預設值也更為方便。Validating admission controllers 則無法修改 resources 內容,只能做出允許或拒絕操作的決策,為了能夠驗證修改後的 resources 內容,編排在 mutating admission controllers 後執行,常用於執行特定設定上的管制政策。由於 Kubernetes 功能上的廣泛,不適合將每個功能都規劃成獨立的 resource 種類,用 RBAC 針對 resource 種類進行存取控制有時會顯得不足,admission control 便補足了這方面的彈性。

Kubernetes 內建許多 admission controllers,其中一些用來實做基本功能並預設啟用,例如資源配額的部份邏輯即是以這個機制實做。另外也有些預設停用的 admission controllers,提供給管理者進行平台加固或者調整行為使用。
Kubernetes 內建許多 admission controllers,其中一些用來實做基本功能並預設啟用,如資源配額的部份邏輯。另外也有些預設停用的 admission controllers,提供給管理者進行平台加固或者調整行為使用。

對於內建的 admission controllers 不敷使用的場合,Kubernetes 提供兩個機制讓管理者進一步自訂邏輯:webhooks 與 Common Expression Language (簡稱 CEL)。Webhooks 透過呼叫管理者提供的 HTTPS API 達成,支援 mutating 與 validating,可以透過任何能架設 HTTPS API 的語言編寫,在生態系上已經有多個框架可以協助開發,例如:Open Policy Agent 與 Kyverno 等。CEL 為一結構資料處理語言,常用以使軟體功能可程式化,以 Kubernetes 1.31 而言,目前只有 validating 進入穩定狀態,對 mutating 的支援仍在測試階段 (alpha)。相對於 webhooks,使用 CEL 可以直接在 kube-apiserver 上執行邏輯,省略了呼叫 HTTPS API 的網路溝通,減少造成的延遲影響與管理負擔,但能夠進行的操作受限於 Kubernetes 對其執行環境提供的函式庫。
對於內建的 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 對其執行環境提供的函式庫。

\section{Helm}

Helm 是用來簡化 Kubernetes 上的應用部屬流程的工具,其手段是透過模板化,使得部屬上的設定可以透過更貼近應用本身的角度撰寫。在 Kubernetes 上,典型的部屬應用流程會牽涉多個 resources,例如:Deployment\footnote{Deployment: Resources 種類,提供高層次的 Pod 管理,以實做 Pod 的更新與複製等。} 用以管控 Pods、Service 將 Pods 提供的服務集結做負載均衡、Ingress\footnote{Ingress: Kubernetes resources 種類,配置叢集的 HTTP 反向代理,將多個網頁服務集中提供外界存取。} 為 Service 的網頁服務設立反向代理至公網公開等。多個 resources 使得應用部屬有一定的複雜程度,Helm 可以提供更高層級、以應用為中心的單一設定界面,藉此簡化 Kubernetes 的使用。
Helm\cite{helm} 是用來簡化 Kubernetes 上的應用部屬流程的工具,其原理為透過模板化,使得部屬上的設定可以透過更貼近應用本身的角度撰寫。在 Kubernetes 上,典型的部屬應用流程涉及多個 resources,例如:Deployment\footnote{Deployment: Resource 種類,提供高層次的 Pod 管理,以實做 Pod 的更新與複製等。} 用以管控 Pods、Service 將 Pods 提供的服務集結做負載均衡、Ingress\footnote{Ingress: Resource 種類,配置叢集的 HTTP 反向代理,將多個網頁服務集中提供外界存取。} 為 Service 的網頁服務設立反向代理至公網公開等。多個 resources 使得應用部屬有一定的複雜程度,Helm 可以提供更高層級、以應用為中心的單一設定界面,藉此簡化 Kubernetes 的使用。

Helm 用來產生 Kubernetes resources 的模板稱為 Helm Chart,Helm Charts 會集中在 Helm Repository 裡提供使用,Helm Chart 的模板參數稱為 Helm Values,由 Helm 安裝起來的一套應用稱為 Helm Release。透過模板產生的 resources 定義除了套用到 Kubernetes 上之外,Release 會對 resources 額外進行版本紀錄,用以實做更新、回滾、解除安裝等操作。Release 的版本追蹤資訊通常以 Secrets 的形式儲存在叢集內。
Helm 用來產生 Kubernetes resources 的模板稱為 Helm Chart,Helm Charts 會集中在 Helm Repository 裡提供使用,Helm Chart 的模板參數稱為 Helm Values,由 Helm 安裝起來的一套應用稱為 Helm Release。透過模板產生的 resources 定義除了套用到叢集上以外,Release 會對其額外進行版本紀錄,用以實做更新、回滾、解除安裝等操作。Release 的版本追蹤資訊通常以 Secrets 的形式儲存在叢集內。

\begin{figure}[htb]
    \centering


@@ 71,16 82,16 @@ Helm 用來產生 Kubernetes resources 的模板稱為 Helm Chart,Helm Charts 
    \caption{Helm 原理示意圖}
\end{figure}

Helm 使得在 Kubernetes 叢集上安裝軟體變得相當簡便,Helm Chart 已經成為相當常見的軟體交付手段。在生態系上,軟體開發者通常會於自己架設的 Helm Repository 提供產品的 Helm Chart。另外也存在第三方的業者(如 Bitnami)對常見的開放原始碼軟體進行包裝,大量的提供 Helm Charts。
Helm 使得在 Kubernetes 叢集上安裝軟體變得相當簡便,Helm Chart 已經成為十分常見的軟體交付手段。在生態系上,軟體開發者通常會於自行架設的 Helm Repository 提供產品的 Helm Charts。另外也存在第三方的業者(如 Bitnami)對常見的開放原始碼軟體進行包裝,大量的提供 Helm Charts。

\section{Single-Page Application}

Single-Page Application (簡稱 SPA)是一種網頁架構。傳統網頁架構由伺服器端控制網頁內容,在伺服器上執行模板輸出 HTML。SPA 則以 API 的形式從伺服器端獲取資料,再由瀏覽器端執行呈現邏輯。以瀏覽器端控制呈現可以局部的修改 HTML,在不重新載入整個頁面的情況下達到動態的資料更新。SPA 同時也以瀏覽器端邏輯控制頁面載入,透過局部更新使在不同頁面間的導覽轉換更為順暢。不同網址的頁面實質上是以同樣的起始 HTML 載入瀏覽器端程式碼,再經由程式碼中的分流邏輯根據網址做不同的呈現。比起傳統網頁架構,SPA 除了能達成更流暢的使用者體驗外,因為將呈現邏輯移到了瀏覽器端,於伺服器端的負擔降低,在運行成本上也有相當的優勢。在網頁編寫上,將資料處理(伺服器端)與資料呈現(瀏覽器端)分離,也有助於將兩者使用不同語言或框架,分別採用對更擅長於該方面的產品實做。
Single-Page Application (簡稱 SPA)是一種網頁架構。傳統網頁架構由伺服器端控制網頁內容,在伺服器上執行模板輸出 HTML。SPA 則以 API 的形式從伺服器端獲取資料,再由瀏覽器端執行呈現邏輯。以瀏覽器端控制呈現可以局部的修改 HTML,在不重新載入整個頁面的情況下達到動態的資料更新。SPA 同時也以瀏覽器端邏輯控制頁面導覽,透過局部更新使在不同頁面間的轉換更為順暢。不同網址的頁面實質上是以同樣的起始 HTML 載入瀏覽器端程式碼,再經由程式碼中的分流邏輯根據網址做不同的呈現。比起傳統網頁架構,SPA 除了能達成更流暢的使用者體驗外,因為將呈現邏輯移到了瀏覽器端,於伺服器端的負擔降低,在運行成本上也有相當的優勢。在網頁編寫上,將資料處理(伺服器端)與資料呈現(瀏覽器端)分離,也有助於將兩者使用不同語言或框架,分別採用對更擅長於該方面的產品實做。

\section{WebAssembly}

WebAssembly (簡稱 WASM)是在瀏覽器上的一個通用型虛擬機指令集,用途並非模擬實際存在的硬體架構,而是提供一個一致的軟體執行環境。比起其他類似目的的通用虛擬機(例如 Java virtual machine 等),WebAssembly 設計上接近硬體,但仍然維持一定程度的通用性,使得可以在各種不同的硬體架構上以較接近原生應用的效能執行。許多程式語言透過對編譯器增加對 WebAssembly 指令集的支援,達成有效率的支援瀏覽器環境,使得網頁開發技術有更多不同的選擇,同時也有利於將一般應用程式或函式庫移植到瀏覽器上運行。WebAssembly 也包含與瀏覽器上 JavaScript 程式碼界接的基本要素,使得 WebAssembly 程式可以利用瀏覽器上既有的程式化界面,另外也令網頁開發能夠採取傳統 JavaScript 與 WebAssembly 混合的策略。
WebAssembly\cite{haas2017bringing} (簡稱 WASM)是在瀏覽器上的一個通用型虛擬機指令集,用途並非模擬特定實際存在的硬體架構,而是提供一個一致的軟體執行環境。比起其他類似目的的通用虛擬機(如 Java virtual machine),WebAssembly 設計上更接近硬體,但仍然維持一定程度的通用性,使其能夠在各種不同的硬體架構上,以較為接近原生應用的效能執行。許多程式語言透過於編譯器增加對 WebAssembly 指令集的支援,達成有效率地支援瀏覽器環境,使得網頁開發技術有更多不同的選擇,同時也有利於將一般應用程式或函式庫移植到瀏覽器上運行。WebAssembly 也包含與瀏覽器上 JavaScript 程式碼界接的基本要素,使得 WebAssembly 程式可以利用瀏覽器上既有的程式化界面,另外也令網頁開發能夠採取傳統 JavaScript 與 WebAssembly 混合的策略。

% 以下講了沒啥用 不講又覺得缺了點什麼

WebAssembly 近期也有在網頁生態以外的應用。透過 WebAssembly 與外界溝通能力,只須界定一個 Application Binary Interface (ABI),即可建構一個擴充元件的機制,使得軟體產品可以利用許多不同的程式語言擴充邏輯,並且不受運行環境的硬體架構限制,比起傳統使用 C 語言動態載入函式庫作為中介的方式來的更有彈性。
WebAssembly 近期也發展出網頁生態以外的應用。透過 WebAssembly 與外界溝通的能力,只須定義 Application Binary Interface (ABI),即可建構一個擴充元件的機制,使得軟體產品能夠利用多種不同的程式語言擴充邏輯,並且不受運行環境的硬體架構限制,比起傳統使用 C 語言動態載入函式庫作為中介的方式來的更有彈性。

M Sections/3.RelatedWorks.tex => Sections/3.RelatedWorks.tex +10 -9
@@ 5,11 5,11 @@

\section{CScloud}

先前系計中已經有意識到基於容器的網頁服務代管平台需求,發展出一套雛型系統,並且歷經兩代變革,分別為 CScloud\cite{cskloud} 與 CScloud with PEKOS (Policy-Enforced Kubernetes OAuth System)\cite{pekos},本文以「一代」與「二代」代稱。雖然發展已久,但實做仍不完全,並未上線開放使用,在架構規劃也有部份缺點。以下簡單帶過其歷史沿革,並以二代為主進行介紹。
先前系計中已經有意識到基於容器的網頁服務代管平台需求,發展出一套雛型系統,並且歷經兩代變革,分別為 CScloud\cite{cskloud} 與 CScloud with PEKOS (Policy-Enforced Kubernetes OAuth System)\cite{pekos},本文以「一代」與「二代」代稱。雖然發展已久,但實做仍不完全,並未上線開放使用,在架構規劃也有部份缺點。以下簡略帶過其歷史沿革,並以二代為主進行介紹。

一代系統確立了對平台的大致規劃:以 Kubernetes 提供基於容器的網頁代管服務、以 Kubernetes Namespace 在單一叢集下實施多租戶設計、串接 Kubernetes 內建資源配額機制。作者經由自訂 Kubernetes resources,實做了透過根據由 LDAP\footnote{Lightweight Directory Access Protocol,用於提供身份資訊存取服務的協定。} 獲取的使用者資訊,為使用者設立 Namespace、資源配額以及以 RBAC 控管使用的機制。另外提供對平台網頁界面的設計稿,提出以 Helm 簡化使用方式的想法。在使用者驗證上,作者規劃以平台網頁界面透過串接系計中的身份驗證系統,再由網頁界面創立 token 以進行 Kubernetes API 驗證的使用流程。使用者可以根據該 token 自行存取 Kubernetes API,或者直接使用平台網頁界面存取部份功能。但由於作為身份驗證手段的網頁界面尚未實做,使用者無法進行任何操作,系統無法使用待進一步開發。另外作者指出設計上尚缺乏域名使用權的管控機制。
一代系統確立了對平台的大致規劃:以 Kubernetes 提供基於容器的網頁代管服務、以 Namespace 在單一叢集下實施多租戶設計、串接 Kubernetes 內建資源配額機制。作者經由自訂 Kubernetes resource 種類,實做了根據自 LDAP\footnote{Lightweight Directory Access Protocol,用於提供身份資訊存取服務的協定。} 獲取的使用者資訊,為使用者設立 Namespace、資源配額與以 RBAC 控管使用的機制。另外提供對平台網頁界面的初步設計稿,提出以 Helm 簡化使用方式的想法。在使用者身份驗證上,作者構思了以平台網頁界面串接系計中的身份驗證系統,再於網頁界面上創立 token 以進行 Kubernetes API 驗證的使用流程。使用者可以透過該 token 自行存取 Kubernetes API,或者直接使用平台網頁界面存取部份功能。但由於作為身份驗證手段的網頁界面尚未實做,使用者無法進行任何操作,系統無法使用,有待進一步開發。另外作者指出設計上尚缺乏域名使用權的管控機制。

二代系統沿襲了一代對於多租戶與資源配額的設計,另外將身份驗證以 OIDC 實做,發展出可運作的基本網頁界面,並實做部屬單一網頁服務,以及安裝少數特定軟體的功能,但並未如一代規劃開放使用者直接存取 Kubernetes API。對於 Kubernetes 叢集本身,二代系統指出在此基於 Namespace 的多租戶設計下,Kubernetes RBAC 驗證對於限制使用者的行為並不足夠,並且導入 admission control 作為加固手段,以 Open Policy Agent 框架透過 webhooks 自行實做 admission control 邏輯,同時也以此實做域名使用權管控機制。二代系統雖然已經可以運作,具有一定的基本功能,卻因為實做皆以概念驗證的角度撰寫,品質並不適合開放使用,導致系計中普遍對系統有安全性疑慮,並未實際上線。
二代系統沿襲了一代對於多租戶與資源配額的設計,另外將身份驗證以 OIDC 實做,發展出可運作的基本網頁界面,並實做部屬單一網頁服務,以及安裝少數特定軟體的功能,但並未如一代規劃開放使用者直接存取 Kubernetes API。對於叢集本身,二代指出在此基於 Namespace 的多租戶設計下,RBAC 對於限制使用者的行為並不足夠,並且導入 admission control 作為加固手段,以 Open Policy Agent 框架透過 webhooks 自行實做 admission control 邏輯,同時也以此實做域名使用權管控機制。二代系統雖然已經可以運作,具有些許的基本功能,卻因為實做皆以概念驗證的角度撰寫,品質並不適合開放使用,導致系計中內部普遍對系統有安全性疑慮,並未實際上線運行。

\begin{figure}[htb]
    \centering


@@ 17,13 17,14 @@
    \caption{CScloud with PEKOS 實做架構簡易示意圖}
\end{figure}

在實做方面,為了簡化同時避免使用 LDAP、OIDC 兩個協定在類似的場景,二代去除了一代使用自訂 Kubernetes resources 種類實做的 LDAP 使用者開通功能,取而代之的是由網頁界面本身,在使用者首次登入時進行相關的開通,而開通後的操作皆由使用者對應的身份操作 Kubernetes。
在實做方面,為了避免同時使用 LDAP、OIDC 兩個協定在類似的場景,二代去除了一代使用自訂 Kubernetes resource 種類實做的 LDAP 使用者開通功能,取而代之的是由網頁界面本身,在使用者首次登入時進行相關的開通,而開通後的互動皆由使用者對應的身份操作 Kubernetes。

對於安裝少數特定軟體的功能實質是使用 Helm 實做,但網頁界面只提供極少數的 Charts 開放使用,並由程式邏輯產生其 Values 設定,使用者無法對安裝設定(例如資源配置等)做任何修改。由類似的方式可以將功能推廣至其他應用的安裝,以達成一代規劃藉由 Helm 簡化系統使用的願景,但需要人力為每個應用逐一撰寫產生 Values 的邏輯,過於勞力密集且十分缺乏彈性,並且尚未實做更新、回滾等功能。
二代安裝少數特定軟體的功能實質是使用 Helm 實做,但網頁界面僅提供極少數的 Helm Charts 開放使用,並由程式邏輯產生其 Helm Values 設定,使用者無法對安裝設定(例如資源配置等)做任何修改。由相同的機制可以將功能推廣至其他應用的安裝,以達成一代規劃藉由 Helm 簡化系統使用的願景,但需要人力為每個應用逐一撰寫產生 Values 的邏輯,過於勞力密集且十分缺乏彈性,並且尚未實做更新、回滾等功能。

在部屬單一網頁服務的部份,則是先設計一個部屬設定客製化表單,再透過填入一個 resources 模板達成,由開發者自行設想的使用需求出發,因此成果也容易顯的相當侷限。以這個角度設計容易帶有過多的假設,例如:假定只須一個容器、假定容器提供服務的 HTTP port number 等,並且沒有顧慮到如安裝資料庫等網頁服務本體外的基礎建設場景。
在部屬單一網頁服務的部份,則是先設計一個部屬設定客製化表單,再透過填入固定的 resources 模板達成,由開發者自行設想的使用需求出發,因此成果也容易顯得相當侷限。以這個角度設計容易忽略部份需求,而帶有過多的假設,例如:假定只須一個容器、假定容器提供服務的 HTTP port number 等,並且無法相容於如安裝資料庫等網頁服務本體外的基礎建設場景。另外,基於模板的概念與 Helm 相似,實做上還有統一簡化的空間。

二代的網頁界面實做使用單體式的傳統架構,包含使用者開通的功能,全部由單一一個網頁後端伺服器負責。使用者開通是藉由以管理者身份存取 Kubernetes API 達成,管理者的驗證相關資訊必須在存放在網頁伺服器上,單體式的架構使得有過大的攻擊面,其他功能的程式碼紕漏可能會導致管理者金鑰外洩,使攻擊者得以藉此控制整座叢集。在安裝特定軟體的部份,因為使用的程式語言與 Helm 不符,採取以執行指令操作 Helm CLI 達成。這種方式雖然易於實做,但也容易產生使用者能夠注入其他指令或是預期外的參數等漏洞。
二代的網頁界面實做採用單體式的傳統架構,包含使用者開通的功能,全部由單一一個網頁後端伺服器負責。使用者開通是藉由管理者身份存取 Kubernetes API 達成,管理者的驗證相關資訊必須在存放在網頁伺服器上,單體式的架構使得這部份有過大的潛在攻擊面,其他功能的程式碼紕漏可能會導致管理者金鑰外洩,使攻擊者得以藉此控制整座叢集。

% 大概留到設計那邊, 帶出 from KaaS 立足點出發的不同
% 二代的實做明顯是由「容器網頁代管平台」、特定用途的 PaaS 的角度出發設計,導致界面功能侷限,沒有充分發揮 Kubernetes 的功能。
在安裝特定軟體的方面,因為使用的程式語言 PHP 與 Helm 所採用的 Go 不符,二代採取以執行指令操作伺服器上的 Helm CLI 達成。這種方式雖然易於實做,但也容易產生使用者能夠注入其他指令或是預期外的參數等漏洞,影響到伺服器的安全。

由於 Kubernetes 非同步的設計,狀態更新的推送顯得十分重要,而二代的網頁實做並沒有針對這點設計,而是仰賴於完整的頁面刷新,這也可能造成過度重複執行其餘資料未變更的邏輯運算,間接使得運行成本增加。

M Sections/4.Architecture.tex => Sections/4.Architecture.tex +4 -4
@@ 1,7 1,7 @@
\chapter{設計方法與實做}
\label{ch:architecture}

本章節敘述本研究基於 CScloud 改良所產生的 CSKloud V3 架構。
本章節敘述本研究吸收 CScloud 的想法,重新設計出的 CSKloud V3 架構,其實做方法,以及網頁界面的功能性。

\section{設計需求}



@@ 129,11 129,11 @@ Namespace 上 \verb|u-| 以及平台提供域名中 \verb|u.| 的命名切分設

ResourceQuota 是 Kubernetes 的一個 resource 種類,用來實做單一 Namespace 下的資源配額,其運作邏輯大致分兩大塊:admission controller 與一般的 controller。ResourceQuota 的 admission controller 屬於 validating,負責在創立或更新 resource 時推算其資源用量的變化值,並且拒絕用量會超出配額的請求。一般的 controller 端則是以更為全面的觀點,監控整體 resources 的變更,並且統計資源用量總額。

ResourceQuota 所能管控的資源大致有兩種:運算資源以及 resources 的數量。運算資源具有量值,例如部屬容器時設定的 CPU 或者記憶體用量限制,以及 PersistentVolumeClaim (PVC)\footnote{PVC: Resources 種類,表示儲存空間請求,需自動或手動與 PersistentVolume(PV,分配實體)耦合。} 中的儲存用量請求。Resources 的數量則是滿足特定條件的 resources 的個數,例如正在運行的 Pods。
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|。

除了運算資源,以及上述針對 resource 內容的管控,我們也對所有使用者能夠創立的 resources 種類進行總量限制,避免濫用。在其限額設計上,我們仍盡量保持讓使用者可以在運算資源限制合理地自由運用。
除了運算資源,以及上述針對 resource 內容的管控,我們也對所有使用者能夠創立的 resource 種類進行總量限制,避免濫用。在其限額設計上,我們仍盡量保持讓使用者可以在運算資源限制合理地自由運用。

\subsection{LimitRange}



@@ 293,7 293,7 @@ CSKloud 開放使用者直接存取 API,並且提供 kubectl 連線設定檔
    \caption{CSKloud V3 網頁界面 Resource Explorer 頁面}
\end{figure}

Resource Explorer 提供對 Kubernetes resource 的基本列出、創立、編輯、刪除的功能,作為使用者與 Kubernetes 互動中最基礎的功能。這個頁面採用 Kubernetes API discovery 機制,在運行時會從 Kubernetes API 查詢所有支援的 resources 種類,未來如果隨著 Kubernetes 演進而有所增減,這個頁面不須經過修改可以直接沿用。
Resource Explorer 提供對 Kubernetes resource 的基本列出、創立、編輯、刪除的功能,作為使用者與 Kubernetes 互動中最基礎的功能。這個頁面採用 Kubernetes API discovery 機制,在運行時會從 Kubernetes API 查詢所有支援的 resource 種類,未來如果隨著 Kubernetes 演進而有所增減,這個頁面不須經過修改可以直接沿用。

在列表的部份,這個頁面採用 Kubernetes API 本身的製表功能,可以對 resources 產出基本的概要,kubectl 的表格呈現亦是採用此機制。使用者可以將游標移動到表格欄位名稱上方,透過提示框了解欄位意義,也可以點擊針對欄位排序。右下方的浮動按鈕可以撰寫新的 resource,點擊表格列則是查看對應的 resource 的完整內容,以 YAML 的形式呈現。在單一 resource 完整呈現中右下方的浮動按鈕功能列表,也有編輯與刪除等功能。


M assets/kubernetes.png => assets/kubernetes.png +0 -0
M ref.bib => ref.bib +28 -4
@@ 1,19 1,43 @@
@materthesis{cskloud,
    title	= {基於 {Kubernetes} 個別用戶資源管控之 {PaaS} 平台},
    author	= {周詳},
    year	= 2021,
    year	= {2021},
    month	= {January},
    % TODO available where?
    school	= {國立交通大學},
    type	= {碩士論文},
    type	= {Master's thesis},
}

@materthesis{pekos,
    title	= {基於 {Kubernetes} 使用者專案管理之 {PaaS} 平台},
    author	= {李宗緯},
    year	= 2022,
    year	= {2022},
    month	= {August},
    % TODO available where?
    school	= {國立陽明交通大學},
    type	= {碩士論文},
    type	= {Master's thesis},
}

@online{kubernetes,
    title 	= {{Kubernetes}},
    author	= {{The Kubernetes Authors}},
    year	= {2024},
    url		= {https://kubernetes.io/},
    urldate	= {2024-09-23},
}

@online{helm,
    title	= {{Helm}},
    author	= {{Helm Authors}},
    year	= {2024},
    url		= {https://helm.sh/},
    urldate	= {2024-09-23},
}

@inproceedings{haas2017bringing,
    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},
}