Google Cloud Apigee 지원 케이스 권장사항

ApigeeApigee Hybrid 문서입니다.
Apigee Edge 문서 보기

지원 케이스에 세부정보 및 필수 정보를 제공하면 Google Cloud 지원팀에서 더 빠르고 효율적으로 응답하기가 쉽습니다. 지원 케이스에 중요한 세부정보가 누락되어 있으면 지원팀에서 여러 번 반복하여 정보를 요청할 수 있습니다. 이렇게 하면 시간이 오래 걸리고 문제 해결이 지연될 수 있습니다. 이 권장사항 가이드에서는 Google이 기술 지원 케이스를 빠르게 확인하는 데 필요한 정보를 설명합니다.

문제 설명

문제에는 예상 동작과 실제 동작의 차이와 언제 어떻게 발생했는지에 대한 세부정보를 설명하는 정보가 포함되어야 합니다. 올바른 지원 케이스에는 각 Apigee 제품에 대한 다음과 같은 주요 정보가 포함되어야 합니다.

주요 정보 설명 Google Cloud 기반 Apigee Apigee Hybrid
제품 문제가 관찰되는 특정 Apigee 제품(해당하는 경우 버전 정보 포함)
  • 하이브리드 버전
문제 세부정보 문제에 대한 명확하고 자세한 설명(오류 메시지가 있는 경우 포함)
  • 오류 메시지
  • 디버그 도구 출력
  • 문제를 재현하기 위한 단계
  • 전체 API 요청/명령어
  • 오류 메시지
  • 디버그 도구 출력
  • 문제를 재현하기 위한 단계
  • 전체 API 요청/명령어
  • 구성요소 진단 로그
  • Cloud Monitoring 측정항목
시간 문제가 시작된 구체적인 타임스탬프 및 지속 시간
  • 문제가 발생한 날짜, 시간, 표준 시간대
  • 문제가 지속된 기간
  • 문제가 발생한 날짜, 시간, 표준 시간대
  • 문제가 지속된 기간
설정 문제가 관찰되는 자세한 정보
  • 조직 이름
  • 환경 이름
  • API 프록시 이름
  • 버전

다음 섹션에서 이러한 개념을 보다 자세히 설명합니다.

제품

Google Cloud 기반 ApigeeApigee Hybrid 등 다양한 Apigee 제품이 있으므로 문제가 발생하는 특정 제품에 대한 구체적인 정보가 필요합니다.

다음 표에서는 권장사항 열에 전체 정보를 보여주고 금지사항 열에 불완전한 정보를 보여주는 몇 가지 예시를 제공합니다.

권장사항 금지사항
Google Cloud 기반 Apigee 조직에서 API 프록시 OAuth2 배포에 실패했습니다.

API 프록시 배포 실패

(Google에서는 문제가 발생한 Apigee 제품을 알아야 함)

Apigee Hybrid 버전 1.3에서 cqlsh를 사용하여 Cassandra에 액세스하는 동안 다음 오류가 발생했습니다.

cqlsh를 사용하여 Cassandra에 액세스할 수 없음

(하이브리드 버전 정보 누락)

문제 세부정보

오류 메시지(해당하는 경우)와 예상 동작 및 관찰된 실제 동작을 포함하여 관찰되는 문제에 대한 정확한 정보를 제공합니다.

다음 표에서는 권장사항 열에 전체 정보를 보여주고 금지사항 열에 불완전한 정보를 보여주는 몇 가지 예시를 제공합니다.

권장사항 금지사항

edgemicro 프록시 edgemicro_auth가 다음 오류와 함께 실패합니다.

{"error":"missing_authorization","error_description":"Missing Authorization header"}

오늘 만든 새 edgemicro 프록시가 작동하지 않음

(프록시 이름은 알 수 없습니다. 프록시가 오류를 반환하는지 또는 예기치 못한 응답을 반환하는지 명확하지 않습니다.)

API 프록시에 요청을 수행하는 동안 클라이언트에 다음 오류 메시지와 함께 500 오류가 발생합니다.

{"fault":{"faultstring":"Execution of JSReadResponse failed with error: Javascript runtime error: \"TypeError: Cannot read property \"content\" from undefined. (JSReadResponse.js:23)","detail":{"errorcode":"steps.javascript.ScriptExecutionFailed"}}}

API 프록시에 요청을 수행하는 동안 클라이언트에 500 오류가 발생합니다.

(500 오류를 전달하는 것만으로는 문제를 조사하기에 충분한 정보가 제공되지 않습니다. 관찰되는 실제 오류 메시지와 오류 코드를 알아야 합니다.)

시간

시간은 매우 중요한 정보입니다. 지원 엔지니어는 이 문제를 처음 관찰한 시점, 지속된 시간, 현재 문제 지속 여부를 파악하는 것이 중요합니다.

이 문제를 해결하는 지원 엔지니어가 고객과 같은 시간대에 있지 않을 수 있으므로 시간에 대해 상대적 문구를 사용하면 문제를 진단하기가 더 어렵습니다. 따라서 날짜 및 시간 스탬프에 ISO 8601 형식을 사용하여 문제가 발견된 정확한 시간 정보를 제공하는 것이 좋습니다.

다음 표에서는 권장사항 열에 문제가 발생한 정확한 시간 및 기간을 보여주고 금지사항 열에 문제가 발생한 시기에 대해 모호하거나 분명하지 않은 정보를 보여주는 몇 가지 예시를 제공합니다.

권장사항 금지사항
어제 2020-11-06 17:30 PDT2020-11-06 17:35 PDT 사이에 대량의 503s가 관찰되었습니다.

대량의 503s이 어제 오후 5시 30분에 5분 동안 관찰되었습니다.

(암시적 날짜를 사용해야 하므로 이 문제가 관찰된 시간대를 알 수 없습니다.)

2020-11-09 15:30 IST 2020-11-09 18:10 IST 사이에 다음 API 프록시에서 긴 지연시간이 관찰되었습니다.

지난주에 일부 API 프록시에서 긴 지연시간이 관찰되었습니다.

(지난주에 이 문제가 발생한 요일과 기간은 명확하지 않습니다.)

설정

정확히 어디에서 문제가 발생했는지에 대해 자세히 알아야 합니다. 사용 중인 제품에 따라 다음 정보가 필요합니다.

  • Google Cloud를 사용하는 경우 조직이 둘을 초과하여 있을 수 있으므로 문제를 관찰하는 특정 조직 및 기타 세부정보를 알아야 합니다.
    • 조직 및 환경 이름
    • API 프록시 이름 및 버전 번호(API 요청 실패의 경우)
  • 하이브리드를 사용하는 경우 지원되는 여러 하이브리드 플랫폼과 설치 토폴로지 중 하나를 사용할 수 있습니다. 따라서 Google에서는 데이터 센터 및 노드 수 같은 세부정보를 비롯해 사용 중인 하이브리드 플랫폼과 토폴로지를 알아야 합니다.

다음 표에서는 권장사항 열에 전체 정보를 보여주고 금지사항 열에 불완전한 정보를 보여주는 몇 가지 예시를 제공합니다.

권장사항 금지사항

2020-11-06 09:30 CST 이후 Google Cloud 기반 Apigee에서 401 오류가 증가했습니다.

Apigee 설정 세부정보:

실패한 API의 세부정보는 다음과 같습니다.
  조직 이름: myorg
  환경 이름: test
   API 프록시 이름: myproxy
   버전 번호: 3

오류:

{"fault":{"faultstring":"Failed to resolve API Key variable request.header.X-APP-API_KEY","detail":{"errorcode":"steps.oauth.v2.FailedToResolveAPIKey"}}}

401 오류가 증가했습니다.

(문제가 관찰되거나 설정 세부정보를 사용할 때 사용되는 제품에 관한 정보는 제공하지 않습니다.)

Apigee Hybrid 버전 1.3에서 다음 오류와 함께 디버그가 실패합니다.

오류:

Error while Creating trace session for corp-apigwy-discovery, revision 3, environment dev.

Failed to create DebugSession {apigee-hybrid-123456 dev corp-apigwy-discovery 3 ca37384e-d3f4-4971-9adb-dcc36c392bb1}

Apigee Hybrid 설정 세부정보:

  • Apigee Hybrid 플랫폼:
      Anthos GKE On-Prem 버전 1.4.0
  • Google Cloud 프로젝트, 하이브리드 조직 및 환경
      Google Cloud 프로젝트 ID: apigee-hybrid-123456
      Apigee Hybrid 조직: apigee-hybrid-123456
      Apigee Hybrid 환경: dev
  • Kubernetes 클러스터 이름 세부정보:
      k8sCluster:
      이름: user-cluster-1
      리전: us-east1
  • 네트워크 토폴로지
    network-topology.png 파일을 연결했습니다.
Apigee Hybrid에서 디버그가 실패합니다.

유용한 아티팩트

문제와 관련된 아티팩트를 Google에 제공하면 해결 속도가 빨라집니다. 관찰하는 정확한 동작을 파악하여 더 많은 유용한 정보를 파악할 수 있기 때문입니다.

이 섹션에서는 모든 Apigee 제품에 유용한 몇 가지 유용한 아티팩트를 설명합니다.

모든 Apigee 제품의 일반 아티팩트

다음 아티팩트는 Google Cloud 기반 ApigeeApigee Hybrid 등 모든 Apigee 제품에 유용합니다.

아티팩트 설명
디버그 도구 출력 디버그 도구 출력에는 Apigee 제품을 통해 전송되는 API 요청에 대한 자세한 정보가 포함됩니다. 이는 4XX, 5XX, 지연 시간 문제와 같은 모든 런타임 오류에 유용합니다.
스크린샷 스크린샷은 실제 동작이나 관찰되는 오류의 컨텍스트를 릴레이하는 데 도움이 됩니다. UI 또는 애널리틱스와 같이 관찰된 모든 오류나 문제에 유용합니다.
HAR(Http ARchive) HAR은 모든 UI 관련 문제를 디버깅하기 위해 HTTP 세션 도구에서 캡처한 파일입니다. Chrome, Firefox, Internet Explorer 등의 브라우저를 사용하여 캡처할 수 있습니다.
tcpdumps tcpdump 도구는 네트워크를 통해 전송되거나 수신되는 TCP/IP 패킷을 캡처합니다. 이는 TLS 핸드셰이크 실패, 502 오류, 지연 시간 문제와 같은 네트워크 관련 문제에 유용합니다.

하이브리드를 위한 추가 아티팩트

하이브리드의 경우 문제를 더 빨리 진단하는 데 도움이 되는 아티팩트가 필요할 수 있습니다.

아티팩트 설명
Apigee Hybrid 플랫폼 사용된 다음 지원되는 하이브리드 플랫폼 중 하나를 지정합니다.
  • GKE
  • GKE On-Prem
  • AKS(Azure Kubernetes 서비스)
  • Amazon EKS
  • GKE on AWS
Apigee Hybrid 및 종속 구성요소 버전
  • Apigee Hybrid CLI 버전:
    apigeectl 버전
  • Apigee Connect Agent 버전:
    kubectl -n=apigee get pods -l app=apigee-connect-agent -o=json | jq '.items[].spec.containers[].image'
  • Apigee MART 버전:
    kubectl -n=apigee get pods -l app=apigee-mart -o=json | jq '.items[].spec.containers[].image'
  • Apigee 동기화 담당자 버전:
    kubectl -n=apigee get pods -l app=apigee-synchronizer -o=json | jq '.items[].spec.containers[].image'
  • Apigee Cassandra 버전:
    kubectl -n=apigee get pods -l app=apigee-cassandra -o=json | jq '.items[].spec.containers[].image'
  • Apigee 런타임 버전:
    kubectl -n=apigee get pods -l app=apigee-runtime -o=json | jq '.items[].spec.containers[].image'
  • Kubernetes CLI 및 서버 버전:
    kubectl 버전
  • Istio CLI 및 서버 버전:
    istioctl 버전
네트워크 토폴로지 모든 데이터 센터, Kubernetes 클러스터, 네임스페이스, pod를 포함하여 하이브리드 설정을 설명하는 Apigee 설치 토폴로지 다이어그램입니다.
YAML 파일 재정의 각 데이터 센터에서 Apigee Hybrid 런타임 영역을 설치하는 데 사용되는 overrides.yaml 파일입니다.
Apigee Hybrid 배포 상태

각 데이터 센터/Kubernetes 클러스터에서의 다음 명령어 출력입니다.

kubectl get pods -A
kubectl get services -A

Apigee Hybrid 구성요소 로그

하이브리드 구성요소의 StackDriver 로그 링크 제공하거나,

각 데이터 센터/Kubernetes 클러스터에서 다음 명령어를 사용하여 Apigee Hybrid 구성요소 로그를 가져와 이를 Google과 공유할 수 있습니다.

kubectl -n {namespace} get pods
kubectl -n {namespace} logs {pod-name}

  • Apigee Connect Agent 로그:
    kubectl -n {namespace} get pods
    kubectl -n {namespace} logs {apigee-connect-agent-pod-name}
  • MART 로그:
    kubectl -n {namespace} get pods
    kubectl -n {namespace} logs {apigee-mart-pod-name}
  • 동기화 담당자 로그:
    kubectl -n {namespace} get pods
    kubectl -n {namespace} logs {synchronizer-pod-name}
  • Apigee Cassandra 로그:
    kubectl -n {namespace} get pods
    kubectl -n {namespace} logs {apigee-cassandra-pod-name}
  • MP/Apigee 런타임 로그(모든 Apigee 런타임 pod에 대한):
    kubectl -n {namespace} get pods
    kubectl -n {namespace} logs {apigee-runtime-pod-name}
로그 설명

pod에 관한 자세한 정보입니다.

이는 pod가 CrashLoopBackoff 상태에서 멈춰 있는 등의 문제를 관찰하는 경우에 특히 유용합니다.

kubectl -n apigee describe pod {pod-name}

Cloud Monitoring
  • 측정항목 대시보드 링크입니다.
  • Cloud Monitoring 측정항목과 관련된 대시보드의 스냅샷입니다.

Apigee Hybrid 수집 필요

아래 나열된 명령어에 따라 수집 필요 스크립트를 실행할 수도 있습니다.

###--- "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 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 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 볼 하나로 압축합니다.

	# tar -cvzf /tmp/apigee_hybrid_logs_$(date +%Y.%m.%d_%H.%M).tar.gz /tmp/k_*

tar 파일의 크기가 25MB보다 크면 Google Drive에 업로드하고 링크를 Google과 공유하면 됩니다. 또는 분할 명령어를 사용하여 대용량 파일을 25MB 단위로 분할해 지원 포털에 업로드할 수 있습니다.

	# split -b 25M diagnostic.tar.gz "diagnostic.tar.gz.part"

케이스 템플릿 및 샘플 케이스

이 섹션에서는 이 문서에 설명된 권장사항을 기반으로 다양한 제품의 케이스 템플릿 및 샘플 케이스를 제공합니다.

Apigee Cloud

템플릿

이 섹션에서는 Google Cloud 기반 Apigee용 샘플 템플릿을 제공합니다.

문제:

<고객 측에서 관찰되는 문제 또는 동작에 대한 자세한 설명을 제공합니다. 해당하는 경우 제품 이름 및 버전을 포함합니다.>

오류 메시지:

<확인된 전체 오류 메시지 포함(있는 경우)>

문제 시작 시간 (ISO 8601 형식):

문제 종료 시간 (ISO 8601 형식):

Apigee 설정 세부정보:
  조직 이름:
  환경 이름:
  API 프록시 이름:
  버전 번호:

재현 단계:

<가능한 경우 문제를 재현하기 위한 단계 제공>

진단 정보:

<첨부 파일 목록>

샘플 케이스

이 섹션에서는 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용 샘플 템플릿을 제공합니다.

문제:

<고객 측에서 관찰되는 문제 또는 동작에 대한 자세한 설명을 제공합니다. 해당하는 경우 제품 이름 및 버전을 포함합니다.>

오류 메시지:

<확인된 전체 오류 메시지 포함(있는 경우)>

문제 시작 시간 (ISO 8601 형식):

문제 종료 시간 (ISO 8601 형식):

Apigee Hybrid 설정 세부정보:

  • Apigee Hybrid 플랫폼:

    <하이브리드 및 해당 버전을 설치한 플랫폼에 대한 정보를 제공합니다.>

  • Google Cloud 프로젝트, 하이브리드 조직 및 환경:
      Google Cloud 프로젝트 ID:
      <Google Kubernetes Engine(GKE)을 사용하는 경우 클러스터가 위치한 프로젝트 ID를 제공해야 합니다. GKE On-Prem, Azure Kubernetes Service 또는 Amazon EKS를 사용하는 경우 로그를 전송하는 프로젝트 ID를 제공합니다.>
      Apigee Hybrid 조직:
      Apigee Hybrid 환경:
  • Apigee Hybrid 및 기타 CLI 버전
      Apigee Hybrid CLI(apigeectl) 버전:
      Kubectl 버전:
  • Kubernetes 클러스터 이름 세부정보:
      k8sCluster:
      이름:
      리전:
  • 네트워크 토폴로지:
    <데이터 센터, Kubernetes 클러스터, 네임스페이스, pod를 비롯한 Apigee Hybrid 설정을 설명하는 네트워크 토폴로지를 연결합니다.>
  • 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 PDT부터 시작됩니다.

문제 종료 시간 (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 버전:
        Client 버전:
    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:
      이름: user-cluster-1
      리전: 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 로그
  • 동기화 담당자 로그