Kubernetes 佈署是確保應用程式高用性和穩定性的關鍵機制。本文從佈署的基本概念出發,逐步講解如何在 Kubernetes 中佈署和管理微服務。涵蓋了佈署的自動重啟機制、組態方法,並以影片串流媒體微服務為例,演示瞭如何建立佈署和服務,以及如何使用 YAML 檔案定義佈署組態。同時,也說明瞭 Deployment 和 Service 的作用,以及它們之間的關係,並以圖表形式展示了微服務佈署的流程。最後,文章還介紹瞭如何在本地和雲端環境中佈署微服務,以及如何使用 kubectl 命令列工具管理 Kubernetes 資源。

佈署的重要性

在 Kubernetes 中,佈署(Deployment)是一種物件,用於描述應用程式的期望狀態。它可以確保您的微服務始終可用和穩定,即使個別的 Pod 發生故障。讓我們深入瞭解佈署的工作原理和它如何幫助我們維持微服務的可靠性。

自動重啟

當我們的微服務當機時,佈署會自動重啟它。這意味著如果您的應用程式遇到問題,Kubernetes 會自動干預並還原服務,確保您的使用者始終能夠存取您的應用程式。這種自動重啟機制是維持高用性的關鍵部分。

簡單組態

在本章中,我們的組態相當簡單。我們有一個微服務執行在一個容器中,並且這個容器又執行在一個單獨的 Pod 中。這種簡單的組態使我們能夠專注於理解佈署的基本概念,而不需要處理複雜的設定。

影片串流媒體微服務

作為示例,讓我們考慮一個影片串流媒體微服務。這個服務建立了一條 DNS 記錄,使得微服務可以被存取。透過使用佈署, мы 可以確保這個微服務始終可用,即使底層的基礎設施發生變化。

內容解密:

# 佈署組態範例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: video-streaming
spec:
  replicas: 1
  selector:
    matchLabels:
      app: video-streaming
  template:
    metadata:
      labels:
        app: video-streaming
    spec:
      containers:
      - name: video-streaming
        image: video-streaming:latest
        ports:
        - containerPort: 80

在這個範例中,我們定義了一個名為 video-streaming 的佈署,它執行一個副本(replica)並使用 video-streaming:latest 這個 Docker 映象。容器暴露在 port 80 上。

圖表翻譯:

  flowchart TD
    A[佈署] --> B[建立 Pod]
    B --> C[執行容器]
    C --> D[暴露連線埠]
    D --> E[建立 DNS 記錄]
    E --> F[提供服務]

這個流程圖顯示了從佈署到提供服務的過程。首先,佈署建立了一個 Pod,然後在這個 Pod 中執行一個容器。接下來,容器暴露在指定的連線埠上,並建立了一條 DNS 記錄,使得服務可以被存取。最後,服務被提供給使用者。

Kubernetes 微服務佈署架構

在 Kubernetes 中,微服務的佈署是透過 Pod 來實作的。每個 Pod 都是一個獨立的容器,包含了微服務的程式碼和依賴函式庫。當我們建立一個 Deployment 時,Kubernetes 會自動建立多個副本(replica)以確保微服務的高用性。

Deployment 和 Service

Deployment 是 Kubernetes 中的一種資源,負責管理 Pod 的生命週期,包括建立、更新和刪除。它確保微服務始終有指定數量的副本在執行。Service 是另一種資源,負責將流量分配到多個 Pod 上,實作負載平衡。

微服務佈署過程

  1. 建立 Deployment:定義微服務的 Docker 映象、連線埠號和副本數量等引數。
  2. 建立 Service:定義 Service 的型別、連線埠號和選擇器等引數。
  3. 啟動 Deployment:Kubernetes 會自動建立指定數量的 Pod。
  4. 啟動 Service:Service 會自動將流量分配到多個 Pod 上。

內容解密:

在上述過程中,Deployment 和 Service 是兩個關鍵的資源。Deployment 負責管理 Pod 的生命週期,而 Service 負責將流量分配到多個 Pod 上。這樣可以確保微服務的高用性和負載平衡。

  graph LR
    A[Deployment] -->|建立|> B[Pod]
    B -->|啟動|> C[Service]
    C -->|分配流量|> D[Pod]
    D -->|傳回結果|> C

圖表翻譯:

上述 Mermaid 圖表展示了微服務佈署過程中 Deployment、Pod 和 Service 之間的關係。Deployment 建立 Pod,Service 將流量分配到多個 Pod 上,實作負載平衡。這樣可以確保微服務的高用性和可擴充套件性。

微服務與 Kubernetes

在現代軟體開發中,微服務架構是一種流行的設計模式。它將一個大型應用程式分解成多個小型、獨立的服務,每個服務負責特定的功能。這種架構可以提高開發效率、增強系統可靠性和擴充套件性。

微服務的優點

  • 彈性: 每個微服務可以獨立開發、測試和佈署,減少了整個系統的耦合度。
  • 可擴充套件性: 根據需求,可以增加或減少每個微服務的例項數量,從而提高系統的整體效能。
  • 容錯性: 如果一個微服務出現問題,其他微服務可以繼續執行,從而提高系統的可靠性。

Kubernetes 介紹

Kubernetes 是一個開源的容器協調系統,可以自動化佈署、擴充套件和管理容器化應用程式。它提供了一個簡單、靈活和可擴充套件的方式來管理微服務。

Kubernetes 的優點

  • 自動化佈署: Kubernetes 可以自動化佈署和更新微服務,減少了人工干預的需要。
  • 自我修復: 如果一個微服務出現問題,Kubernetes 可以自動重啟或重新佈署它。
  • 資源管理: Kubernetes 可以自動管理資源,例如 CPU 和記憶體,從而提高系統的整體效能。

啟用本地 Kubernetes 例項

要啟用本地 Kubernetes 例項,可以按照以下步驟進行:

  1. 啟動 Docker Desktop。
  2. 點選設定按鈕。
  3. 選擇 Kubernetes 標籤。
  4. 點選啟用 Kubernetes 按鈕。
  5. 點選套用和重啟按鈕。

啟用本地 Kubernetes 例項後,可以使用 kubectl 命令列工具來管理和佈署微服務。

安裝 Kubernetes 命令列工具

kubectl 是 Kubernetes 的命令列工具,可以用來管理和佈署微服務。如果您使用 Docker Desktop,則已經安裝了 kubectl。如果您使用 Linux,則需要手動安裝 kubectl

驗證 kubectl 安裝

可以使用以下命令來驗證 kubectl 安裝:

kubectl version

如果輸出難以閱讀,可以增加 --short 引數:

kubectl version --short

輸出將顯示 kubectl 客戶端和伺服器版本。

連線到正確的 Kubernetes 叢集

如果您之前已經安裝或組態過 kubectl,或者已經連線到其他 Kubernetes 叢集,則可能需要重新連線到正確的叢集。可以使用以下命令來檢查當前連線的叢集:

kubectl cluster-info

如果顯示錯誤訊息,則需要重新連線到正確的叢集。

專案結構

在佈署微服務到 Kubernetes 之前,讓我們簡要看看範例微服務專案的結構,並瞭解它如何與 Kubernetes 佈署相關。圖 6.9 顯示了第 6 章的範例-1 結構。您可以看到 JavaScript 原始碼(index.js)、Node.js 專案檔(package.json,於第 2 章中介紹)和生產 Docker 檔(Dockerfile-prod),我們用它來建立微服務的生產 Docker 映像(於第 3 章中介紹)。

您會發現,就像在第 3 章一樣,我們直接將影片嵌入 Docker 映像中。這不是一個好的生產實踐,但我們這樣做是為了在學習如何將單個微服務佈署到 Kubernetes 時保持簡單。當我們到達第 10 章時,您會看到真正的 FlixTube 應用程式使用雲端儲存來儲存其檔案,並使用 MongoDB 資料函式庫來儲存資訊(就像我們在第 4 章中設定的一樣)。

這裡的新東西是 deploy.yaml 檔,您可以在圖 6.9 中看到。這個檔包含將微服務佈署到 Kubernetes 的組態。稍後,我們將更詳細地檢視這個檔。

佈署到本地 Kubernetes 例項

在本章中,主要目標是佈署到雲端中的 Kubernetes 叢集,但我們尚未討論如何在雲端建立叢集。稍後我們將進行這一步。 一個更容易的起點是先練習將影片串流微服務佈署到本地 Kubernetes 例項。由於我們已經有了本地例項,因此不需要安裝任何東西;我們可以直接練習佈署微服務。

建立微服務映像

在佈署微服務之前,我們需要建立其映像。這是我們在第 3 章中已經做過的事情,但讓我們在這裡再次執行這些步驟。對於這個映像,我們將使用第 6 章程式碼倉函式庫中的範例-1。 開啟終端,複製第 6 章程式碼(見 6.2 節),切換到 example-1 目錄,然後建立映像:

cd chapter-6/example-1
docker build -t video-streaming:1 --file Dockerfile-prod.

example-1 目錄包含以下檔案: -.dockerignore

  • Dockerfile-prod
  • package-lock.json
  • package.json
  • README.MD
  • scripts
  • deploy.yaml
  • src
  • index.js
  • videos
  • SampleVideo_1280x720_1mb.mp4

Dockerfile 用於建立生產 Docker 映像,deploy.yaml 是 YAML 組態檔,用於將微服務佈署到 Kubernetes。src 目錄包含微服務的原始碼,videos 目錄包含要嵌入 Docker 映像的樣本影片。

內容解密:

上述指令建立了名為 video-streaming:1 的 Docker 映像,使用 Dockerfile-prod 作為映像建立檔。這個映像包含了微服務的生產環境組態和嵌入的影片檔案。接下來,我們將使用這個映像佈署微服務到 Kubernetes。

圖表翻譯:

  graph LR
    A[建立 Docker 映像] --> B[使用 Dockerfile-prod]
    B --> C[嵌入影片檔案]
    C --> D[建立生產環境組態]
    D --> E[佈署到 Kubernetes]

此圖表顯示了建立 Docker 映像、嵌入影片檔案、建立生產環境組態和佈署到 Kubernetes 的流程。

佈署微服務到 Kubernetes

在上一節中,我們已經建立了微服務的 Docker 映像,並將其標記為 video-streaming:1。現在,我們需要建立一個 Kubernetes 佈署組態檔案,以便將微服務佈署到本地的 Kubernetes 例項中。

建立佈署組態檔案

以下是 deploy.yaml 檔案的內容:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: video-streaming
spec:
  replicas: 1
  selector:
    matchLabels:
      app: video-streaming
  template:
    metadata:
      labels:
        app: video-streaming
    spec:
      containers:
      - name: video-streaming
        image: video-streaming:1
        imagePullPolicy: Never
        env:
        - name: PORT
          value: "4000"
---
apiVersion: v1
kind: Service
metadata:
  name: video-streaming
spec:
  selector:
    app: video-streaming
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 4000
    nodePort: 30000

這個組態檔案定義了兩個資源:一個佈署(Deployment)和一個服務(Service)。

佈署資源

佈署資源負責管理微服務的生命週期,包括啟動、停止和重啟。以下是佈署資源的詳細訊息:

  • metadata.name: 佈署的名稱為 video-streaming
  • spec.replicas: 啟動 1 個副本(replica) của微服務。
  • spec.selector.matchLabels: 選擇具有 app: video-streaming 標籤的 pod。
  • spec.template: 定義了 pod 的範本,包括容器和環境變數。

服務資源

服務資源負責將微服務暴露給外部,包括 DNS 和連線埠。以下是服務資源的詳細訊息:

  • metadata.name: 服務的名稱為 video-streaming
  • spec.selector: 選擇具有 app: video-streaming 標籤的 pod。
  • spec.type: 服務型別為 NodePort,表示將服務暴露給外部。
  • spec.ports: 定義了服務的連線埠,包括協定、連線埠號和目標連線埠號。

應用組態檔案

現在,我們可以使用 kubectl apply 命令將組態檔案應用到 Kubernetes 例項中:

kubectl apply -f deploy.yaml

這將建立佈署和服務資源,並啟動微服務的副本。

驗證微服務

我們可以使用 kubectl get 命令驗證微服務的狀態:

kubectl get deployments
kubectl get pods
kubectl get services

這些命令將顯示佈署、pod 和服務的狀態,包括名稱、狀態和連線埠號。

存取微服務

現在,我們可以使用 curl 命令存取微服務:

curl http://localhost:30000

這將傳回微服務的回應,包括 HTML 頁面或 JSON 資料。

在下一節中,我們將學習如何更新微服務的版本號,並將新的版本佈署到 Kubernetes 例項中。

Kubernetes 服務組態與佈署

在佈署微服務到 Kubernetes 叢集時,需要組態服務以使其可被存取。這涉及到建立一個服務組態檔案,定義服務的屬性和行為。

服務組態檔案

以下是服務組態檔案的範例:

apiVersion: v1
kind: Service
metadata:
  name: video-streaming
spec:
  selector:
    app: video-streaming
  ports:
  - name: http
    port: 80
    targetPort: 4000
    nodePort: 30000
  type: NodePort

在這個範例中,我們定義了一個名為 video-streaming 的服務,該服務選擇具有 app: video-streaming 標籤的 pod。服務暴露在 port 80 上,並將流量轉發到 pod 的 port 4000 上。同時,服務也組態為 NodePort 型別,暴露在 port 30000 上。

服務型別

Kubernetes 提供了三種服務型別:

  • ClusterIP:預設型別,僅在叢集內部可被存取。
  • NodePort:在叢集內部和外部都可被存取,需要指定一個 port 範圍(30000-32767)。
  • LoadBalancer:在雲端環境中使用,將流量分配到多個 pod 上。

佈署服務

建立服務組態檔案後,可以使用 kubectl apply 命令將其應用到叢集中:

kubectl apply -f service.yaml

這將建立一個新的服務,並將其組態為指定的屬性和行為。

存取服務

要存取服務,可以使用 kubectl port-forward 命令將流量轉發到本地機器:

kubectl port-forward svc/video-streaming 8080:80 &

這將在本地機器的 port 8080 上暴露服務,允許您存取服務。

圖表翻譯:

  graph LR
    A[服務組態檔案] -->|建立|> B[服務]
    B -->|選擇|> C[pod]
    C -->|暴露|> D[NodePort]
    D -->|轉發|> E[本地機器]

這個圖表展示了服務組態檔案、服務、pod、NodePort 和本地機器之間的關係。

內容解密:

在這個範例中,我們建立了一個服務組態檔案,定義了一個名為 video-streaming 的服務。該服務選擇具有 app: video-streaming 標籤的 pod,並暴露在 port 80 上。同時,服務也組態為 NodePort 型別,暴露在 port 30000 上。要存取服務,可以使用 kubectl port-forward 命令將流量轉發到本地機器。

佈署到本地Kubernetes例項

在上一節中,我們已經為微服務建立了映象,並建立了一個Kubernetes組態檔案來佈署它。現在,我們需要將kubectl連線到本地Kubernetes例項。

如果您是第一次使用Kubernetes,並且剛剛安裝了Docker Desktop(並在6.5節中啟用了Kubernetes),則您應該已經連線好了。安裝過程會自動設定這些。

但是,為了確保,我們可以檢查當前連線的叢集。開啟一個終端並執行以下命令:

kubectl config current-context

如果您已經連線到本地叢集,輸出應該類別似於:

docker-desktop

如果您之前使用過kubectl並連線到其他叢集(例如,如果您已經在工作中使用它),您可能會發現自己連線到其他叢集,或者根本沒有連線到任何叢集,並且會看到6.6節中提到的錯誤。如果是這種情況,您可以使用以下命令連線到本地叢集:

kubectl config use-context docker-desktop

要檢視您組態的連線上下文列表,請執行以下命令:

kubectl config get-contexts

如果您已經安裝了Docker Desktop並啟用了Kubernetes(請參閱6.5節),您應該會看到 docker-desktop(或類別似的東西)出現在列表中。

一旦連線到本地Kubernetes例項,我們就可以執行一個測試來確保連線正常。以下命令列出了叢集中正在執行的所有Pod:

kubectl get pods

如果您正在執行一個新的Kubernetes例項,您應該會看到一個空列表,因為您還沒有執行任何Pod。如果您之前已經在Kubernetes上進行了實驗,您可能會看到一些之前佈署的Pod執行。如果是這種情況,您可能想要點選重置按鈕以獲得一個空的叢集(請參閱6.5節)。

另一個好的測試是檢視系統Pod:

kubectl get pods --namespace kube-system

您應該會看到一個短列表,顯示Kubernetes系統Pod正在您的叢集中執行。由玄貓,這些通常是隱藏的,但我們在這裡透過玄貓的方式將其暴露出來。

佈署微服務到本地Kubernetes

現在是佈署我們的影片串流媒體微服務到本地Kubernetes叢集的時候了。請確保您已經連線到本地Kubernetes叢集,如前一節所述。然後,在您的終端中,切換到 example-1 目錄,並使用kubectl佈署微服務:

cd chapter-6/example-1
kubectl apply -f scripts/deploy.yaml

-f 引數指定要使用哪個組態檔案,而 apply 子命令在您的Kubernetes叢集中建立指定的物件。如果佈署成功,您應該會看到類別似於以下的輸出:

deployment.apps/video-streaming created
service/video-streaming created

現在讓我們檢查所請求的物件是否正在我們的本地Kubernetes例項中執行(就像之前在圖6.5中顯示的結構)。要檢查現在執行的Pod,請執行以下命令:

kubectl get pods

您應該會看到輸出,顯示我們的影片串流媒體微服務現在作為一個Pod執行:

NAME READY STATUS RESTARTS AGE
video-streaming-56d66b75c7-fp44x 1/1 Running 0 92s

請注意,Pod的名稱以 video-streaming- 開頭,但結尾是一個唯一的數字。Kubernetes為此Pod生成了一個唯一的數字,因為它可能是為此佈署建立的一個副本。在這種情況下,我們保持簡單,只建立了一個副本,因此我們只應該在Pod列表中看到一個Pod。

要檢查現在執行的佈署,請執行以下命令:

kubectl get deployments

您應該會看到 video-streaming 佈署列在輸出中:

NAME READY UP-TO-DATE AVAILABLE AGE
video-streaming 1/1 1 1 5m25s

要檢查現在執行的服務,請執行以下命令:

kubectl get services

您應該會看到 video-streaming 服務列在輸出中。

6.8.6 測試本地佈署的微服務

現在,我們必須測試我們的微服務是否真正運作。由於我們設定服務型別為 NodePort 並組態連線埠號為 30000(參考清單 6.1),我們現在應該可以測試我們的微服務並檢視串流影片。

如果微服務運作正常,則表示您的影片串流微服務現在正在 Kubernetes 上執行。如果微服務無法運作,則最常見的問題是無法從主機電腦存取連線埠。請檢查您的組態以確保連線埠匹配,並使用 kubectl get services 來雙重檢查服務的連線埠號。如果連線埠 30000 對您無效,請嘗試使用允許的範圍(30000-32767)內的其他連線埠,或者從組態中刪除 nodePort 行以使用可用的連線埠。

6.8.7 刪除佈署

當我們完成測試微服務後,可以刪除佈署以清理叢集:

kubectl delete -f scripts/deploy.yaml

這將刪除佈署、Pod 和服務——所有從該組態檔案建立的東西現在都應該被刪除。如果您想確認一切都已被刪除,可以使用 kubectl get deploymentskubectl get services 來確認。

6.8.8 為什麼不使用本地 Kubernetes 進行開發?

我們有一個本地 Kubernetes 叢集非常方便且隨時可用,所以為什麼不在開發過程中使用它,而是使用 Docker Compose?為什麼應該在開發過程中使用 Docker Compose,而在生產環境中使用 Kubernetes?

雖然可以使用本地 Kubernetes 進行開發,但我更喜歡使用 Docker Compose 進行開發和測試。原因包括:

  • 啟動多個微服務的應用程式在 Kubernetes 中可能很麻煩。
  • 在專案之間切換也可能很麻煩。
  • 本地 Kubernetes 的組態可能與生產組態不同。
  • 本地 Kubernetes 例項可能很耗資源,特別是在筆記型電腦上。

6.9 建立 Azure 中的受管 Kubernetes 叢集

現在是建立 Azure 中真正的生產 Kubernetes 叢集並將我們的影片串流微服務佈署到其中的時候了。佈署到根據雲的 Kubernetes 叢集將與佈署到本地 Kubernetes 例項非常相似,但有一些差異。例如,要佈署我們的微服務,首先需要構建它並將其釋出到容器登入函式庫中。

如果您尚未註冊 Azure,現在是註冊的時候了。請參考第 3 章,第 3.9.1 節,註冊 Azure,然後建立您的容器登入函式庫。如果您仍然有第 3 章中建立的容器登入函式庫,則可以繼續在本章中使用它。

接下來,我們將逐步建立 Kubernetes 叢集。開啟 Azure 入口網站,點選「建立」下拉選單,然後點選「Kubernetes 服務」。然後,我們組態 Kubernetes 叢集的詳細訊息,如圖 6.12 所示。請務必選擇您的免費試用訂閱(如果您有多個訂閱),以便由 Azure 支付。您可能需要向 Azure 增加信用卡詳細訊息以建立叢集,即使您需要這樣做,叢集也應該由 Azure 支付。但是,如果您用盡了這些信用,Microsoft 將開始向您收取真實金錢。一旦我們完成了這個 Kubernetes 叢集,我們將在任何情況下都刪除它,以確保安全。

選擇或建立一個資源組來包含您的新 Kubernetes 叢集。Azure 中的資源組允許我們分組和組織雲資源。您還必須為您的 Kubernetes 叢集選擇一個名稱。請記住您用於資源組和叢集的名稱;您很快就會再次需要這些詳細訊息。

選擇您要主機叢集的位置。出於實驗和學習目的,位置並不重要,因此您可以自由使用預設位置。但是,如果預設位置不可用,您可能需要在不同的位置建立叢集。

搜尋「Kubernetes」,然後點選「建立」>「Kubernetes 服務」,如圖 6.11 所示。

Kubernetes 佈署已成為微服務架構管理的基本。本文深入探討了佈署的運作機制、YAML 組態檔撰寫、服務型別選擇以及本地與雲端佈署的完整流程,並以影片串流媒體微服務為例,展現了其在確保應用程式高用性和穩定性方面的關鍵作用。分析 Kubernetes 佈署的架構細節,可以發現它巧妙地結合了宣告式組態和自動化管理,簡化了複雜的容器協調任務。然而,本地 Kubernetes 環境的資源消耗和組態複雜性,使其在開發階段的效率略遜於 Docker Compose。權衡開發效率與生產環境一致性,建議開發階段採用 Docker Compose,生產環境則使用 Kubernetes 佈署,以達到最佳平衡。展望未來,隨著 Serverless 技術的興起和邊緣計算的普及,Kubernetes 生態系統將持續發展,預計將出現更輕量級的佈署方案和更精細化的資源管理工具。玄貓認為,掌握 Kubernetes 佈署的精髓,將是未來微服務架構師和開發者的必備技能,對於構建高度可擴充套件和彈性的雲原生應用程式至關重要。