このページは Apigee と Apigee ハイブリッドに適用されます。
Apigee Edge のドキュメントを表示する。
このページでは、Apigee Operator for Kubernetes を使用して、Apigee ランタイム ポリシーと Google トークン挿入ポリシーを Google Kubernetes Engine(GKE)Gateway に追加する方法について説明します。使用可能なポリシーセットを Gateway に追加すると、API プロダクトの適用を超えて Gateway の機能を拡張し、追加のセキュリティ ルールとビジネスルールを含めることができます。
Apigee Operator for Kubernetes を使用して、Gateway に次のポリシーを追加できます。
- SpikeArrest ポリシー
- JavaScript ポリシー
- Google トークン挿入ポリシー
- GenerateJWT ポリシー
- KVM ポリシー
- OASValidation ポリシー
- ServiceCallout ポリシー
- OAuthV2 ポリシー
- ResponseCache ポリシー
- VerifyAPIKey ポリシー
概要
以降のセクションでは、次の方法について説明します。
- GKE Gateway にポリシーを追加する。
- ポリシーの使用を適用するテンプレート ルールを作成する。
- テンプレート ルールを使用する Apigee テンプレートを作成する。
- テンプレートを使用して Apigee Gateway ポリシーをデプロイする。
- ポリシー適用を検証する。
始める前に
このガイドの例として使用されているすべてのポリシーを使用して GKE Gateway を変更するには、Apigee 内でトークンを作成し、プロキシと拡張機能をデプロイするために必要なロールが付与されているサービス アカウントが必要です。 Google トークンを作成しない場合は、サービス アカウントに追加のロールを追加する必要はありません。次のセクションに進みます。
必要な権限を持ったサービス アカウントを作成するには:
- Apigee Operator for Kubernetes のインストール ガイドで
apigee-apim-gsa
という名前のサービス アカウントを作成した場合は、このステップをスキップして次のステップに進みます。それ以外の場合は、サービス アカウントを作成します。gcloud iam service-accounts create apigee-apim-gsa --project=$PROJECT_ID
- トークンの作成に必要なロールをサービス アカウントに付与します。
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "serviceAccount:apigee-apim-gsa@$PROJECT_ID.iam.gserviceaccount.com" \ --role "roles/iam.serviceAccountTokenCreator"
apigee-apim-gsa
サービス アカウントに、プロキシと拡張機能をデプロイするために必要なロールを付与します。gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "serviceAccount:apigee-apim-gsa@$PROJECT_ID.iam.gserviceaccount.com" \ --role "roles/iam.serviceAccountUser"
ポリシーを使用して GKE Gateway を変更する
1 つ以上のポリシーを使用して GKE Gateway を変更し、機能を拡張できます。このチュートリアルの例では、2 つの Apigee ポリシーと Google トークン挿入ポリシーの仕様を含む yaml
ファイルを Gateway に適用します。
次の yaml
ファイルを使用して Gateway に適用される各ポリシーは、Gateway に送信されたリクエストを評価するときにそれぞれ異なるロールを実行します。
- SpikeArrest ポリシーは、一定の時間内に許可されるリクエストの最大レートを定義することで、ピーク メッセージ レートを制御します。この例では、最大レートは 1 分あたり 5 に設定されています。SpikeArrest ポリシーを使用してトラフィックの急増を緩和する方法については、SpikeArrest ポリシーをご覧ください。
- JavaScript ポリシーを使用すると、Gateway リクエストにカスタム JavaScript コードを追加できます。この例では、ポリシーを使用してリクエストにカスタム ヘッダーを追加します。JavaScript ポリシーを使用してカスタムコードを追加する方法については、JavaScript ポリシーをご覧ください。
- Google トークン挿入ポリシーは、AssignMessage ポリシーを使用して、 Google 認証アクセス トークンを Gateway リクエストに挿入するために使用されます。Apigee では、 Google OAuth トークンまたは OpenID Connect トークンを使用した Google サービスでの認証をサポートしています。認証トークンの詳細については、Google 認証システムの使用をご覧ください。
ポリシーを Gateway に追加します。
apim
名前空間にapigee-policies.yaml
という名前の新しいファイルを作成します。- 次のファイルの内容を、作成した新しいファイルにコピーします。
# apigee-policies.yaml apiVersion: apim.googleapis.com/v1 kind: SpikeArrest metadata: name: spike-arrest namespace: apim spec: identifier: ref: request.header.name useEffectiveCount: true peakMessageRate: value: "5pm" --- apiVersion: apim.googleapis.com/v1 kind: Javascript metadata: name: js-add-headers namespace: apim spec: timeLimit: 2000 source: | var sum = 1+1; context.setVariable("request.header.first", 1); context.setVariable("request.header.second", 1); context.setVariable("request.header.sum", sum); --- apiVersion: apim.googleapis.com/v1 kind: AssignMessage metadata: name: google-token-policy namespace: apim spec: setActions: - authentication: googleAccessToken: scopes: - 'https://www.googleapis.com/auth/cloud-platform' AssignTo: createNew: false type: request --- apiVersion: apim.googleapis.com/v1 kind: KVM metadata: name: kvm-1 namespace: apim spec: delete: - keys: - value: mykey exclusiveCache: true expiryTimeInSecs: 3600 get: - assignTo: response.header.mykvm keys: - value: mykey initialEntries: - keys: - key1 values: - val1 - keys: - mykey values: - initvalue isEncrypted: false put: - keys: - value: mykey values: - value: request.header.mykvm scope: environment --- apiVersion: apim.googleapis.com/v1 kind: OASValidation metadata: name: oas-validation-1 namespace: apim spec: openApiSpec: | openapi: 3.0.4 info: title: Sample API description: Optional multi/single line description. version: 0.1.9 servers: - url: http://apigee-apim-operator-test.apigee.net description: Optional server description, our main host in httproute paths: /get: get: summary: just for test description: Optional extended description in CommonMark or HTML. parameters: - name: X-Request-Type in: header description: Must be 'internal' or 'external'. required: true schema: type: string enum: - internal - external responses: '200': # status code description: A JSON object content: application/json: schema: type: object properties: headers: type: object source: request --- apiVersion: apim.googleapis.com/v1 kind: ServiceCallout metadata: name: service-callout-1 namespace: apim spec: request: clearPayload: true variable: myRequest ignoreUnresolvedVariables: true removeActions: - payload: true - queryParams: - name: rq-param1 - name: rq-param2 copyActions: - version: true - verb: true addActions: - headers: - name: X-header1 value: value1 - name: X-header2 value: value2 - queryParams: - name: q-param1 value: value1 - name: q-param2 value: value2 setActions: - verb: PUT - formParams: - name: f-param1 value: value1 - name: f-param2 value: value2 response: calloutResponse timeout: 30000 httpTargetConnection: URL: https://httpbin.org/put properties: - name: success.codes value: 1xx,2xx,3xx,400 - name: supports.http11 value: "true"
- 次のコマンドを使用して、
yaml
ファイルを Gateway に適用します。kubectl -n apim apply -f apigee-policies.yaml
SharedFlow テンプレートとして TemplateRule を作成する
このステップでは、Gateway に追加したポリシーを適用するために TemplateRule
を作成します。テンプレート ルールとは、組織管理者が作成する SharedFlow のルールであり、サービス デベロッパーが承認済みポリシーのみを Gateway トラフィックに適用できるようにします。テンプレート ルールにより、デベロッパーは使用可能なポリシー、特定のユースケースに必要なポリシー、サービス デベロッパーが使用できないポリシーを把握できます。
テンプレート ルールを作成する
AssignMessage ポリシーの使用を適用するテンプレート ルールを作成します。
apim
名前空間にtemplate-rule.yaml
という名前の新しいyaml
ファイルを作成します。- 次のファイルの内容を、作成した新しいファイルにコピーします。
# template-rule.yaml apiVersion: apim.googleapis.com/v1 kind: ApimTemplateRule metadata: name: template-rule namespace: apim spec: allowList: [SpikeArrest, Javascript, GenerateJWT, KVM, OASValidation, OAuthv2, ServiceCallout] requiredList: [AssignMessage] denyList: []
この例では、テンプレート ルールにより、デベロッパーは Google トークン挿入ポリシーを記述する AssignMessage ポリシーが必要であることを理解できます。また、API 管理で SpikeArrest、JavaScript、GenerateJWT、KVM、OASValidation、OAuthV2、ServiceCallout ポリシーを使用できることもわかります。拒否リストに指定されたポリシーはありません。
テンプレート ルールを適用する
次のコマンドを使用してテンプレート ルールを適用します。
kubectl apply -f template-rule.yaml
テンプレート ルールを使用する Apigee テンプレートを作成する
前のセクションで作成したテンプレート ルールを追加するように Apigee テンプレートを作成します。
apim
名前空間にnew-admin-template.yaml
という名前の新しいyaml
ファイルを作成します。- 次のファイルの内容を、作成した新しいファイルにコピーします。
# new-admin-template.yaml apiVersion: apim.googleapis.com/v1 kind: ApimTemplate metadata: name: new-admin-template namespace: apim spec: apimTemplateRule: group: apim.googleapis.com kind: ApimTemplateRule name: template-rule namespace: apim templates: - mode: REQUEST flows: - name: preflow policies: - group: apim.googleapis.com kind: OASValidation name: oas-validation-1 namespace: apim - group: apim.googleapis.com kind: SpikeArrest name: spike-arrest namespace: apim - name: ConditionalGetFlow policies: - group: apim.googleapis.com kind: Javascript name: js-add-headers namespace: apim condition: request.verb="GET" - name: postflow policies: - group: apim.googleapis.com kind: AssignMessage name: google-token-policy namespace: apim - group: apim.googleapis.com kind: ServiceCallout name: service-callout-1 namespace: apim - mode: RESPONSE flows: - name: postflow policies: - group: apim.googleapis.com kind: KVM name: kvm-1 namespace: apim
- 次のコマンドを使用して、新しいテンプレートを適用します。
kubectl apply -f new-admin-template.yaml
Apigee Gateway ポリシーをデプロイする
この手順では、ApigeeGatewayPolicy
の仕様を含む新しいファイルを Gateway に適用します。このポリシーは、Apigee テンプレートを Gateway にデプロイするために使用されます。
Apigee Gateway ポリシーをデプロイします。
apim
名前空間にapigee-gateway-policy-withSA.yaml
という名前の新しいyaml
ファイルを作成します。- 次のファイルの内容を、作成した新しいファイルにコピーします。
# apigee-gateway-policy-withSA.yaml apiVersion: apim.googleapis.com/v1 kind: ApigeeGatewayPolicy metadata: name: apim-template-injection namespace: apim spec: serviceAccount: apigee-apim-gsa@PROJECT_ID.iam.gserviceaccount.com ref: group: apim.googleapis.com kind: ApimTemplate name: new-admin-template namespace: apim targetRef: group: apim.googleapis.com kind: APIMExtensionPolicy name: APIMEXTENSION_POLICY_NAME namespace: apim
PROJECT_ID は、実際の Google Cloud プロジェクト ID に置き換えます。
APIMEXTENSION_POLICY_NAME は、Apigee Gateway ポリシーの適用に使用する APIMExtensionPolicy の名前に置き換えます。トラフィック拡張機能を作成するために APIMExtensionPolicy を作成した場合は、作成したポリシーの名前を使用します。ApigeeBackendService を使用してトラフィック拡張機能を作成した場合は、ApigeeBackendService の名前を使用します。ApigeeBackendService を作成すると、Apigee Operator for Kubernetes により、BackendService と同じ名前と名前空間の APIMExtensionPolicy が作成されます。
- ポリシーを適用します。
kubectl apply -f apigee-gateway-policy-withSA.yaml
- 新しい Gateway ポリシーのデプロイ ステータスを確認します。
kubectl -n apim get ApigeeGatewayPolicy
デプロイすると、ポリシー
STATUS
にCREATED
と表示されます。
新しい Gateway ポリシーがデプロイされたら、2 分待ってから Gateway にリクエストを送信し、ポリシーがクラスタに伝播されるようにします。
ポリシーの適用を確認する
Apigee Gateway ポリシーが想定どおりに機能していることを確認するには、次のセクションで説明するように Gateway にリクエストを送信します。
AssignMessage ポリシーの適用
AssignMessage ポリシーを使用して {company_name} トークンがリクエストに挿入されていることを確認するには、次のコマンドを使用して Gateway にリクエストを送信します。
curl http://GATEWAY_IP_ADDRESS/get -H "Host: HOST_NAME" -H "x-api-key: API_KEY"
ここで
GATEWAY_IP_ADDRESS
は Gateway の IP アドレスです。Gateway の IP アドレスは、次のコマンドを使用して取得できます。kubectl get gateway GATEWAY_NAME
HOST_NAME
はホストの名前です。API_KEY
は API キー値です。
正常なレスポンスには、次のように Authorization
ヘッダーと生成された署名なしトークンが含まれます。
{ "args": {}, "headers": { "Accept": "*/*", "Authorization": "Bearer ya29.c.c0ASRK0Gbw03y9cfvxL11DxaRYBQUU18SmUP4Vu63OckHI5cX7wJ4DmGMG2vbDDS69HXJHqMj-lak4tcqOsJGmE65crn2gNuJLanXidwM8", "First": "1.0", "Host": "apigee-apim-operator-test.apigee.net", "Second": "1.0", "Sum": "2", "User-Agent": "curl/8.7.1", "X-Api-Key": "McYcHGR3PTSGLXExvKADwQ1JJeCjgPDUvAakCl0rJKCFaX0Y", "X-Cloud-Trace-Context": "0fd3dadc2a3c328fa968d5f5f1434c29/18300783092696918345" }, "origin": "34.54.108.129", "url": "apigee-apim-operator-test.apigee.net/get" }
SpikeArrest ポリシーの適用
SpikeArrest ポリシーの適用をテストするには、1 分以内に Gateway に 10 回リクエストを送信します。
次のスクリプトを実行してリクエストを生成できます。
#!/bin/sh for i in $(seq 1 11); do curl http://GATEWAY_IP_ADDRESS/get -H "Host: HOST_NAME" -H "x-api-key: API_KEY" sleep 1 done
ここで:
GATEWAY_IP_ADDRESS
は Gateway の IP アドレスです。Gateway の IP アドレスは、次のコマンドを使用して取得できます。ここで、GATEWAY_NAME
は Gateway の名前です。kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
HOST_NAME
は、Gateway のHTTPRoute
で定義されたホスト名です。API_KEY
は、テストの設定で取得した API キー値です。
レスポンスは次のようになります。
"fault":{"faultstring":"Spike arrest violation. Allowed rate : MessageRate{capacity=5, period=Minutes}","detail":{"errorcode":"policies.ratelimit.SpikeArrestViolation"}}}
JavaScript ポリシーの適用
JavaScript ポリシーが想定どおりに機能していることを確認するには、次のコマンドを使用して Gateway にリクエストを送信します。
curl http://GATEWAY_IP_ADDRESS/get \ -H "Host: HOST_NAME" \ -H "x-api-key: API_KEY" \ -H "X-Request-Type: external" -i
ここで
GATEWAY_IP_ADDRESS
は Gateway の IP アドレスです。Gateway の IP アドレスは、次のコマンドを使用して取得できます。ここで、GATEWAY_NAME
は Gateway の名前です。kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
HOST_NAME
は、Gateway のHTTPRoute
で定義されたホスト名です。API_KEY
は、テストの設定で取得した API キー値です。
JavaScript ポリシーは、レスポンスにあるように、First
、Second
、Sum
の 3 つのリクエスト ヘッダーを設定します。
HTTP/1.1 200 OK ... { "args": {}, "headers": { ... "First": "1.0", ... "Second": "1.0", "Sum": "2", ... }, ... }
OASValidation ポリシーの適用
OASValidation ポリシーが想定どおりに機能していることを確認するには、次のコマンドを使用して Gateway にリクエストを送信します。
curl "http://GATEWAY_IP_ADDRESS/get" \ -H "Host: HOST_NAME" \ -H "x-api-key: API_KEY" \ -H "X-Request-Type: badvalue"
ここで
GATEWAY_IP_ADDRESS
は Gateway の IP アドレスです。Gateway の IP アドレスは、次のコマンドを使用して取得できます。ここで、GATEWAY_NAME
は Gateway の名前です。kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
HOST_NAME
は、Gateway のHTTPRoute
で定義されたホスト名です。API_KEY
は、テストの設定で取得した API キー値です。
このコマンドの X-Request-Type
ヘッダーには無効な値が含まれています。リクエストは失敗し、次のようなレスポンスが返されます。
{"fault":{"faultstring":"OASValidation oas-validation-1 with resource \"oas:\/\/oas-validation-1.yaml\": failed with reason: \"[ERROR - Instance value (\"badvalue\") not found in enum (possible values: [\"internal\",\"external\"]): []]\"","detail":{"errorcode":"steps.oasvalidation.Failed"}}}
X-Request-Type
ヘッダーに有効な値を指定して同じリクエストを送信すると、リクエストは成功します。次に例を示します。
curl "http://GATEWAY_IP_ADDRESS/get" \ -H "Host: HOST_NAME" \ -H "x-api-key: API_KEY" \ -H "X-Request-Type: external" -i
ここで
GATEWAY_IP_ADDRESS
は Gateway の IP アドレスです。Gateway の IP アドレスは、次のコマンドを使用して取得できます。ここで、GATEWAY_NAME
は Gateway の名前です。kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
HOST_NAME
は、Gateway のHTTPRoute
で定義されたホスト名です。API_KEY
は、テストの設定で取得した API キー値です。
ServiceCallout ポリシーの適用
ServiceCallout ポリシーの適用を確認するには、デバッグ セッションを開き、プロキシに有効なリクエストをいくつか送信します。
デバッグ セッションを開く手順は次のとおりです。
- Google Cloud コンソールで、[API プロキシ] ページに移動します。
- Apigee Operator for Kubernetes 用に作成された環境にデプロイした
global-ext-lb1-apim-policy
プロキシを選択します。 - [Debug] タブをクリックします。
- [Debug session] ウィンドウで、[Start Debug Session] をクリックします。
- [Debug session] ペインで、次の項目を選択します。
- 環境: 使用可能な環境のリストから、Apigee Operator for Kubernetes 用に作成した環境を選択します。
- フィルタ: [None (All transaction)] を選択します。
- [開始] をクリックします。
セッションが開始されたら、有効なリクエストをプロキシに送信できます。
curl "GATEWAY_IP_ADDRESSget" \ -H "Host: HOST_NAME" \ -H "x-api-key: API_KEY" \ -H "X-Request-Type: external" -i
ここで
GATEWAY_IP_ADDRESS
は Gateway の IP アドレスです。Gateway の IP アドレスは、次のコマンドを使用して取得できます。ここで、GATEWAY_NAME
は Gateway の名前です。kubectl get gateway GATEWAY_NAME
HOST_NAME
は、Gateway のHTTPRoute
で定義されたホスト名です。API_KEY
は、テストの設定で取得した API キー値です。
リクエスト トランザクションとレスポンス トランザクションが [トランザクション] ペインに表示されます。リストから成功したトランザクションを選択して、フローを表示します。ServiceCallout
ポリシーが正常に実行されたことを確認できます。
KVM ポリシーの適用
KVM ポリシーが正常に実行されると、キー mykey
の開始値で KVM が初期化されます。レスポンス トランザクションがある場合、KVM ポリシーは mykey
の値を取得し、レスポンス ヘッダー mykvm
に保存します。KVM ポリシーが再度実行されると、リクエスト ヘッダー mykvm
から取得した mykey
に新しい値を挿入します。
次の例に示すように、各トランザクションのヘッダーをチェックして、あるトランザクションでポリシーが KVM に値を保存し、次のトランザクションで同じ値を取得していることを確認できます。
KVM ポリシーをテストします。
- Gateway にリクエストを送信します。
curl -i "http://GATEWAY_IP_ADDRESS/get" \ -H "Host: HOST_NAME" \ -H "x-api-key: API_KEY" \ -H "X-Request-Type: external" \ -H "KVM_NAME: next-value1" -i
ここで
GATEWAY_IP_ADDRESS
は Gateway の IP アドレスです。Gateway の IP アドレスは、次のコマンドを使用して取得できます。ここで、GATEWAY_NAME
は Gateway の名前です。kubectl get gateway GATEWAY_NAME
HOST_NAME
は、Gateway のHTTPRoute
で定義されたホスト名です。API_KEY
は、テストの設定で取得した API キー値です。KVM_NAME
は、KVM の名前です。
- レスポンス ヘッダーをチェックして、KVM ポリシーが正常に実行され、
mykvm
に初期値が保存されたことを確認します。レスポンスは次のようになります。HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * Content-Length: 517 content-type: application/json date: ... server: gunicorn/19.9.0 mykvm: initvalue via: 1.1 google { "args": { ... "url": "http://apigee-apim-operator-test.apigee.net/get" } }
- Gateway に別のリクエストを送信します。
curl -i "http://GATEWAY_IP_ADDRESS/get" \ -H "Host: HOST_NAME" \ -H "x-api-key: API_KEY" \ -H "mykvm: next"X-Request-Type: external" -H "mykvm: next-value2" -i
レスポンスは次のようになります。
HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * Content-Length: 517 content-type: application/json date: ... server: gunicorn/19.9.0 mykvm: next-value2 via: 1.1 google { "args": { ... "url": "http://apigee-apim-operator-test.apigee.net/get?rq-param2=rq-val1&x-param1=xval1" } }
mykvm
ヘッダーの値がリクエスト ヘッダーmykvm
の値に更新されているため、KVM ポリシーが正常に実行されたことがわかります。 - さらに 1 つリクエストを送信します。
curl -i "http://GATEWAY_IP_ADDRESS/get" \ -H "Host: HOST_NAME" \ -H "x-api-key: API_KEY" \ -H "X-Request-Type: external" -H "mykvm: next-value3" -i
レスポンスは次のようになります。
HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * Content-Length: 517 content-type: application/json date: ... server: gunicorn/19.9.0 mykvm: next-value2 via: 1.1 google { "args": { ... "url": "http://apigee-apim-operator-test.apigee.net/get?rq-param2=rq-val1&x-param1=xval1" } }
mykvm
ヘッダーの値が再度更新され、レスポンスに表示された値が前のトランザクションに保存された値であることを示しています。
トラブルシューティング
GKE Gateway にポリシーを追加するときに問題が発生した場合は、Apigee Operator for Kubernetes のトラブルシューティングで一般的なエラーの解決策をご覧ください。
次のステップ
- SpikeArrest ポリシーの詳細を確認する。
- JavaScript ポリシーの詳細を確認する。