Anthos Service Mesh の例: 認可


このチュートリアルでは、サンプル アプリケーションで Anthos Service Mesh を使用して認可を有効にする方法と、マイクロサービスに対して認可ポリシーを有効にする方法を説明します。マイクロサービスへのアクセスを DENY(拒否)する AuthorizationPolicy を作成してから、特定のマイクロサービスへのアクセスを ALLOW(許可)する AuthorizationPolicy 作成します。

認可とは

認証では本人確認(このサービスを使用する人は自分を誰だと言っているかの確認)を行います。認可では権限を確認(このサービスで何が許可されているのかの確認)を行います。ID はこの考え方の根幹を担っています。Anthos Service Mesh では、AuthorizationPolicies を使用してメッシュ内のワークロード間通信を行い、セキュリティとアクセスを改善できます。

マイクロサービス アーキテクチャでは、ネットワークの境界を越えて呼び出しが行われ、従来の IP ベースのファイアウォール ルールではワークロード間のアクセスを保護するのに不十分であることがよくあります。Anthos Service Mesh では、認可ルールを次のように設定できます。

  • メッシュ内のワークロードへのアクセス(ワークロード間またはエンドユーザーからワークロード間)の制御
  • ニーズに応じて、幅広く(または細かく)ポリシーを定義します。ポリシーとベスト プラクティスの構成の詳細については、Anthos Service Mesh による認可をご覧ください。

費用

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

  • GKE
  • Anthos Service Mesh
  • このチュートリアルの終了後に作成したリソースを削除すれば、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

    始める前に

    • リポジトリのクローンを作成します。

      git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
      cd anthos-service-mesh-samples
      

    Ingress ゲートウェイをデプロイする

    1. kubectl の現在のコンテキストをクラスタに設定します。

      gcloud container clusters get-credentials CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION
      
    2. Ingress ゲートウェイの名前空間を作成します。

      kubectl create namespace asm-ingress
      
    3. インジェクションの名前空間を有効にします。手順は Anthos Service Mesh のタイプ(マネージドまたはクラスタ内)によって異なります。

      マネージド

      asm-managed リビジョン ラベルを名前空間に適用します。

      kubectl label namespace asm-ingress \
        istio-injection- istio.io/rev=asm-managed --overwrite
      

      このラベルは、Anthos Service Mesh バージョンの現在のマネージド Anthos Service Mesh のリリース チャンネルに対応します。

      クラスタ内

      1. 次のコマンドを使用して、istiod のリビジョン ラベルを探します。

        kubectl get deploy -n istio-system -l app=istiod -o \
          jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
        
      2. リビジョン ラベルを名前空間に適用します。次のコマンドで、REVISION は前の手順でメモした istiod リビジョン ラベルの値です。

        kubectl label namespace asm-ingress \
          istio-injection- istio.io/rev=REVISION --overwrite
        
    4. anthos-service-mesh-samples リポジトリにサンプル ゲートウェイをデプロイします。

      kubectl apply -n asm-ingress \
      -f docs/shared/asm-ingress-gateway
      

      予想される出力:

      serviceaccount/asm-ingressgateway configured
      service/asm-ingressgateway configured
      deployment.apps/asm-ingressgateway configured
      gateway.networking.istio.io/asm-ingressgateway configured
      

    Online Boutique サンプル アプリケーションをデプロイする

    1. まだ行っていない場合は、kubectl の現在のコンテキストをクラスタに設定します。

      gcloud container clusters get-credentials CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION
      
    2. サンプル アプリケーションの名前空間を作成します。

      kubectl create namespace onlineboutique
      
    3. Envoy プロキシを自動的に挿入するには、onlineboutique 名前空間にラベルを付けます。自動サイドカー インジェクションを有効にする手順を行います。

    4. サンプルアプリ、フロントエンド用の VirtualService、ワークロードのサービス アカウントをデプロイします。このチュートリアルでは、マイクロサービス デモアプリである Online Boutique をデプロイします。

      kubectl apply \
      -n onlineboutique \
      -f docs/shared/online-boutique/virtual-service.yaml
      kubectl apply \
      -n onlineboutique \
      -f docs/shared/online-boutique/service-accounts
      

    サービスを表示する

    1. onlineboutique Namespace の Pod を表示します。

      kubectl get pods -n onlineboutique
      

      予想される出力:

      NAME                                     READY   STATUS    RESTARTS   AGE
      adservice-85598d856b-m84m6               2/2     Running   0          2m7s
      cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
      checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
      currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
      emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
      frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
      loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
      paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
      productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
      recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
      redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
      shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
      

      アプリケーションのすべての Pod が稼働状態になり、READY 列に 2/2 が入力されます。これは、Pod に Envoy サイドカー プロキシが正常に挿入されたことを示します。数分経っても 2/2 が表示されない場合は、トラブルシューティング ガイドをご覧ください。

    2. 外部 IP を取得して、変数に設定します。

      kubectl get services -n asm-ingress
      export FRONTEND_IP=$(kubectl --namespace asm-ingress \
      get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \
      )
      

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

      NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
      asm-ingressgateway   LoadBalancer   10.19.247.233   35.239.7.64   80:31380/TCP,443:31390/TCP,31400:31400/TCP   27m
      
      
    3. ウェブブラウザで EXTERNAL-IP のアドレスにアクセスします。ブラウザに Online Boutique のショップが表示されます。

      オンライン ショップのフロントエンド

    ワークロードの DenyAll 認可

    このセクションでは、AuthorizationPolicy を追加して通貨サービスへのすべての受信トラフィックを拒否します。AuthorizationPolicies は、AuthorizationPolicies を Envoy で読み取り可能な構成に変換し、その構成をサイドカー プロキシに適用することで機能します。これにより、Envoy プロキシはサービスへの受信リクエストを認可または拒否できます。

    1. AuthorizationPolicycurrencyservice に適用します。YAML ファイルの currencyservice というラベルが一致していることに注意してください。

      kubectl apply -f docs/authorization/currency-deny-all.yaml -n onlineboutique
      
      apiVersion: security.istio.io/v1beta1
      kind: AuthorizationPolicy
      metadata:
        name: currency-policy
      spec:
        selector:
          matchLabels:
            app: currencyservice
    2. ゲートウェイの EXTERNAL-IP にアクセスして、ウェブブラウザで Online Boutique を表示してみます。currency service からの認可エラー(500 内部サービスエラー)が表示されます。

      authz rbac 500 エラー

    サイドカー プロキシのログを観察する

    サイドカー プロキシで何が起こっているかを確認するには、Pod のログを確認します。

    1. currencyservice Pod の名前を取得します。

      CURRENCY_POD=$(kubectl get pod -n onlineboutique |grep currency|awk '{print $1}')
      
    2. トレースレベルのログを許可するように Envoy プロキシを設定します。デフォルトでは、ブロックされた認可呼び出しはログに記録されません。

      kubectl exec -it $CURRENCY_POD -n onlineboutique -c istio-proxy -- curl -X POST "http://localhost:15000/logging?level=trace"
      

      予想される出力: active loggers: admin: trace alternate_protocols_cache: trace ... tracing: trace upstream: trace udp: trace wasm: trace

    3. curl を使用して EXTERNAL_IP にトラフィックを送信し、ログを生成します。

      for i in {0..10}; do
      curl -s -I $FRONTEND_IP ; done
      
    4. istio-proxy でロールベースのアクセス制御(RBAC)関連のログを表示します。

      kubectl logs -n onlineboutique $CURRENCY_POD -c istio-proxy | grep -m5 rbac
      

      予想される出力:

      2022-07-08T14:19:20.442920Z     debug   envoy rbac      checking request: requestedServerName: outbound_.7000_._.currencyservice.onlineboutique.svc.cluster.local, sourceIP: 10.8.8.5:34080, directRemoteIP: 10.8.8.5:34080, remoteIP: 10.8.8.5:34080,localAddress: 10.8.0.6:7000, ssl: uriSanPeerCertificate: spiffe://christineskim-tf-asm.svc.id.goog/ns/onlineboutique/sa/default, dnsSanPeerCertificate: , subjectPeerCertificate: OU=istio_v1_cloud_workload,O=Google LLC,L=Mountain View,ST=California,C=US, headers: ':method', 'POST'
      2022-07-08T14:19:20.442944Z     debug   envoy rbac      enforced denied, matched policy none
      2022-07-08T14:19:20.442965Z     debug   envoy http      [C73987][S13078781800499437460] Sending local reply with details rbac_access_denied_matched_policy[none]
        ```
      

    ログに「enforced denied」というメッセージが表示されます。これは、currencyservice が受信リクエストをブロックするように設定されていることを表しています。

    制限付きアクセスを許可する

    DENYALL ポリシーの代わりに、特定のワークロードのみを許可するように接続を設定できます。これは、認可されたサービス間の通信のみを許可するマイクロサービス アーキテクチャに関連します。

    このセクションでは、frontendcheckout サービスが currency サービスと通信できるようにします。

    1. 次のファイルでは、特定の source.principal(クライアント)が currencyservice へのアクセス許可リストに登録されています。
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: currency-policy
    spec:
      selector:
        matchLabels:
          app: currencyservice
      rules:
      - from:
        - source:
            principals: ["cluster.local/ns/onlineboutique/sa/frontend"]
      - from:
        - source:
            principals: ["cluster.local/ns/onlineboutique/sa/checkoutservice"]

    ポリシーを適用します。

    kubectl apply -f docs/authorization/currency-allow-frontend-checkout.yaml -n onlineboutique
    
    1. ウェブブラウザで EXTERNAL-IP にアクセスすると、Online Boutique にアクセスできるようになります。

    Anthos Service Mesh セキュリティ UI でサービスを観察する

    1. Google Cloud コンソールで、[GKE Enterprise Security] ページに移動します。

      [GKE Enterprise Security] に移動

    2. [セキュリティ] ページでは、アプリケーション ワークロードを保護する機能の追加または有効化が可能です。詳細については、メッシュ セキュリティのモニタリングをご覧ください。[ポリシー監査] タブを選択して、ワークロードの概要を表示します。

    3. [サービスのアクセス制御] 列で [有効] と表示されるのは currencyservice のみです。[有効] をクリックして AuthorizationPolicy の詳細を表示します。

      セキュリティ ポリシーの監査

    ここでは、適用した AuthorizationPolicy を確認できます。これは、特にワークロードに多数のポリシーが適用されている場合に、アプリケーション全体を把握するのに役立ちます。UI を探索します。相互にやり取りするサービスを表示でき、セキュリティの状況を可視化するのに使用できます。これは、ワークロードを保護するときにポリシーがもたらすメリットの一例です。

    クリーンアップ

    このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

    このチュートリアルで使用したリソースについて、これ以降 Google Cloud アカウントに課金されないようにするには、プロジェクトを削除するか、個々のリソースを削除します。

    プロジェクトの削除

    Cloud Shell で、プロジェクトを削除します。

    gcloud projects delete PROJECT_ID
    

    リソースを削除する

    • クラスタを維持して Online Boutique のサンプルを削除するには:

      1. アプリケーションの名前空間を削除します。

        kubectl delete namespace onlineboutique
        

        予想される出力:

        namespace "onlineboutique" deleted
        
      2. Ingress ゲートウェイの Namespace を削除します。

        kubectl delete namespace asm-ingress
        

        予想される出力:

        amespace "asm-ingress" deleted
        
    • 追加料金の発生を回避するには、クラスタを削除します。

      gcloud container clusters delete  CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION
      

    次のステップ