Kubernetes 自架多節點與 LoadBalance 設定 — 下篇

本文前半部將會介紹多節點加入,後半部為測試與 LoadBalancer 設定範例

Published in
9 min readOct 11, 2020

--

前言

本文接續上篇(Kubernetes 自架),到第二台 ( N台 ) Server 安裝好 Kubeadm / Kubelet
( 到第 3 步驟, 設定服務自動重啟 )

本文前半部將會介紹多節點加入,後半部為測試與 LoadBalancer 設定範例
( 如果想看 k8s LoadBalance 基本設定的教學可以直接看後半部 )

我們這邊使用一台 Kubernetes Master 另外兩台 K8s Node 作為示範

1. 加入節點

確定機器上有 cri-o 與 kubelet 等等設定正確( 請參考上篇文章 )

這裡說明一下 kubeadm 指令
kubeadm init 是建立主機 ( 上篇文章我們已經建立 )
kubeadm join 就是讓這台機器加入其他機器 ( 本篇與其他機器需要 )

我們直接輸入主機上 kubeadm init 後告訴我們的指令 ( kubeadm let )
(以下為範例,實際請看自己的 Master,本文 192.168.100.10 為 Master 節點 IP )

kubeadm join 192.168.100.10:6443 --token xxxxxx     --discovery-token-ca-cert-hash sha256:xxxx

如果看到類似錯誤 :

Found multiple CRI sockets, please use --cri-socket to select one: /var/run/dockershim.sock, /var/run/crio/crio.sockTo see the stack trace of this error execute with --v=5 or higher

一樣是因為我們同時有 docker 與 crio, 這時候指定一下即可
(加上下面粗體參數 )

kubeadm join 192.168.100.10:6443 --token xxxxxx     --discovery-token-ca-cert-hash sha256:xxxx --cri-socket=/var/run/crio/crio.sock

加入成功應該會看到類似以下訊息:
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run ‘kubectl get nodes’ on the control-plane to see this node join the cluster.

2. 驗證節點成功

重複以上步驟可以加入隨意數量的 Node ( Server ),然後我們回到主控端 ( Master ) 或是有辦法操作 kubectl 的電腦 / 使用者

a. 狀態檢查

輸入以下指令 ( 以下為 master server 上一般 user 輸入 )

kubectl get nodes

應該會看到有 master 與其他 node 加入了 ( 如附圖 )

b. Deployment Pods 部署測試

然後我們部署一些測試 pod 來看看是否會分散在不同的 Node 上
( 下指令部署六份 nginx 作為測試 )

kubectl create deployment test-nodes --image=nginx --replicas=6

輸入以下指令可以看到 Pods 在什麼 Node 上

kubectl get pods -o json -o=jsonpath='{range .items[*]}{.metadata.name}{" on "}{.spec.nodeName}{"\n"}{end}'

應該會看到類似如下輸出 ( Node name 不同 )
格式為 “pod name “ on “節點”

test-nodes-549c96888d-6dwt7 on k8s-vm1
test-nodes-549c96888d-9x4xt on k8s-vm3
test-nodes-549c96888d-h29d4 on k8s-vm3
test-nodes-549c96888d-t6vh2 on k8s-vm2-node
test-nodes-549c96888d-z44mc on k8s-vm2-node
test-nodes-549c96888d-zg7g4 on k8s-vm1

可以看到有 k8s-vm1, k8s-vm2-node, k8s-vm3 這三台機器平衡的配置

確實分散在不同的 Node 上了

表示成功了

3. LoadBalancer設定

kuberneters 最大的好處就是可以用多個 pod 來執行我們需要的服務
這其中特別重要的就是如何讓流量可以跑道各個 pod

a. 更換 image

上一步驟我們建立了 test-nodes 這個 deployment,因為 nginx 不是很好觀察 LoadBalancer,這步驟看個人喜好可跳過,但是建議使用方便觀察的 image 會比較好

這邊可以使用本人建立的測試用 image ( seachaos/kube-demo-request:v0.1.0 )
透過以下指令更新來更換 test-nodes 的 image

kubectl set image deployment/test-nodes nginx=seachaos/kube-demo-request:v0.1.0
pod 的 image 正在更換中

輸入指令後可以透過 kubectl get pods 觀察狀況 ( 如上圖 )

b. 設定 LoadBalancer

如果我們是自架的 kubernetes ( 非 AWS / GKE 這種 cloud provider 的 ),沒有特別的 external-ip,所以往往建立 LoadBalancer 時會發現 ip 處於 pending 狀態 ( 即卡在 loadbalancer 等待外部 ip )

要消除 pending 的方法就是明定 external ip 給 LoadBalancer

我們輸入以下範例指令(參數請依照自己環境修改)

kubectl expose deployment test-nodes \
--name=lb-test-nodes \
--external-ip=192.168.100.10 \
--port=8080 \
--type=LoadBalancer \
—-target-port=3000

參數解說 :

name: 為這個 service 名稱,方便管理用

external-ip: 就是我們其中想要對外的實體機器 IP ( 也可能 VM ),實務上這個機器可以放置在 DMZ 或是有其他的 NAT / Port Forwarding
這裡我們設定為我們 K8S 主機的 IP ( 或是其中一個 Node 也行 )

port: 對外的 port,會讓服務整體來看是 external-ip : port ( 例如 192.168.100.10:8080 )

type: 這邊一般常見的有 NodePort / ClusterIP / LoadBalancer ,本範例使用 LoadBalancer ,其他日後有空再介紹

target-port: 這邊是對應到 pod 的 Port, 如果 images 維持 nginx 的話就是 80,如果有執行 [a. 更換 image ] 這步驟更換成本人的測試 image, 就是 3000 ,或是其他您想跑的 service port 也行

接下來輸入指令觀察看看使否成功 ( kubectl get services ) 為完整指令,下為簡化指令

kubectl get svc

應該會看到類似下圖 ( 注意紅圈處 )

LoadBalancer 建立成功而且沒有 pending 的 external ip

LoadBalancer 的 External IP 沒有 Pending 的話就表示正常 (如果有的話可以等一下看看,但是應該不會太久 )

c. 測試

我們可以打開瀏覽器看看 ( 例如 http://192.168.100.10:8080 ,看各位的機器實體 IP )

瀏覽器看到網頁

由於使用本人的測試 Image,每個 Pod 都會有不同的 ID,所以可以透過重新整理網頁發現 Server Id 一直在變化,這就表示每次我們的連線都是到不同的 Pod,即表示成功了

或是透過指令觀察

watch curl http://192.168.100.10:8080
透過指令觀察

也可以發現 Server ID 一直在變 ( watch 指令預設兩秒左右一次 )

4. 測試 Pods 復活

既然我們有了 LoadBalancer ,表示我們服務應該可以很好的運行
透過指令觀察一下 Pods 所在位置

kubectl get pods -o wide
Pods 分散在不同的機器 ( Node ) 上

然後有興趣的人可以觀察一下 Server ID 變化,應該只有六組重複 ( 就是因為我們有 6 個 Pod )

我們可以任意地透過以下指令來刪除任意 Pod

kubectl delete pods [NAME]

實際上不管我們怎麼刪除 Pod,我們的服務都會透過 LoadBalancer 保持,或是極端一點透過

kubectl delete pods --all

刪除所有的 Pods,但只要 Pods 開始長回來,我們的網頁又馬上回來了
( 而且 ID 都變了,不是之前那六組 )

或是將 2 號, 3 號機關閉 ( 將 Node 機器關機,假裝 offline )
會發現 ID 剩下兩組在變化 ( 兩個 Pod 在 Master 上 )

關閉 2 號 和 3 號機

然後再啟動 2, 3 號機 ( k8s node ),等他們回來,SERVER ID 就可以看到又是六組在變化了

以上就是建立多 Node 的 Kubernetes 的教學

--

--