/

快速體驗 kubernetes 的強大之處

前言

容器技術近年來非常流行,相信各位在不同地方多少有聽過 kubernetes(或是它的簡稱 k8s)這項技術。但是很多人了解 k8s 之後會被這個技術嚇到,原因是因為有大量的名詞,像是 Pod, Service 等等(這些元件數量高達 60 多種),然後又有一大堆的架構圖,很多人可能還沒開始就先放棄了。

這篇文章的目的沒有要教大家了解 k8s 背後的觀念,而是要透過簡單的小實驗來讓大家了解 k8s 的作用到底為何?讓大家有點感覺,後續如果各位要深入了解,可能也會有點幫助。

簡單來說 k8s 是一項可以管理容器的技術,而且可以分散式的管理。意思就是容器掛掉之後 k8s 會自動偵測並且讓容器重新啟動。當然還有非常多的功能,但是主要的核心目的就是保持應用程式的 高可用性(high availability)(簡稱 HA)。

本篇實驗會透過一個簡單例子來讓大家看到 k8s 達成高可用性的成效。

實驗必備

  • docker
  • minikube

一般容器

在開始之前,大家可以先跑這個容器(yiyu0x/current-time)起來玩玩看

docker run -d -p 3000:3000 yiyu0x/current-time

這個容器會在 localhost 3000 port 開一個顯示目前時間的 API:

如果順利的話訪問 localhost:3000 會得到:

1
Current time is 4:2:48

我們可以後過 docker ps 來確認這個 container 正確無誤的運作:

1
2
3
~/dev/k8s-post/my-api ❯ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d5662a916aed yiyu0x/current-time "docker-entrypoint.s…" 10 seconds ago Up 8 seconds 0.0.0.0:3000->3000/tcp tender_hypatia

但是我們如果去戳 localhost:3000/bye 這個位置的話,會發現容器掛掉了:

1
~/dev/k8s-post/my-api ❯ docker ps

這個行為模擬出當應用程式意外結束的情況。

導入 k8s

建立一個 pod 內容是剛才的 current-timecontainer
kubectl run --image=yiyu0x/current-time curr-time --generator=run-pod/v1

1
2
3
~/dev/k8s-post/my-api ❯ kubectl get po
NAME READY STATUS RESTARTS AGE
curr-time 0/1 ContainerCreating 0 16s

將他 expose 出去:

kubectl expose pod curr-time --port 3000 --type=NodePort

取得位置並且訪問:

1
2
~/dev/k8s-post/my-api ❯ minikube service curr-time --url         
http://192.168.64.6:30948

此時建議再開一個 terminal 的 tab 使用:
watch kubectl get po
(感謝學長 Jerry Wang 指正,可以用 kubectl get po -w 就不用額外安裝 watch 指令了!)

監測該 pod 的狀態並且去戳 http://192.168.64.6:30948/bye

你會發現容器掛掉後幾秒鐘,又自己重新跑起來了,並且 RESTARTS 的數量變成 1 了(原本是 0):

1
2
NAME        READY   STATUS    RESTARTS   AGE
curr-time 1/1 Running 1 8m56s

更強大的高可用性 - replicas

透過以上例子已經可以感覺到 k8s 的威力,但是其實 docker 本身就可以監測容器的狀態並且重新啟動了。k8s 更強大的地方在於它可以一次建立多個 pod 並且在一個 pod 掛掉時透過 loadbalancer 馬上把流量切換到其他 pod 中,這樣子使用者完全感覺不出來原來服務有掛掉過。

建立 replicas
kubectl run curr-time --image=yiyu0x/current-time --replicas=3 --port 3000

對外打開:
kubectl expose deployment curr-time --port=3000 --type=NodePort

一樣透過 watch kubectl get po 來監控 pod

(2019/1/17 更新:或是用 kubectl get po -w

1
2
3
4
5
6
Every 2.0s: kubectl get po                                       

NAME READY STATUS RESTARTS AGE
curr-time-6f9cb4fdf9-crc66 1/1 Running 3 7m41s
curr-time-6f9cb4fdf9-hbkx5 1/1 Running 2 7m41s
curr-time-6f9cb4fdf9-s742x 1/1 Running 2 7m41s

然後戳一下 API 的 bye 位置,會發現:

1
2
3
4
5
6
Every 2.0s: kubectl get po                                       

NAME READY STATUS RESTARTS AGE
curr-time-6f9cb4fdf9-crc66 0/1 Completed 3 8m40s
curr-time-6f9cb4fdf9-hbkx5 1/1 Running 2 8m40s
curr-time-6f9cb4fdf9-s742x 1/1 Running 2 8m40s

三個服務中的容器一個掛掉其他兩個還是正常運作中,使用者根本感覺不出來(流量會被導入到正常運作的 pod 中)後面的容器原來掛掉了!

更更更強大的高可用性

以上例子使用 minikube 來實驗,只有一個節點。真實情況甚至可以把好幾台機器全部給 k8s 進行管理。這樣子甚至連機器掛掉都可以保證服務不中斷,這才是真正的高可用性!

文中透過一個例子讓讀者了解到 k8s 的用處,但是沒有解釋很多問題,像是:

  • 為什麼建立的是 pod 不是 container
  • 為什麼需要 expose
  • minikube 是什麼?

原因在於我認為先體驗一次這個技術的效果再去學習這個技術細解,有時候可能會比起直接去記憶那些硬生生的名詞來得有效果,所以看完這篇文章之後,如果不太懂裡面的細解可以再去看官方文件或是查閱其他 k8s 的概念講解文章。

看完之後再回來自己玩過一次,我相信會有不一樣的感覺的!