最近阿猩在Windows環境中,使用Docker Desktop,大量的測試docker及K8S,測試建立.NET6專案容器,也將.NET5專案微痛升級至.NET6容器。在Docker的基礎知識下,延伸至K8S,將關注點從容器擴大至Node。本篇阿猩除了操作流程之外,最後也概略性的,將阿猩對於K8S運作流程重點做筆記。
環境安裝流程
安裝K8S
至K8S官網查詢安裝指令,例如
curl.exe -LO https://dl.k8s.io/v1.27.1/bin/windows/amd64/kubectl-convert.exe.sha256
因阿猩已安裝Docker Desktop,故還可以使用Docker Desktop安裝Kubernetes(圖1)。
環境檢視入門
確認安裝是否成功
開啟cmd 或powershell,輸入下列指令
kubectl version
看的到Client Version及Server Version就代表成功啦。
K8S相關的基礎概念
應用程式部屬演進
早期應用程式部署,會將應用程式執行於硬體伺服器,後來引進了虛擬化的概念,利用不同的虛擬機,實現OS層隔離,並可隨時設定、調整一台VM可用的硬體資源。因VM包含OS所需檔案,且需要透過Hypervisor與OS層溝通,故占的儲存空間,以及使用的硬體資源都比容器要多。近幾年則進入到容器部屬,因容器少了Hypervisor,直接與OS層溝通,容器本身沒有OS的檔案,故容量較小,執行速度也較快(圖2)。
K8S是什麼
Kubernetes(常簡稱K8S)。原為Google設計的開源系統,主要用於自動部屬、擴展和管理容器化應用程式。基於容器技術,發展出更多部署的功能,例如:監測、自動擴展、負載平衡、滾動式換版等。在K8S中,最小部屬單位稱為POD,一個POD中可包含1個至多個Container。
YAML檔是什麼
YAML是一種資料序列化的格式,常見的資料序列化格式還有XML、JSON。
- XML:以Tag方式定義資料。
- JSON:以Key-Vvalue的方式定義資料。
- YAML:以Dictionary的方式定義資料,以每行開頭空格數表示物件階級。
XML、JSON、YAML分別表示2台Server,且描述各自的ServerName及IP,則會像圖3。
YAML、POD、Service、Deployment
練習撰寫YAML
一開始接觸K8S,可能還沒有自己專案的映像檔,所以阿猩先使用dockerhub上的image作測試。新增一個檔案,命名為nginx.yaml,在裡面寫入下列內容
apiVersion: v1
kind: Pod
metadata:
labels:
app: yaml-test
name: yaml-test
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
- 將POD名稱命名為yaml-test
- 在POD內部,從dockerhub下載nginx的image
- 在POD內部,建立1個名為nginx的容器。
- 將容器內部對node的開啟port設為80
此範例yaml的步驟流程為
- 將POD名稱命名為yaml-test
- 在POD內部,從dockerhub下載nginx的image
- 在POD內部,建立1個名為nginx的容器。
- 將容器內部對node的開啟port設為80
YAML欄位說明,可自行Google或使用kubectl explain指令查看說明,例如
kubectl explain pod
kubectl explain pod.apiVersion
建立POD
開啟cmd或powershell,進到nginx.yaml所在目錄,執行
kubectl apply -f nginx.yaml
kubectl get pod
若成功則會顯示目前擁有的POD(圖4)。
建立暫時性的port-forward
因CLI不可以直接跟POD溝通,所以需要額外對外可連線的PORT,一般會透過SVC進行設定,這裡測試暫時使用port-forward測試。
kubectl port-forward yaml-test 8080:80
開啟瀏覽器並輸入localhost:8080,可看到圖5代表成功。
認識其他可建立對象
POD為K8S最小部屬單位,K8S也可用於自動部屬、擴展和管理容器化應用程式,故在YAML檔中的Kind欄位,也可指定POD以外的類型,用於不同的時機,例如Deployment、Service、DaemonSet、Jobs、CronJob等(圖6)。因這裡的資訊太過龐大,一時之間阿猩也無法完整說明,僅紀錄使用時機及重點。
- Deployment:可作滾動式換版、設定replicas數量,kube-controller-manager會確保POD數量不小於replicas設定的數量。
- Service:可用於設定port, Type可指定為Cluster IP、NodePort、LoadBalance等。
- DaemonSet: 新增node時,會主動建立一個特定用途的POD,例如kube-proxy、log處理。
- Jobs:處理一次性任務。
- CronJob:類似排程服務,基於時間做管理。
K8S的運作流程概要
K8S的運作流程水很深,阿猩只能盡可能的整理,釐清概念性的脈絡,如有不正確的地方,也請大家不吝於告訴我。K8S大致運作概念為圖7。
Node
K8S主要可依職責分為Master Node與Work Node。Master node包含kube-apiserver、Controller Manager、scheduler、etcd,用於管理Work Node。而Work Node則包含與應用程式相關的Pod、kubelet、kube-proxy等。
Controller Manager
監聽容器狀態,確保健康度、replicas數量、滾動式換版等工作。YAML檔會長得像是
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-test
labels:
app: deployment-test
spec:
replicas: 2
selector:
matchLabels:
app: deployment-test
template:
metadata:
labels:
app: deployment-test
spec:
containers:
- name: testapi
image: testapi
imagePullPolicy: Never
ports:
- containerPort: 80
kube-apiserver
開發者在CLI下kubectl 指令時,會以Restful API作為協定向Master Node溝通,再由Master Node透過kube-apiserver向Work Node溝通(圖8)。Master Node內部溝通、Master Node與Work Node溝通,大多屬Protobuf協定。
kubelet
Kubelet會依照yaml.spc的設定,對Node內部的Pod進行管理。Kubelet 會詢問 kube-apiserver ,會依照yaml.spc的設定,對Node內部的Pod進行管理,確保容器的狀態,例如在此Node啟動Pod。後續透過不同的協定,如Protobuf、CNI、CRI、OCI等協定,完成不同性質的工作。例如
CNI:調用容器網路接口,取得網路資訊,如IP等
CRI:定義了容器與鏡像檔接口,用於建立容器,並把網路資訊設定帶入容器
OCI:開放容器的標準,CRI會調用OCI用於創建容器,常見的就是大家所使用的Docker,但可以使用其他技術。
Pod
K8S中最小的單位,可包含1個至多個容器。
Kube-proxy
因外部不可以直接與Pod進行溝通,故應用程式若要開發給其他使用者,需另外設定proxy,K8S 可透過Service利用Cluster IP、LoadBalance等設定。YAML內容會像是
apiVersion: v1
kind: Service
metadata:
name: svc-testapi
spec:
type: LoadBalancer
selector:
app: testapi
ports:
- port: 80
targetPort: 80