Service Mesh (ASM) は Open Policy Agent (OPA) と統合されています。 OPA を使用してアクセス制御ポリシーを定義し、アプリケーションにきめ細かいアクセス制御を実装できます。 v1.8.6.41 以降の ASM インスタンスでは、ConfigMap を作成して OPA ポリシーをコンテナに自動的にプッシュできます。 これにより、OPA ポリシーを動的に更新できます。 このトピックでは、ASM で OPA ポリシーを動的に更新する方法について説明します。
前提条件
バージョンが v1.8.6.41-gb1d8f288-aliyun 以降の ASM インスタンスが作成されていること。 詳細については、「ASM インスタンスの作成」をご参照ください。
ACK マネージドクラスターが作成されていること。 詳細については、「ACK マネージドクラスターの作成」をご参照ください。
クラスターが ASM インスタンスに追加されていること。 詳細については、「ASM インスタンスへのクラスターの追加」をご参照ください。
背景情報
OPA は、Cloud Native Computing Foundation (CNCF) によって管理されているインキュベーションレベルのプロジェクトです。 ポリシーエンジンとして、OPA を使用してアプリケーションにきめ細かいアクセス制御を実装できます。 OPA は、マイクロサービスとともにスタンドアロンサービスとしてデプロイできます。 アプリケーションを保護するには、マイクロサービスへの各リクエストが処理される前に承認されていることを確認します。 承認を確認するために、マイクロサービスは OPA に API 呼び出しを行い、リクエストが承認されているかどうかを判断します。 
手順 1:OPA を有効にする
ASM コンソール にログインします。
左側のナビゲーションペインで、 を選択します。
[メッシュ管理] ページで、構成する ASM インスタンスを見つけます。[管理] 列の [アクション] をクリックするか、ASM インスタンスの名前をクリックします。
[基本情報] セクションの右上隅にある [設定] をクリックします。
[設定の更新] パネルで、[OPA プラグインを有効にする] を選択します。
[OK] をクリックします。
[基本情報] セクションで、[OPAプラグイン] フィールドのステータスが [有効] に変更されていることを確認できます。
手順 2:ConfigMap を作成する
ASM は OPA ポリシーの動的更新をサポートしています。 openpolicyagent.org/policy=rego ラベルを含む ConfigMap を作成して、OPA ポリシーを定義できます。 OPA ポリシーは、すべての名前空間で OPA サイドカーコンテナが挿入されたポッドに自動的にプッシュされます。 ConfigMap を削除すると、OPA ポリシーもポッドから削除されます。
ポッドの OPA ポリシーを定義する場合は、1 つの OPA ポリシーのみに
default allowフィールドが含まれていることを確認してください。 複数の OPA ポリシーの ConfigMap がポッドに適用され、各 OPA ポリシーにdefault allowフィールドが定義されている場合、複数のdefault allowフィールドが原因で OPA ポリシーの動的更新に失敗します。OPA サイドカーコンテナの起動は、opa-policy という名前の ConfigMap に依存しています。 ConfigMap を削除すると、ConfigMap が定義する OPA ポリシーも OPA サイドカーコンテナから削除されます。 ConfigMap を再作成しても、削除された OPA ポリシーは復元されません。 OPA ポリシーを再度使用するには、OPA ポリシーが最初にプッシュされたポッドを再作成する必要があります。
KubeConfig 認証情報タイプを指定します。 詳細については、「手順 2:クラスター認証情報の種類を選択する」をご参照ください。
opa-policy という名前の ConfigMap を作成します。
OPA サイドカーコンテナの起動は、opa-policy という名前の ConfigMap に依存します。ConfigMap は、OPA ポリシーの動的な更新をサポートしています。 ConfigMap には基本的なポリシー設定のみを構成することをお勧めします。 複雑なポリシー設定を構成するには、他の ConfigMap を作成できます。
以下のコンテンツを使用して、opa-policy という名前の YAML ファイルを作成します。
apiVersion: v1 kind: ConfigMap metadata: name: opa-policy data: policy.rego: | ### OPA ポリシーの動的プッシュは、ConfigMap で許可されているパスに依存します。 ConfigMap でパスを指定しないと、OPA ポリシーは動的に更新されません。 package istio.authz import input.parsed_path allow { parsed_path[0] = "v1" parsed_path[1] = "policies" }次のコマンドを実行して、ConfigMap を作成します。
kubectl apply -f opa-policy.yaml
opa-policy-add という名前の ConfigMap を作成します。
ConfigMap を使用して OPA ポリシーを定義します。
以下の内容を使用して、opa-policy-add という名前の YAML ファイルを作成します。
apiVersion: v1 kind: ConfigMap metadata: name: opa-policy-add labels: ### ConfigMap に次のラベルを設定する必要があります。設定しないと、ConfigMap が定義する OPA ポリシーを動的に更新できません。 openpolicyagent.org/policy: rego data: policy.rego: | ### 次のコードは、サンプルポリシーの定義を示しています。実際のニーズに基づいてポリシーを定義してください。 package istio.authz import input.attributes.request.http as http_request default allow = false allow { roles_for_user[r] required_roles[r] } roles_for_user[r] { r := user_roles[user_name][_] } required_roles[r] { perm := role_perms[r][_] perm.method = http_request.method perm.path = http_request.path } user_name = parsed { [_, encoded] := split(http_request.headers.authorization, " ") [parsed, _] := split(base64url.decode(encoded), ":") } user_roles = { "guest1": ["guest"], "admin1": ["admin"] } role_perms = { "guest": [ {"method": "GET", "path": "/productpage"}, ], "admin": [ {"method": "GET", "path": "/productpage"}, {"method": "GET", "path": "/api/v1/products"}, ], }user_roles: ユーザーにロールを割り当てます。この例では、guest1 ユーザーに guest ロールを、admin1 ユーザーに admin ロールを割り当てます。
role_perms: 各ロールの権限を指定します。この例では、guest ロールに /productpage を含む URL を使用してアプリケーションにアクセスする権限を付与し、admin ロールに /productpage または /api/v1/products を含む URL を使用してアプリケーションにアクセスする権限を付与します。
次のコマンドを実行して、ConfigMap を作成します。
kubectl apply -f opa-policy-add.yaml
次のコマンドを実行して、ポリシーのプッシュ結果を表示します。
ポリシーのプッシュ結果は、ConfigMap の
annotationsパラメーターに記録されます。kubectl get configmap opa-policy-add -o yamlコマンド出力で ConfigMap を表示します。
プッシュが成功した場合、ConfigMap に次の情報が表示されます。
openpolicyagent.org/policy-status: '{"status":"ok"}'プッシュが失敗した場合、ConfigMap に対応するエラー情報が表示されます。
手順 3:OPA サイドカーを挿入する
ASM インスタンスにサンプルアプリケーション Bookinfo をデプロイし、OPA サイドカーが Bookinfo アプリケーションの各ポッドに挿入されているかどうかを確認します。
ASM インスタンスに Bookinfo アプリケーションをデプロイします。 詳細については、「ASM インスタンスへのアプリケーションのデプロイ」をご参照ください。
必要に応じて、Istio 仮想サービスとイングレスゲートウェイサービスを定義します。 詳細については、「Istio リソースを使用してトラフィックをサービスの異なるバージョンにルーティングする」をご参照ください。
Bookinfo アプリケーションの各アプリケーションの Pod に OPA サイドカーが挿入されているかどうかを確認します。
ACKコンソール にログオンします。
ACKコンソールの左側のナビゲーションペインで、[クラスター] をクリックします。
[クラスター] ページで、管理するクラスターを見つけ、クラスターの名前をクリックするか、詳細[アクション] 列の をクリックします。クラスターの詳細ページが表示されます。
詳細ページの左側のナビゲーションペインで、 を選択します。
[ポッド] ページの上部にある 既定[名前空間] ドロップダウンリストから を選択します。アプリケーションのポッド名をクリックします。
[コンテナー] タブで、istio-proxy という名前のサイドカープロキシと opa-istio という名前の OPA サイドカーが各コンテナーに挿入されていることを確認できます。各アプリケーションのコンテナーを順番に確認し、サイドカープロキシと OPA サイドカーが各コンテナーに挿入されていることを確認します。

手順 4:OPA ポリシーが期待どおりにアクセス制御を実装していることを確認する
次の cURL コマンドを実行します。 結果は、guest ロールが guest1 ユーザーに割り当てられていることを示しています。 さらに、guest1 ユーザーは、/productpage を含む URL を使用してアプリケーションにアクセスする権限を持っていますが、/api/v1/products を含む URL を使用してアプリケーションにアクセスする権限はありません。
curl -X GET http://{{イングレスゲートウェイサービスの IP アドレス}}/productpage --user guest1:password -I次の出力が想定されます。
HTTP/1.1 200 OKcurl -X GET http://{{イングレスゲートウェイサービスの IP アドレス}}/api/v1/products --user guest1:password -I次の出力が想定されます。
HTTP/1.1 403 Forbidden次の cURL コマンドを実行します。 結果は、admin ロールが admin1 ユーザーに割り当てられていることを示しています。 さらに、admin1 ユーザーは、/productpage または /api/v1/products を含む URL を使用してアプリケーションにアクセスする権限を持っています。
curl -X GET http://{{イングレスゲートウェイサービスの IP アドレス}}/productpage --user admin1:password -I次の出力が想定されます。
HTTP/1.1 200 OKcurl -X GET http://{{イングレスゲートウェイサービスの IP アドレス}}/api/v1/products --user admin1:password -I次の出力が想定されます。
HTTP/1.1 200 OK上記の結果は、定義された OPA ポリシーが期待どおりにアクセス制御を実装していることを示しています。
手順 5:OPA ポリシーを動的に更新する
opa-policy-add という名前の ConfigMap を更新するには、ACK クラスタで次のコマンドを実行します。
kubectl replace -n {The namespace where the ACK cluster resides} -f - <<EOF apiVersion: v1 kind: ConfigMap metadata: name: opa-policy-add labels: ### ConfigMap に次のラベルを設定する必要があります。設定しないと、ConfigMap が定義する OPA ポリシーを動的に更新できません。 openpolicyagent.org/policy: rego data: policy.rego: | ### 次のコードは、サンプルポリシーの定義を示しています。実際のニーズに基づいてポリシーを定義します。 package istio.authz import input.attributes.request.http as http_request default allow = false allow { roles_for_user[r] required_roles[r] } roles_for_user[r] { r := user_roles[user_name][_] } required_roles[r] { perm := role_perms[r][_] perm.method = http_request.method perm.path = http_request.path } user_name = parsed { [_, encoded] := split(http_request.headers.authorization, " ") [parsed, _] := split(base64url.decode(encoded), ":") } user_roles = { "guest1": ["guest", "admin"], "admin1": ["admin"] } role_perms = { "guest": [ {"method": "GET", "path": "/productpage"}, ], "admin": [ {"method": "GET", "path": "/productpage"}, {"method": "GET", "path": "/api/v1/products"}, ], } EOFuser_roles: ユーザーにロールを割り当てます。この例では、guest1 ユーザーに guest ロールと admin ロールを割り当て、admin1 ユーザーに admin ロールを割り当てます。
role_perms: 各ロールの権限を指定します。この例では、/productpage を含む URL を使用してアプリケーションにアクセスする権限を guest ロールに付与し、/productpage または /api/v1/products を含む URL を使用してアプリケーションにアクセスする権限を admin ロールに付与します。
ポリシーのプッシュ結果を表示するには、次のコマンドを実行します。
ポリシーのプッシュ結果は、ConfigMap の
annotationsパラメーターに記録されます。kubectl get configmap opa-policy-add -o yamlコマンド出力で ConfigMap を表示します。
プッシュが成功した場合、ConfigMap に次の情報が表示されます。
openpolicyagent.org/policy-status: '{"status":"ok"}'プッシュが失敗した場合、ConfigMap に対応するエラー情報が表示されます。
手順 6:OPA ポリシーが動的に更新されたことを確認する
次の cURL コマンドを実行します。 結果は、admin ロールが guest1 ユーザーに割り当てられていることを示しています。 さらに、guest1 ユーザーは、/productpage または /api/v1/products を含む URL を使用してアプリケーションにアクセスする権限を持っています。
curl -X GET http://{{イングレスゲートウェイサービスの IP アドレス}}/productpage --user guest1:password -I次の出力が想定されます。
HTTP/1.1 200 OKcurl -X GET http://{{イングレスゲートウェイサービスの IP アドレス}}/api/v1/products --user guest1:password -I次の出力が想定されます。
HTTP/1.1 200 OKOPA ポリシーが更新される前は、guest1 ユーザーは /productpage を含む URL を使用してアプリケーションにアクセスできましたが、/api/v1/products を含む URL を使用してアプリケーションにアクセスできませんでした。 OPA ポリシーが更新された後、guest1 ユーザーは /productpage または /api/v1/products を含む URL を使用してアプリケーションにアクセスできます。 この結果は、OPA ポリシーが動的に更新されたことを示しています。