返回文章列表

Kubernetes Istio 環境建置與流量管理

本文介紹如何在 Kubernetes 叢集中安裝和設定 Istio 服務網格,包含 kubectl、Istio CLI 的安裝步驟,以及 Istio 的佈署和驗證。文章涵蓋 Istio Ingress Gateway 的設定、Sidecar 自動注入、流量管理、服務版本控制和生產流量映象等關鍵技術,並提供 YAML

容器技術 微服務

Kubernetes 和 Istio 的整合,為微服務架構提供強大的流量管理和安全控制能力。本文詳細說明如何在 Kubernetes 叢集環境下安裝設定 Istio,從 kubectl 和 Istio CLI 的安裝開始,逐步引導讀者完成 Istio 的佈署和驗證。接著,文章探討 Istio 的核心功能,包含 Ingress Gateway 的設定、Sidecar 自動注入組態,以及如何利用 Istio 進行服務版本控制、流量分割和生產流量映象等進階操作。這些技術有效提升服務佈署的靈活性和可靠性,讓開發者更容易管理和控制微服務之間的互動。

Kubernetes 與 Istio 環境設定

安裝 Kubernetes 命令列工具 kubectl

在開始之前,我們需要安裝 Kubernetes 的命令列工具 kubectl。首先,下載並安裝適合您作業系統的 kubectl 版本。以下是在 Linux 系統上安裝 kubectl 的指令:

curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.5/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/kubectl

內容解密:

  1. curl -LO:下載指定的 URL 內容並儲存到本地檔案。
  2. https://storage.googleapis.com/kubernetes-release/release/v1.18.5/bin/linux/amd64/kubectl:kubectl 的下載路徑,根據您的需求選擇適合的版本。
  3. chmod +x kubectl:賦予下載的 kubectl 檔案執行許可權。
  4. sudo mv kubectl /usr/local/bin/kubectl:將 kubectl 移動到系統的執行檔路徑下,以便在任何地方都能執行。

驗證 kubectl 安裝

安裝完成後,執行以下指令驗證安裝是否成功:

kubectl version

內容解密:

  1. kubectl version:顯示 kubectl 的版本資訊。
  2. 正確的輸出應該包含 Client 和 Server 版本資訊。如果只看到 Client 版本,可能是因為您的 Kubernetes 叢集尚未設定或正在執行中。

確認目前的 Kubernetes 環境 context:

kubectl config current-context

內容解密:

  1. kubectl config current-context:顯示目前使用的 Kubernetes context。
  2. 若使用 Minikube,通常預設 context 為 minikube

開啟 Kubernetes 儀錶板

執行以下指令開啟 Kubernetes 儀錶板:

minikube dashboard

內容解密:

  1. minikube dashboard:啟動 Minikube 的 Kubernetes 儀錶板,並在預設瀏覽器中開啟。
  2. 此指令會在終端機持續執行,直到手動停止。

安裝 Istio

下載並安裝 Istio。在 macOS 或 Linux 上執行以下指令:

curl -L https://git.io/getLatestIstio | sh -

內容解密:

  1. curl -L:下載指定的 URL 內容,並跟隨重定向。
  2. https://git.io/getLatestIstio:下載最新版本的 Istio 安裝指令碼。
  3. sh -:直接執行下載的指令碼。

建立 istioctl 的符號連結(或將其複製到 /usr/local/bin):

ln -s $PWD/istioctl /usr/local/bin/istioctl

內容解密:

  1. ln -s:建立符號連結。
  2. $PWD/istioctl:當前目錄下的 istioctl 執行檔。
  3. /usr/local/bin/istioctl:連結到的目標路徑。

驗證 Istio 安裝

執行以下指令驗證 Istio 是否安裝成功:

istioctl version

內容解密:

  1. istioctl version:顯示 Istio 的版本資訊。
  2. 如果看到 “no running Istio pods in ‘istio-system’",表示 Istio CLI 已安裝,但尚未佈署到叢集中。

將 Istio 佈署到 Kubernetes 叢集

Istio 提供多種設定檔(profiles)供不同需求使用。列出所有可用的設定檔:

istioctl profile list

使用 demo 設定檔佈署 Istio(本文範例使用此設定檔):

istioctl install --set profile=demo

內容解密:

  1. istioctl install:佈署 Istio 到 Kubernetes 叢集。
  2. --set profile=demo:選擇使用 demo 設定檔進行佈署,適用於展示和測試。

在佈署前,先執行 precheck 以確保叢集環境符合 Istio 的需求:

istioctl experimental precheck

內容解密:

  1. istioctl experimental precheck:檢查叢集是否準備好安裝 Istio。
  2. 此指令會檢查 Kubernetes API、版本相容性等。

設定 Kubernetes 與 Istio

安裝 Istio

在安裝 Istio 之前,需要進行前置檢查,以確保 Kubernetes 叢集已準備就緒。執行以下命令進行檢查:

$ istioctl x precheck

檢查透過後,即可安裝 Istio。使用以下命令安裝 Istio 的 demo 設定檔:

$ istioctl install --set profile=demo

安裝完成後,所有 Istio Pod 應該都在執行中。可以使用以下命令檢查 Pod 狀態:

$ kubectl get po -n istio-system

輸出結果如下:

NAME                                    READY   STATUS    RESTARTS   AGE
istio-egressgateway-8556f8c8dc-vjqtj    1/1     Running   0          85s
istio-ingressgateway-589d868684-nnt57   1/1     Running   0          85s
istiod-86d65b6959-zh787                 1/1     Running   0          2m24s

使用 Istio Operator

另一種安裝 Istio 的方法是使用 Istio Operator。首先,佈署 Istio Operator:

$ istioctl operator init

然後,建立 istio-system 名稱空間,並建立 IstioOperator 資源:

$ kubectl create ns istio-system
$ cat <<EOF | kubectl apply -f -
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  namespace: istio-system
  name: my-istio
spec:
  profile: demo
EOF

Istio Operator 將根據 IstioOperator 資源的設定自動安裝 Istio。

自動注入 Sidecar

要啟用自動注入 Sidecar,需要標記名稱空間為 istio-injection=enabled

$ kubectl label namespace default istio-injection=enabled

驗證名稱空間是否已正確標記:

$ kubectl get namespace -L istio-injection

輸出結果如下:

NAME              STATUS   AGE    ISTIO-INJECTION
default           Active   13d    enabled
istio-system      Active   2m45s  disabled
kube-node-lease   Active   13d    
kube-public       Active   13d    
kube-system       Active   13d    
kubernetes-dashboard   Active   11m    

解除安裝 Istio

要完全解除安裝 Istio,請執行以下命令:

$ istioctl x uninstall --purge

並手動刪除 istio-system 名稱空間:

$ kubectl delete namespace istio-system

流量管理

在本章中,我們將討論如何使用服務網格(Service Mesh)來路由流量。我們將學習如何設定 Ingress 資源以允許流量進入叢集,以及 Egress 資源以允許流量離開叢集。我們還將討論如何佈署新版本的服務,並在不影響生產流量的情況下與現有的生產版本一起執行。

使用 Ingress 和 Egress 資源管理流量

首先,我們需要設定 Ingress 資源以允許流量進入叢集。然後,我們將討論如何使用 Egress 資源來管理離開叢集的流量。

佈署新版本的服務

我們將學習如何佈署新版本的服務,並在不影響生產流量的情況下與現有的生產版本一起執行。然後,我們將逐漸將新版本的服務開放給外部流量。

映象生產流量

最後,我們將討論如何映象生產流量到新佈署的服務,而不會影響終端使用者。

程式碼範例:

以下是一個簡單的範例,展示瞭如何使用 Istio 設定 Ingress Gateway:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: example-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - '*'
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: example-virtualservice
spec:
  hosts:
  - '*'
  gateways:
  - example-gateway
  http:
  - match:
    - uri:
        prefix: /v1
    route:
    - destination:
        host: example-service
        port:
          number: 80

內容解密:

  • 上述程式碼定義了一個名為 example-gateway 的 Gateway 物件,用於設定 Ingress Gateway。
  • selector 欄位指定了要使用的 Ingress Gateway。
  • servers 欄位定義了 Gateway 的監聽設定,包括協定、埠號和主機名稱。
  • VirtualService 物件定義了流量的路由規則,將符合特定條件的請求路由到指定的目的地。
  • hostsgateways 欄位指定了 VirtualService 的作用範圍。
  • http 欄位定義了 HTTP 流量的路由規則,包括匹配條件和目的地。

這個範例展示瞭如何使用 Istio 設定 Ingress Gateway 和 VirtualService,以實作流量的管理和路由。

佈署範例服務與流量管理

在本章中,我們將使用兩個不同的服務:Hello Web 和 Greeter Service。Hello Web 是一個簡單的前端網頁應用程式,它會呼叫 Greeter Service。我們將使用多個版本的 Greeter Service 來示範流量路由的使用。

圖 3.1:Hello Web 和 Greeter Service 架構圖

@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333

title 圖 3.1:Hello Web 和 Greeter Service 架構圖

rectangle "圖 3.1:Hello Web" as n1
rectangle "Greeter Service 架構圖" as n2

n1 --> n2

@enduml

佈署 Greeter Service V1

首先,我們將佈署 Greeter Service V1。建立一個名為 greeter-service-v1 的 Kubernetes Deployment 和 Service,並將資源佈署到預設的名稱空間中。

greeter-service-v1.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: greeter-service-v1
  labels:
    app: greeter-service
    version: v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: greeter-service
      version: v1
  template:
    metadata:
      labels:
        app: greeter-service
        version: v1
    spec:
      containers:
      - image: learnistio/greeter-service:1.0.0
        imagePullPolicy: Always
        name: svc
        ports:
        - containerPort: 3000
---
kind: Service
apiVersion: v1
metadata:
  name: greeter-service
  labels:
    app: greeter-service
spec:
  selector:
    app: greeter-service
  ports:
  - port: 3000
    name: http

建立 Greeter Service V1 資源

cat <<EOF | kubectl create -f -
# greeter-service-v1.yaml 的內容
EOF

內容解密:

  1. Deployment 定義:定義了一個名為 greeter-service-v1 的 Deployment,具有三個副本,使用 learnistio/greeter-service:1.0.0 映像檔,並開放 3000 連線埠。
  2. Service 定義:定義了一個名為 greeter-service 的 Service,選擇器選擇標籤為 app: greeter-service 的 Pod,將流量導向 3000 連線埠。

佈署 Hello Web

接下來,我們將佈署 Hello Web 前端服務。同樣地,建立一個名為 hello-web 的 Kubernetes Deployment 和 Service。

hello-web.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloweb
  labels:
    app: helloweb
    version: v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: helloweb
      version: v1
  template:
    metadata:
      labels:
        app: helloweb
        version: v1
    spec:
      containers:
      - image: learnistio/hello-web:1.0.0
        imagePullPolicy: Always
        name: web
        ports:
        - containerPort: 3000
        env:
        - name: GREETER_SERVICE_URL
          value: 'http://greeter-service.default.svc.cluster.local:3000'
---
kind: Service
apiVersion: v1
metadata:
  name: helloweb
  labels:
    app: helloweb
spec:
  selector:
    app: helloweb
  ports:
  - port: 3000
    name: http

建立 Hello Web 資源

cat <<EOF | kubectl create -f -
# hello-web.yaml 的內容
EOF

內容解密:

  1. 環境變數設定:在 Hello Web 的容器中設定了一個名為 GREETER_SERVICE_URL 的環境變數,指定了 Greeter Service 的 URL。
  2. 服務發現:Kubernetes 的 DNS 功能使得 Hello Web 能夠解析 greeter-service.default.svc.cluster.local 並與 Greeter Service 通訊。

檢視佈署狀態

使用 kubectl get pods --watch 命令觀察 Pod 的狀態變化,或使用 kubectl get pods 檢視所有 Pod 的目前狀態。

存取已佈署的服務

預設情況下,服務網格內的服務不會自動暴露在叢集外部。要允許外部流量進入叢集,需要建立一個外部負載平衡器。

Istio Ingress Gateway

Istio 提供了一個名為 istio-ingressgateway 的 Service,用於管理進入叢集的流量。

kubectl get svc istio-ingressgateway -n istio-system

根據叢集的執行環境(Minikube、Docker for Mac/Windows 或託管式 Kubernetes),設定 GATEWAY 環境變數以存取服務。

設定 GATEWAY 環境變數

  • Minikube:執行 minikube tunnel 後,使用分配的外部 IP 位址。
  • Docker for Mac/Windows:設定 GATEWAY=http://localhost
  • 託管式 Kubernetes:使用 istio-ingressgateway 的外部 IP 位址。

本文將在範例中使用 GATEWAY 環境變數來存取服務。