雖然 Minikube、K3D 或者 Docker for Desktop 都提供 Kubernetes 測試環境可以方便開發雲原生應用軟體。但從運維角度來說,這些工具並不適合用來測試與驗證需要多節點的方案,例如: 高可用的 etcd;K8S 的儲存方案如 OpenEBS ⎘, ROOK ⎘ 等需要額外的儲存媒體(e.g. 硬碟)來實現;又或者有在主機系統額外安裝套件的需求。本文山姆鍋利用 Vagrant 跟 VirtualBox 虛擬技術作為快速拆建的實驗環境。
本文所使用的原始碼可以在 GitHub ⎘ 上取得。
設計目標
此實驗環境主要是針對想深入了解 K8S 如何部署與維護的運維人員,設定如下目標:
- 近似生產環境:此實驗環境要盡可能與實際的生產環境組態相近。
- 支援分散式架構:多節點叢集方便模擬節點故障與新增以驗證系統的可用性、擴展性以及可靠性。
- 模擬雲端託管:提供負載均衡器(load balancer)以及持久卷(persistent volumes)等資源的動態建立。
實作考量
如同其他技術專案一樣,在規劃這個實驗環境時也需要面臨不同方案的取捨,以下針對幾個重要的技術選型說明背後的理由。
虛擬技術
山姆鍋希望這個環境設定可以跨平台(Windows、OS X以及 Linux)。在實際決定選用 Vagrant + VirtualBox 之前,山姆鍋評估過使用 Multipass 作為輕量的替代方案,但由於 Multipass 缺少下列特性而打消主意:
- 支援固定的 IP 位址: 無法預先知道環境中節點的 IP 位址大大增加組態設定的複雜度。
- 附加額外的硬碟: 由於這個環境主要是針對運維需求,也會用來實驗 K8S 不同的儲存方案,尤其是 OpenEBS以及 ROOK。雖然某些情況下可以使用 loop device 使用檔案來模擬硬碟,但這會增加設定的複雜度也跟實際部署作法不同。
另外也評估過使用 Vagrant + Libvirt(KVM) 這個方案,但對於沒有原生 Linux 環境的使用者就需要使用支援 Nested virtualization 的虛擬機方案,例如:VMWare fusion/workstation。隨著 VirtualBox 支援 Nested virtualization 的普及,之後也許會改成 Vagrant + Libvirt(KVM) 方案。
K8S 發行版本
由於此實驗環境一般情況下是在技術人員的工作機上執行,原本也考量使用 K3S 這個輕量化的發行版本來減少記憶體等系統資源的使用量。但稍微深入思考,會發現使用 K3S 會有下列的問題:
- K3S 不是 Kubernetes 雲端部署環境的主流
- K3S 與託管的 K8S 雲端服務架構上元件有明顯差異。
由於前述理由選用 kubeadm 工具來部署跟多數雲端託管服務更相近的 K8S 叢集。
組態管理工具
安裝設定方面,在使用 BASH 腳本或者 Ansible playbooks 兩者之間猶疑不定。由於已經確定選擇透過 kubeadm 來部署 K8S 叢集,使用 BASH 腳本的複雜度還在可以控制的範圍,但山姆鍋的 BASH 腳本的功力普通,如果看到憋腳的用法還請多擔待!
系統需求
山姆鍋是在自己的 MacBook Pro(i7, 16GB RAM) 上測試整個實驗環境,最低的系統需求也跟環境節點數量以及設定有關。不過,還是建議工作機至少具備下列要求:
項目 | 數值 |
---|---|
RAM | 12GB+ |
CPU | 2GHz+, 4+ cores |
硬碟空間 | 60GB+ |
在工作機上要預先安裝好 Vagrant 以及 VirtualBox,相關的安裝步驟可以參考 「Vagrant+VirtualBox 跨平台虛擬環境」這篇文章。
叢集架構
此實驗環境預設是由一個控制節點(也就是 master node)以及三個工作節點(worker node)組成。叢集底層的作業系統選擇 Ubuntu,除了是因為山姆鍋比較熟悉的系統外,在雲端託管的K8S服務中也是移植性(portability)較高的選項。
下圖是此實驗環境的架構示意圖:
控制節點 (Master nodes)
雖然控制節點的高可用測試也很重要,但相對於其他元件的測試頻率低很多,加上此環境主要用來作為平台元件的部署測試用途,所以預設只使用一個控制節點。這裏所謂的「平台元件」泛指為了支援應用元件而部署的服務套件,例如為了監控用途的 Prometheus, 為了日誌需要的 ELK 推疊等等。跟雲端託管環境類似,此實驗環境預設不允許將元件部署在控制節點。
此實驗環境可以支援最多三個控制節點,主機名稱(hostname)分別為: spkmaster-1, spkmaster-2 以及 spkmaster-3。其中,spkmaster-1 負責整個叢集的初始化工作。
提醒:三個節點才能允許其中一個控制節點故障。即使是有兩個控制節點存在,只要其中一個故障,叢集的控制平面依然是不可用的。
控制平面端點 (Control Plane Endpoint)
叢集中的控制節點組成一個控制平面,控制平面端點提供固定位址作為其它節點或者命令行工具(e.g. kubectl)存取入口。此實驗環境中,控制平面端點是由 HAProxy + Keepalived 來負責實現,即使只有單一的控制節點也是如此。有了統一的控制平面端點,控制節點可以平順地從1個節點擴展到3個。
工作節點 (Worker nodes)
不少平台元件的高可用是基於 Quorum ⎘ 機制來避免 split-brain 問題,而為了維持 Quorum, 元件至少要有 3 個副本(replica)。基於這個需要,此實驗環境選擇啟動 3 個工作節點以更完整模擬實際部署設定。為了支援 OpenEBS 這類透過 iSCSI 協定提供區塊裝置(block device)的儲存方案,工作節點也預先安裝好了 open-iscsi
系統套件。每個工作節點額外有一個硬碟(/dev/sdb)但並沒有自動附掛(mount),此硬碟就是為了可以測試 OpenEBS 這類的存儲方案。
此實驗環境最多可以支援九個工作節點,名稱分別為:spkworker-1 到 spkworker-9。
之所以會有節點數量限制,是因為節點域名解析是透過 /etc/hosts 查詢,相關名稱與IP在建立環境時便固定了。
服務負載均衡器 (Service Loadbalancers)
在雲端託管的 K8S 環境中,雲端供應商會提供服務負載均衡器的支援。透過這樣的支援,運維人員可以透過宣告的方式建立型態(type)為 LoadBalancer 的服務資源(service resource),雲端供應商會根據此資源物件自動建立與銷毀對應的網路負載均衡器的實例。在此實驗環境,服務負載均衡器是藉由 MetalLB ⎘ 實現。
開始動手
底下的指令,山姆鍋都只在 MacBook Pro 上測試過。另外,有些指令需要您根據自己的系統修改。
首先從 GitHub 上,複製(clone)本文相關的程式:
git clone https://github.com/sampot/spk-cluster-lab.git
底下都假設工作目錄位於 spk-cluster-lab
中。
此實驗環境利用一個 .env
檔案來提供環境組態,使用下列指令複製範例檔:
cp .env.example .env
透過 .env
檔案裡的變數可以調整控制節點、工作節點的數量,CPU跟記憶體大小等等。
跟其它 Vagrant 的環境相同,可以透過指令來對環境進行操作。下面指令可以自動建置並設定好實驗環境(第一次需要下載跟安裝,會耗費一些時間):
vagrant up
使用虛擬機的好處是可以使用快照(snapshot)來儲存與回復當前狀態。環境剛部署好時,可以使用下列指令建立一個快照:
vagrant snapshot save baseline
其中,baseline
是快照名稱,您可以自己決定。
實驗測試完後,要讓環境回到已知的快照,可以使用下列指令:
vagrant snapshot restore baseline
其它 Vagrant 虛擬機管理操作,請自行參考 Vagrant 文件 ⎘。
為了避免依賴工作機的設置,程式碼儲存庫中的腳本大多假設是從第一個控制節點(master node)內操作,該節點同時安裝常用的工具如 kubectl, helm 等。可以透過下列指令登入第一個控制節點:
vagrant ssh spkmaster-1
下圖是登入 spkmaster-1 後,執行 kubectl get nodes
的畫面:
從工作機操作
雖然可以從虛擬機內進行大部分操作,但如果需要使用工作機現有的工具來操作叢集,可以按照下列步驟進行。
設定 /etc/hosts 檔案(Windows 系統則是 c:\Windows\System32\Drivers\etc\hosts),增加:
172.42.42.10 spkcluster spkcluster.lab.local
‘172.42.42.10’ 是個虛擬IP位址作為 K8S 控制平面的端點位址,當前綁定的控制節點如果故障,此IP會自動轉移到另一個控制節點(如果有設定高可用的話)。
設定 KUBECONFIG
環境變數,讓 KUBECONFIG
指到 spk-cluster-lab
目錄中的 .kube/config
檔案。在 Linux 或者 OS X 可以下列指令設定:
export KUBECONFIG=$(PWD)/.kube/config
一旦設定完成則可以使用工作機上的 kubectl
來進行操作。
小結
此文描述的是此實驗環境的基本設定,除了高可用 K8S 叢集,GitHub 上的腳本已經可以支援服務負載均衡以及動態持久卷(dynamic persistent volumes)的支持。即使功能看起來完整,但山姆鍋是不建議將這樣的設置複製為生產環境的。