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
內容解密:
curl -LO:下載指定的 URL 內容並儲存到本地檔案。https://storage.googleapis.com/kubernetes-release/release/v1.18.5/bin/linux/amd64/kubectl:kubectl 的下載路徑,根據您的需求選擇適合的版本。chmod +x kubectl:賦予下載的 kubectl 檔案執行許可權。sudo mv kubectl /usr/local/bin/kubectl:將 kubectl 移動到系統的執行檔路徑下,以便在任何地方都能執行。
驗證 kubectl 安裝
安裝完成後,執行以下指令驗證安裝是否成功:
kubectl version
內容解密:
kubectl version:顯示 kubectl 的版本資訊。- 正確的輸出應該包含 Client 和 Server 版本資訊。如果只看到 Client 版本,可能是因為您的 Kubernetes 叢集尚未設定或正在執行中。
確認目前的 Kubernetes 環境 context:
kubectl config current-context
內容解密:
kubectl config current-context:顯示目前使用的 Kubernetes context。- 若使用 Minikube,通常預設 context 為
minikube。
開啟 Kubernetes 儀錶板
執行以下指令開啟 Kubernetes 儀錶板:
minikube dashboard
內容解密:
minikube dashboard:啟動 Minikube 的 Kubernetes 儀錶板,並在預設瀏覽器中開啟。- 此指令會在終端機持續執行,直到手動停止。
安裝 Istio
下載並安裝 Istio。在 macOS 或 Linux 上執行以下指令:
curl -L https://git.io/getLatestIstio | sh -
內容解密:
curl -L:下載指定的 URL 內容,並跟隨重定向。https://git.io/getLatestIstio:下載最新版本的 Istio 安裝指令碼。sh -:直接執行下載的指令碼。
建立 istioctl 的符號連結(或將其複製到 /usr/local/bin):
ln -s $PWD/istioctl /usr/local/bin/istioctl
內容解密:
ln -s:建立符號連結。$PWD/istioctl:當前目錄下的 istioctl 執行檔。/usr/local/bin/istioctl:連結到的目標路徑。
驗證 Istio 安裝
執行以下指令驗證 Istio 是否安裝成功:
istioctl version
內容解密:
istioctl version:顯示 Istio 的版本資訊。- 如果看到 “no running Istio pods in ‘istio-system’",表示 Istio CLI 已安裝,但尚未佈署到叢集中。
將 Istio 佈署到 Kubernetes 叢集
Istio 提供多種設定檔(profiles)供不同需求使用。列出所有可用的設定檔:
istioctl profile list
使用 demo 設定檔佈署 Istio(本文範例使用此設定檔):
istioctl install --set profile=demo
內容解密:
istioctl install:佈署 Istio 到 Kubernetes 叢集。--set profile=demo:選擇使用 demo 設定檔進行佈署,適用於展示和測試。
在佈署前,先執行 precheck 以確保叢集環境符合 Istio 的需求:
istioctl experimental precheck
內容解密:
istioctl experimental precheck:檢查叢集是否準備好安裝 Istio。- 此指令會檢查 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物件定義了流量的路由規則,將符合特定條件的請求路由到指定的目的地。hosts和gateways欄位指定了 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
內容解密:
- Deployment 定義:定義了一個名為
greeter-service-v1的 Deployment,具有三個副本,使用learnistio/greeter-service:1.0.0映像檔,並開放 3000 連線埠。 - 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
內容解密:
- 環境變數設定:在 Hello Web 的容器中設定了一個名為
GREETER_SERVICE_URL的環境變數,指定了 Greeter Service 的 URL。 - 服務發現: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 環境變數來存取服務。