使用 Istio 保護 Kubernetes 服務


本教學課程適用於 Kubernetes 使用者和管理員,他們有興趣使用 Istio 服務網格安全地部署 Kubernetes 服務,並啟用相互 TLS (mTLS) 通訊。

Istio 和 Cloud Service Mesh

Istio 不是 Google 支援的產品。建議改用代管的 Cloud Service Mesh。詳情請參閱「在 GKE Autopilot 叢集上佈建 Cloud Service Mesh」。

Cloud Service Mesh 具有下列優點:

  • 您可以使用 Fleet API 佈建受管理 Cloud Service Mesh,不必使用 istioctl 等用戶端工具。
  • Cloud Service Mesh 會自動將 Sidecar Proxy 插入工作負載,不必授予容器更高的權限。
  • 您無須進行任何額外設定,即可查看網格和服務的豐富資訊主頁,然後使用這些指標設定服務等級目標 (SLO) 和快訊,監控應用程式的健康狀態。
  • 系統會自動升級代管 Cloud Service Mesh 控制層,確保您取得最新的安全性修補程式和功能。
  • Cloud Service Mesh 代管資料層會自動升級工作負載中的 Sidecar Proxy,因此當 Proxy 升級和安全修補程式可用時,您不需要自行重新啟動服務。
  • Cloud Service Mesh 是支援的產品,可使用標準開放原始碼 Istio API 進行設定。詳情請參閱支援的功能

目標

本教學課程包含下列步驟:

  • 建立 GKE Autopilot 叢集。
  • 使用 istioctl 指令列工具安裝 Istio。
  • 部署範例應用程式,測試雙向傳輸層安全標準 (mTLS) 驗證。
  • 設定 Istio,透過PeerAuthentication自訂資源,對服務間的通訊使用 mTLS 驗證。
  • 使用 Kiali 資訊主頁驗證 mTLS 驗證。

費用

在本文件中,您會使用 Google Cloud的下列計費元件:

如要根據預測用量估算費用,請使用 Pricing Calculator

初次使用 Google Cloud 的使用者可能符合免費試用資格。

完成本文所述工作後,您可以刪除已建立的資源,避免繼續計費。詳情請參閱清除所用資源一節。

事前準備

Cloud Shell 已預先安裝本教學課程所需的軟體,包括 kubectlgcloud CLITerraform。如果您未使用 Cloud Shell,則必須安裝 gcloud CLI。

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  4. To initialize the gcloud CLI, run the following command:

    gcloud init
  5. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the GKE API:

    gcloud services enable container.googleapis.com
  8. Install the Google Cloud CLI.

  9. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  10. To initialize the gcloud CLI, run the following command:

    gcloud init
  11. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Make sure that billing is enabled for your Google Cloud project.

  13. Enable the GKE API:

    gcloud services enable container.googleapis.com
  14. Grant roles to your user account. Run the following command once for each of the following IAM roles: roles/container.clusterAdmin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
    • Replace PROJECT_ID with your project ID.
    • Replace USER_IDENTIFIER with the identifier for your user account. For example, user:myemail@example.com.

    • Replace ROLE with each individual role.

準備環境

如要設定環境,請按照下列步驟操作:

  1. 設定環境變數:

    export PROJECT_ID=PROJECT_ID
    gcloud config set project $PROJECT_ID
    gcloud config set compute/region us-central1
    

    PROJECT_ID 替換為 Google Cloud專案 ID

  2. 複製 GitHub 存放區:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
    
  3. 變更為工作目錄:

    cd kubernetes-engine-samples/service-mesh/istio-tutorial
    

建立 GKE 叢集

啟用 Istio 要求的 Linux 功能:NET_RAWNET_ADMIN。 GKE Autopilot 預設不允許 NET_ADMIN,但您可以在 GKE 1.27 以上版本中,使用 --workload-policies=allow-net-admin 指令啟用 NET_ADMIN

gcloud container clusters create-auto istio-cluster \
    --location="us-central1" \
    --workload-policies="allow-net-admin"

如要進一步瞭解 GKE Autopilot 安全性,請參閱「內建安全性設定」。

安裝 Istio

您可以使用 Istioctl 在 GKE 叢集上安裝 Istio。

在本教學課程中,您將安裝 Istio,並使用建議用於實際工作環境部署作業的預設設定檔

  1. 安裝 Istio:

    • 如要安裝最新版 Istio,請按照下列步驟操作:

      curl -L https://istio.io/downloadIstio | sh -
      
    • 如要安裝特定版本的 Istio,請按照下列步驟操作:

      export ISTIO_VERSION=VERSION_NUMBER
      curl -L https://istio.io/downloadIstio | TARGET_ARCH=$(uname -m) sh -
      

      VERSION_NUMBER 替換為要安裝的 Istio 版本。如要瞭解 Istio 版本,請參閱「版本公告」。

  2. istioctl 指令列工具新增至 PATH:

    cd istio-*
    export PATH=$PWD/bin:$PATH
    
  3. 在叢集上安裝 Istio:

    istioctl install --set profile="default" -y
    

    這個步驟可能需要幾分鐘的時間。

  4. 等待 Istio Pod 準備就緒:

    watch kubectl get pods -n istio-system
    

    輸出結果會與下列內容相似:

    NAME                                    READY   STATUS        RESTARTS   AGE
    istio-ingressgateway-5c47bff876-wjm96   1/1     Running       0          2m54s
    istiod-5fc7cb65cd-k8cp4                 1/1     Running       0          2m57s
    

    當 Istio Pod 處於 Running 狀態時,請按下 Ctrl+C 返回指令列。

部署範例應用程式

在本節中,您會使用 Bank of Anthos 範例應用程式建立服務網格,並啟用 mTLS 驗證。

  1. 新增命名空間標籤,指示 Istio 啟用 Envoy 補充資訊 Proxy 的自動插入功能:

    kubectl label namespace default istio-injection=enabled
    
  2. 部署範例應用程式:

    cd ..
    git clone https://github.com/GoogleCloudPlatform/bank-of-anthos.git
    kubectl apply -f bank-of-anthos/extras/jwt/jwt-secret.yaml
    kubectl apply -f bank-of-anthos/kubernetes-manifests/
    
  3. 等待應用程式準備就緒:

    watch kubectl get pods
    

    輸出結果會與下列內容相似:

    NAME                                 READY   STATUS    RESTARTS   AGE
    accounts-db-0                        2/2     Running   0          2m16s
    balancereader-5c695f78f5-x4wlz       2/2     Running   0          3m8s
    contacts-557fc79c5-5d7fg             2/2     Running   0          3m7s
    frontend-7dd589c5d7-b4cgq            2/2     Running   0          3m7s
    ledger-db-0                          2/2     Running   0          3m6s
    ledgerwriter-6497f5cf9b-25c6x        2/2     Running   0          3m5s
    loadgenerator-57f6896fd6-lx5df       2/2     Running   0          3m5s
    transactionhistory-6c498965f-tl2sk   2/2     Running   0          3m4s
    userservice-95f44b65b-mlk2p          2/2     Running   0          3m4s
    

    當 Pod 處於 Running 狀態時,請按下 Ctrl+C 返回指令列。

  4. 請查看下列資訊清單:

    # Copyright 2020 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: frontend-gateway
    spec:
      selector:
        istio: ingressgateway # use Istio default gateway implementation
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: frontend-ingress
    spec:
      hosts:
      - "*"
      gateways:
      - frontend-gateway
      http:
      - route:
        - destination:
            host: frontend
            port:
              number: 80

    這個資訊清單會說明 Istio Gateway 和 VirtualService 資源,這些資源會公開應用程式,並將 Istio 做為 Ingress 控制器。

  5. 將資訊清單套用至叢集:

    kubectl apply -f bank-of-anthos/extras/istio/frontend-ingress.yaml
    

設定 mTLS

Istio 預設會啟用相互傳輸層安全標準 (mTLS) 驗證。也就是說,Istio 會監控已遷移至 Istio Proxy 的伺服器工作負載,並自動設定用戶端 Proxy,與這些工作負載建立 mTLS 連線。此外,Istio 也會設定用戶端 Proxy,在連線至沒有 Sidecar Proxy 的工作負載時,不要使用 mTLS。

Istio 可將 mTLS 設為下列三種模式:

  • PERMISSIVE:工作負載可接受 mTLS 和純文字流量。
  • STRICT:工作負載只接受 mTLS 流量。
  • DISABLE:mTLS 已停用。如要使用自己的安全解決方案,請使用這個模式。

您可以全域套用 mTLS 設定,也可以為每個命名空間或工作負載套用設定。在本教學課程中,您將使用 STRICT mTLS 模式,為每個命名空間套用設定。

  1. 請查看下列資訊清單:

    apiVersion: security.istio.io/v1beta1
    kind: PeerAuthentication
    metadata:
      name: default
    spec:
      mtls:
          mode: STRICT

    這個資訊清單說明對等互驗 Istio 自訂資源。

  2. 將資訊清單套用至叢集:

    kubectl apply -f peer-authentication.yaml
    

如要進一步瞭解 Istio 中的 mTLS,請參閱相互傳輸層安全標準 (mTLS) 驗證

確認已啟用 mTLS

Kiali 是 Istio 服務網格的網頁式可觀測性資訊主頁,可提供微服務環境的圖形檢視畫面,方便您監控及排解應用程式問題。您可以使用 Kiali 驗證 mTLS 驗證是否已啟用,且在 Istio 服務網格中正常運作。Kiali 需要 Prometheus 做為遙測資料來源。本教學課程會使用 Google Cloud Managed Service for Prometheus

安裝查詢介面

  1. 建立 IAM 服務帳戶,並授予 roles/monitoring.viewer,允許查詢介面存取指標:

    gcloud iam service-accounts create monitoring \
        --display-name="Service account for query interface"
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member "serviceAccount:monitoring@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/monitoring.viewer
    gcloud iam service-accounts add-iam-policy-binding \
      monitoring@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[monitoring/default]"
    
  2. 建立 Kubernetes 命名空間:

    kubectl create namespace monitoring
    
  3. 在命名空間中註解預設 Kubernetes 服務帳戶,以設定 Workload Identity Federation for GKE

    kubectl annotate serviceaccount -n monitoring default \
        iam.gke.io/gcp-service-account=monitoring@PROJECT_ID.iam.gserviceaccount.com --overwrite
    
  4. 部署查詢介面工作負載:

    kubectl -n monitoring apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/prometheus-engine/v0.7.1/examples/frontend.yaml
    
  5. 請查看下列資訊清單:

    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: istiod
      namespace: istio-system
    spec:
      selector:
        matchLabels:
          app: istiod
      endpoints:
      - port: 15014
        path: /metrics
        timeout: 30s
        interval: 60s

    這份資訊清單說明 PodMonitoring 資源,用於收集 Istio 和 Envoy Proxy 指標。

  6. 將資訊清單套用至叢集:

    kubectl apply -f pod-monitorings.yaml
    
  7. 取得範例應用程式的連結:

    INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo "http://$INGRESS_HOST"
    
  8. 開啟連結即可查看範例應用程式。使用預設使用者名稱和密碼登入,在微服務之間產生流量。

安裝 Kiali

建議您使用 Kiali Operator 安裝 Kiali。

  1. 安裝 Kiali Operator:

    helm repo add kiali https://kiali.org/helm-charts
    helm repo update
    helm install \
        --namespace kiali-operator \
        --create-namespace \
        kiali-operator \
        kiali/kiali-operator
    
  2. 請查看下列資訊清單:

    apiVersion: kiali.io/v1alpha1
    kind: Kiali
    metadata:
      name: kiali
      namespace: istio-system
    spec:
      deployment:
        namespace: istio-system
      auth:
        strategy: anonymous
      external_services:
        custom_dashboards:
          prometheus:
            url: "http://frontend.monitoring:9090/"
            auth:
              type: none
        prometheus:
          url: "http://frontend.monitoring:9090/"
          auth:
            type: none
        tracing:
          enabled: false
        grafana:
          enabled: false

    這個資訊清單說明 Operator 自訂資源,用於定義 Kiali 伺服器。

  3. 將資訊清單套用至叢集:

    kubectl apply -f kiali.yaml
    
  4. 等待 Kiali 伺服器準備就緒:

    watch kubectl get pods -n istio-system
    

    輸出結果會與下列內容相似:

    NAME                                    READY   STATUS    RESTARTS   AGE
    istio-ingressgateway-6845466857-92zp8   1/1     Running   0          9m11s
    istiod-6b47d84cf-4cqlt                  1/1     Running   0          12m
    

    當 Pod 處於 Running 狀態時,請按下 Ctrl+C 返回指令列。

  5. 在 Kiali 伺服器服務上設定通訊埠轉送,以便存取資訊主頁:

    kubectl -n istio-system port-forward svc/kiali 8080:20001
    
  6. 開啟網頁預覽。在 Kiali 中,前往「Graph」部分,然後在「Display」下拉式選單中選取「Security」選項。這個檢視畫面會顯示圖中每個節點的安全狀態。如果節點顯示「已啟用 mTLS」徽章,表示該服務已啟用 mTLS;如果節點未顯示徽章,表示 mTLS 未啟用。

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取本教學課程中所用資源的相關費用,請刪除含有該項資源的專案,或者保留專案但刪除個別資源。

刪除專案

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

刪除個別資源

如果您使用現有專案,但不想刪除專案,請刪除個別資源。

  1. 刪除 Kiali:

    kubectl -n istio-system delete kiali kiali
    helm uninstall --namespace kiali-operator kiali-operator
    
  2. 刪除監控資源:

    kubectl -n monitoring delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/prometheus-engine/v0.7.1/examples/frontend.yaml
    
  3. 刪除範例應用程式:

    kubectl delete -f bank-of-anthos/extras/istio/frontend-ingress.yaml
    kubectl delete -f bank-of-anthos/kubernetes-manifests
    
  4. 解除安裝 Istio:

    istioctl uninstall --purge -y
    
  5. 刪除 GKE 叢集:

    gcloud container clusters delete --region us-central1 istio-cluster --quiet
    

後續步驟

  • 探索 Google Cloud 的參考架構、圖表和最佳做法。 歡迎瀏覽我們的雲端架構中心