利用 Istio 網格擴充功能來支援遷移作業:教學課程

本教學課程說明如何初始化及設定可支援從內部部署 (舊版) 資料中心將功能逐一遷移至 Google Cloud Platform (GCP)服務網格。本教學課程及隨附的概念性文章的適用對象為想使用服務網格將流量動態轉送至原有環境或 GCP 的系統管理員、開發人員和工程師。

服務網格可將網路功能從服務功能中分離出來,因此能大幅降低遷移作業和重構工作的複雜性。此外,由於具備負載平衡、流量管理、監控和可觀察性等功能與特性,服務網格還可降低網路作業的複雜性。

下圖顯示如何使用服務網格將流量轉送至在原有環境或 GCP 中執行的微服務:

使用服務網格將流量轉送至在原有環境或 GCP 中執行的微服務

在本教學課程中,您將使用下列軟體:

目標

  • 初始化模擬內部部署資料中心的環境。
  • 將工作負載範例部署至內部部署資料中心。
  • 測試在內部部署資料中心執行的工作負載。
  • 在 GCP 上設定目的地環境。
  • 將工作負載從內部部署資料中心遷移至目的地環境。
  • 測試在目的地環境中執行的工作負載。
  • 淘汰內部部署資料中心。

費用

本教學課程使用的 GCP 可計費元件包括:

使用 Pricing Calculator 根據預測使用量產生預估費用。

事前準備

  1. 登入您的 Google 帳戶。

    如果您沒有帳戶,請申請新帳戶

  2. 選取或建立 Google Cloud Platform 專案。

    前往「Manage resources」(管理資源) 頁面

  3. 請確認您已啟用 Google Cloud Platform 專案的計費功能。

    瞭解如何啟用計費功能

  4. 啟用Compute Engine and GKE API。

    啟用 API

完成此教學課程後,您可刪除已建立的資源以免繼續計費。詳情請參閱清除所用資源一節。

準備環境

您將在 Cloud Shell 中執行本教學課程中的大部分步驟。

  1. 開啟 Cloud Shell:

    開啟 Cloud Shell

  2. 將工作目錄變更為 $HOME 目錄:

    cd "$HOME"
    
  3. 複製 Git 存放區,當中包含用於部署及設定示範應用程式的指令碼和資訊清單檔案:

    git clone https://github.com/GoogleCloudPlatform/solutions-istio-mesh-expansion-migration
    
  4. 設定預設地區和區域:

    gcloud config set compute/region us-east1
    gcloud config set compute/zone us-east1-b
    
  5. 初始化儲存 Istio 版本 ID 的環境變數:

    export ISTIO_VERSION=1.1.1
    
  6. 下載並擷取 Istio:

    wget https://github.com/istio/istio/releases/download/"$ISTIO_VERSION"/istio-"$ISTIO_VERSION"-linux.tar.gz
    tar -xvzf istio-"$ISTIO_VERSION"-linux.tar.gz
    
  7. 初始化儲存解壓縮 Istio 的路徑、Helm 版本 ID 和擷取 Helm 之路徑的環境變數:

    ISTIO_PATH="$HOME"/istio-"$ISTIO_VERSION"
    HELM_VERSION=v2.13.0
    HELM_PATH="$HOME"/helm-"$HELM_VERSION"
    
  8. 下載並擷取 Helm:

    wget https://storage.googleapis.com/kubernetes-helm/helm-"$HELM_VERSION"-linux-amd64.tar.gz
    tar -xvzf helm-"$HELM_VERSION"-linux-amd64.tar.gz
    mv linux-amd64 "$HELM_PATH"
    

工作負載範例

在本教學課程中,您將使用 Bookinfo 應用程式,這是可顯示書籍資訊的 4 層 Polyglot 微服務應用程式。此應用程式專為在 Kubernetes 上執行而設計,但您必須先使用 Docker 和 Docker Compose 將其部署在 Compute Engine 執行個體上,其中 Docker Compose 可讓您使用 YAML 描述元來描述多容器應用程式。接著,您就能執行單一指令來啟動此應用程式。

雖然工作負載範例已容器化,但此方法也適用於非容器化的服務。在這種情況下,您可以加入「現代化階段」,將要遷移的服務容器化

Bookinfo 應用程式具有四個微服務元件:

  • productpage:呼叫 detailsratingsreviews 微服務以在書籍資訊頁面填入資訊
  • details:提供書籍的相關資訊
  • reviews:包含書評
  • ratings:傳回隨書評顯示的書籍排名資訊

設定環境

第一步是設定本教學課程所需的環境:

  • 模擬 (舊版) 內部部署資料中心的環境
  • 模擬遷移目的地的環境

本教學課程旨在協助您從非 GCP 環境 (例如內部部署或其他雲端服務供應商) 遷移至 GCP。您必須在非 GCP 環境和 GCP 環境之間設定安全的通訊管道,因此這類遷移作業具有一定的網路複雜度。

在本教學課程中,兩種環境都會在 GCP 中執行,這樣僅需單一開機載入階段,可簡化設定程序。

佈建原有環境

在本節中,您將透過初始化 Compute Engine 執行個體及部署要遷移的工作負載來設定模擬非 GCP 環境的 GCP 環境。下圖顯示原有環境的目標架構:

佈建原有環境的架構

建立防火牆規則

您可以建立防火牆規則,允許外部存取微服務和資料庫。

  • 在 Cloud Shell 中,建立節點間通訊所需的防火牆規則:

    gcloud compute firewall-rules create bookinfo \
        --description="Bookinfo App rules" \
        --action=ALLOW \
        --rules=tcp:9080,tcp:9081,tcp:9082,tcp:9083,tcp:9084 \
        --target-tags=bookinfo-legacy-vm
    

初始化用於管理 Compute Engine 執行個體的服務帳戶

在本教學課程中,您將建立管理 Compute Engine 執行個體的服務帳戶。最佳做法是將該服務帳戶限制為僅擁有執行應用程式所需的角色和存取權限。在本教學課程中,服務帳戶所需的唯一角色是 Compute 檢視者角色 (roles/compute.viewer)。此角色提供 Compute Engine 資源的唯讀存取權。

  1. 在 Cloud Shell 中,初始化儲存服務帳戶名稱的環境變數:

    GCE_SERVICE_ACCOUNT_NAME=istio-migration-gce
    
  2. 建立服務帳戶:

    gcloud iam service-accounts create "$GCE_SERVICE_ACCOUNT_NAME" --display-name="$GCE_SERVICE_ACCOUNT_NAME"
    
  3. 初始化儲存完整服務帳戶電子郵件地址的環境變數:

    GCE_SERVICE_ACCOUNT_EMAIL="$(gcloud iam service-accounts list \
        --format='value(email)' \
        --filter=displayName:"$GCE_SERVICE_ACCOUNT_NAME")"
    
  4. compute.viewer 角色繫結至服務帳戶:

    gcloud projects add-iam-policy-binding "$(gcloud config get-value project 2> /dev/null)" \
        --member serviceAccount:"$GCE_SERVICE_ACCOUNT_EMAIL" \
        --role roles/compute.viewer
    

初始化執行階段環境

下一步是建立及設定用於託管要遷移之工作負載的 Compute Engine 執行個體。

  1. 在 Cloud Shell 中,使用 Compute Engine 執行個體名稱初始化及匯出變數:

    export GCE_INSTANCE_NAME=legacy-vm
    
  2. 建立 Compute Engine 執行個體:

    gcloud compute instances create "$GCE_INSTANCE_NAME" \
        --boot-disk-device-name="$GCE_INSTANCE_NAME" \
        --boot-disk-size=10GB \
        --boot-disk-type=pd-ssd \
        --image-family=ubuntu-1804-lts \
        --image-project=ubuntu-os-cloud \
        --machine-type=n1-standard-1 \
        --metadata-from-file startup-script="$HOME"/solutions-istio-mesh-expansion-migration/gce-startup.sh \
        --scopes=storage-ro,logging-write,monitoring-write,service-control,service-management,trace \
        --service-account="$GCE_SERVICE_ACCOUNT_EMAIL" \
        --tags=bookinfo-legacy-vm
    

    在此指令中指定的 n1-standard-1 機器類型是可讓您在不影響效能的情況下執行工作負載範例的最小值。指令執行完畢後,主控台將顯示新執行個體的詳細資料:

    NAME           ZONE        MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP   STATUS
    legacy-vm      us-east1-b  n1-standard-1               10.142.0.38  34.73.53.145  RUNNING
    

開機指令碼會透過下列方式設定 Compute Engine 執行個體:

  • 安裝 Docker
  • 安裝 Docker Compose
  • 安裝 Dnsmasq

在原有環境中部署工作負載

在本教學課程中,您會將 Istio Bookinfo 應用程式部署為要遷移的工作負載。

  1. 在 Cloud Shell 中,將 Docker Compose 描述元複製到 Compute Engine 執行個體:

    gcloud compute scp --recurse \
    "$HOME"/solutions-istio-mesh-expansion-migration/compose \
    "$GCE_INSTANCE_NAME":/tmp --zone=us-east1-b
    
  2. 等待 Docker Compose 安裝作業完成:

    gcloud compute ssh "$GCE_INSTANCE_NAME" \
        --zone=us-east1-b \
        --command='while ! command -v docker-compose; do echo "Waiting for docker-compose to be installed"; sleep 5; done'
    
  3. 使用 Docker Compose 啟動 Bookinfo 應用程式:

    gcloud compute ssh "$GCE_INSTANCE_NAME" \
        --zone=us-east1-b \
        --command='sudo docker-compose -f /tmp/compose/bookinfo.yaml up -d'
    

在原有環境中測試部署

您已完成設定工作負載範例,現在可以對其進行測試。

  1. 在 Cloud Shell 中,找出執行工作負載範例之 Compute Engine 執行個體的外部 IP 位址:

    gcloud compute instances describe "$GCE_INSTANCE_NAME" \
        --zone=us-east1-b \
        --format='value(networkInterfaces[0].accessConfigs[0].natIP)'
    
  2. 開啟瀏覽器並前往以下網址,其中 [EXTERNAL_IP] 是上一步的 IP 位址:

    http://[EXTERNAL_IP]:9083/productpage
    

    頁面顯示的內容含有書籍的詳細資料和相關評分:

    書籍的詳細資料和相關評分

佈建目的地執行階段環境

在本節中,您將使用 Istio 初始化 GKE 叢集及公開舊版服務,藉此在 GCP 中設定目的地環境。下圖顯示目的地執行階段環境的目標架構:

佈建目的地執行階段環境的架構

初始化用於管理 GKE 叢集的服務帳戶

在本教學課程中,您將建立在 GKE 叢集中管理 Compute Engine 執行個體的服務帳戶。如要提供比授予給預設服務帳戶更少的權限,GKE 叢集節點會使用此服務帳戶,而非預設的服務帳戶。

此服務帳戶需要的角色為 monitoring.viewermonitoring.metricWriterlogging.logWriter,如強化叢集的安全防護一文所述。

  1. 在 Cloud Shell 中,初始化儲存服務帳戶名稱的環境變數:

    GKE_SERVICE_ACCOUNT_NAME=istio-migration-gke
    
  2. 建立服務帳戶:

    gcloud iam service-accounts create "$GKE_SERVICE_ACCOUNT_NAME" \
        --display-name="$GKE_SERVICE_ACCOUNT_NAME"
    
  3. 初始化儲存服務帳戶電子郵件名稱的環境變數:

    GKE_SERVICE_ACCOUNT_EMAIL="$(gcloud iam service-accounts list \
        --format='value(email)' \
        --filter=displayName:"$GKE_SERVICE_ACCOUNT_NAME")"
    
  4. monitoring.viewermonitoring.metricWriterlogging.logWriter 角色授予服務帳戶:

    gcloud projects add-iam-policy-binding \
        "$(gcloud config get-value project 2> /dev/null)" \
        --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \
        --role roles/monitoring.viewer
    gcloud projects add-iam-policy-binding \
        "$(gcloud config get-value project 2> /dev/null)" \
        --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \
        --role roles/monitoring.metricWriter
    gcloud projects add-iam-policy-binding \
        "$(gcloud config get-value project 2> /dev/null)" \
        --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \
        --role roles/logging.logWriter
    

準備 GKE 叢集

在本節中,您將啟動 GKE 叢集、安裝 Istio、公開 Istio 服務,並完成叢集設定。第一步是建立及啟動 GKE 叢集。

  1. 在 Cloud Shell 中,初始化並匯出儲存 GKE 叢集名稱的環境變數:

    export GKE_CLUSTER_NAME=istio-migration
    
  2. 建立地區性 GKE 叢集,每個區域都包含一個節點集區和一個節點:

    gcloud container clusters create "$GKE_CLUSTER_NAME" \
        --addons=HorizontalPodAutoscaling,HttpLoadBalancing \
        --enable-autoupgrade \
        --enable-network-policy \
        --enable-ip-alias \
        --machine-type=n1-standard-4 \
        --metadata disable-legacy-endpoints=true \
        --node-locations us-east1-b,us-east1-c,us-east1-d \
        --no-enable-legacy-authorization \
        --no-enable-basic-auth \
        --no-issue-client-certificate \
        --num-nodes=1 \
        --region us-east1 \
        --service-account="$GKE_SERVICE_ACCOUNT_EMAIL"
    

    此指令會建立一個名稱為 istio-migration 的 GKE 叢集。執行此指令可能需要五分鐘的時間。指令執行完畢後,主控台將顯示新建立叢集的詳細資料:

    NAME             LOCATION  MASTER_VERSION  MASTER_IP      MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
    istio-migration  us-east1  1.11.7-gke.4    35.196.136.88  n1-standard-8  1.11.7-gke.4  3          RUNNING
    

接下來,您將使用 Helm 在叢集中安裝 Istio。

  1. 在 Cloud Shell 中,初始化並匯出儲存 Istio 命名空間名稱的環境變數:

    export ISTIO_NAMESPACE=istio-system
    
  2. 建立 Istio 命名空間:

    kubectl apply -f "$ISTIO_PATH"/install/kubernetes/namespace.yaml
    
  3. Tiller (Helm 的伺服器部分) 建立 Kubernetes 服務帳戶

    kubectl apply -f "$ISTIO_PATH"/install/kubernetes/helm/helm-service-account.yaml
    
  4. 在叢集中安裝 Tiller:

    "$HELM_PATH"/helm init --service-account tiller
    
  5. 安裝 istio-init 圖表以啟動所有 Istio 的自訂資源定義

    "$HELM_PATH"/helm install "$ISTIO_PATH"/install/kubernetes/helm/istio-init --name istio-init --namespace "$ISTIO_NAMESPACE"
    

    指令執行完畢後,主控台將顯示安裝在 GKE 叢集中的新物件摘要:

    NAME:   istio-init
    LAST DEPLOYED: Wed Mar 20 11:39:12 2019
    NAMESPACE: istio-system
    STATUS: DEPLOYED
    RESOURCES:
    ==> v1/ClusterRole
    NAME                     AGE
    istio-init-istio-system  1s
    ==> v1/ClusterRoleBinding
    NAME                                        AGE
    istio-init-admin-role-binding-istio-system  1s
    ==> v1/ConfigMap
    NAME          DATA  AGE
    istio-crd-10  1     1s
    istio-crd-11  1     1s
    ==> v1/Job
    NAME               COMPLETIONS  DURATION  AGE
    istio-init-crd-10  0/1          1s        1s
    istio-init-crd-11  0/1          1s        1s
    ==> v1/Pod(related)
    NAME                     READY  STATUS             RESTARTS  AGE
    istio-init-crd-10-2s28z  0/1    ContainerCreating  0         1s
    istio-init-crd-11-28n9r  0/1    ContainerCreating  0         1s
    ==> v1/ServiceAccount
    NAME                        SECRETS  AGE
    istio-init-service-account  1        1s
    
  6. 確認 Istio CRD 已提交至 Kubernetes api-server

    kubectl get crds | grep 'istio.io\|certmanager.k8s.io' | wc -l
    

    預期的輸出內容為 53

  7. 安裝 Istio 圖表:

    "$HELM_PATH"/helm install "$ISTIO_PATH"/install/kubernetes/helm/istio \
        --name istio \
        --namespace "$ISTIO_NAMESPACE" \
        --set gateways.istio-ilbgateway.enabled=true \
        --set global.meshExpansion.enabled=true \
        --set global.meshExpansion.useILB=true \
        --set grafana.enabled=true \
        --set kiali.enabled=true \
        --set kiali.createDemoSecret=true \
        --set kiali.dashboard.grafanaURL=http://grafana:3000 \
        --set prometheus.enabled=true \
        --set tracing.enabled=true
    

    執行此指令可能需要兩分鐘的時間。指令執行完畢後,主控台將顯示安裝在 GKE 叢集中的新物件摘要:

    NAME:   istio
    LAST DEPLOYED: Wed Mar 20 11:43:08 2019
    NAMESPACE: istio-system
    STATUS: DEPLOYED
    RESOURCES:
    

    此摘要後面是已部署資源的清單。

您要新增至服務網格的 Compute Engine 執行個體必須能夠存取 Istio 控制層服務 (Pilot、Mixer、Citadel),因此須透過 istio-ingressgatewayistio-ilbgateway 服務來公開這些服務。此外,您需要使用內部負載平衡器來公開 Kubernetes DNS 伺服器,使叢集中執行的服務名稱能透過查詢伺服器的方式解析出來,也須公開 Kiali 以視覺化服務網格。

  1. 在 Cloud Shell 中,建立內部負載平衡器以公開 Kubernetes DNS 伺服器:

    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/kube-dns-ilb.yaml
    
  2. 等待系統為名稱為 kube-dns-ilb 的 Service 物件指派一個外部 IP 位址:

    kubectl get svc kube-dns-ilb -n kube-system --watch
    

    輸出結果會顯示 EXTERNAL-IP 的 IP 位址:

    NAME           TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    kube-dns-ilb   LoadBalancer   10.35.252.144   10.128.0.3    53:31054/UDP   4d
    

    如要停止該指令,請按下 Control+C

  3. 等待系統為名稱為 istio-ingressgateway 的 Service 物件指派一個外部 IP 位址:

    kubectl get svc istio-ingressgateway -n "$ISTIO_NAMESPACE" --watch
    

    輸出結果會顯示 EXTERNAL-IP 的 IP 位址:

    NAME                   TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)                                                                                                                   AGE
    istio-ingressgateway   LoadBalancer   10.48.2.195   34.73.84.179   80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:31145/TCP,8060:30381/TCP,853:30784/TCP,15030:32124/TCP,15031:32703/TCP   4d
    

    如要停止該指令,請按下 Control+C

  4. 等待系統為名稱為 istio-ilbgateway 的 Service 物件指派一個外部 IP 位址:

    kubectl get svc istio-ilbgateway -n "$ISTIO_NAMESPACE" --watch
    

    輸出結果會顯示 EXTERNAL-IP 的 IP 位址:

    NAME               TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                         AGE
    istio-ilbgateway   LoadBalancer   10.48.14.190   10.142.0.31   15011:30805/TCP,15010:31082/TCP,8060:30953/TCP,5353:30536/TCP   2m
    

    如要停止該指令,請按下 Control+C

  5. 使用 GatewayVirtualService 公開 Kiali:

    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/kiali.yaml
    

設定 Istio 網格擴充功能

在本節中,您將設定 Istio 網格擴充功能,使 Compute Engine 執行個體能夠加入服務網格。第一步是產生要部署在加入網格之每個 Compute Engine 執行個體中的設定檔。

  1. 在 Cloud Shell 中,初始化並匯出儲存預設命名空間名稱的環境變數:

    export SERVICE_NAMESPACE=default
    
  2. 擷取 Istio 所使用的服務帳戶金鑰:

    "$ISTIO_PATH"/install/tools/setupMeshEx.sh machineCerts default "$SERVICE_NAMESPACE" all
    
  3. 初始化並匯出儲存設定產生指令碼選項的環境變數:

    export GCP_OPTS="--region $(gcloud config get-value compute/region 2> /dev/null)"
    
  4. 執行叢集環境設定產生指令碼:

    "$ISTIO_PATH"/install/tools/setupMeshEx.sh generateClusterEnv "$GKE_CLUSTER_NAME"
    
  5. 執行 DNS 設定產生指令碼:

    "$HOME"/solutions-istio-mesh-expansion-migration/gce-mesh-expansion-setup.sh
    

接下來,您將設定要加入網格的 Compute Engine 執行個體。

  1. 取消設定 GCP_OPTS 變數,讓初始化指令碼挑選預設值:

    unset GCP_OPTS
    
  2. 初始化並匯出儲存設定指令碼路徑的環境變數:

    export SETUP_ISTIO_VM_SCRIPT="$ISTIO_PATH"/install/tools/setupIstioVM.sh
    
  3. 為 Compute Engine 執行個體初始化作業準備 Istio 版本描述元:

    cp "$ISTIO_PATH"/istio.VERSION "$HOME"
    
  4. 執行叢集環境設定產生指令碼:

    "$ISTIO_PATH"/install/tools/setupMeshEx.sh gceMachineSetup "$GCE_INSTANCE_NAME"
    
  5. 設定將在內送服務使用 Envoy 補充的本機通訊埠:

    gcloud compute ssh "$GCE_INSTANCE_NAME" \
        --zone=us-east1-b \
        --command='sudo sed -i -e "\$aISTIO_INBOUND_PORTS=9081,9082,9083,9084" /var/lib/istio/envoy/sidecar.env'
    
  6. 設定叢集的命名空間:

    gcloud compute ssh "$GCE_INSTANCE_NAME" \
        --zone=us-east1-b \
        --command='sudo sed -i -e "\$aISTIO_NAMESPACE='"$SERVICE_NAMESPACE"'" /var/lib/istio/envoy/sidecar.env'
    
  7. 重新啟動 Istio:

    gcloud compute ssh "$GCE_INSTANCE_NAME" \
        --zone=us-east1-b \
        --command='sudo systemctl restart istio'
    
  8. 檢查 Istio 是否已正確啟動:

    gcloud compute ssh "$GCE_INSTANCE_NAME" \
        --zone=us-east1-b \
        --command='sudo systemctl --type=service --state=running list-units | grep "dnsmasq\|istio\|systemd-resolved"'
    

    輸出結果會顯示 dnsmasqistioistio-auth-node-agentsystemd-resolved 服務已載入、生效且正在執行中:

    dnsmasq.service                  loaded active running dnsmasq - A lightweight DHCP and caching DNS server
    istio-auth-node-agent.service    loaded active running istio-auth-node-agent: The Istio auth node agent
    istio.service                    loaded active running istio-sidecar: The Istio sidecar
    systemd-resolved.service         loaded active running Network Name Resolution
    

接著,您需要將在 Compute Engine 執行個體上執行的服務加入 Istio 服務網格。

  1. 在 Cloud Shell 中,建立不含選取器的 Kubernetes Service,以公開在 Compute Engine 執行個體中執行的服務:

    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/selectorless-services.yaml
    
  2. 初始化儲存執行工作負載範例的 Compute Engine 執行個體 IP 位址的環境變數:

    GCE_INSTANCE_IP="$(gcloud compute instances describe "$GCE_INSTANCE_NAME" --format='value(networkInterfaces[].networkIP)')"
    
  3. 將服務註冊到網格:

    "$ISTIO_PATH"/bin/istioctl register details "$GCE_INSTANCE_IP" http:9082 -n "$SERVICE_NAMESPACE"
    "$ISTIO_PATH"/bin/istioctl register productpage "$GCE_INSTANCE_IP" http:9083 -n "$SERVICE_NAMESPACE"
    "$ISTIO_PATH"/bin/istioctl register ratings "$GCE_INSTANCE_IP" http:9081 -n "$SERVICE_NAMESPACE"
    "$ISTIO_PATH"/bin/istioctl register reviews "$GCE_INSTANCE_IP" http:9084 -n "$SERVICE_NAMESPACE"
    

最後,為目前在 Compute Engine 執行個體上執行之網格中的服務設定 VirtualService 和相應的轉送規則。此外,您也須透過 Istio 輸入閘道公開 productpage 服務。

  1. 在 Cloud Shell 中,部署 Gateway 物件以公開服務:

    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/gateway.yaml
    
  2. 部署 VirtualService,將來自 Gateway 物件的流量轉送至在 Compute Engine 中執行的 productpage 執行個體:

    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/virtualservice-productpage-vm.yaml
    
  3. 建立 ServiceEntry,為在 Compute Engine 執行個體中執行的服務啟用服務探索功能:

    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/serviceentry.yaml
    
  4. 等待系統為名稱為 istio-ingressgateway 的 Service 物件指派一個外部 IP 位址:

    kubectl get svc istio-ingressgateway -n istio-system --watch
    

    您應會在輸出內容中看到 EXTERNAL-IP 的 IP 位址:

    NAME                   TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)                                                                                                                   AGE
    istio-ingressgateway   LoadBalancer   10.48.2.195   34.73.84.179   80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:31145/TCP,8060:30381/TCP,853:30784/TCP,15030:32124/TCP,15031:32703/TCP   4d
    
  5. 確認已建立名稱為 bookinfo-gateway 的 Gateway 物件:

    kubectl get gateway --watch
    

    您應會在輸出內容的 Gateway 物件清單中看到 bookinfo-gateway

    NAME               AGE
    bookinfo-gateway   3h
    

測試 Istio 網格擴充功能

您已使用 Istio 公開了在 Compute Engine 執行個體中執行的工作負載範例,現在可以對其進行測試:

  1. 在 Cloud Shell 中,找出 Istio 輸入閘道的外部 IP 位址:

    kubectl get svc istio-ingressgateway -n istio-system
    
  2. 開啟瀏覽器並前往以下網址,其中 [EXTERNAL_IP] 是上一步的 IP 位址:

    http://[EXTERNAL_IP]/productpage
    

    頁面顯示的內容含有書籍的相關資訊和評分:

    書籍和相關評分

視覺化服務網格

在本節中,您將使用 Kiali 來檢視以視覺化方式呈現的服務網格資料。

  1. 在 Cloud Shell 中,找出 Istio 輸入閘道的外部 IP 位址:

    kubectl get svc istio-ingressgateway -n istio-system
        EXTERNAL_IP="$(kubectl get svc istio-ingressgateway -n istio-system -o=jsonpath="{.status.loadBalancer.ingress[0].ip}")"
    
  2. 開啟瀏覽器並前往以下網址,其中 [EXTERNAL_IP] 是上一步的 IP 位址:

    http://[EXTERNAL_IP]:15029/kiali/console/graph/namespaces/?  edges=requestsPercentOfTotal&graphType=versionedApp&namespaces=default&injectServiceNodes=true&duration=60&pi=5000&layout=dagre
    
  3. 在 Kiali 登入畫面中,使用下列憑證登入:

    • 使用者名稱:admin
    • 密碼:admin

    Kiali 登入畫面

  4. 為工作負載範例的主頁面多次執行要求:

    for i in {1..10000}; do curl -s -o /dev/null -w "%{http_code}\n"  http://"$EXTERNAL_IP"/productpage; done
    

    您可以使用此指令為 Bookinfo 應用程式產生流量。預期的輸出內容為每個要求的 HTTP 傳回碼清單 (在本例中為 200 OK):

    200
    200
    200
    [...]
    

    在 Kiali 服務資訊主頁中,您應會看到目前網格的圖表,以及所有已轉送至在 Compute Engine 中執行之服務的流量。所有流量都會從 istio-ingressgateway 轉送至 Kubernetes Service productpage.default.svc.cluster.local,並指向在 Compute Engine 執行個體上執行的 productpage 微服務。您不會在圖表中看到其他微服務 (detailsreviewsratings),因為 Docker Compose 是在 Compute Engine 執行個體上處理本機轉送。

    如果您沒有看到圖表,請重新整理 Kiali 資訊主頁。

    目前網格的圖表

遷移工作負載

在本節中,您會將工作負載範例的元件從 Compute Engine 執行個體遷移至 GKE 叢集。您需要為工作負載範例的每個服務執行下列操作:

  1. 部署一個在 GKE 叢集中執行服務的 Pod
  2. 設定流量拆分規則,以在 GKE 叢集與 Compute Engine 執行個體中執行的服務之間拆分流量。
  3. 逐步遷移流量,從在 Compute Engine 執行個體中執行的服務遷移至 GKE 叢集。
  4. 停止在 Compute Engine 執行個體中執行的服務。

下圖顯示本節的系統目標架構:

遷移工作負載的架構

啟用 Istio 補充植入功能

每個服務都須具備 Envoy 補充 Proxy 才能加入 Istio 服務網格。如要避免手動編輯 Pod 設定的麻煩,您可以啟用自動補充植入功能

  1. 在 Cloud Shell 中,按下 Control+C 以停止流量產生指令。

  2. 在您要部署服務執行個體的 Kubernetes 命名空間中啟用 Istio 代管的自動補充植入功能:

    kubectl label namespace "$SERVICE_NAMESPACE" istio-injection=enabled
    

在 GKE 叢集中部署服務

在本節中,您將在 GKE 叢集中部署執行個體,並將部分流量轉送至這些執行個體。

  1. 在 Cloud Shell 中,刪除 ServiceEntry,然後再部署網格中的其他服務。刪除這些項目可防止系統將要求轉送至尚未就緒的執行個體:

    kubectl delete -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/serviceentry.yaml
    
  2. 為叢集中的 productpagedetailsreviewsratings 微服務部署 Pod 和 Kubernetes Service:

    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/productpage.yaml
    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/details.yaml
    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/ratings.yaml
    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/reviews.yaml
    
  3. 更新 VirtualService 設定,以在 Compute Engine 機器與 GKE 叢集中執行的執行個體之間拆分連入流量:

    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/virtualservice-productpage-split.yaml
    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/virtualservice-details-split.yaml
    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/virtualservice-ratings-split.yaml
    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/virtualservice-reviews-split.yaml
    
  4. 建立 ServiceEntry,為在 Compute Engine 執行個體中執行的服務啟用服務探索功能:

    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/serviceentry.yaml
    

接下來,請檢查導向至兩種環境 (Compute Engine 和 GKE) 中所有微服務執行個體的流量,藉此驗證混合式部署。

您將使用 Kiali 來檢視以視覺化方式呈現的服務網格資料:

  1. 在 Cloud Shell 中,找出 Istio 輸入閘道的外部 IP 位址:

    kubectl get svc istio-ingressgateway -n istio-system
    EXTERNAL_IP="$(kubectl get svc istio-ingressgateway -n istio-system -o=jsonpath="{.status.loadBalancer.ingress[0].ip}")"
    
  2. 開啟瀏覽器並前往以下網址,其中 [EXTERNAL_IP] 是上一步的 IP 位址:

    http://[EXTERNAL_IP]:15029/kiali/console/graph/namespaces/?edges=requestsPercentOfTotal&graphType=versionedApp&namespaces=default&injectServiceNodes=true&duration=60&pi=5000&layout=dagre
    
  3. 在 Kiali 登入畫面中,視需要使用下列憑證登入:

    • 使用者名稱:admin
    • 密碼:admin
  4. 為工作負載範例的主頁面多次執行要求:

    for i in {1..10000}; do curl -s -o /dev/null -w "%{http_code}\n"  http://"$EXTERNAL_IP"/productpage; done
    

    您可以使用此指令為 Bookinfo 應用程式產生流量。預期的輸出內容為每個要求的 HTTP 傳回碼清單 (在本例中為 200 OK):

    200
    200
    200
    [...]
    

    在 Kiali 服務資訊主頁中,您應會看到流量幾乎被平均拆分至在 Compute Engine 與 GKE 中執行的微服務執行個體 (服務 ID 的第一部分含有後置字串 -gke)。這是因為您已在 VirtualService 中設定了相同權重的路徑。

    如果您沒有看到圖表,請重新整理 Kiali 資訊主頁。

    顯示流量拆分情況的資訊主頁

將流量僅轉送至 GKE 叢集

當您對 GKE 叢集中的部署有信心時,可以更新 Service 和 VirtualService,將流量僅轉送至叢集。

下圖顯示本節的系統目標架構:

將流量僅轉送至 GKE 叢集

  1. 在 Cloud Shell 中,按下 Control+C 以停止流量產生指令。

  2. 更新 Service 和 VirtualService,將流量導向至 GKE 叢集中的微服務執行個體:

    kubectl apply -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/virtualservice-gke.yaml
    

如要驗證部署,請檢查檢查導向至兩種環境 (Compute Engine 和 GKE) 中所有微服務執行個體的流量。

您將使用 Kiali 來檢視以視覺化方式呈現的服務網格資料:

  1. 在 Cloud Shell 中,找出 Istio 輸入閘道的外部 IP 位址:

    kubectl get svc istio-ingressgateway -n istio-system
    EXTERNAL_IP="$(kubectl get svc istio-ingressgateway -n istio-system -o=jsonpath="{.status.loadBalancer.ingress[0].ip}")"
    
  2. 開啟瀏覽器並前往以下網址,其中 [EXTERNAL_IP] 是上一步的 IP 位址:

    http://[EXTERNAL_IP]:15029/kiali/console/graph/namespaces/?edges=requestsPercentOfTotal&graphType=versionedApp&namespaces=default&injectServiceNodes=true&duration=60&pi=5000&layout=dagre

  3. 在 Kiali 登入畫面中,視需要使用下列憑證登入:

    • 使用者名稱:admin
    • 密碼:admin
  4. 為工作負載範例的主頁面多次執行要求:

    for i in {1..10000}; do curl -s -o /dev/null -w "%{http_code}\n"  http://"$EXTERNAL_IP"/productpage; done
    

    您可以使用此指令為 Bookinfo 應用程式產生流量。預期的輸出內容為每個要求的 HTTP 傳回碼清單 (在本例中為 200 OK):

    200
    200
    200
    [...]
    

    在 Kiali 服務資訊主頁中,您應會看到流量僅轉送至在 GKE 叢集中執行的微服務執行個體 (服務 ID 的第一部分含有後置字串 -gke),沒有任何流量被轉送至在 Compute Engine 中執行的執行個體。如果您沒有看到圖表,請重新整理 Kiali 資訊主頁。雖然您為每個微服務部署了兩個執行個體 (一個在 Compute Engine 執行個體中執行,另一個在 GKE 叢集中執行),但您已將 VirtualService 設為將流量僅轉送至 GKE 叢集中執行的微服務執行個體。

    如果您沒有看到圖表,請重新整理 Kiali 資訊主頁。

    僅會轉送至在 GKE 叢集中執行之執行個體的流量

淘汰舊版資料中心

由於所有流量都被轉送至 GKE 叢集,您現在可以為在 Compute Engine 中執行的微服務刪除 ServiceEntry,並停止 Docker Compose。

下圖顯示本節的系統目標架構:

淘汰舊版資料中心的架構

  1. 在 Cloud Shell 中,按下 Control+C 以停止流量產生指令。

  2. 刪除 ServiceEntry,然後再部署網格中的其他服務:

    kubectl delete -f "$HOME"/solutions-istio-mesh-expansion-migration/kubernetes/bookinfo/istio/serviceentry.yaml
    
  3. 停止以 Docker Compose 執行的工作負載範例:

    gcloud compute ssh "$GCE_INSTANCE_NAME" \
        --zone=us-east1-b \
        --command='sudo docker-compose -f /tmp/compose/bookinfo.yaml down --remove-orphans -v'
    

視覺化擴充網格:僅在 GKE 中執行

在本節中,您將檢查導向至兩種環境 (Compute Engine 和 GKE) 中所有微服務執行個體的流量,藉此驗證您的部署。

您將使用 Kiali 來檢視以視覺化方式呈現的服務網格資料:

  1. 在 Cloud Shell 中,找出 Istio 輸入閘道的外部 IP 位址:

    kubectl get svc istio-ingressgateway -n istio-system
    EXTERNAL_IP="$(kubectl get svc istio-ingressgateway -n istio-system -o=jsonpath="{.status.loadBalancer.ingress[0].ip}")"
    
  2. 開啟瀏覽器並前往以下網址,其中 [EXTERNAL_IP] 是上一步的 IP 位址:

    http://[EXTERNAL_IP]:15029/kiali/console/graph/namespaces/?edges=requestsPercentOfTotal&graphType=versionedApp&namespaces=default&injectServiceNodes=true&duration=60&pi=5000&layout=dagre
    
  3. 在 Kiali 登入畫面中,視需要使用下列憑證登入:

    • 使用者名稱:admin
    • 密碼:admin
  4. 為工作負載範例的主頁面多次執行要求:

    for i in {1..10000}; do curl -s -o /dev/null -w "%{http_code}\n"  http://"$EXTERNAL_IP"/productpage; done
    

    您可以使用此指令為 Bookinfo 應用程式產生流量。預期的輸出內容為每個要求的 HTTP 傳回碼清單 (在本例中為 200 OK):

    200
    200
    200
    [...]
    

    在 Kiali 服務資訊主頁中,您應該僅會看到指向 GKE 叢集中之執行個體 (服務 ID 的第一部分含有後置字串 -gke) 的服務。由於您已刪除相關的 ServiceEntry,指向 Compute Engine 中之執行個體的服務不再屬於此網格。

    如果您沒有看到圖表,請重新整理 Kiali 資訊主頁:

    視覺化擴充網格

清除所用資源

如要避免系統向您的 Google Cloud Platform 帳戶收取您在本教學課程中使用資源的相關費用:

  1. 前往 GCP 主控台的「Projects」(專案) 頁面。

    前往「Projects」(專案) 頁面

  2. 在專案清單中,找到您要刪除的專案並按一下「刪除」圖示 delete
  3. 在對話方塊中輸入專案 ID,按一下 [Shut down] (關閉) 即可刪除專案。

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
解決方案