本頁面適用於 Apigee,但不適用於 Apigee Hybrid。
查看
Apigee Edge 說明文件。
本頁面說明如何使用 Kubernetes 適用的 Apigee APIM Operator,在 Google Kubernetes Engine (GKE) Gateway 中新增 Apigee 執行階段政策和 Google 符記插入政策。將可用的政策組新增至 Gateway,即可擴充 Gateway 的功能,除了執行 API 產品外,還可納入其他安全性和業務規則。
您可以使用 Kubernetes 適用的 Apigee APIM Operator,將下列政策新增至 Gateway:
- SpikeArrest 政策
- JavaScript 政策
- Google 權杖插入政策
- GenerateJWT 政策
- KVM 政策
- OASValidation 政策
- ServiceCallout 政策
- OAuthv2 政策
- ResponseCache 政策
- VerifyAPIKey 政策
總覽
以下各節將說明如何:
事前準備
如要使用本指南中用於示例的完整政策集修改 GKE Gateway,您必須擁有服務帳戶,並具備在 Apigee 中建立符記及部署 Proxy 和擴充功能所需的角色。如果您選擇「不」建立 Google 權杖,就不需要在服務帳戶中新增其他角色,可以直接跳到下一節。
如何建立具備必要權限的服務帳戶:
- 如果您在 Kubernetes 適用的 Apigee APIM Operator 安裝指南中建立了名為
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
服務帳戶必要的角色,以便部署 Proxy 和擴充功能:gcloud projects add-iam-policy-binding $PROJECT_ID \ --member "serviceAccount:apigee-apim-gsa@$PROJECT_ID.iam.gserviceaccount.com" \ --role "roles/iam.serviceAccountUser"
使用政策修改 GKE 閘道
您可以選擇使用一或多項政策修改 GKE Gateway,藉此擴充功能。這個範例逐步操作說明會將 yaml
檔案套用至 Gateway,其中包含兩個 Apigee 政策和一個 Google 符記插入政策的規格。
使用下列 yaml
檔案套用至 Gateway 的每項政策,在評估傳送至 Gateway 的要求時,會執行不同的角色:
- SpikeArrest 政策會定義一段時間內允許的最大要求頻率,藉此控制訊息傳送頻率的尖峰值。在這個範例中,每分鐘的最大速率設為五次。如要進一步瞭解如何使用 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 description: kvm1 displayName: kvm1 exclusiveCache: true expiryTimeInSecs: 3600 get: - assignTo: response.header.mykvm index: 0 keys: - value: mykey initialEntries: - keys:s - key1 values:s - val1 - keys:s - mykey values: - initvalue isEncrypted: false mapIdentifier: mapIdentifier mapName:s ref: kvm.mapname value: kvmname put: - keys: - value: mykey values: - value: request.header.mykvm scope: environment --- apiVersion: apim.googleapis.com/v1 kind: OASValidation metadata: name: oas-validation-1 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
建立 TemplateRule 做為 SharedFlow 範本
在這個步驟中,您將建立 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: []
在這個範例中,範本規則會告知開發人員,必須使用 AssignMessage 政策,才能說明 Google 權杖插入政策。這項政策也會告知開發人員,他們可以在 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 政策
在這個步驟中,您會將新檔案套用至 Gateway,其中包含 ApigeeGatewayPolicy
的規格。這項政策用於將 Apigee 範本部署至閘道。
部署 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: global-ext-lb1-apim-policy namespace: apim
- 套用政策:
kubectl apply -f apigee-gateway-policy-withSA.yaml
- 驗證新 Gateway 政策的部署狀態:
kubectl -n apim get ApigeeGatewayPolicy
部署完成後,政策
STATUS
應會顯示CREATED
。
部署新 Gateway 政策後,請等待兩分鐘,再向 Gateway 傳送要求,讓政策傳播至叢集。
驗證政策違規處置
如要確認 Apigee Gateway 政策運作正常,請按照下列各節所述,向 Gateway 傳送要求。
指派訊息政策違規處置
如要確認系統會使用「AssignMessage」政策將 {company_name} 權杖插入要求中,請使用下列指令向 Gateway 傳送要求:
curl http://GATEWAY_IP_ADDRESS/get -H "Host: HOST_NAME" -H "x-api-key: API_KEY"
其中:
GATEWAY_IP_ADDRESS
是閘道的 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 政策的執行情況,方法是在一分鐘內向 Gateway 傳送十次要求。
您可以執行下列指令碼來產生要求:
#!/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
是閘道的 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
是閘道的 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
,如回應所示:
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
是閘道的 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
是閘道的 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 政策強制執行
您可以開啟偵錯工作階段,並向 Proxy 傳送一些有效要求,藉此驗證 ServiceCallout 政策的執行情況。
如要開啟偵錯工作階段,請按照下列步驟操作:
- 前往 Google Cloud 控制台的「API Proxies」頁面。
- 選取已部署至為 Kubernetes 的 Apigee APIM Operator 建立的環境中的
global-ext-lb1-apim-policy
Proxy。 - 按一下「Debug」分頁標籤。
- 在「Debug session」視窗中,按一下「Start Debug Session」。
- 在「Debug session」窗格中,選取下列項目:
- 環境:從可用環境清單中選取您為 APIM 操作員建立的環境。
- 篩選條件:選取「無 (所有交易)」。
- 按一下「啟動」。
工作階段開始後,您就可以向 Proxy 傳送有效要求:
curl "GATEWAY_IP_ADDRESSget" \ -H "Host: HOST_NAME" \ -H "x-api-key: API_KEY" \ -H "X-Request-Type: external" -i
其中:
GATEWAY_IP_ADDRESS
是閘道的 IP 位址。您可以使用下列指令擷取 Gateway IP 位址,其中GATEWAY_NAME
是 Gateway 的名稱:kubectl get gateway GATEWAY_NAME
HOST_NAME
是 Gateway 的HTTPRoute
中定義的主機名稱。API_KEY
是「測試設定」中取得的 API 金鑰值。
要求和回應交易會顯示在「Transactions」窗格中。從清單中選取成功的交易,即可顯示流程。您應該會看到 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
其中:
- 請檢查回應標頭,確認 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" } }
您可以看到 KVM 政策已成功執行,因為
mykvm
標頭的值已更新為要求標頭mykvm
的值。 - 再傳送一次要求:
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 新增政策時遇到問題,請參閱「排解 APIM Operator 問題」,瞭解如何解決常見錯誤。
後續步驟
- 進一步瞭解SpikeArrest 政策。
- 進一步瞭解 JavaScript 政策。