Kubernetes 是一個開源容器協調系統,能簡化容器化應用程式的佈署、擴充套件和管理。本文將會逐步引導讀者如何在 Kubernetes 叢集中佈署微服務,並討論微服務之間的通訊方式,包含直接訊息與間接訊息,以及 HTTP 和 RabbitMQ 的比較。我們也會深入探討 Kubernetes 的核心概念,例如 Pod、Deployment 和 Service,並示範如何使用 YAML 檔案定義佈署設定。實作上,我們將使用 Docker 建立容器映像,並使用 kubectl 命令列工具與叢集互動,實際操作佈署一個視訊串流微服務至本地與雲端 Kubernetes 叢集。最後,我們將探討如何將多個微服務佈署到同一個 Kubernetes 叢集,以提升資源利用率、系統擴充套件性和容錯能力。

5.8.1 間接訊息的優點

間接訊息有幾個優點:

  • 解耦: 間接訊息可以讓微服務之間解耦,減少彼此之間的依賴性。
  • 靈活性: 間接訊息可以讓微服務之間的溝通更加靈活,方便增加或刪除微服務。
  • 可擴充套件性: 間接訊息可以讓微服務架構更加可擴充套件,方便增加新的微服務。

5.8.2 RabbitMQ 的間接訊息

RabbitMQ 是一個流行的訊息佇列系統,支援間接訊息。使用 RabbitMQ,可以輕鬆地實作間接訊息的釋出和接收。

5.8.2.1 釋出間接訊息

要釋出間接訊息,需要先建立一個交換器(exchange),然後將訊息釋出到該交換器。交換器會將訊息路由到多個佇列(queue),然後由各個佇列的消費者(consumer)接收和處理。

5.8.2.2 接收間接訊息

要接收間接訊息,需要先建立一個佇列(queue),然後將佇列繫結到交換器(exchange)。當交換器收到訊息時,會將訊息路由到繫結的佇列,然後由佇列的消費者(consumer)接收和處理。

5.8.3 間接訊息的應用

間接訊息可以用於各種場景,例如:

  • 影片播放: 當使用者播放影片時,可以釋出一個間接訊息到交換器,然後由多個微服務接收和處理,例如記錄播放次數、更新使用者資料等。
  • 使用者行為: 當使用者進行某些行為時,可以釋出一個間接訊息到交換器,然後由多個微服務接收和處理,例如記錄使用者行為、更新使用者資料等。
圖表翻譯:

此圖表示了間接訊息的釋出和接收過程。首先,釋出者釋出一個間接訊息到交換器(exchange),然後交換器將訊息路由到多個佇列(queue)。各個佇列的消費者(consumer)會接收和處理該佇列中的訊息。這樣可以實作多個微服務之間的解耦和溝通。

微服務間的溝通:直接與間接訊息

在微服務架構中,各個服務之間的溝通是非常重要的。有兩種主要的溝通方式:直接訊息(Direct Messaging)和間接訊息(Indirect Messaging)。在本章中,我們將探討這兩種方式的差異和使用場景。

直接訊息

直接訊息是指一個微服務直接向另一個微服務傳送訊息,通常使用 HTTP 請求。這種方式可以用於需要確認訊息處理結果的情況,例如需要確保訊息被成功處理或失敗的情況。直接訊息也可以用於需要序列化後續訊息的情況,例如需要在第一個訊息完成後傳送第二個訊息。

間接訊息

間接訊息是指一個微服務傳送訊息到一個中間層(如 RabbitMQ),然後由中間層將訊息轉發給其他微服務。這種方式可以用於需要廣播訊息給多個微服務的情況,或者需要解耦傳送者和接收者,使得他們可以獨立地變化和演化。

使用場景

以下是直接訊息和間接訊息的使用場景:

  • 直接訊息:
    • 需要確認訊息處理結果。
    • 需要序列化後續訊息。
    • 需要一個微服務來協調其他微服務的活動。
  • 間接訊息:
    • 需要廣播訊息給多個微服務。
    • 需要解耦傳送者和接收者。
    • 需要確保傳送者和接收者的效能是獨立的。
    • 需要確保如果訊息處理失敗,會自動重試直到成功。
圖表翻譯:
  graph LR
    A[微服務A] -->|直接訊息|> B[微服務B]
    A -->|間接訊息|> C[RabbitMQ]
    C -->|轉發|> D[微服務D]
    C -->|轉發|> E[微服務E]

內容解密:

在上面的圖表中,微服務 A 可以直接向微服務 B 傳送訊息,也可以向 RabbitMQ 傳送間接訊息。RabbitMQ 會將間接訊息轉發給微服務 D 和微服務 E。這種方式可以實作廣播訊息和解耦傳送者和接收者。

程式碼範例:

import requests

# 直接訊息
def send_direct_message(url, data):
    response = requests.post(url, json=data)
    if response.status_code == 200:
        print("訊息傳送成功")
    else:
        print("訊息傳送失敗")

# 間接訊息
import pika

def send_indirect_message(exchange, routing_key, data):
    connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
    channel = connection.channel()
    channel.basic_publish(exchange=exchange, routing_key=routing_key, body=data)
    connection.close()

圖表示意:

  sequenceDiagram
    participant 微服務A
    participant RabbitMQ
    participant 微服務D
    participant 微服務E
    Note over 微服務A,RabbitMQ: 間接訊息
    微服務A->>RabbitMQ: 傳送間接訊息
    RabbitMQ->>微服務D: 轉發訊息
    RabbitMQ->>微服務E: 轉發訊息

程式碼解說:

在上面的程式碼範例中,send_direct_message 函式用於直接向另一個微服務傳送訊息,而 send_indirect_message 函式用於向 RabbitMQ 傳送間接訊息。RabbitMQ 會將間接訊息轉發給其他微服務。這種方式可以實作廣播訊息和解耦傳送者和接收者。

微服務之間的通訊:HTTP 與 RabbitMQ

在微服務架構中,服務之間的通訊是非常重要的。有兩種主要的通訊方式:直接(同步)通訊和間接(非同步)通訊。

直接通訊

直接通訊是指服務之間直接交換訊息,通常使用 HTTP 請求。這種方式適合於需要明確序列化訊息流或需要即時反饋的場景。例如,當一個服務需要呼叫另一個服務的 API 時,可以使用 HTTP POST 請求直接傳送訊息。

間接通訊

間接通訊是指服務之間透過一個中間層交換訊息,通常使用 RabbitMQ 這種訊息佇列軟體。這種方式可以幫助解耦服務之間的依賴關係,提高系統的靈活性和可擴充套件性。例如,當一個服務需要傳送一條訊息給多個其他服務時,可以使用 RabbitMQ 將訊息廣播給所有相關服務。

RabbitMQ

RabbitMQ 是一種流行的訊息佇列軟體,允許服務之間透過訊息交換訊息。它提供了一種簡單而有效的方式來實作間接通訊。使用 RabbitMQ,可以將訊息傳送到一個佇列中,然後由多個服務從佇列中消費訊息。

如何選擇

是否使用 HTTP 或 RabbitMQ 取決於具體的情況。以下是一些需要考慮的因素:

  • 需要即時反饋嗎?如果是,HTTP 可能是更好的選擇。
  • 需要解耦服務之間的依賴關係嗎?如果是,RabbitMQ 可能是更好的選擇。
  • 需要廣播訊息給多個服務嗎?如果是,RabbitMQ 可能是更好的選擇。
內容解密:

在上面的內容中,我們討論了微服務之間的通訊方式,包括直接通訊和間接通訊。直接通訊使用 HTTP 請求,適合於需要明確序列化訊息流或需要即時反饋的場景。間接通訊使用 RabbitMQ 這種訊息佇列軟體,適合於需要解耦服務之間的依賴關係或需要廣播訊息給多個服務的場景。

  flowchart TD
    A[微服務] --> B[直接通訊]
    A --> C[間接通訊]
    B --> D[HTTP 請求]
    C --> E[RabbitMQ]
    E --> F[廣播訊息]

圖表翻譯:

上面的圖表展示了微服務之間的通訊方式。微服務可以選擇直接通訊或間接通訊。直接通訊使用 HTTP 請求,適合於需要明確序列化訊息流或需要即時反饋的場景。間接通訊使用 RabbitMQ 這種訊息佇列軟體,適合於需要解耦服務之間的依賴關係或需要廣播訊息給多個服務的場景。RabbitMQ 可以廣播訊息給多個服務,提高系統的靈活性和可擴充套件性。

第六章:邁向生產環境

6.1 新工具

本章介紹了 Kubernetes、Kubernetes 命令列工具(kubectl)和 Azure 命令列工具(Azure CLI),如表 6.1 所示。Kubernetes 是一個非常重要的工具,因為它是本章封面的主題。kubectl 是我們用來從本地電腦與 Kubernetes 叢集互動的命令列工具。Azure CLI 很有用,因為它可以輕鬆地建立組態以連線 kubectl 到我們在 Azure 上執行的 Kubernetes 叢集。然後,我們可以使用 kubectl 佈署我們的微服務並與叢集互動。

6.2 取得程式碼

要跟隨本章,您需要下載程式碼或複製儲存函式庫。 您可以使用 Git 來複製程式碼:

git clone <儲存函式庫 URL>

如果您需要幫助安裝和使用 Git,請參考第二章。如果您遇到程式碼問題,請在 GitHub 儲存函式庫中記錄一個問題。

6.3 佈署到生產環境

現在是佈署我們的應用程式到生產環境的時候了,也就是客戶導向的環境。因此,「佈署到生產環境」意味著將我們的應用程式佈署到某個地方,以便客戶可以看到和使用它。對於我們來說,那個地方將是一個在雲端執行的 Kubernetes 叢集。 可能看起來為時尚早地將這個小應用程式佈署到生產環境,但其實,在正常的開發情況下,我們應該盡早地將應用程式佈署到生產環境。也許不是這麼早,但是在應用程式仍然小的時候佈署到生產環境是很好的做法。為什麼呢?因為將產品展示給使用者以獲得反饋、適應他們的需求和建立有價值的功能是非常重要的。如果我們不佈署到生產環境,我們就不會獲得這些反饋。 另外,佈署到生產環境的最容易時機就是當應用程式仍然小的時候。隨著應用程式變得越來越大,它將變得越來越難以管理和佈署到生產環境。因此,從小應用程式開始佈署到生產環境是最好的做法。

6.4 在 Kubernetes 上託管微服務

在本章中,我們將練習如何將單個微服務佈署到 Kubernetes。您將學習如何使用一個範例微服務將其佈署到 Kubernetes。我們現在還沒有將整個應用程式上線,但我們正在使用 Kubernetes 進行熱身。稍後,在第十章中,我們將看到如何將完整的 FlixTube 應用程式佈署到 Kubernetes。 我們正在採取小步驟將應用程式帶到生產環境。最終,我們將在叢集中執行多個微服務,但工作必須從某個地方開始。因此,在本章中,我們將回到我們在第三章結束時的簡單視訊串流微服務(當時我們第一次釋出它到容器登入函式庫)。 注意:Kubernetes 是一個用於管理根據容器的應用程式的計算平臺。它最初由 CNCF(雲原生計算基金會)建立,該基金會具有巨大的行業支援,並且還負責許多其他有趣的專案。Kubernetes 通常被稱為容器協調平臺,這告訴我們所有需要知道的東西。該平臺可以管理和自動化容器的佈署和擴充套件。Kubernetes 是我們微服務應用程式的生產骨幹。我喜歡把 Kubernetes 想象成一個微服務平臺。 圖 6.1 和圖 6.2 顯示了我們在本章中要做的事情。首先,我們將利用 Docker Desktop 附帶的本地 Kubernetes 例項(圖 6.1),然後…

開發電腦

kubectl

開發人員

Docker Desktop

Kubernetes 叢集 視訊串流微服務被構建為 Docker 映像。

瞭解更多…

Kubernetes 入門與微服務佈署

在本章中,我們將探討如何使用 Kubernetes 將微服務佈署到雲端。首先,我們將使用 Docker Desktop 中的本地 Kubernetes 例項來進行實驗。Kubernetes 的命令列工具將是我們與叢集互動的主要方式。

微服務佈署組態

為了佈署微服務,我們需要建立一個 YAML 檔案來組態佈署細節。這個 YAML 檔案將定義如何佈署我們的影片串流微服務到叢集中。以下是相關檔案的概覽:

  • deploy.yaml:定義了微服務的佈署組態。
  • Dockerfile-prod:用於生產環境的 Dockerfile,定義瞭如何構建微服務的 Docker 映象。

佈署流程

以下是佈署影片串流微服務到本地 Kubernetes 叢集的步驟:

  1. 啟用 Docker Desktop 中的 Kubernetes 功能。
  2. 使用 kubectl 命令列工具與叢集互動。
  3. 建立一個 YAML 檔案來定義微服務的佈署組態。
  4. 執行 kubectl apply 命令來套用佈署組態。

為什麼選擇 Kubernetes?

有許多理由選擇使用 Kubernetes。最簡單的理由是避免供應商鎖定(vendor lock-in)。所有主要的雲端供應商都提供自己的容器協調服務,但這些服務都有自己的限制和特點。使用 Kubernetes 可以讓我們的應用程式在任何雲端供應商上都能夠順暢地執行。

學習 Kubernetes(至少基礎知識)是值得的,因為這些知識可以在不同雲端供應商之間轉移。雖然在本章中,我們是在 Azure 上託管 Kubernetes 叢集,但您可以將 Kubernetes 技能應用於您偏好的任何雲端供應商。

圖表翻譯:

  graph LR
    A[Development Computer] -->|使用 Docker Desktop|> B[Local Kubernetes Instance]
    B -->|佈署微服務|> C[Azure Kubernetes Cluster]
    C -->|執行微服務|> D[End User]

這個圖表展示了從開發電腦到 Azure Kubernetes 叢集的微服務佈署流程。

建立 Azure 上的 Kubernetes 叢集

在本章的第二部分,我們將建立一個 Azure 上的管理型 Kubernetes 叢集,並將影片串流微服務佈署到該叢集中。建立叢集的過程相當簡單,只需要在 Azure UI 中進行幾次點選即可完成。

內容解密:

# 啟用 Docker Desktop 中的 Kubernetes 功能
docker-desktop enable kubernetes

# 使用 kubectl 命令列工具與叢集互動
kubectl get nodes

# 建立一個 YAML 檔案來定義微服務的佈署組態
cat > deploy.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: video-streaming
spec:
  replicas: 3
  selector:
    matchLabels:
      app: video-streaming
  template:
    metadata:
      labels:
        app: video-streaming
    spec:
      containers:
      - name: video-streaming
        image: <your-docker-image>
        ports:
        - containerPort: 80
EOF

# 執行 kubectl apply 命令來套用佈署組態
kubectl apply -f deploy.yaml

這個程式碼片段展示瞭如何啟用 Docker Desktop 中的 Kubernetes 功能,使用 kubectl 命令列工具與叢集互動,建立一個 YAML 檔案來定義微服務的佈署組態,然後執行 kubectl apply 命令來套用佈署組態。

虛擬機器與容器技術

在現代軟體開發中,虛擬機器(Virtual Machine)和容器(Container)是兩種非常重要的技術。虛擬機器允許我們在單一物理機器上執行多個獨立的作業系統,而容器則提供了一種輕量級的虛擬化方式,讓我們可以在單一作業系統上執行多個獨立的應用程式。

Kubernetes 叢集

Kubernetes 是一個開源的容器協調系統,允許我們自動化容器的佈署、擴充套件和管理。透過使用 Kubernetes,我們可以輕鬆地建立和管理一個容器叢集,從而提高應用程式的可擴充套件性和可靠性。

容器登入函式庫

容器登入函式庫(Container Registry)是一種儲存和管理容器映像的倉函式庫。透過使用容器登入函式庫,我們可以輕鬆地儲存和分享容器映像,從而提高開發效率和協作性。

Kubectl

Kubectl 是 Kubernetes 的命令列工具,允許我們與 Kubernetes 叢集進行互動。透過使用 Kubectl,我們可以輕鬆地建立、更新和刪除容器,從而提高應用程式的管理效率。

微服務架構

微服務架構是一種軟體架構風格,將應用程式分解為多個小型、獨立的服務。每個服務負責完成一個特定的任務,從而提高應用程式的可擴充套件性和可靠性。透過使用微服務架構,我們可以輕鬆地開發和維護複雜的應用程式。

Docker

Docker 是一個流行的容器化平臺,允許我們輕鬆地建立、佈署和管理容器。透過使用 Docker,我們可以輕鬆地封裝和佈署應用程式,從而提高開發效率和協作性。

Dockerfile-prod

Dockerfile-prod 是一個 Dockerfile 檔案,用於定義生產環境下的容器映像。透過使用 Dockerfile-prod,我們可以輕鬆地建立和管理生產環境下的容器映像。

Docker 映像

Docker 映像是 Docker 容器的範本,包含了容器執行所需的所有檔案和設定。透過使用 Docker 映像,我們可以輕鬆地建立和管理容器。

deploy.yaml

deploy.yaml 是一個 YAML 檔案,用於定義 Kubernetes 的佈署設定。透過使用 deploy.yaml,我們可以輕鬆地定義和管理 Kubernetes 的佈署。

圖表翻譯:

  graph LR
    A[虛擬機器] -->|虛擬化|> B[容器]
    B -->|容器化|> C[Kubernetes 叢集]
    C -->|自動化|> D[容器登入函式庫]
    D -->|儲存|> E[Docker 映像]
    E -->|佈署|> F[Kubernetes]
    F -->|管理|> G[微服務架構]

以上圖表展示了虛擬機器、容器、Kubernetes 叢集、容器登入函式庫、Docker 映像和微服務架構之間的關係。透過使用這些技術,我們可以輕鬆地建立和管理複雜的應用程式。

微服務佈署於 Kubernetes 叢集

在微服務架構中,Kubernetes 是一個重要的工具,能夠幫助我們管理和佈署微服務。下面,我們將探討如何將微服務佈署於 Kubernetes 叢集。

什麼是 Kubernetes?

Kubernetes 是一個開源的容器協調系統,最初由 Google 開發,現在由 Cloud Native Computing Foundation (CNCF)維護。它提供了一個自動化的方式來佈署、管理和擴充套件容器化應用程式。

Kubernetes 的基本概念

在 Kubernetes 中,有幾個基本概念需要了解:

  • 節點(Node):節點是 Kubernetes 叢集中的單個機器,可以是物理機器或虛擬機器。
  • Pod:Pod 是 Kubernetes 中的基本計算單元,代表了一組一個或多個容器的集合。
  • 佈署(Deployment):佈署是一種管理 Pod 的方式,能夠自動化地建立、更新和擴充套件 Pod。
  • 服務(Service):服務是一種抽象的資源,提供了一個穩定的網路身份和負載平衡功能。

佈署微服務於 Kubernetes

要佈署微服務於 Kubernetes,我們需要建立一個佈署(Deployment)資源,然後指定微服務的容器映像和組態。

以下是建立一個簡單的佈署範例:

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: <your-docker-image-name>
        ports:
        - containerPort: 8080

這個範例建立了一個名為 video-streaming 的佈署,使用 <your-docker-image-name> 容器映像,並將容器連線埠 8080 暴露給外部。

建立服務

要使微服務能夠被外部存取,我們需要建立一個服務(Service)資源。

以下是建立一個簡單的服務範例:

apiVersion: v1
kind: Service
metadata:
  name: video-streaming
spec:
  selector:
    app: video-streaming
  ports:
  - name: http
    port: 80
    targetPort: 8080
  type: LoadBalancer

這個範例建立了一個名為 video-streaming 的服務,選擇 video-streaming 標籤的 Pod,並將服務連線埠 80 對映到容器連線埠 8080。

內容解密:
  • Kubernetes:是一個開源的容器協調系統,能夠自動化地佈署、管理和擴充套件容器化應用程式。
  • 節點(Node):是 Kubernetes 叢集中的單個機器,可以是物理機器或虛擬機器。
  • Pod:是 Kubernetes 中的基本計算單元,代表了一組一個或多個容器的集合。
  • 佈署(Deployment):是一種管理 Pod 的方式,能夠自動化地建立、更新和擴充套件 Pod。
  • 服務(Service):是一種抽象的資源,提供了一個穩定的網路身份和負載平衡功能。

圖表翻譯:

  graph LR
    A[Kubernetes] -->|管理|> B[Pod]
    B -->|包含|> C[Container]
    C -->|暴露|> D[Service]
    D -->|提供|> E[LoadBalancer]

這個圖表顯示了 Kubernetes、Pod、Container、Service 和 LoadBalancer 之間的關係。Kubernetes 管理 Pod,Pod 包含 Container,Container 暴露 Service,Service 提供 LoadBalancer。

Kubernetes 叢集架構

Kubernetes 叢集是由多個節點(Node)組成,每個節點包含一個或多個 Pod。每個 Pod 又包含一個或多個容器(Container),而每個容器內執行著一個微服務(Microservice)。

Pod 結構

如圖 6.4 所示,Pod 是 Kubernetes 中的基本執行單元。每個 Pod 包含一個或多個容器,且這些容器分享相同的網路名稱空間和資源。這意味著在同一個 Pod 中的容器可以直接透過 localhost 通訊。

微服務佈署

我們的微服務執行在容器內,而容器則執行在 Pod 中。當我們將微服務佈署到 Kubernetes 時,Kubernetes 會自動管理 Pod 的生命週期,包括啟動、停止和重啟。這樣可以確保微服務始終可用,即使個別容器發生故障。

自動重啟機制

Kubernetes 提供了一種稱為 Deployment 的資源,可以用來管理 Pod 的生命週期。當我們建立一個 Deployment 時,Kubernetes 會自動監視相關的 Pod,如果發現某個 Pod 故障或無回應,Kubernetes 會自動啟動一個新的 Pod 來取代它。這樣可以確保微服務始終可用。

Kubernetes 主要概念

要將微服務佈署到 Kubernetes 生產環境中,我們需要了解以下幾個主要概念:

  1. Pod:Kubernetes 中的基本執行單元,包含一個或多個容器。
  2. Deployment:用於管理 Pod 生命週期的資源,可以自動重啟故障的 Pod。
  3. Service:提供了一種方式來存取 Pod 中的容器,允許我們透過一個穩定的網路身份存取微服務。

雖然在本章中,我們只簡單地介紹瞭如何將一個微服務佈署到 Kubernetes 中,但是在未來,我們可能會需要將多個微服務佈署到同一個叢集中,如圖 6.6 所示。這樣可以更好地利用資源,提高系統的可擴充套件性和容錯性。

內容解密:

上述內容介紹了 Kubernetes 叢集的架構、Pod 的結構、微服務佈署以及 Kubernetes 的主要概念。同時,也提到了未來可能的發展方向,即將多個微服務佈署到同一個叢集中,以提高系統的可擴充套件性和容錯性。

圖表翻譯:

圖 6.3 展示了 Kubernetes 叢集的結構,包括節點、Pod 和容器。圖 6.4 顯示了 Pod 的結構,包括多個容器分享相同的網路名稱空間和資源。圖 6.5 顯示了微服務執行在 Pod 中,並由 Deployment 管理。圖 6.6 展示了未來可能的發展方向,即將多個微服務佈署到同一個叢集中。

微服務架構的興起伴隨著 Kubernetes 等容器協調平臺的日益成熟。深入剖析 Kubernetes 的核心架構,可以發現它提供了一種高效且可靠的方式來佈署、管理和擴充套件微服務應用。透過容器化技術和自動化佈署流程,Kubernetes 有效解決了微服務架構在複雜環境下的佈署挑戰,並提升了系統的彈性與容錯能力。然而,Kubernetes 的學習曲線較陡峭,技術團隊需要投入一定的學習成本才能有效駕馭。對於資源有限的團隊,建議優先關注核心業務微服務的容器化和佈署,逐步累積 Kubernetes 的實踐經驗。從技術演進角度,Kubernetes 代表了雲原生應用平臺的主流方向,值得技術團隊提前佈局。玄貓認為,掌握 Kubernetes 的核心概念和操作技能,將成為未來微服務架構師和開發者的必備技能。隨著生態系統的日趨完善,我們預見 Kubernetes 的應用門檻將逐步降低,更多企業將受益於其帶來的效率提升和成本最佳化。