使用 Istio 保護 Kubernetes 服務

本教學課程適用於對使用 Istio 服務網格感興趣的 Kubernetes 使用者和管理員,瞭解如何安全地部署 Kubernetes 服務,並啟用相互 TLS (mTLS) 通訊。

Istio 和 Cloud Service Mesh

Istio 不是 Google 支援的產品。建議您改用代管的 Cloud Service Mesh。詳情請參閱「在 GKE 上佈建代管 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. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  2. 安裝 Google Cloud CLI。

  3. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  4. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  5. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
    • 建立專案:如要建立專案,您需要具備專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  6. 確認專案已啟用計費功能 Google Cloud

  7. 啟用 GKE API:

    啟用 API 時所需的角色

    如要啟用 API,您需要具備服務使用情形管理員 IAM 角色 (roles/serviceusage.serviceUsageAdmin),其中包含 serviceusage.services.enable 權限。瞭解如何授予角色

    gcloud services enable container.googleapis.com
  8. 安裝 Google Cloud CLI。

  9. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  10. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  11. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
    • 建立專案:如要建立專案,您需要具備專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  12. 確認專案已啟用計費功能 Google Cloud

  13. 啟用 GKE API:

    啟用 API 時所需的角色

    如要啟用 API,您需要具備服務使用情形管理員 IAM 角色 (roles/serviceusage.serviceUsageAdmin),其中包含 serviceusage.services.enable 權限。瞭解如何授予角色

    gcloud services enable container.googleapis.com
  14. 將角色授予使用者帳戶。針對下列每個 IAM 角色,執行一次下列指令: roles/container.clusterAdmin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    更改下列內容:

    • PROJECT_ID:專案 ID。
    • USER_IDENTIFIER:使用者帳戶的 ID。 例如:myemail@example.com
    • ROLE:授予使用者帳戶的 IAM 角色。

準備環境

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

  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,請參閱「相互 TLS 驗證」。

確認已啟用 mTLS

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

安裝查詢介面

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

    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

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

  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 收取費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。

刪除專案

    刪除 Google Cloud 專案:

    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 --location us-central1 istio-cluster --quiet
    

後續步驟