您正在查看 Apigee 和 Apigee Hybrid 說明文件。
查看
Apigee Edge 說明文件。
在客服案件中提供詳細的必要資訊,可協助 Google Cloud 支援團隊迅速且有效率地回覆您。如果您的客服案件缺少重要細節,我們會需要花費額外的時間來詢問相關資訊,可能需要多次來回溝通。這會耗費更多時間,且可能導致問題解決時間延後。本最佳做法指南可讓您瞭解我們在解決技術性客服案件時所需要的資訊,
描述問題
問題應包含詳細資訊,說明實際發生的情況與預期情況的差異,以及發生的時間和方式。良好的客服案件應包含每個 Apigee 產品的下列重要資訊:
重要資訊 | 說明 | Google Cloud 上的 Apigee | Apigee Hybrid |
---|---|---|---|
產品 | 發生問題的特定 Apigee 產品,包括適用的版本資訊。 |
|
|
問題詳細資料 | 清楚且詳細的問題說明,概述問題,包括完整的錯誤訊息 (如有)。 |
|
|
時間 | 問題開始發生的確切時間戳記,以及問題持續的時間。 |
|
|
設定 | 發生問題的詳細資訊。 |
|
|
下列各節會進一步說明這些概念。
產品
我們提供多種 Apigee 產品,包括 Google Cloud 上的 Apigee 和 Apigee hybrid,因此需要具體資訊,才能瞭解哪項產品出現問題。
下表列出一些範例,說明「應做」欄中的完整資訊,以及「不應做」欄中的不完整資訊:
正確做法 | 禁止事項 |
---|---|
在 Google Cloud 上的 Apigee 機構中,API proxy OAuth2 的部署作業失敗 ... |
API Proxy 部署失敗 (我們需要知道您在哪個 Apigee 產品中遇到問題。) |
在 Apigee hybrid 1.3 上使用 cqlsh 存取 Cassandra 時,我們會收到以下錯誤... |
我們無法使用 (缺少混合型版本資訊) |
問題詳細資料
請提供觀察到的問題的確切資訊,包括錯誤訊息 (如有) 以及觀察到的預期和實際行為。
下表列出一些範例,說明「應做」欄中的完整資訊,以及「不應做」欄中的不完整資訊:
正確做法 | 禁止事項 |
---|---|
新的
|
今天建立的新 (代理名稱不明。無法確定 Proxy 是傳回錯誤或任何非預期的回應。) |
我們的客戶在向 API 代理提出要求時,會收到
|
我們的客戶在向 API 代理提出要求時,會收到
(僅傳送 |
時間
時間是相當重要的資訊。支援工程師必須瞭解你首次發現問題的時間、問題持續多久,以及問題是否仍在發生。
負責解決問題的支援工程師可能不在您的時區,因此類似下列的敘述會使問題難以診斷。因此,建議您使用 ISO 8601 格式輸入日期時間戳記,以便提供問題發生時間的確切時間資訊。
下表列出一些範例,說明「應做」欄中顯示的問題發生時間和持續時間,以及「不應做」欄中顯示的問題發生時間不明確或不清楚的資訊:
正確做法 | 禁止事項 |
---|---|
昨天在 2020-11-06 17:30 PDT 和 2020-11-06 17:35 PDT 之間,我們觀察到大量 503s ... |
昨天下午 5 點 30 分,系統觀察到大量 (我們必須使用隱含日期,而且也無法確認這個問題發生的時區)。 |
我們發現下列 API Proxy 的延遲時間過長,從 2020-11-09 15:30 IST 到 2020-11-09 18:10 IST ... |
上週我們發現部分 API Proxy 的延遲時間偏高。 (無法確定這個問題在過去一週內發生的日期和時間長度)。 |
設定
我們需要瞭解您在哪裡遇到問題的詳細資訊。 視您使用的產品而定,我們需要以下資訊:
- 如果您在 Google Cloud 上使用 Apigee,可能會有多個機構,因此我們需要知道您觀察到問題的特定機構和其他詳細資料:
- 機構和環境名稱
- API Proxy 名稱和修訂版本號碼 (適用於 API 要求失敗)
- 如果您使用混合式,可能會使用許多支援的 混合式平台和安裝拓撲之一。因此,我們需要瞭解您使用的混合雲平台和拓樸,包括資料中心和節點數量等詳細資料。
下表列出一些範例,說明「DO」欄位顯示完整資訊,而「DON'T」欄位顯示不完整的資訊:
正確做法 | 禁止事項 |
---|---|
Apigee 設定詳細資料:
失敗 API 的詳細資料如下:
錯誤:
|
(不會提供任何有關使用中產品的資訊,例如問題發生時的時間或任何設定詳細資料)。 |
在 Apigee Hybrid 1.3 版本上,偵錯作業會失敗並顯示以下錯誤 錯誤:
Apigee Hybrid 設定詳細資料:
| 在 Apigee Hybrid 上無法進行偵錯。 |
有用的資料
提供與問題相關的資料可協助我們確切瞭解您觀察到的行為,並進一步深入瞭解,進而加快解決問題的速度。
本節將說明一些實用成果,可供所有 Apigee 產品使用:
所有 Apigee 產品的通用構件
下列構件適用於所有 Apigee 產品:Google Cloud 上的 Apigee 和 Apigee hybrid:
構件 | 說明 |
---|---|
偵錯工具輸出內容 | 偵錯工具輸出內容包含透過 Apigee 產品傳送的 API 要求詳細資訊。這對於任何執行階段錯誤 (例如 4XX 、5XX 和延遲問題) 都很有幫助。 |
螢幕截圖 | 螢幕截圖可協助我們瞭解實際行為或觀察到的錯誤。這項功能可協助您找出任何錯誤或問題,例如在使用者介面或 Analytics 中。 |
HAR (HTTP 存檔) | HAR 是 HTTP 工作階段工具擷取的檔案,可用於偵錯任何 UI 相關問題。您可以使用 Chrome、Firefox 或 Internet Explorer 等瀏覽器擷取螢幕截圖。 |
tcpdumps |
tcpdump 工具會擷取透過網路傳送或接收的 TCP/IP 封包。這項功能可用於任何網路相關問題,例如 TLS 握手失敗、502 錯誤和延遲問題等。 |
混合型應用程式的其他構件
對於混合型應用程式,我們可能需要一些額外的構件,以便更快診斷問題。
構件 | 說明 |
---|---|
Apigee Hybrid 平台 | 指定您使用的任何
支援的混合型平台:
|
Apigee Hybrid 和相關元件版本 |
|
網路拓撲 | Apigee 安裝拓樸圖表,說明混合式設定,包括所有資料中心、Kubernetes 叢集、命名空間和 Pod。 |
覆寫 YAML 檔案 | 在各資料中心用於安裝 Apigee Hybrid 執行階段平面時使用的 overrides.yaml 檔案。 |
Apigee Hybrid 部署狀態 |
每個資料中心/Kubernetes 叢集中下列指令的輸出內容:
|
Apigee Hybrid 元件記錄 |
提供混合式元件的 Cloud Operations (StackDriver) 記錄連結,或 您可以在每個資料中心/Kubernetes 叢集中使用下列指令擷取 Apigee Hybrid 元件記錄,並與我們分享:
|
說明記錄 |
Pod 的詳細資訊。 如果您觀察到 Pod 卡在
|
Cloud Monitoring |
|
Apigee Hybrid 必備收集
您也可以根據下列指令執行 Must-Gather 指令碼,
###--- "kubectl config" commands to get the config details of the whole Apigee Hybrid cluster ---#### kubectl config get-clusters 2>&1 | tee /tmp/k_config_get_clusters_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl config get-contexts 2>&1 | tee /tmp/k_config_get_contexts_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl config get-users 2>&1 | tee /tmp/k_config_get_users_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl config view 2>&1 | tee /tmp/k_config_view_$(date +%Y.%m.%d_%H.%M.%S).txt ### --- Collect all details of all nodes in the Kubernetes cluster.---### kubectl describe node 2>&1 | tee /tmp/k_describe_node_$(date +%Y.%m.%d_%H.%M.%S).txt ###--- "kubectl get -A " commands to get CRD details for the whole Apigee Hybrid setup ---#### kubectl get clusterissuers -A -o wide 2>&1 | tee /tmp/k_get_clusterissuers_all$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get certificate -A -o wide 2>&1 | tee /tmp/k_get_certificate_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get certificaterequest -A -o wide 2>&1 | tee /tmp/k_get_certificaterequest_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get crd -A -o yaml 2>&1 | tee /tmp/k_get_crd_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get ConfigMap -A 2>&1 | tee /tmp/k_get_ConfigMap_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get ClusterRole -A -o wide 2>&1 | tee /tmp/k_get_clusterrole_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get ClusterRoleBinding -A -o wide 2>&1 | tee /tmp/k_get_clusterrole_binding_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get Deployments -A -o wide >&1 | tee /tmp/k_get_deployments_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get events -A -o wide 2>&1 | tee /tmp/k_get_events_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get endpoints -A 2>&1 | tee /tmp/k_get_endpoints_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get issuers -A -o wide 2>&1 | tee /tmp/k_get_issuers_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get mutatingwebhookconfigurations 2>&1 | tee /tmp/k_get_mutatingwebhookconfigurations_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get nodes -o wide --show-labels 2>&1 | tee /tmp/k_get_nodes_labels_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get ns 2>&1 | tee /tmp/k_get_namespace_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get PriorityClass -A -o wide 2>&1 | tee /tmp/k_get_PriorityClass_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get pv -A -o wide 2>&1 | tee /tmp/k_get_pv_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get pvc -A -o wide 2>&1 | tee /tmp/k_get_pvc_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get Role -A -o wide 2>&1 | tee /tmp/k_get_role_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get RoleBinding -A -o wide 2>&1 | tee /tmp/k_get_Role_Binding_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get replicaset -A -o wide 2>&1 | tee /tmp/k_get_replicaset_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get sa -A -o wide 2>&1 | tee /tmp/k_get_service_accounts_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get services -A -o wide 2>&1 | tee /tmp/k_get_services_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get svc -A 2>&1 | tee /tmp/k_get_svc_all$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get secrets -A 2>&1 | tee /tmp/k_get_secrets_all_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get validatingwebhookconfigurations -A 2>&1 | tee /tmp/k_get_validatingwebhookconfigurations_all$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get validatingwebhookconfigurations apigee-validating-webhook-configuration 2>&1 | tee /tmp/k_get_apigee-validating-webhook-configuration_$(date +%Y.%m.%d_%H.%M.%S).txt ### --- List top resource consuming nodes and pods ---#### kubectl top nodes 2>&1 | tee /tmp/k_top_nodes_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl top pod -A --containers 2>&1 | tee /tmp/k_top_pod_all_containers_$(date +%Y.%m.%d_%H.%M.%S).txt ###----- "kubectl get" commands to fetch list of all CRD for "apigee" namespace ----- ##### kubectl get all -n apigee -o wide 2>&1 | tee /tmp/k_get_all_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get ad -n apigee 2>&1 | tee /tmp/k_get_ad_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get apigeeorganization -n apigee 2>&1 | tee /tmp/k_get_apigeeorganization_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get apigeeenv -n apigee 2>&1 | tee /tmp/k_get_apigeeenv_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get apigeeds -n apigee 2>&1 | tee /tmp/k_get_apigeeds_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get apigeedatastore -n apigee 2>&1 | tee /tmp/k_get_apigeedatastore_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get ApigeeDeployment -n apigee 2>&1 | tee /tmp/k_get_apigeedeployment_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get ApigeeRedis -n apigee 2>&1 | tee /tmp/k_get_ApigeeRedis_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get ApigeeRoute -n apigee 2>&1 | tee /tmp/k_get_ApigeeRoute_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get ApigeeRouteConfig -n apigee 2>&1 | tee /tmp/k_get_ApigeeRoutesconfig_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get Apigeetelemetry -n apigee 2>&1 | tee /tmp/k_get_Apigeetelemetry_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get apigeeissues -n apigee 2>&1 | tee /tmp/k_get_apigeeissues_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get ControllerRevision -n apigee -o wide 2>&1 | tee /tmp/k_get_ControllerRevision_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get cronjob -n apigee -o wide 2>&1 | tee /tmp/k_get_cronjob_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get gateway -n apigee 2>&1 | tee /tmp/k_get_gateway_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get PodDisruptionBudget -n apigee -o wide 2>&1 | tee /tmp/k_get_PodDisruptionBudget_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get sc -n apigee -o wide 2>&1 | tee /tmp/k_get_storageclass_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get sr -n apigee -o wide 2>&1 | tee /tmp/k_get_sr_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get sts -n apigee 2>&1 | tee /tmp/k_get_sts_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get volumesnapshot -n apigee -o wide 2>&1 | tee /tmp/k_get_volumesnapshot_n_apigee_$(date +%Y.%m.%d_%H.%M.%S).txt ###----- "kubectl describe" commands to fetch details of all CRD for "apigee" namespace ----- ##### for p in $(kubectl -n apigee get apigeeorganization --no-headers -o custom-columns=":metadata.name") ; do kubectl describe apigeeorganization ${p} -n apigee 2>&1 | tee /tmp/k_desc_apigeeorganization_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get apigeeenv --no-headers -o custom-columns=":metadata.name") ; do kubectl describe apigeeenv ${p} -n apigee 2>&1 | tee /tmp/k_desc_apigeeenv_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get apigeeds --no-headers -o custom-columns=":metadata.name") ; do kubectl describe apigeeds ${p} -n apigee 2>&1 | tee /tmp/k_desc_apigeeds_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get apigeedatastore --no-headers -o custom-columns=":metadata.name") ; do kubectl describe apigeedatastore ${p} -n apigee 2>&1 | tee /tmp/k_desc_apigeedatastore_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get ApigeeDeployment --no-headers -o custom-columns=":metadata.name") ; do kubectl describe ApigeeDeployment ${p} -n apigee 2>&1 | tee /tmp/k_desc_ApigeeDeployment_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get ApigeeRedis --no-headers -o custom-columns=":metadata.name") ; do kubectl describe ApigeeRedis ${p} -n apigee 2>&1 | tee /tmp/k_desc_ApigeeRedis_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get ApigeeRoute --no-headers -o custom-columns=":metadata.name") ; do kubectl describe ApigeeRoute ${p} -n apigee 2>&1 | tee /tmp/k_desc_ApigeeRoute_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get ApigeeRouteConfig --no-headers -o custom-columns=":metadata.name") ; do kubectl describe ApigeeRouteConfig ${p} -n apigee 2>&1 | tee /tmp/k_desc_ApigeeRouteConfig_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get Apigeetelemetry --no-headers -o custom-columns=":metadata.name") ; do kubectl describe Apigeetelemetry ${p} -n apigee 2>&1 | tee /tmp/k_desc_Apigeetelemetry_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get apigeeissues --no-headers -o custom-columns=":metadata.name") ; do kubectl describe apigeeissues ${p} -n apigee 2>&1 | tee /tmp/k_desc_apigeeissues_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get ControllerRevision --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee describe ControllerRevision ${p} 2>&1 | tee /tmp/k_desc_ControllerRevision_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get certificate --no-headers -o custom-columns=":metadata.name") ; do kubectl describe certificate ${p} -n apigee 2>&1 | tee /tmp/k_desc_certificate_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get cronjob --no-headers -o custom-columns=":metadata.name") ; do kubectl describe cronjob ${p} -n apigee 2>&1 | tee /tmp/k_desc_cronjob_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get daemonset --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee describe daemonset ${p} 2>&1 | tee /tmp/k_desc_daemonset_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get deployments --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee describe deployments ${p} 2>&1 | tee /tmp/k_desc_deployment_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get hpa --no-headers -o custom-columns=":metadata.name") ; do kubectl describe hpa ${p} -n apigee 2>&1 | tee /tmp/k_desc_hpa_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get jobs --no-headers -o custom-columns=":metadata.name") ; do kubectl describe jobs ${p} -n apigee 2>&1 | tee /tmp/k_desc_jobs_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get po --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee describe po ${p} 2>&1 | tee /tmp/k_desc_pod_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get PodDisruptionBudget --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee describe PodDisruptionBudget ${p} 2>&1 | tee /tmp/k_desc_PodDisruptionBudget_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get pv --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee describe pv ${p} 2>&1 | tee /tmp/k_desc_pv_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt; done for p in $(kubectl -n apigee get pvc --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee describe pvc ${p} 2>&1 | tee /tmp/k_desc_pvc_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt; done for p in $(kubectl -n apigee get rs --no-headers -o custom-columns=":metadata.name") ; do kubectl describe rs ${p} -n apigee 2>&1 | tee /tmp/k_desc_replicaset_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get sc --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee describe sc ${p} 2>&1 | tee /tmp/k_desc_storageclass_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt; done for p in $(kubectl -n apigee get sts --no-headers -o custom-columns=":metadata.name") ; do kubectl describe sts ${p} -n apigee 2>&1 | tee /tmp/k_desc_sts_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get secrets --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee describe secrets ${p} 2>&1 | tee /tmp/k_desc_secrets_n_apigee${p}_$(date +%Y.%m.%d_%H.%M.%S).txt; done for p in $(kubectl -n apigee get services --no-headers -o custom-columns=":metadata.name") ; do kubectl describe service ${p} -n apigee 2>&1 | tee /tmp/k_desc_services_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get sa --no-headers -o custom-columns=":metadata.name") ; do kubectl describe sa ${p} -n apigee 2>&1 | tee /tmp/k_desc_service_account_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee get svc --no-headers -o custom-columns=":metadata.name") ; do kubectl describe svc ${p} -n apigee 2>&1 | tee /tmp/k_desc_svc_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done ###----- "kubectl logs" command to fetch logs of all containers in the "apigee" namespace ----- ##### for p in $(kubectl -n apigee get po --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee logs ${p} --all-containers 2>&1 | tee /tmp/k_logs_n_apigee_${p}_$(date +%Y.%m.%d_%H.%M.%S).log ; done ###----- "kubectl get" commands for "apigee-system" namespace ----- ##### kubectl get all -n apigee-system -o wide 2>&1 | tee /tmp/k_get_all_n_apigee_system_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get jobs -o wide -n apigee-system 2>&1 | tee /tmp/k_get_jobs_n_apigee_system_$(date +%Y.%m.%d_%H.%M.%S).txt ###----- "kubectl describe" commands for "apigee-system" namespace ----- ##### for p in $(kubectl -n apigee-system get certificate --no-headers -o custom-columns=":metadata.name") ; do kubectl describe certificate ${p} -n apigee-system 2>&1 | tee /tmp/k_desc_certificate_n_apigee_system_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee-system get deployment --no-headers -o custom-columns=":metadata.name") ; do kubectl describe deployment ${p} -n apigee-system 2>&1 | tee /tmp/k_desc_deployment_n_apigee_system_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee-system get jobs --no-headers -o custom-columns=":metadata.name") ; do kubectl describe jobs ${p} -n apigee-system 2>&1 | tee /tmp/k_desc_jobs_n_apigee_system_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee-system get po --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee-system describe po ${p} 2>&1 | tee /tmp/k_desc_pod_n_apigee_system_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee-system get rs --no-headers -o custom-columns=":metadata.name") ; do kubectl describe rs ${p} -n apigee-system 2>&1 | tee /tmp/k_desc_replicaset_n_apigee_system_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee-system get rolebinding --no-headers -o custom-columns=":metadata.name") ; do kubectl describe rolebinding ${p} -n apigee-system 2>&1 | tee /tmp/k_desc_rolebinding_n_apigee_system_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee-system get services --no-headers -o custom-columns=":metadata.name") ; do kubectl describe service ${p} -n apigee-system 2>&1 | tee /tmp/k_desc_services_n_apigee_system_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee-system get sa --no-headers -o custom-columns=":metadata.name") ; do kubectl describe sa ${p} -n apigee-system 2>&1 | tee /tmp/k_desc_serviceaccount_n_apigee_system_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n apigee-system get secrets --no-headers -o custom-columns=":metadata.name") ; do kubectl describe secrets ${p} -n apigee-system 2>&1 | tee /tmp/k_desc_secrets_n_apigee_system_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done ###----- "kubectl logs" command for "apigee-system" namespace ----- ##### for p in $(kubectl -n apigee-system get po --no-headers -o custom-columns=":metadata.name") ; do kubectl -n apigee-system logs ${p} --all-containers 2>&1 | tee /tmp/k_logs_n_apigee_system_${p}_$(date +%Y.%m.%d_%H.%M.%S).log ; done ###----- "kubectl get" command for "cert-manager" namespace ----- ##### kubectl get all -n cert-manager -o wide 2>&1 | tee /tmp/k_get_all_n_cert_manager_$(date +%Y.%m.%d_%H.%M.%S).txt kubectl get crd -n cert-manager 2>&1 | tee /tmp/k_get_crd_n_cert_manager_$(date +%Y.%m.%d_%H.%M.%S).txt ###----- "kubectl describe" command for "cert-manager" namespace ----- ##### for p in $(kubectl -n cert-manager get deployment --no-headers -o custom-columns=":metadata.name") ; do kubectl -n cert-manager describe deployment $(p) 2>&1 | tee /tmp/k_desc_deployment_n_cert_manager_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n cert-manager get endpoints --no-headers -o custom-columns=":metadata.name") ; do kubectl describe endpoints ${p} -n cert-manager 2>&1 | tee /tmp/k_desc_endpoints_n_cert_manager_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n cert-manager get po --no-headers -o custom-columns=":metadata.name") ; do kubectl -n cert-manager describe po ${p} 2>&1 | tee /tmp/k_desc_po_n_cert_manager_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n cert-manager get rs --no-headers -o custom-columns=":metadata.name") ; do kubectl describe rs ${p} -n cert-manager 2>&1 | tee /tmp/k_desc_replicaset_n_cert_manager_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n cert-manager get sa --no-headers -o custom-columns=":metadata.name") ; do kubectl describe sa ${p} -n cert-manager 2>&1 | tee /tmp/k_desc_serviceaccount_n_cert_manager_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n cert-manager get secrets --no-headers -o custom-columns=":metadata.name") ; do kubectl describe secrets ${p} -n cert-manager 2>&1 | tee /tmp/k_desc_secrets_n_cert_manager_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n cert-manager get services --no-headers -o custom-columns=":metadata.name") ; do kubectl describe service ${p} -n cert-manager 2>&1 | tee /tmp/k_desc_service_n_cert_manager_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done for p in $(kubectl -n cert-manager get svc --no-headers -o custom-columns=":metadata.name") ; do kubectl describe svc ${p} -n cert-manager 2>&1 | tee /tmp/k_desc_svc_n_cert_manager_${p}_$(date +%Y.%m.%d_%H.%M.%S).txt ; done ###----- "kubectl logs" command for "cert-manager" namespace ----- ##### for p in $(kubectl -n cert-manager get po --no-headers -o custom-columns=":metadata.name") ; do kubectl -n cert-manager logs ${p} --all-containers 2>&1 | tee /tmp/k_logs_n_cert_manager_${p}_$(date +%Y.%m.%d_%H.%M.%S).log ; done
# tar -cvzf /tmp/apigee_hybrid_logs_$(date +%Y.%m.%d_%H.%M).tar.gz /tmp/k_*
如果 tar 檔案的大小超過 25 MB,您可以將檔案上傳至 Google 雲端硬碟,然後與我們分享連結。或者,您也可以使用分割指令,將大型檔案切割成 25 MB 的區塊,再上傳至支援入口網站。
# split -b 25M diagnostic.tar.gz "diagnostic.tar.gz.part"
Apigee Hybrid Cassandra 必須收集
收集基本資料
用下列資訊作答:
- Apigee Hybrid 平台 (GKE、GKE On-Prem、AKS、EKS 等)
- Apigee Hybrid 版本
- Google Cloud 專案 ID
- Apigee Hybrid 機構
- Apigee Hybrid 環境
- 這是單一或多區域部署嗎?
overrides.yaml
檔案 (每個叢集一個)- 一個叢集可安裝多少個 Apigee Hybrid 機構?
- 近期是否有任何異動?
收集 Cassandra 偵錯資訊
Run the below script to capture Cassandra debugging information from an Apigee hybrid cluster: # Create a temporary directory to store the Cassandra debugging information. mkdir /tmp/apigee-cassandra-debug-info/ # Loop through all Cassandra pods for APIGEE_CASSANDRA_POD in $(kubectl -n apigee get pods -l app=apigee-cassandra --no-headers -o custom-columns=":metadata.name") ; do # Get Cassandra version kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD version' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_version_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt # Get Cassandra datacenter status kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD status' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_status_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt # Get Cassandra cluster information kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD describecluster' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_describecluster_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt # Get current ring/token status across the datacenter kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD ring' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_ring_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt # Get more information about heap usage, uptime, exceptions, etc kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD info' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_info_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt # Get gossip info kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD gossipinfo' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_gossipinfo_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt # Get Cassandra compaction details kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD compactionstats' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_compactionstats_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD compactionhistory' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_compactionhistory_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD getcompactionthroughput' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_getcompactionthroughput_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD getconcurrentcompactors' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_getconcurrentcompactors_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt # Get status of current Cassandra operations kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD tablestats' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_tablestats_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD tpstats' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_tpstats_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD netstats' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_netstat_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD tablestats' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_tablestats_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD gcstats' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_gcstats_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt # Get proxy histograms (shows the full request latency recorded by the coordinator) kubectl -n apigee exec $APIGEE_CASSANDRA_POD -- bash -c 'nodetool -u $APIGEE_JMX_USER -pw $APIGEE_JMX_PASSWORD proxyhistograms' 2>&1 | tee /tmp/apigee-cassandra-debug-info/nodetool_proxyhistograms_$APIGEE_CASSANDRA_POD-$(date +%Y.%m.%d_%H.%M.%S).txt done # compress all collected data tar -czvf apigee-cassandra-debug-info-$(date +%Y.%m.%d_%H.%M.%S).tar.gz -C /tmp apigee-cassandra-debug-info
個案範本和個案
本節將根據本文所述的最佳做法,提供不同產品的案件範本和示例案件:
Apigee Cloud
範本
本節提供 Google Cloud 上的 Apigee 範本。
問題:
<請詳細說明問題或您觀察到的行為。請在適用情況下提供產品名稱和版本。>
錯誤訊息:
<Include the complete error message observed (if any)>
問題開始時間 (ISO 8601 格式):
問題結束時間 (ISO 8601 格式):
Apigee 設定詳細資料:
機構名稱:
環境名稱:
API Proxy 名稱:
修訂版本號碼:
重現問題的步驟:
<提供重現問題的步驟 (如有)>
診斷資訊:
<附件檔案清單>
範例
本節將提供 Google Cloud 上的 Apigee 範例案例。
問題:
我們在 公用雲 機構中看到大量 503 服務無法使用錯誤。請你調查並解決這個問題,或是建議我們如何解決這個問題。
錯誤訊息:
{"fault":{"faultstring":"The Service is temporarily available", "detail":{"errorcode":"messaging.adaptors.http.flow.ServiceUnavailable"}}}
問題開始時間 (ISO 8601 格式):2020-10-04 06:30 IST
問題結束時間 (ISO 8601 格式):問題仍在發生中。
Apigee Cloud 設定詳細資料:
機構名稱:myorg
環境名稱:dev
API 代理程式名稱:myproxy
修訂版本號碼:3
重現問題的步驟:
執行下列 curl
指令,重現問題:
curl -X GET 'https://myorg-dev.apigee.net/v1/myproxy'
診斷資訊:
偵錯工具輸出內容 (trace-503.xml
)
混合
範本
本節提供 Apigee Hybrid 範本。
問題:
<請詳細說明問題或您觀察到的行為。請在適用情況下提供產品名稱和版本。>
錯誤訊息:
<Include the complete error message observed (if any)>
問題開始時間 (ISO 8601 格式):
問題結束時間 (ISO 8601 格式):
Apigee Hybrid 設定詳細資料:
- Apigee Hybrid 平台:
<請提供您安裝 hybrid 的平台資訊,以及該平台的版本。>
- Google Cloud 專案、混合式機構和環境:
Google Cloud 專案 ID:
<如果您使用 Google Kubernetes Engine (GKE),請務必提供叢集所在的專案 ID。如果您使用的是 GKE on-prem、Azure Kubernetes Service 或 Amazon EKS,請提供您要傳送記錄的專案 ID。>
Apigee 混合式機構:
Apigee 混合式環境: - Apigee Hybrid 和其他 CLI 版本:
Apigee Hybrid CLI (apigeectl
) 版本:
Kubectl 版本: - Kubernetes 叢集名稱詳細資料:
k8sCluster:
name:
region: - 網路拓撲:
<附上網路拓撲,說明 Apigee Hybrid 的設定,包括資料中心、Kubernetes 叢集、命名空間和 Pod。> - 覆寫 YAML 檔案:
<附加覆寫 YAML 檔案。>
重現問題的步驟
<提供重現問題的步驟 (如有)>
診斷資訊:
<附件檔案清單>
範例
本節提供 Apigee Hybrid 的範例。
問題:
在 Apigee Hybrid 1.3 版本上執行管理 API 時,我們會收到錯誤訊息。
錯誤訊息:
[ERROR] 400 Bad Request { "error": { "code": 400, "message": "Error processing MART request: INTERNAL_ERROR", "errors": [ { "message": "Error processing MART request: INTERNAL_ERROR", "domain": "global", "reason": "failedPrecondition" } ], "status": "FAILED_PRECONDITION" } }
問題開始時間 (ISO 8601 格式):自 2020 年 10 月 24 日 10 點 30 分 (太平洋時間) 起
問題結束時間 (ISO 8601 格式):持續觀察問題。
Apigee Hybrid 設定詳細資料:
- Apigee Hybrid 平台
GKE 1.15.1 版 - Google Cloud 專案、混合機構和環境
Google Cloud 專案 ID:apigee-hybrid-123456
注意:這是叢集所在的專案 ID。
Apigee Hybrid 機構:apigee-hybrid-123456
Apigee Hybrid 環境:dev
- Apigee hybrid 和其他 CLI 版本:
Apigee hybrid CLI (apigeectl
) 版本:
版本:1.2.0
提交:ac09109
建構 ID:214
建構時間:2020-03-30T20:23:36Z
Go 版本:go1.12
Kubectl 版本:
用戶端版本:version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.0", GitCommit:"e8462b5b5dc2584fdcd18e6bcfe9f1e4d970a529", GitTreeState:"clean", BuildDate:"2019-06-19T16:40:16Z", GoVersion:"go1.12.5", Compiler:"gc", Platform:"darwin/amd64"}
伺服器版本:version.Info{Major:"1", Minor:"14+", GitVersion:"v1.14.10-gke.36", GitCommit:"34a615f32e9a0c9e97cdb9f749adb392758349a6", GitTreeState:"clean",
- Kubernetes 叢集名稱詳細資料:
k8sCluster:
name:user-cluster-1
region:us-east1
- 網路拓撲
已附加檔案network-topology.png
- 覆寫 YAML 檔案
已附加檔案overrides.yaml
檔案
重現問題的步驟:
執行下列管理 API 即可觀察錯誤:
curl -X GET --header "Authorization: Bearer <TOKEN>" "https://apigee.googleapis.com/v1/organizations/apigee-hybrid-123456/environments/dev/keyvaluemaps"
診斷資訊:
已附加下列檔案:
network-topology.png
overrides.yaml file
- MART 記錄
- 同步處理工具記錄