Istio で Kubernetes Service を保護する

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

Istio と Cloud Service Mesh

Istio は、サポートされている Google プロダクトではありません。代わりにマネージド Cloud Service Mesh を実行することをおすすめします。詳細については、GKE でマネージド 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. Google Cloud アカウントにログインします。 Google Cloudを初めて使用する場合は、 アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
  2. Google Cloud CLI をインストールします。

  3. 外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。

  4. gcloud CLI を初期化するには、次のコマンドを実行します。

    gcloud init
  5. Google Cloud プロジェクトを作成または選択します

    プロジェクトの選択または作成に必要なロール

    • プロジェクトを選択する: プロジェクトの選択に特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトであれば、どのプロジェクトでも選択できます。
    • プロジェクトを作成する: プロジェクトを作成するには、resourcemanager.projects.create 権限を含むプロジェクト作成者ロール(roles/resourcemanager.projectCreator)が必要です。詳しくは、ロールを付与する方法をご覧ください。
    • 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 を有効にするには、serviceusage.services.enable 権限を含む Service Usage 管理者 IAM ロール(roles/serviceusage.serviceUsageAdmin)が必要です。詳しくは、ロールを付与する方法をご覧ください。

    gcloud services enable container.googleapis.com
  8. Google Cloud CLI をインストールします。

  9. 外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。

  10. gcloud CLI を初期化するには、次のコマンドを実行します。

    gcloud init
  11. Google Cloud プロジェクトを作成または選択します

    プロジェクトの選択または作成に必要なロール

    • プロジェクトを選択する: プロジェクトの選択に特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトであれば、どのプロジェクトでも選択できます。
    • プロジェクトを作成する: プロジェクトを作成するには、resourcemanager.projects.create 権限を含むプロジェクト作成者ロール(roles/resourcemanager.projectCreator)が必要です。詳しくは、ロールを付与する方法をご覧ください。
    • 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 を有効にするには、serviceusage.services.enable 権限を含む Service Usage 管理者 IAM ロール(roles/serviceusage.serviceUsageAdmin)が必要です。詳しくは、ロールを付与する方法をご覧ください。

    gcloud services enable container.googleapis.com
  14. ユーザー アカウントにロールを付与します。次の IAM ロールごとに次のコマンドを 1 回実行します。 roles/container.clusterAdmin

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

    次のように置き換えます。

    • PROJECT_ID: プロジェクト ID。
    • USER_IDENTIFIER: ユーザー アカウントの識別子。たとえば、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. 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 アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトを削除する

    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
    

次のステップ