IAP と Anthos Service Mesh の統合


このチュートリアルでは、Identity-Aware Proxy(IAP)を Anthos Service Mesh と統合する方法について説明します。IAP を Anthos Service Mesh と統合すると、Google の BeyondCorp の原則に基づいて、サービスに安全にアクセスできるようになります。IAP は、ユーザー ID とリクエストのコンテキストを確認し、ユーザーにアプリケーションまたはリソースへのアクセスを許可するかどうかを決定します。IAP を Anthos Service Mesh と統合すると、次のメリットがあります。

  • Anthos Service Mesh で実行されるワークロードに対するコンテキストアウェア アクセスの制御。発信元リクエストの属性(ユーザー ID、IP アドレス、デバイスの種類など)に基づいて、きめ細かいアクセス ポリシーを設定できます。リクエスト URL のホスト名とパスに基づいて、アクセス ポリシーと制限を組み合わせることができます。

  • Anthos Service Mesh 認証におけるコンテキストアウェア クレームのサポート。

  • Google Cloud ロードバランサを介したアプリケーションに対する、スケーラブルで安全かつ可用性の高いアクセス。高パフォーマンスの負荷分散では、組み込みの保護機能で分散型サービス拒否(DDoS)攻撃を防ぎ、グローバルなエニーキャスト IP アドレスを使用できます。

目標

  • 設定を行う。
    1. Google Cloud プロジェクトを設定し、権限を付与して、IAP で必要な Google API を有効にする。
    2. 外部静的 IP アドレスを予約し、ロードバランサで必要となる IP アドレスを使用するようにドメイン名を構成する。
    3. IAP と Anthos Service Mesh の統合に必要なオプションを使用して、新しい Google Kubernetes Engine(GKE)クラスタを設定する。
    4. 統合に必要なオプションを使用して Anthos Service Mesh をインストールする。
    5. サンプル アプリケーションをデプロイする。
    6. ロードバランサをデプロイする。
  • IAP を有効にする。

  • サービス メッシュで RCToken サポートを有効にする。

費用

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

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

要件

  • Anthos の試用版ライセンスまたはサブスクリプションが必要です。詳細については、Anthos 料金ガイドをご覧ください。

  • GKE クラスタは次の要件を満たす必要があります。

  • サービス メッシュに含めるには、サービスポートに名前を付ける必要があります。名前には、name: protocol[-suffix] の構文でポートのプロトコルを含める必要があります。角かっこは、ダッシュで始まるオプションの接尾辞です。詳細については、サービスポートの命名をご覧ください。

  • Anthos Service Mesh を限定公開クラスタにインストールする場合に、自動サイドカー インジェクションを使用するには、ポート 9443 を開くファイアウォール ルールを追加する必要があります。ファイアウォール ルールを追加せず、自動サイドカー インジェクションを有効にすると、ワークロードのデプロイでエラーが発生します。ファイアウォール ルールの追加方法については、特定のユースケースに対するファイアウォール ルールの追加をご覧ください。

  • 組織にサービス境界を作成した場合は、Mesh CA サービスを境界に追加する必要があります。詳細については、サービス境界へのメッシュ CA の追加をご覧ください。

環境設定

Google Kubernetes Engine へのインストールは、インストール ガイドに沿って行います。インストールは、Cloud Shell、Google Cloud リソースに対するブラウザ内コマンドライン インターフェース、Linux または macOS を実行している独自のコンピュータを使用して行うことができます。

オプション A: Cloud Shell を使用する

Cloud Shell は、Debian ベースの Linux オペレーティング システムを実行している g1-small Compute Engine 仮想マシン(VM)をプロビジョニングします。Cloud Shell を使用する利点は次のとおりです。

  • Cloud Shell には、必要な gcloudkubectlhelm コマンドライン ツールが含まれています。

  • Cloud Shell の $HOME ディレクトリには 5 GB の永続ストレージ スペースがあります。

  • テキスト エディタを選択できます。

    • コードエディタ。Cloud Shell ウィンドウの上部にある をクリックしてアクセスします。

    • Emacs、Vim、Nano。Cloud Shell のコマンドラインからアクセスします。

Cloud Shell を使用するには:

  1. Google Cloud コンソールに移動します。
  2. Google Cloud プロジェクトを選択します。
  3. Google Cloud コンソール ウィンドウの上部にある [Cloud Shell をアクティブにする] ボタンをクリックします。

    Google Cloud Platform コンソール

    Google Cloud コンソールの一番下にある新しいフレームの中で Cloud Shell セッションが開き、コマンドライン プロンプトが表示されます。

    Cloud Shell セッション

  4. コンポーネントを更新します。

    gcloud components update
    

    次のような出力が返されます。

    ERROR: (gcloud.components.update)
    You cannot perform this action because the gcloud CLI component manager
    is disabled for this installation. You can run the following command
    to achieve the same result for this installation:
    
    sudo apt-get update && sudo apt-get --only-upgrade install ...
  5. long コマンドをコピーし、貼り付けてコンポーネントを更新します。

  6. kubectl をインストールします。

    sudo apt-get install kubectl
    
  7. kpt をインストールします。

    sudo apt-get install google-cloud-sdk-kpt
    

オプション B: ローカルのコマンドライン ツールを使用する

ローカルマシンに gcloud CLI をインストールして初期化します。

gcloud CLI がすでにインストールされている場合は、次の手順を行います。

  1. gcloud CLI を使用して認証します。

    gcloud auth login
    
  2. コンポーネントを更新します。

    gcloud components update
    
  3. kubectl をインストールします。

    gcloud components install kubectl
    
  4. kpt をインストールします。

    gcloud components install kpt
    

プロジェクトの設定

  1. クラスタが作成されるプロジェクトのプロジェクト ID を取得します。

    gcloud

    gcloud projects list

    コンソール

    1. Google Cloud コンソールで、[ダッシュボード] ページに移動します。

      [ダッシュボード] ページに移動する

    2. ページ上部の [選択元] プルダウン リストをクリックします。表示された [選択元] ウィンドウで、プロジェクトを選択します。

      プロジェクト ID は、プロジェクト ダッシュボードの [プロジェクト情報] カードに表示されます。

  2. プロジェクト ID の環境変数を作成します。
    export PROJECT_ID=YOUR_PROJECT_ID
    
  3. gcloud コマンドライン ツールのデフォルトのプロジェクト ID を設定します。
    gcloud config set project ${PROJECT_ID}
  4. プロジェクト番号の環境変数を作成します。
    export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")

  5. 必要な Identity and Access Management(IAM)のロールを設定します。プロジェクト オーナーの場合、インストールを完了し、クラスタを Environ に登録するために必要なすべての権限が付与されています。プロジェクト オーナーでない場合は、次の IAM ロールを付与する担当者が必要になります。次のコマンドで、GCP_EMAIL_ADDRESS を Google Cloud へのログインに使用するアカウントに変更します。
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
         --member user:GCP_EMAIL_ADDRESS \
         --role=roles/editor \
         --role=roles/compute.admin \
         --role=roles/container.admin \
         --role=roles/resourcemanager.projectIamAdmin \
         --role=roles/iam.serviceAccountAdmin \
         --role=roles/iam.serviceAccountKeyAdmin \
         --role=roles/gkehub.admin

    IAM のロールを付与する方法については、リソースへのアクセス権の付与、変更、取り消しをご覧ください。これらのロールの説明については、Anthos Service Mesh のインストールに必要な権限をご覧ください。

  6. 次の API を有効にします。
    gcloud services enable \
        container.googleapis.com \
        compute.googleapis.com \
        monitoring.googleapis.com \
        logging.googleapis.com \
        cloudtrace.googleapis.com \
        meshca.googleapis.com \
        meshtelemetry.googleapis.com \
        meshconfig.googleapis.com \
        iamcredentials.googleapis.com \
        anthos.googleapis.com \
        gkeconnect.googleapis.com \
        gkehub.googleapis.com \
        cloudresourcemanager.googleapis.com \
        iap.googleapis.com
    

    API の有効化に数分かかることがあります。API が有効になると、次のような出力が表示されます。

    Operation "operations/acf.601db672-88e6-4f98-8ceb-aa3b5725533c" finished
    successfully.
    

静的 IP アドレスの予約と DNS の構成

Identity-Aware Proxy を Anthos Service Mesh と統合するには、Google Cloud HTTP(S) ロードバランサを設定する必要があります。この設定では、静的 IP アドレスを参照するドメイン名が必要です。静的外部 IP アドレスを予約すると、明示的に解放するまで、このアドレスを無期限でプロジェクトに割り当てることができます。

  1. 静的外部 IP アドレスを予約します。

    gcloud compute addresses create example-static-ip --global
    
  2. 静的 IP アドレスを取得します。

    gcloud compute addresses describe example-static-ip --global
    
  3. ドメイン名登録事業者で、静的 IP アドレスを含む完全修飾ドメイン名(FQDN)を構成します。通常、DNS 設定に A レコードを追加します。FQDN の A レコードを追加する構成手順と用語は、使用するドメイン名登録事業者によって異なります。

  4. 環境変数にドメイン名を設定します。

    export DOMAIN_NAME=YOUR_DOMAIN_NAME

    DNS 設定が反映されるまでに、24~48 時間かかります。このチュートリアルに従って設定を続けられますが、DNS 設定が反映されるまで設定のテストはできません。

新しい GKE クラスタの設定

このセクションでは、Anthos Service Mesh に必要なオプションで GKE クラスタを作成する際の基本について説明します。詳細については、クラスタの作成をご覧ください。

新しいクラスタを設定するには:

  1. 新しいクラスタのゾーンまたはリージョンマシンタイプ、GKE リリース チャンネルを選択します。Anthos Service Mesh で必要な最小マシンタイプは e2-standard-4 です。任意のリリース チャンネル オプションを使用できます。

    • シングルゾーン クラスタを作成する場合は、次のコマンドを実行して、使用可能な GCP ゾーンのリストを取得します。

      gcloud compute zones list
      
    • リージョン クラスタを作成する場合は、次のコマンドを実行して、使用可能なリージョンのリストを取得します。

      gcloud compute regions list
      
    • マシンタイプのリストを取得するには:

      gcloud compute machine-types list | more
      
  2. 次の環境変数を作成します。

    • クラスタ名を設定します。

      export CLUSTER_NAME=YOUR_CLUSTER_NAME

      クラスタ名に使用できるのは、英小文字、数字、- のみです。先頭は英字、末尾は英数字を使用し、40 文字以下にする必要があります。

    • CLUSTER_LOCATION をクラスタのゾーンまたはリージョンに設定します。

      export CLUSTER_LOCATION=YOUR_ZONE_OR_REGION
    • ワークロード プールを設定します。

      export WORKLOAD_POOL=${PROJECT_ID}.svc.id.goog
    • メッシュ ID を設定します。

      export MESH_ID="proj-${PROJECT_NUMBER}"
    • リリース チャンネルを設定します。YOUR_CHANNELregularstablerapid のいずれかに置き換えます。

      export CHANNEL=YOUR_CHANNEL

      各チャネルの説明については、利用可能なチャネルをご覧ください。

  3. Google Cloud CLI のデフォルトのゾーンまたはリージョンを設定します。

    • シングルゾーン クラスタの場合は、デフォルト ゾーンを設定します。

      gcloud config set compute/zone ${CLUSTER_LOCATION}
    • リージョン クラスタの場合は、デフォルト リージョンを設定します。

      gcloud config set compute/region ${CLUSTER_LOCATION}

    ヒント: 今後のシェル環境の設定を容易にするために、各環境変数の export ステートメントをコピーして、新しいシェルの起動時に source するシンプルなシェル スクリプトに貼り付けることができます。スクリプトにデフォルト値を設定する gcloud コマンドを追加することもできます。または、gcloud init を使用して、名前付きの gcloud 構成を作成して有効にすることもできます。

  4. Anthos Service Mesh で必要なオプションでクラスタを作成します。次のコマンドは、4 つの vCPU を持つマシンタイプ e2-standard-4 の 4 つのノードを含むクラスタを作成します。これは、Anthos Service Mesh に必要な最小マシンタイプとノード数です。少なくとも 4 つの vCPU が存在する限り、別のマシンタイプを指定できます。また、システム要件に応じてノード数を増やすことができます。

    gcloud beta container clusters create ${CLUSTER_NAME} \
        --machine-type=e2-standard-4 \
        --num-nodes=4 \
        --workload-pool=${WORKLOAD_POOL} \
        --enable-stackdriver-kubernetes \
        --subnetwork=default \
        --labels=mesh_id=${MESH_ID} \
        --release-channel=${CHANNEL}

    clusters create コマンドを使用します。

    • workload-pool=${WORKLOAD_POOL}: Workload Identity を有効にします。これは、GKE アプリケーションから Google Cloud サービスに安全にアクセスする方法として推奨される方法です。

    • enable-stackdriver-kubernetes: GKE で Cloud Monitoring と Cloud Logging を有効にします。

    • subnetwork=default: デフォルトのサブネットワークを作成します。

    • labels mesh_id=${MESH_ID}: クラスタに mesh_id ラベルを設定します。これは、Google Cloud コンソールの Anthos Service Mesh ページに指標を表示するために必要です。

    • release-channel ${CHANNEL}: 指定したリリース チャネルにクラスタを登録します。

Anthos Service Mesh のインストールの準備

次に進む前に、ASM Mesh Data Plane Service Account がプロジェクトのメンバーであることを確認します。

gcloud projects get-iam-policy ${PROJECT_ID} | grep -B 1 'roles/meshdataplane.serviceAgent'

上述のコマンドで何も出力されない場合は、認証情報と権限の設定セクションに戻り、curl コマンドを実行します。

    Linux

  1. Anthos Service Mesh インストール ファイルを現在の作業ディレクトリにダウンロードします。
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-linux.tar.gz
  2. 署名ファイルをダウンロードし、openssl を使用して署名を検証します。
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-linux.tar.gz.1.sig
    openssl dgst -verify - -signature istio-1.4.10-asm.18-linux.tar.gz.1.sig istio-1.4.10-asm.18-linux.tar.gz <<'EOF'
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWZrGCUaJJr1H8a36sG4UUoXvlXvZ
    wQfk16sxprI2gOJ2vFFggdq3ixF2h4qNBt0kI7ciDhgpwS8t+/960IsIgw==
    -----END PUBLIC KEY-----
    EOF

    想定される出力は Verified OK です。

  3. Mac OS

  4. Anthos Service Mesh インストール ファイルを現在の作業ディレクトリにダウンロードします。
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-osx.tar.gz
  5. 署名ファイルをダウンロードし、openssl を使用して署名を検証します。
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-osx.tar.gz.1.sig
    openssl dgst -sha256 -verify /dev/stdin -signature istio-1.4.10-asm.18-osx.tar.gz.1.sig istio-1.4.10-asm.18-osx.tar.gz <<'EOF'
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWZrGCUaJJr1H8a36sG4UUoXvlXvZ
    wQfk16sxprI2gOJ2vFFggdq3ixF2h4qNBt0kI7ciDhgpwS8t+/960IsIgw==
    -----END PUBLIC KEY-----
    EOF

    想定される出力は Verified OK です。

  6. Windows

  7. Anthos Service Mesh インストール ファイルを現在の作業ディレクトリにダウンロードします。
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-win.zip
  8. 署名ファイルをダウンロードし、openssl を使用して署名を検証します。
    curl -LO https://storage.googleapis.com/gke-release/asm/istio-1.4.10-asm.18-win.zip.1.sig
    openssl dgst -verify - -signature istio-1.4.10-asm.18-win.zip.1.sig istio-1.4.10-asm.18-win.zip <<'EOF'
    -----BEGIN PUBLIC KEY-----
    MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWZrGCUaJJr1H8a36sG4UUoXvlXvZ
    wQfk16sxprI2gOJ2vFFggdq3ixF2h4qNBt0kI7ciDhgpwS8t+/960IsIgw==
    -----END PUBLIC KEY-----
    EOF

    想定される出力は Verified OK です。

  9. ファイル システム上の任意の場所にファイルの内容を抽出します。たとえば、現在の作業ディレクトリにコンテンツを抽出するには、次のコマンドを実行します。
    tar xzf istio-1.4.10-asm.18-linux.tar.gz

    このコマンドにより、現在の作業ディレクトリに istio-1.4.10-asm.18 という名前のインストール ディレクトリが作成されます。このディレクトリには、次のものが含まれます。

    • samples にはサンプル アプリケーション。
    • bin ディレクトリには次のツール:
      • istioctl: istioctl は Anthos Service Mesh のインストールに使用します。
      • asmctl: asmctl を使用して、Anthos Service Mesh をインストールした後、セキュリティ構成を検証します(現在、asmctl は Anthos clusters on VMware ではサポートされていません)。

  10. Anthos Service Mesh インストールのルート ディレクトリに移動していることを確認します。
    cd istio-1.4.10-asm.18
  11. 利便性を考えて、/bin ディレクトリ内のツールを PATH に追加します。
    export PATH=$PWD/bin:$PATH

Anthos Service Mesh のインストール

Anthos Service Mesh をインストールし、Anthos Service Mesh を IAP と統合するために必要なオプションを設定します。

PERMISSIVE mTLS

istioctl manifest apply --set profile=asm \
  --set values.gateways.istio-ingressgateway.type=NodePort \
  --set values.global.trustDomain=${WORKLOAD_POOL} \
  --set values.global.sds.token.aud=${WORKLOAD_POOL} \
  --set values.nodeagent.env.GKE_CLUSTER_URL=https://container.googleapis.com/v1/projects/${PROJECT_ID}/locations/${CLUSTER_LOCATION}/clusters/${CLUSTER_NAME} \
  --set values.global.meshID=${MESH_ID} \
  --set values.global.proxy.env.GCP_METADATA="${PROJECT_ID}|${PROJECT_NUMBER}|${CLUSTER_NAME}|${CLUSTER_LOCATION}"

STRICT mTLS

istioctl manifest apply --set profile=asm \
  --set values.gateways.istio-ingressgateway.type=NodePort \
  --set values.global.trustDomain=${WORKLOAD_POOL} \
  --set values.global.sds.token.aud=${WORKLOAD_POOL} \
  --set values.nodeagent.env.GKE_CLUSTER_URL=https://container.googleapis.com/v1/projects/${PROJECT_ID}/locations/${CLUSTER_LOCATION}/clusters/${CLUSTER_NAME} \
  --set values.global.meshID=${MESH_ID} \
  --set values.global.proxy.env.GCP_METADATA="${PROJECT_ID}|${PROJECT_NUMBER}|${CLUSTER_NAME}|${CLUSTER_LOCATION}" \
  --set values.global.mtls.enabled=true

istio-ingressgatewayNodePort を指定すると、サービス メッシュで特定のポートを開くように {[mesh_name]} が構成されます。また、ドメイン名に送信されたトラフィックがこのポートに転送されるようにロードバランサを設定できます。もう一方のオプションは、Anthos Service Mesh 認証局(Mesh CA)を有効にします。

コントロール プレーン コンポーネントを確認する

istio-system のコントロール プレーン Pod が稼働していることを確認します。

kubectl get pod -n istio-system

出力は次のようになります。

NAME                                      READY   STATUS      RESTARTS   AGE
istio-galley-5c65896ff7-m2pls             2/2     Running     0          18m
istio-ingressgateway-587cd459f-q6hqt      2/2     Running     0          18m
istio-nodeagent-74w69                     1/1     Running     0          18m
istio-nodeagent-7524w                     1/1     Running     0          18m
istio-nodeagent-7652w                     1/1     Running     0          18m
istio-nodeagent-7948w                     1/1     Running     0          18m
istio-pilot-9db77b99f-7wfb6               2/2     Running     0          18m
istio-sidecar-injector-69c4d9f875-dt8rn   1/1     Running     0          18m
promsd-55f464d964-lqs7w                   2/2     Running     0          18m

クラスタ内の各ノードの istio-nodeagent のインスタンスが表示されます。Citadel OSS Istio コンポーネントを置き換える Mesh CA は、サービス メッシュで実行されているワークロードの mTLS 証明書を発行するノード エージェントを作成します。

サンプル アプリケーションのデプロイ

IAP を有効にする前に、GKE クラスタでアプリケーションを実行して、すべてのリクエストに ID があることを確認する必要があります。このガイドでは、Bookinfo サンプルを使用して、HTTP(S) ロードバランサを設定して IAP を有効にします。

アプリケーション サービスを開始する

  1. Anthos Service Mesh がインストールされたルート ディレクトリに移動します。

  2. 自動サイドカー インジェクションを使用するため、default 名前空間にラベルを付けます。

    kubectl label namespace default istio-injection=enabled
    
  3. アプリケーションをデプロイします。

    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
    
  4. bookinfo サービスがすべて実行されていることを確認します。

    kubectl get services
    

    予想される出力は次のようになります。

    NAME                       CLUSTER-IP   EXTERNAL-IP   PORT(S)              AGE
    details                    10.0.0.31            9080/TCP             6m
    kubernetes                 10.0.0.1             443/TCP              7d
    productpage                10.0.0.120           9080/TCP             6m
    ratings                    10.0.0.15            9080/TCP             6m
    reviews                    10.0.0.170           9080/TCP             6m
  5. すべての Pod が実行中であることを確認します。

    kubectl get pods
    

    予想される出力は次のようになります。

    NAME                                        READY     STATUS    RESTARTS   AGE
    details-v1-1520924117-48z17                 2/2       Running   0          6m
    productpage-v1-560495357-jk1lz              2/2       Running   0          6m
    ratings-v1-734492171-rnr5l                  2/2       Running   0          6m
    reviews-v1-874083890-f0qf0                  2/2       Running   0          6m
    reviews-v2-1343845940-b34q5                 2/2       Running   0          6m
    reviews-v3-1813607990-8ch52                 2/2       Running   0          6m
  6. Bookinfo アプリケーションが実行中であることを確認します。

    kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
    

    予想される出力:

    <title>Simple Bookstore App</title>
  7. アプリケーションの Ingress ゲートウェイと仮想サービスを定義します。

    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
    
  8. ゲートウェイが作成されたことを確認します。

    kubectl get gateway
    

    予想される出力は次のようになります。

    NAME                AGE
    bookinfo-gateway    32s

外部リクエスト

Bookinfo のゲートウェイ リソース(samples/bookinfo/networking/bookinfo-gateway.yaml で定義)は、事前構成の istio-ingressgateway を使用します。Anthos Service Mesh をデプロイするときに、istio-ingressgatewayNodePort を指定しました。これにより、サービス メッシュで特定のポートが開きます。ロードバランサを設定するまで、Bookinfo アプリケーションは GKE クラスタの外部(ブラウザなど)からアクセスできません。クラスタ内のノードには外部 IP アドレスが設定されていますが、クラスタの外部からのリクエストは Google Cloud ファイアウォール ルールによってブロックされます。IAP を使用すると、ロードバランサを使用してアプリケーションを公共のインターネットに公開できます。IAP をバイパスするファイアウォール ルールを使用してノードアドレスを公開しないでください。

Bookinfo にリクエストをルーティングするには、Google Cloud プロジェクトに HTTP(S) ロードバランサを設定します。ロードバランサはプロジェクト内にあります。これはファイアウォールの内側にあるため、クラスタ内のノードにアクセスできます。静的 IP アドレスとドメイン名を使用してロードバランサを構成すると、ドメイン名にリクエストを送信できるようになります。ロードバランサは、これらのリクエストをクラスタ内のノードに転送します。

ロードバランサのデプロイ

Ingress リソースを使用すると、自動構成の SSL 証明書で HTTP(S) ロードバランサを作成できます。Google マネージド SSL 証明書はドメインに対してプロビジョニング、更新、管理が行われます。

  1. ManagedCertificate リソースを作成します。このリソースは、SSL 証明書のドメインを指定します。spec.domains リストに複数のドメインを入れることはできません。ワイルドカード ドメインはサポートされていません。

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.gke.io/v1beta1
    kind: ManagedCertificate
    metadata:
      name: example-certificate
    spec:
      domains:
        - ${DOMAIN_NAME}
    EOF
  2. ロードバランサを作成するには、Ingress リソースを定義します。

    • 前の手順で作成した証明書の名前 example-certificatenetworking.gke.io/managed-certificates アノテーションに設定します。

    • 予約した静的 IP アドレスの名前 example-static-ipkubernetes.io/ingress.global-static-ip-name アノテーションに設定します。

    • serviceNameistio-ingressgateway に設定します。これは、Bookinfo サンプルのゲートウェイ リソースで使用されます。

    cat <<EOF | kubectl create -f -
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: example-ingress
      namespace: istio-system
      annotations:
        kubernetes.io/ingress.global-static-ip-name: example-static-ip
        networking.gke.io/managed-certificates: example-certificate
    spec:
      backend:
        serviceName: istio-ingressgateway
        servicePort: 80
    EOF
  3. Google Cloud コンソールで、[Kubernetes Engine] > [Services と Ingress] ページに移動します。

    [Services と Ingress] ページに移動

    [ステータス] 列に「Creating Ingress」と表示されます。GKE に Ingress が完全にプロビジョニングされてから次に進みます。数分ごとにページを更新し、Ingress の最新ステータスを確認します。Ingress がプロビジョニングされると、「OK」ステータスが表示されるか、「All backend services are in UNHEALTHY state.」というエラーが表示されます。デフォルトのヘルスチェックでは、GKE がプロビジョニングするリソースの 1 つが対象になります。エラー メッセージが表示された場合、Ingress がプロビジョニングされ、デフォルトのヘルスチェックが実行されています。「OK」ステータスまたはエラーが表示されている場合は、次のセクションでロードバランサのヘルスチェックを構成します。

ロードバランサのヘルスチェックを構成する

ヘルスチェックを構成するには、Ingress によって作成されたデフォルトのヘルスチェックの ID を取得してから、istio-ingress のヘルスチェックのパスとポートを使用するようにヘルスチェックを更新する必要があります。

  1. アプリケーションのデフォルト認証情報に使用する新しいユーザー認証情報を取得します。

      gcloud auth application-default login

  2. Ingress によって作成されたデフォルトのヘルスチェックの ID を取得します。

    1. 次の環境変数を設定します。

      • バックエンド サービス: 特定の Service NodePort にさまざまなインスタンス グループをブリッジします。

        BACKEND_SERVICE=$(gcloud compute url-maps list | grep example-ingress | awk '{print $2}' | cut -d'/' -f 2)

      • ヘルスチェック: Ingress のデプロイ時に自動的に作成されるデフォルトのヘルスチェック。

        HC=$(gcloud compute backend-services describe ${BACKEND_SERVICE} --global | grep healthChecks | cut -d'/' -f 10 | tail -n 1)

      • ヘルスチェックの Ingress ポート: istio-ingress のヘルスチェック ポート。

        export HC_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')

      • ヘルスチェック Ingress パス: istio-ingress のヘルスチェック パス。

        export HC_INGRESS_PATH=$(kubectl -n istio-system get deployments istio-ingressgateway -o jsonpath='{.spec.template.spec.containers[?(@.name=="istio-proxy")].readinessProbe.httpGet.path}')

      • ヘルスチェック API: ヘルスチェックの構成で呼び出す API。
        export HC_API=https://compute.googleapis.com/compute/v1/projects/${PROJECT_ID}/global/healthChecks/${HC}

    2. デフォルトのヘルスチェックを JSON ファイルに挿入する際に healthChecks API を呼び出します。

      curl --request GET  --header "Authorization: Bearer $(gcloud auth application-default print-access-token)" ${HC_API} > health_check.json
  3. istio-ingress のヘルスチェックのパスとポートを使用するようにヘルスチェックを更新します。

    1. 次のように health_check.json ファイルを更新します。

      • httpHealthCheck.port${HC_INGRESS_PORT} の値に設定します。
      • httpHealthCheck.requestPath${HC_INGRESS_PATH} の値に設定します。
      • httpHealthCheck.portSpecification="" 属性を追加して、空の文字列に設定します。

      これを実現するには、Cloud Shell にプリインストールされている jq を使用するのが最も簡単な方法です。

      jq ".httpHealthCheck.port=${HC_INGRESS_PORT} | .httpHealthCheck.requestPath=\"${HC_INGRESS_PATH}\" | .httpHealthCheck.portSpecification=\"\"" health_check.json > updated_health_check.json

      結果の updated_health_check.json ファイルに対して cat を実行すると、次のようになります。

      {
      "id": "5062913090021441698",
      "creationTimestamp": "2019-11-12T10:47:41.934-08:00",
      "name": "${HC}",
      "description": "Default kubernetes L7 Loadbalancing health check.",
      "checkIntervalSec": 60,
      "timeoutSec": 60,
      "unhealthyThreshold": 10,
      "healthyThreshold": 1,
      "type": "HTTP",
      "httpHealthCheck": {
        "port": 32394,
        "requestPath": "/healthz/ready",
        "proxyHeader": "NONE",
        "portSpecification": ""
      },
      "selfLink": "https://www.googleapis.com/compute/v1/projects/${PROJECT_ID}/global/healthChecks/${HC}",
      "kind": "compute#healthCheck"
      }
      

      jq コマンドを使用せずに JSON ファイルを手動で編集した場合は、次のコマンドのファイル名と一致するように、ファイルを updated_health_check.json として保存します。

    2. ヘルスチェックを更新します。

      curl --request PATCH --header "Authorization: Bearer $(gcloud auth application-default print-access-token)" --header "Content-Type: application/json" --data @updated_health_check.json ${HC_API}

    GKE がヘルスチェックを更新するまでに数分かかります。Ingress のステータスが「OK」に変わるまで、Google Cloud コンソールの [Kubernetes Engine] > [Services と Ingress] ページを 1 分ごとに更新します。

  4. ロードバランサをテストします。ブラウザで次の URL にアクセスします。

    http://YOUR_DOMAIN_NAME/productpage

    ここで、YOUR_DOMAIN_NAME は、外部静的 IP アドレスで構成したドメイン名です。

    Bookinfo アプリケーションの productpage が表示されます。ページを複数回更新すると、さまざまなバージョンのビューがラウンドロビン スタイル(赤い星、黒い星、星なし)で表示されます。

    Bookinfo への https アクセスもテストする必要があります。

IAP の有効化

IAP を有効にする手順は以下のとおりです。

  1. list コマンドを使用して、既存のブランドがあるかどうかを確認します。1 つのプロジェクトで使用できるブランドは 1 つだけです。

    gcloud iap oauth-brands list

    ブランドがある場合の gcloud のレスポンスは次のとおりです。

    name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID]
    applicationTitle: [APPLICATION_TITLE]
    supportEmail: [SUPPORT_EMAIL]
    orgInternalOnly: true
    
  2. ブランドが存在しない場合は、create コマンドを使用します。

    gcloud iap oauth-brands create --application_title=APPLICATION_TITLE --support_email=SUPPORT_EMAIL

    上記のフィールドは、この API を呼び出すときに必要になります。

    • supportEmail: OAuth 同意画面に表示されるサポートメール。このメールアドレスは、ユーザーのアドレスでも、Google グループのエイリアスでもかまいません。サービス アカウントにもメールアドレスがありますが、これは実際のメールアドレスではないため、ブランドの作成には使用できません。ただし、サービス アカウントは Google グループのオーナーに設定できます。新しい Google グループを作成するか、既存のグループを構成し、目的のサービス アカウントをそのグループのオーナーに設定します。

    • applicationTitle: OAuth 同意画面に表示されるアプリケーション名。

    レスポンスには、次のフィールドが含まれます。

    name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID]
    applicationTitle: [APPLICATION_TITLE]
    supportEmail: [SUPPORT_EMAIL]
    orgInternalOnly: true
    

IAP OAuth クライアントの作成

  1. create コマンドを使用してクライアントを作成します。前のステップのブランド name を使用します。

    gcloud iap oauth-clients create projects/PROJECT_NUMBER/brands/BRAND-ID --display_name=NAME

    レスポンスには、次のフィールドが含まれます。

    name: projects/[PROJECT_NUMBER]/brands/[BRAND_NAME]/identityAwareProxyClients/[CLIENT_ID]
    secret: [CLIENT_SECRET]
    displayName: [NAME]
    

サービスの IAP の有効化

次のコマンドを使用して、サービスの IAP を有効にします。CLIENT_IDCLIENT_SECRET は、以前に作成したクライアントの OAuth クライアント ID とクライアント シークレットに置き換えます。

gcloud beta iap web enable \
    --oauth2-client-id=CLIENT_ID \
    --oauth2-client-secret=CLIENT_SECRET \
    --resource-type=backend-services \
    --service=${BACKEND_SERVICE}

IAP アクセスリストを構成する

IAP のアクセス ポリシーにユーザーを追加するには:

gcloud beta iap web add-iam-policy-binding \
    --member=user:EMAIL_ADDRESS \
    --role=roles/iap.httpsResourceAccessor \
    --resource-type=backend-services \
    --service=$BACKEND_SERVICE

EMAIL_ADDRESS は、ユーザーの完全なメールアドレスです(例: alice@example.com)。

サービス メッシュで RCToken サポートを有効にする

デフォルトでは、IAP は OAuth クライアントをスコープとする JSON Web Token(JWT)を生成します。Anthos Service Mesh では、RequestContextToken(RCToken)を生成するように IAP を構成できます。これは、JWT ですが、オーディエンスは構成可能です。RCToken を使用すると、JWT のオーディエンスに任意の文字列を構成できます。これを Anthos Service Mesh ポリシーで使用し、きめ細かい認証を実施できます。

RCToken を構成するには:

  1. プロジェクト番号の環境変数を作成します。これは、プロジェクトの作成時に自動的に生成され、割り当てられた番号です(プロジェクト ID とは異なります)。

    export PROJECT_NUMBER=YOUR_PROJECT_NUMBER
  2. RCToken オーディエンスの環境変数を作成します。任意の文字列を指定できます。

    export RCTOKEN_AUD="your-rctoken-aud"
    
  3. 既存の IAP 設定を取得します。

    gcloud beta iap settings get --format json \
    --project=${PROJECT_NUMBER} --resource-type=compute \
    --service=${BACKEND_SERVICE} > iapSettings.json
    
  4. RCToken オーディエンスで IapSettings を更新します。

    cat iapSettings.json | jq --arg RCTOKEN_AUD_STR $RCTOKEN_AUD \
    '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \
    > updatedIapSettings.json
    
    gcloud beta iap settings set updatedIapSettings.json --format json \
    --project=${PROJECT_NUMBER} --resource-type=compute --service=${BACKEND_SERVICE}
    
  5. Istio Ingress ゲートウェイで RCToken 認証を有効にします。

    cat <<EOF | kubectl apply -f -
    apiVersion: "authentication.istio.io/v1alpha1"
    kind: "Policy"
    metadata:
      name: "ingressgateway"
      namespace: istio-system
    spec:
      targets:
      - name: "istio-ingressgateway"
      origins:
      - jwt:
          issuer: "https://cloud.google.com/iap"
          jwksUri: "https://www.gstatic.com/iap/verify/public_key-jwk"
          audiences:
          - "$RCTOKEN_AUD"
          jwt_headers:
          - "ingress-authorization"
          trigger_rules:
          - excluded_paths:
            - exact: /healthz/ready
      principalBinding: USE_ORIGIN
    EOF
  6. Bookinfo productpage へのリクエストが成功していることを確認します。

    http://DOMAIN_NAME/productpage

ポリシーをテストするには:

  1. IapSettings リクエスト オブジェクトを作成します。ただし、rctokenAud には別の文字列を設定します。

    echo $(cat <<EOF
    {
       "name": "projects/${PROJECT_NUMBER}/iap_web/compute/services/${BACKEND_SERVICE}",
       "applicationSettings": {
         "csmSettings": {
           "rctokenAud": "some-other-arbitrary-string"
         }
       }
     }
    EOF
    ) > request.txt
  2. IapSettings API を呼び出して、RCtoken オーディエンスを設定します。

    curl --request PATCH --header "Authorization: Bearer $(gcloud beta auth application-default print-access-token)" ${IAP_SETTINGS_API}
  3. Bookinfo productpage にリクエストを送信すると失敗します。

    http://DOMAIN_NAME/productpage

Pod のセキュリティ ポリシーの有効化

Pod のセキュリティ ポリシーを有効にすると、不正使用された名前空間(istio-system 以外)が、同じノードを共有する別の名前空間のセキュリティに影響しないようにします。Mesh CA で動作するサンプル PodSecurityPolicy リソース ファイルには、Anthos Service Mesh が用意されています。これらのファイルは必要に応じて変更できます。以下では、最初に Pod のセキュリティ ポリシーを適用してから、GKE クラスタの Pod のセキュリティ ポリシーを有効にします。

  1. クラスタ内のすべてのサービス アカウントでデフォルトの Pod のセキュリティ ポリシーを適用します。

    kubectl apply -f "samples/security/psp/all-pods-psp.yaml"
    
  2. Pod セキュリティ ポリシーを適用して Secret Discovery Service(SDS)を保護します。

    kubectl apply -f "samples/security/psp/citadel-agent-psp.yaml"
    

    これにより、ホスト VM 上で UDS パス /var/run/sds を作成する権限が Citadel エージェント(ノード エージェントとも呼ばれる)に付与されます。

  3. 次のコマンドを実行して、Pod のセキュリティ ポリシーを有効にします。

    gcloud beta container clusters update ${CLUSTER_NAME} \
        --enable-pod-security-policy
    

    Pod のセキュリティ ポリシーが有効になるまで数分かかることがあります。このプロセス中、既存のワークロードは Kubernetes マスターに接続できません。Kubernetes マスターが再起動するまで待ちます。クラスタのステータスは、Google Cloud コンソールの Kubernetes クラスタページで確認できます。

    詳細については、Pod のセキュリティ ポリシーの使用をご覧ください。

クリーンアップ

このチュートリアルを完了したら、アカウントで不要な請求が発生しないように、以下のリソースを削除します。

  1. マネージド証明書を削除します。

    kubectl delete managedcertificates example-certificate
  2. Ingress を削除します。これにより、負荷分散リソースの割り当てが解除されます。

    kubectl -n istio-system delete ingress example-ingress

  3. 静的 IP アドレスを削除します。

    gcloud compute addresses delete example-static-ip --global

    これを行う場合は、ドメイン登録事業者から IP アドレスを削除してください。

  4. クラスタを削除します。これにより、クラスタを構成するリソース(コンピューティング インスタンス、ディスク、ネットワーク リソースなど)が削除されます。

    gcloud container clusters delete ${CLUSTER_NAME}