Istio で Kubernetes Service を保護する


このチュートリアルは、Istio サービス メッシュを使用して Kubernetes Services を安全にデプロイし、相互 TLS(mTLS)通信を有効にする方法に関心がある Kubernetes ユーザーと管理者を対象としています。

Istio と Cloud Service Mesh

Istio は、サポートされている Google プロダクトではありません。代わりにマネージド Cloud Service Mesh を実行することをおすすめします。詳細については、GKE Autopilot クラスタで Cloud Service Mesh をプロビジョニングするをご覧ください。

Cloud Service Mesh には次のようなメリットがあります。

  • istioctl などのクライアントサイドのツールを必要とせず、Fleet API を使ってマネージド Cloud Service Mesh をプロビジョニングできます。
  • Cloud Service Mesh は、昇格した権限をコンテナに付与することなく、ワークロードにサイドカー プロキシを自動的に挿入します。
  • 追加の構成なしでメッシュとサービスの詳細なダッシュボードを表示し、その指標を使用することで、サービスレベル目標(SLO)とアラートを構成して、アプリケーションの状況をモニタリングできます。
  • マネージド Cloud Service Mesh コントロール プレーンが自動的にアップグレードされるので、最新のセキュリティ パッチと機能を確実に得られます。
  • Cloud Service Mesh マネージド データプレーンによってワークロードのサイドカー プロキシが自動的にアップグレードするため、プロキシのアップグレードとセキュリティ パッチが提供されたときに自分でサービスを再起動する必要がありません。
  • Cloud Service Mesh はサポートされているプロダクトであり、標準のオープンソースの Istio API を使用して構成できます。詳しくは、サポートされている機能をご覧ください。

目標

このチュートリアルでは、次の手順について説明します。

  • GKE Autopilot クラスタを作成します。
  • istioctl コマンドライン ツールを使用して Istio をインストールします。
  • 相互 TLS(mTLS)認証をテストするサンプル アプリケーションをデプロイします。
  • PeerAuthentication カスタム リソースを使用して、サービス間通信に mTLS 認証を使用するように Istio を構成します。
  • Kiali ダッシュボードを使用して mTLS 認証を確認します。

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい 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. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. 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.

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

  6. Enable the GKE API:

    gcloud services enable container.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. 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.

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

  11. Enable the GKE API:

    gcloud services enable container.googleapis.com
  12. 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_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 をインストールします。

    export ISTIO_VERSION=1.20.2
    curl -L https://istio.io/downloadIstio | TARGET_ARCH=$(uname -m) sh -
    
  2. istioctl コマンドライン ツールを PATH に追加します。

    cd istio-${ISTIO_VERSION}
    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. Envoy サイドカー プロキシの自動挿入を有効にするよう Istio に指示する名前空間ラベルを追加します。

    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 を Ingress コントローラとして使用する Istio の Gateway および VirtualService のリソースが記述されています。

  5. マニフェストをクラスタに適用します。

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

mTLS を構成する

Istio では、相互 TLS(mTLS)認証がデフォルトで有効になっています。つまり、Istio は Istio プロキシに移行されたサーバー ワークロードをモニタリングし、これらのワークロードと mTLS 接続を確立するようにクライアント プロキシを自動的に構成します。Istio はまた、サイドカー プロキシのないワークロードに接続するときには、mTLS を使用しないようにクライアント プロキシを構成します。

Istio では、次の 3 つのモードで動作するように mTLS を構成できます。

  • PERMISSIVE: ワークロードは mTLS と書式なしテキストのトラフィックの両方を受け入れます。
  • STRICT: ワークロードは mTLS トラフィックのみを受け入れます。
  • DISABLE: mTLS は無効です。独自のセキュリティ ソリューションを使用する場合は、このモードを使用します。

mTLS 構成はグローバル、名前空間ごと、またはワークロードごとに適用できます。このチュートリアルでは、STRICT mTLS モードを使用して Namespace ごとに構成を適用します。

  1. 次のマニフェストを確認します。

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

    このマニフェストには、Peer Authentication Istio Custom Resource が記述されています。

  2. マニフェストをクラスタに適用します。

    kubectl apply -f peer-authentication.yaml
    

Istio の mTLS の詳細については、相互 TLS 認証をご覧ください。

mTLS が有効になっていることを確認する

Kiali は、Istio サービス メッシュ用のウェブベースのオブザーバビリティ ダッシュボードです。マイクロサービス環境のグラフが表示され、アプリケーションのモニタリングとトラブルシューティングを行うことができます。Kiali を使用すると、Istio サービス メッシュで mTLS 認証が有効になっていて、正しく機能していることを確認できます。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 Namespace を作成します。

    kubectl create namespace monitoring
    
  3. Namespace のデフォルトの Kubernetes サービス アカウントにアノテーションを付けて、GKE の Workload Identity 連携を構成します。

    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

    このマニフェストでは、Istio と Envoy Proxy の指標を収集する PodMonitoring リソースを記述します。

  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 サーバー Service でポート転送を設定します。

    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
    

次のステップ