Kubernetes 介紹與使用KIND簡單建置Cluster/Local Registry
Kubernetes(K8S)
Kubernetes 是一個協助我們自動化部署、擴張以及管理容器應用程式(containerized applications)的系統。相較於需要手動部署每個容器化應用程式(containers)到每台機器上,
K8S 架構
什麼是 K8S
Kubernetes 可以幫我們做到以下幾件事情:
- 同時部署多個 containers 到一台機器上,甚至多台機器。
- 管理各個 container 的狀態。如果提供某個服務的 container 不小心 crash 了,Kubernetes 會偵測到並重啟這個 container,確保持續提供服務
- 將一台機器上所有的 containers 轉移到另外一台機器上。
- 提供機器高度擴張性。Kubernetes cluster 可以從一台機器,延展到多台機器共同運行。
K8S 架構圖
Master Node
在 k8s 中,Master 扮演著管理叢集的角色,管理者可以透過 CLI (Command Line Interface) 或 APIs (Application Programming Interface) 或控制介面 (Dashboard) 等等不同方式與 Master 溝通進而存取、控制或修改叢集狀態例如配置資源、擴充 Pod 數量等等。
- Scheduler
- Scheduler 會知道目前 Worker Node 的狀況,當需要配置 Pod 時,Scheduler 會找出最合適的 Node 並配置 Pod。
- API Server
- 管理者會透過 REST command 把需要做的工作 (例如,新增或刪除物件) 傳送到 api-server , api-server 會驗證並處理管理者要求執行的工作,當工作執行完畢後,叢集的最新狀態便會儲存到 etcd 中。
- Controller
- Controller 會透過 api-server 了解目前叢集的狀態,並嘗試把目前狀態調整為管理者想要的狀態。
- 管理者想要的狀態可能會因為種種原因無法達成,例如資源不夠 (cpu, memory) 等等。而 Controller 會持續嘗試著把叢集調整成管理者想要的狀態。
- etcd
- etcd 為鍵值儲存區 (key-value storage),在 k8s 中被用來儲存叢集的狀態。
- etcd 可以是 Master 的一部分或者獨立被設置在外部。同樣的,當 etcd 被設置在外部時,Master 會連到 etcd 取得或更新叢集狀態。
- Scheduler
Worker Node
Worker Node 簡單來說就是一台機器,它可以是一台實體機器或虛擬機 (VMs)。而多個運行單位 Pod 會被配置到 Worker Node 中運行,而每個 Pod 中含有一到多個容器。
- kubelet
- kubelet 運行在 Worker Node,負責建立 Pod 中的容器。當 kubelet 收到來自 Master Node 送來 Pod 定義內容時,kubelet 會透過 container runtime 建立 Pod 需要的容器並確保容器狀態是可運行的。
- kube-proxy
- 當 Pod 運行在 Worker Node 之後,外部需要透過 Service 這個 k8s 物件來與 Pod 連線而非直接存取 Pod。
kube-proxy 運行在 Worker Node 且持續監聽 api-server,並知道 Service 被建立或刪除。當 Service 被建立後,kube-proxy 會負責將 Request 導到對應的 Pod。
- 當 Pod 運行在 Worker Node 之後,外部需要透過 Service 這個 k8s 物件來與 Pod 連線而非直接存取 Pod。
- pod
- k8s 基本運行單位。
- kubelet
使用 KinD 架設 K8S Cluster
kind is a tool for running local Kubernetes clusters using Docker container “nodes”.kind was primarily designed for testing Kubernetes itself, but may be used for local development or CI.
- Kind 架構圖
安裝 KinD
- wsl -l -v
- wsl –set-version Ubuntu-22.04 2
- docker 設定中調整 intergration 與 Ubuntu 整合 WSL2 的環境,讓 Ubuntu 可以直接調用 docker cli
- 下載 KinD 並安裝於 Ubuntu
1
2
3curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.17.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
建立 K8S Cluster (要先開 Docker Engine Desktop)
- 先建立 kind.yaml 檔
1
2
3
4
5
6
7
8kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000 #容器的port
hostPort: 5432 #對外開啟的port
- role: worker - 使用 yaml 檔建立叢集
kind create cluster --config kind.yaml -n kind
- 先建立 kind.yaml 檔
將做好的 image 複製進去 kind 所建立的 cluster
進入路徑 ../src/dockerDemo,執行
docker build -t dockerDemo:latest .
執行好後可以先試試看
docker run -it dockerDemo -p 3000:3000
,然後開啟瀏覽器進入 localhost:3000 看是否有看見 Hello World! 的訊息。在 Ubuntu 執行
kind load docker-image -n dockerDemo:latest
執行
docker exec -it kind-worker crictl image
查看是否有正確讀入 image。
建立一個 pod,這個 pod 將會直接在 worker 裡面做為一個單位運行,裡面則會包含使用方才的 image 所起的 Container。而建立好該 Pod 之後則需要建立 Service 來貫通整條路。
- 建立
00-pods-dockerdemo.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13apiVersion: v1 #Pod 使用的 Kubernetes API 是 v1 版本號
kind: Pod #建立類型
metadata:
name: my-pod #該 Pod 的名稱
labels: #標籤, 後續建立 Service 會使用, 所以要記得
app: webserver
spec: #該 Pod 的描述
containers: #所包含的容器
- name: pod-demo #容器名稱
image: dockerdemo:latest #容器映像檔
imagePullPolicy: Never #因為KinD本身已有複製本地的image,所以要設這個。
ports:
- containerPort: 3000 #該容器對外開放的 Port - 建立
00-svc-dockerdemo.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13apiVersion: v1
kind: Service
metadata:
name: dockerdemo-svc
spec:
type: NodePort
ports:
- port: 3000 #指定建立此Service的Cluster IP中是哪個port number要對應到targetPort
nodePort: 30000 #指定這個node透過哪個port連接targetPort
protocol: TCP
targetPort: 3000 #指定的Pod的Port號, 也就是外部會透過port 30000對應到此pod的port 3000
selector:
app: webserver #將特定的port號收到的請求導向app:webserver標籤的pods - 建立 Pods,執行
kubectl apply -f 00-pods-dockerdemo.yaml
- 有了 Pod 之後,需打通其橋梁,因此建立 Service。 執行
kubectl apply -f 00-svc-dockerdemo.yaml
- 可確認其有無完整建立,執行
kubectl get [Resource]
來查看。Resource 可改為 svc 或 pods
- 建立
在 Host 主機打開瀏覽器,進入
127.0.0.1:5432
就可以看到 Hello World! 字樣。而這個 5432 Port 則是 Host 透過該 Port 進入到 Cluster,並由 Cluster 設定的 5432 進入到 30000,然後觸及到 service 的 3000 去對應到 Pod 的 3000。
其實在 Pod 建立好之後,就可以直接透過 Port Foward 的方式來將 Pod 整個暴露給外網的 Port。Port Forward 可以透過 Kubectl 建立起 Proxy 來將外部的流量導入你想進入的 Pod 的 Port。因為要建立起整個 Port 串通是一件不太方便的事情,除此之外在某些狀況也可能暴露整個服務。因此透過這樣的方式能夠更簡便的去除錯。只需要輸入:
kubectl port-forward my-pod 8000:3000
。就能透過 Host 的瀏覽器進入127.0.0.1:8000
就可以看到 **Hello World!**!
K8S Dashboard
因為 KinD 並沒有直接內建儀表板,所以我們得自己安裝回來。
1 | kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml |
安裝好後需建立使用者來取得權限和建立 Token
1 | kubectl create clusterrolebinding default-admin --clusterrole cluster-admin --serviceaccount=default:default |
網址列輸入 http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login
進入 dashboard,貼入方才的 Token 就可以登入。
KinD Local Registry
如果已實作一個 Cluster 的話,那麼要使用 Local Registry 需要重建一個新的 Cluster。因為 KinD 沒辦法針對叢集的設定去做調整,因此在建立時就必須決定好。
通常在 CI/CD 架構中會有個地方存放產出物(Artifact),無論是 Nuget、Npm 或是 Image,因此我們想透過 KinD 去模擬未來的 CI/CD 架構的話,就必須建立一個可以存放產出物的地方。但在初次練習沒有那麼多經驗可能會苦惱究竟要選擇什麼樣的工具或怎麼架。
Nexus Oss Registry、Proget 等等的都可以是未來的解決方案,或者是單純要架設私有的 Image Registry 也可以選擇 Habor。但在這裡我們會選擇最容易架設的 KinD Local Registry。
KinD Local Registry 架設方式只有兩步,到官網 複製執行語法,修改成自己要的。然後在 WSL2 裡面執行就能完成。
以下是我建立時所使用的執行語法。
1 |
|
建立好 Local Registry 然後呢?
- 建立 Docker Image
- 將 Image Push 上去 Registry
- 透過建立 Deployment 來部署
- 透過建立 Service 讓主機能通到 Node 裡 Pod 的 Container
建立 Docker Image
進入路徑 ../src/dockerDemo,執行`docker build -t dockerDemo:latest .`
Tag Image Local Registry
docker tag dockerDemo localhost:5001/dockerDemo:latest
Push Image To Local Registry
docker push localhost:5001/dockerDemo
執行後可以看見像這樣的訊息:
1 | Using default tag: latest |
建立 Deployment 部署,在這裡會向 Local Registry Pull Image
kubectl create deployment test-dockerDemo --image=localhost:5001/dockerDemo
可以檢查 Pod 是否正常運作中
kubectl get pods -o wide
建立 Service 打通 Host 和 Node
1 | apiVersion: v1 |
透過 docker ps
可以看見 K8S 的 Container 的 30000 port 是對應到 Host 的哪個 Port 對外開放。得知之後只要在 Host 的 Browser 進入 127.0.0.1:[Port] 就能看見 Hello World!。
常用指令
1 | # get image list in kind (cluster1 叢集名稱) |
- 標題: Kubernetes 介紹與使用KIND簡單建置Cluster/Local Registry
- 作者: Larry Lai
- 撰寫于 : 2023-11-24 14:40:56
- 更新于 : 2024-07-17 17:01:39
- 連結: https://redefine.ohevan.com/2023/11/24/k8s-introduce-1/
- 版權宣告: 本作品采用 CC BY-NC-SA 4.0 进行许可。