Cloud Run for Anthos on Google Cloud 문제 해결

이 페이지에서는 몇 가지 일반적인 오류의 해결 방법과 문제 해결 전략을 제공합니다.

Cloud Run for Anthos on Google Cloud 문제를 해결할 때는 먼저 컨테이너 이미지를 로컬에서 실행할 수 있는지 확인합니다.

애플리케이션이 로컬에서 실행되고 있지 않으면 진단 후 수정해야 합니다. 배포된 프로젝트를 디버깅하려면 Cloud Logging을 사용하세요.

Cloud Run for Anthos on Google Cloud의 문제 해결이 필요한 경우 다음 섹션을 참조하여 문제를 해결할 수 있습니다.

명령줄 결과 확인

gcloud 명령줄 도구를 사용하는 경우 명령어 결과를 통해 성공 여부를 확인합니다. 예를 들어 배포가 종료에 실패하면 실패 이유를 설명하는 오류 메시지가 표시됩니다.

배포 실패는 잘못 구성된 매니페스트 또는 잘못된 명령어로 인해 발생했을 가능성이 큽니다. 예를 들어 다음 출력에 따르면 경로 트래픽 비율 합계가 100이 되도록 구성해야 합니다.

Error from server (InternalError): error when applying patch:</p><pre>{"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"serving.knative.dev/v11\",\"kind\":\"Route\",\"metadata\":{\"annotations\":{},\"name\":\"route-example\",\"namespace\":\"default\"},\"spec\":{\"traffic\":[{\"configurationName\":\"configuration-example\",\"percent\":50}]}}\n"}},"spec":{"traffic":[{"configurationName":"configuration-example","percent":50}]}}
to:
&{0xc421d98240 0xc421e77490 default route-example STDIN 0xc421db0488 264682 false}
for: "STDIN": Internal error occurred: admission webhook "webhook.knative.dev" denied the request: mutation failed: The route must have traffic percent sum equal to 100.
ERROR: Non-zero return code '1' from command: Process exited with status 1

서비스 로그 확인

Cloud Console에서 Cloud Logging 또는 Cloud Run for Anthos on Google Cloud 페이지를 사용하여 요청 로그 및 컨테이너 로그를 확인할 수 있습니다. 자세한 내용은 로깅 및 로그 보기를 참조하세요.

Cloud Logging을 사용하는 경우 필터링해야 하는 리소스는 Kubernetes 컨테이너입니다.

서비스 상태 확인

다음 명령어를 실행하여 배포된 Cloud Run for Anthos on Google Cloud 서비스의 상태를 가져옵니다.

gcloud kuberun core services describe SERVICE

--format yaml(status) 또는 --format json(status)을 추가하여 전체 상태를 가져올 수 있습니다. 예를 들면 다음과 같습니다.

gcloud kuberun core services describe SERVICE --format 'yaml(status)'

status의 조건을 통해 실패 원인을 찾을 수 있습니다. 조건에는 True, False 또는 Unknown이 포함될 수 있습니다.

  • Ready: True는 서비스가 구성되어 트래픽을 수신할 준비가 되었음을 나타냅니다.
  • ConfigurationReady: True는 기본 구성이 준비되었음을 나타냅니다. False 또는 'Unknown'의 경우 최신 버전의 상태를 확인해야 합니다.
  • RoutesReady: True는 기본 경로가 준비되었음을 나타냅니다. False 또는 'Unknown'의 경우 경로의 상태를 확인해야 합니다.

상태 조건에 대한 자세한 내용은 Knative 오류 신호를 참조하세요.

경로 상태 확인

각 Cloud Run for Anthos on Google Cloud 서비스는 서비스 버전에 대한 현재 라우팅 상태를 나타내는 경로를 관리합니다.

서비스 상태를 보고 경로의 전체 상태를 확인할 수 있습니다.

gcloud kuberun core services describe SERVICE --format 'yaml(status)'

statusRoutesReady 조건은 경로의 상태를 제공합니다.

다음 명령어를 실행하여 경로 상태를 더 진단할 수 있습니다.

kubectl get route SERVICE -o yaml

status의 조건은 실패 이유를 설명합니다. 다음이 이에 해당됩니다.

  • Ready는 서비스가 구성되었고 사용 가능한 백엔드가 있는지 여부를 나타냅니다. true인 경우 경로가 올바르게 구성된 것입니다.

  • AllTrafficAssigned는 서비스가 올바르게 구성되었고 사용 가능한 백엔드가 있는지 여부를 나타냅니다. 이 조건의 statusTrue가 아닌 경우 다음을 수행합니다.

    • 서비스 버전 간 트래픽 분할의 합계가 100%인지 확인해 보세요.

      gcloud kuberun core services describe SERVICE

      그렇지 않은 경우 gcloud kuberun core services update-traffic 명령어를 사용하여 트래픽 분할을 조정합니다.

    • 트래픽을 수신하는 버전이 있는지 버전 상태를 확인해 보세요.

  • IngressReady는 인그레스가 준비되었는지 여부를 나타냅니다. 이 조건의 statusTrue가 아니면 인그레스 상태를 확인해 보세요.

  • CertificateProvisioned는 Knative 인증서가 프로비저닝되었는지 여부를 나타냅니다. 조건의 statusTrue가 아니면 관리 TLS 문제 해결을 시도해 보세요.

상태 조건에 대한 자세한 내용은 Knative 오류 조건 및 보고를 참조하세요.

인그레스 상태 확인

Cloud Run for Anthos on Google Cloud는 클러스터 외부에서 들어오는 트래픽을 처리하는 istio-ingress라는 부하 분산기 Kubernetes 서비스를 사용합니다.

인그레스의 외부 IP 주소를 가져오려면 다음을 사용합니다.

kubectl get svc istio-ingress -n gke-system

EXTERNAL-IPpending인 경우 아래의 외부 IP가 장기간 pending 상태임을 참조하세요.

버전 상태 확인

Google Cloud의 Cloud Run for Anthos 서비스의 최신 버전을 가져오려면 다음 명령어를 실행하세요.

gcloud kuberun core services describe SERVICE --format='value(status.latestCreatedRevisionName)'

다음 명령어를 실행하여 특정 Cloud Run for Anthos on Google Cloud 버전의 상태를 가져옵니다.

gcloud kuberun core revisions describe REVISION

--format yaml(status) 또는 --format json(status)을 추가하여 전체 상태를 가져올 수 있습니다.

gcloud kuberun core revisions describe REVISION --format yaml(status)

status의 조건은 실패 이유를 설명합니다. 다음이 이에 해당됩니다.

  • Ready는 런타임 리소스가 준비되었는지 여부를 나타냅니다. true인 경우 버전이 올바르게 구성된 것입니다.
  • ResourcesAvailable은 기본 Kubernetes 리소스가 프로비저닝되었는지 여부를 나타냅니다. 이 조건의 statusTrue가 아니면 Pod 상태를 확인해 보세요.
  • ContainerHealthy는 버전 준비 검사가 완료되었는지 나타냅니다. 이 조건의 statusTrue가 아니면 Pod 상태를 확인해 보세요.
  • Active는 버전이 트래픽을 수신하는지 여부를 나타냅니다.

이러한 조건의 statusTrue가 아니면 Pod 상태를 확인해 보세요.

Pod 상태 확인

모든 배포의 Pod를 가져오려면 다음 명령어를 실행하세요.

kubectl get pods

이렇게 하면 모든 Pod의 상태가 간략하게 나열됩니다. 예를 들면 다음과 같습니다.

NAME                                                      READY     STATUS             RESTARTS   AGE
configuration-example-00001-deployment-659747ff99-9bvr4   2/2       Running            0          3h
configuration-example-00002-deployment-5f475b7849-gxcht   1/2       CrashLoopBackOff   2          36s

이러한 status를 자세히 알아보려면 다음 명령어 중 하나를 사용하세요. 유용한 필드는 conditionscontainerStatuses입니다.

kubectl get pod POD-NAME -o yaml

외부 IP가 장시간 <pending> 상태임

클러스터를 만든 직후 외부 IP 주소를 가져올 수 없는 경우 외부 IP가 pending으로 표시될 수 있습니다. 예를 들어 다음 명령어를 호출하여 이 문제를 확인할 수 있습니다.

Istio 인그레스 게이트웨이의 외부 IP를 가져오려면 다음 안내를 따르세요.

kubectl get svc istio-ingress -n gke-system

여기서 결과 출력은 다음과 같이 표시됩니다.

NAME            TYPE           CLUSTER-IP     EXTERNAL-IP  PORT(S)
istio-ingress   LoadBalancer   XX.XX.XXX.XX   pending      80:32380/TCP,443:32390/TCP,32400:32400/TCP

부하 분산기의 EXTERNAL-IP는 반드시 사용해야 하는 IP 주소입니다.

즉, Google Cloud의 외부 IP 주소 할당량을 모두 사용했을 수 있습니다. 다음을 호출하여 가능한 원인을 확인할 수 있습니다.

kubectl describe svc istio-ingress -n gke-system

이렇게 하면 다음과 비슷한 출력이 표시됩니다.

Name:                     istio-ingress
Namespace:                gke-system
Labels:                   addonmanager.kubernetes.io/mode=Reconcile
                          app=istio-ingress
                          chart=gateways-1.0.3
                          heritage=Tiller
                          istio=ingress-gke-system
                          k8s-app=istio
                          kubernetes.io/cluster-service=true
                          release=istio
Annotations:              kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"addonmanager.kubernetes.io/mode":"Reconcile","app":"istio-ingressgateway","...
Selector:                 app=ingressgateway,istio=ingress-gke-system,release=istio
Type:                     LoadBalancer
IP:                       10.XX.XXX.XXX
LoadBalancer Ingress:     35.XXX.XXX.188
Port:                     http2  80/TCP
TargetPort:               80/TCP
NodePort:                 http2  31380/TCP
Endpoints:                XX.XX.1.6:80
Port:                     https  443/TCP
TargetPort:               443/TCP
NodePort:                 https  3XXX0/TCP
Endpoints:                XX.XX.1.6:XXX
Port:                     tcp  31400/TCP
TargetPort:               3XX00/TCP
NodePort:                 tcp  3XX00/TCP
Endpoints:                XX.XX.1.6:XXXXX
Port:                     tcp-pilot-grpc-tls  15011/TCP
TargetPort:               15011/TCP
NodePort:                 tcp-pilot-grpc-tls  32201/TCP
Endpoints:                XX.XX.1.6:XXXXX
Port:                     tcp-citadel-grpc-tls  8060/TCP
TargetPort:               8060/TCP
NodePort:                 tcp-citadel-grpc-tls  31187/TCP
Endpoints:                XX.XX.1.6:XXXX
Port:                     tcp-dns-tls  853/TCP
TargetPort:               XXX/TCP
NodePort:                 tcp-dns-tls  31219/TCP
Endpoints:                10.52.1.6:853
Port:                     http2-prometheus  15030/TCP
TargetPort:               XXXXX/TCP
NodePort:                 http2-prometheus  30944/TCP
Endpoints:                10.52.1.6:15030
Port:                     http2-grafana  15031/TCP
TargetPort:               XXXXX/TCP
NodePort:                 http2-grafana  31497/TCP
Endpoints:                XX.XX.1.6:XXXXX
Session Affinity:         None
External Traffic Policy:  Cluster
Events:
  Type    Reason                Age                  From                Message
  ----    ------                ----                 ----                -------
  Normal  EnsuringLoadBalancer  7s (x4318 over 15d)  service-controller  Ensuring load balancer

출력에 IN_USE_ADDRESSES 할당량이 초과되었다는 표시가 있으면 Google Cloud Console의 IAM 및 관리자 페이지로 이동하여 추가 할당량을 요청할 수 있습니다.

게이트웨이는 외부 IP 주소가 할당될 때까지 계속 시도합니다. 몇 분 정도 걸릴 수 있습니다.

관리형 TLS 문제 해결

아래의 문제 해결 단계를 사용하여 관리형 TLS 인증서 기능의 일반적인 문제를 해결하세요.

특정 도메인 매핑의 상태 확인

특정 도메인 매핑의 상태를 확인하려면 다음 안내를 따르세요.

  1. 다음 명령어를 실행합니다.

    gcloud kuberun core domain-mappings describe DOMAIN --namespace NAMESPACE

    다음과 같이 바꿉니다.

    • DOMAIN을 사용 중인 도메인 이름으로 바꿉니다.
    • NAMESPACE를 도메인 매핑에 사용하는 네임스페이스로 바꿉니다.
  2. 이 명령어의 yaml 결과에서 CertificateProvisioned 필드의 조건을 검사하여 오류의 본질을 파악할 수 있습니다.

  3. 표시된 오류가 있다면 아래 표에 나와 있는 오류 중 하나와 일치해야 합니다. 표에 나와 있는 제안사항에 따라 문제를 해결하세요.

사용자 구성 오류

오류 코드 세부 메시지 문제 해결 안내
DNSErrored DNS 레코드가 올바르게 구성되지 않았습니다. [XXX] 도메인을 IP XX.XX.XX.XX에 매핑해야 합니다. 제공된 안내에 따라 DNS 레코드를 올바르게 구성합니다.
RateLimitExceeded acme: urn:ietf:params:acme:error:rateLimited: 새 주문을 만드는 중에 오류가 발생했습니다.

:: 이미 같은 도메인 집합에 대해 발급된 인증서가 너무 많습니다.

test.example.com:

https://letsencrypt.org/docs/rate-limits/를 참조하세요.

해당 호스트의 인증서 할당량을 늘리려면 Let's Encrypt에 문의하세요.
InvalidDomainMappingName DomainMapping 이름 %s은 경로 URL 호스트 %s와 같을 수 없습니다. DomainMapping 이름은 매핑되는 경로의 호스트와 정확히 같을 수 없습니다. DomainMapping 이름에 다른 도메인을 사용하세요.
ChallengeServingErrored 시스템에서 HTTP01 요청을 제공할 수 없습니다. 이 오류는 istio-ingress 서비스가 도메인 소유권 검증을 위해 Let's Encrypt에서 요청을 제공할 수 없는 경우에 발생할 수 있습니다.
  1. Virtual Private Cloud를 사용하지 않고 공개 인터넷에서 istio-ingress 서비스에 액세스할 수 있는지 확인합니다.
  2. istio-ingress 서비스가 URL http://DOMAIN/.well-known/acme-challenge/...의 요청을 허용하는지 확인합니다. 여기서 DOMAIN은 유효성 검사 중인 도메인입니다.

시스템 오류

오류 코드 세부 메시지 문제 해결 안내
OrderErrored

AuthzErrored

ChallengeErrored

이러한 3가지 유형의 오류는 Let's Encrypt에서 도메인 소유권 확인이 실패하는 경우 발생합니다.

이러한 오류는 일반적으로 일시적 오류이며 Cloud Run for Anthos에서 다시 시도합니다.

재시도 지연 시간은 최소 8초에서 최대 8시간까지 차이가 큽니다.

오류를 수동으로 재시도하려면 실패한 주문을 수동으로 삭제하면 됩니다.

kubectl delete order DOMAIN -n NAMESPACE

ACMEAPIFailed 이러한 유형의 오류는 Cloud Run for Anthos가 Let's Encrypt 호출에 실패할 경우에 발생합니다. 일반적으로 일시적 오류이며 Cloud Run for Anthos에서 재시도합니다.

오류를 수동으로 재시도하려면 실패한 주문을 수동으로 삭제하세요.

kubectl delete order DOMAIN -n NAMESPACE

UnknownErrored 이 오류는 알 수 없는 시스템 오류를 표시하며 이는 GKE 클러스터에서 매우 드물게 발생합니다. 이러한 오류가 표시되는 경우 Cloud 지원팀에 문의하여 디버깅에 대한 지원을 받으세요.

주문 상태 확인

주문 상태는 Let's Encrypt와 상호작용하는 과정을 기록하므로 Let's Encrypt와 관련된 문제를 디버깅하는 데 사용할 수 있습니다. 필요한 경우 다음 명령어를 실행하여 주문 상태를 확인합니다.

kubectl get order DOMAIN -n NAMESPACE -oyaml

다음과 같이 바꿉니다.

  • DOMAIN을 사용 중인 도메인 이름으로 바꿉니다.
  • NAMESPACE를 도메인 매핑에 사용하는 네임스페이스로 바꿉니다.

주문이 성공하면 결과에는 발급된 인증서 및 기타 정보가 포함됩니다.

Let's Encrypt 할당량 초과

DomainMapping 상태를 확인합니다. Let's Encrypt 할당량을 초과하는 경우 DomainMapping에 다음과 같은 오류 메시지가 표시됩니다.

acme: urn:ietf:params:acme:error:rateLimited: Error creating new order
:: too many certificates already issued for exact set of domains:
test.example.com:
see https://letsencrypt.org/docs/rate-limits/'

인증서 할당량을 늘리려면 비율 제한에 대한 Let's Encrypt 문서를 참조하세요.

주문 시간 초과

계속 인증서를 가져올 수 없으면 주문 객체는 20분 후에 만료됩니다.

  1. 도메인 매핑 상태를 확인합니다. 시간 초과의 경우 상태 출력에서 다음과 같은 오류 메시지를 찾습니다.

    order (test.example.com) timed out (20.0 minutes)
  2. 시간 초과 문제의 일반적인 원인은 사용 중인 도메인을 gke-systemistio-ingress 서비스 IP 주소에 매핑하도록 DNS 레코드가 올바르게 구성되지 않았기 때문입니다. 다음 명령어를 실행하여 DNS 레코드를 확인합니다.

    host DOMAIN
  3. 다음 명령어를 실행하여 gke-system에서 istio-ingress 서비스의 외부 IP 주소를 확인합니다.

    kubectl get svc istio-ingress -n gke-system

    도메인의 외부 IP 주소가 인그레스 IP 주소와 일치하지 않는 경우 올바른 IP 주소에 매핑되도록 DNS 레코드를 다시 구성합니다.

  4. (업데이트된) DNS 레코드가 적용되면 다음 명령어를 실행하여 주문 객체를 삭제하고 TLS 인증서 요청 프로세스를 다시 트리거합니다.

    kubectl delete order DOMAIN -n NAMESPACE

    다음과 같이 바꿉니다.

    • DOMAIN을 사용 중인 도메인 이름으로 바꿉니다.
    • NAMESPACE를 사용된 네임스페이스로 바꿉니다.

승인 실패

승인 실패는 DNS 레코드가 적시에 전역적으로 전파되지 않을 때 발생할 수 있습니다. 따라서 Let's Encrypt는 도메인 소유권을 확인할 수 없습니다.

  1. 주문 상태를 확인합니다. 상태의 acmeAuthorizations 필드에서 승인 링크를 찾습니다. URL은 다음과 같이 표시됩니다.

    https://acme-v02.api.letsencrypt.org/acme/authz-v3/1717011827
  2. 링크를 엽니다. 다음과 비슷한 메시지가 표시됩니다.

    urn:ietf:params:acme:error:dns

    이 경우 문제의 원인은 불완전한 DNS 전파입니다.

  3. DNS 전파 오류를 해결하려면 다음 안내를 따르세요.

    1. 다음 명령어를 실행하여 gke-system에서 istio-ingress 서비스의 외부 IP를 가져옵니다.
      kubectl get svc istio-ingress -n gke-system
    2. 다음 명령어를 실행하여 도메인에 대한 DNS 레코드를 확인합니다.

      host DOMAIN

      DNS 레코드의 IP 주소가 gke-system에서 istio-ingress 서비스의 외부 IP와 일치하지 않으면 사용자의 도메인을 외부 IP에 매핑하도록 DNS 레코드를 구성합니다.

    3. (업데이트된) DNS 레코드가 적용되면 다음 명령어를 실행하여 주문 객체를 삭제하고 TLS 인증서 요청 프로세스를 다시 트리거합니다.

      kubectl delete order DOMAIN -n NAMESPACE

    다음과 같이 바꿉니다.

    • DOMAIN을 사용 중인 도메인 이름으로 바꿉니다.
    • NAMESPACE를 도메인 매핑에 사용하는 네임스페이스로 바꿉니다.

비공개 클러스터 배포 실패: 웹훅 오류 호출 실패

다음 메시지와 함께 비공개 클러스터에 대한 배포가 실패한 경우 방화벽이 제대로 설정되지 않았을 수 있습니다.

Error: failed calling webhook "webhook.serving.knative.dev": Post
https://webhook.knative-serving.svc:443/?timeout=30s: context deadline exceeded (Client.Timeout
exceeded while awaiting headers)

비공개 클러스터에 대한 배포를 지원하는 데 필요한 방화벽 변경사항에 대한 자세한 내용은 비공개 클러스터에서 배포 사용 설정을 참조하세요.

IngressNotConfigured의 서비스 보고서 상태

서비스 상태로 IngressNotConfigured가 표시되면 gke-system 네임스페이스에서 istio-pilot 배포를 다시 시작해야 할 수 있습니다. kubernetes 1.14에서 자주 발생했었던 이 오류는 istio_pilotVirtualServices를 조정하고 인그레스 게이트웨이로 envoy 구성을 푸시하기 시작하기 전에 서비스가 생성된 경우에 발생할 수 있습니다.

이 문제를 해결하려면 배포를 수평 축소한 후 다음과 비슷한 명령어를 사용하여 다시 수평 확장하세요.

kubectl scale deployment istio-pilot -n gke-system --replicas=0
kubectl scale deployment istio-pilot -n gke-system --replicas=1

요청 수 및 요청 지연 시간 측정항목 누락

워크로드 아이덴티티를 사용 설정하고 서비스에서 사용하는 서비스 계정에 특정 권한을 부여하지 않은 경우 서비스에서 버전 요청 수 및 요청 지연 시간 측정항목을 보고하지 않을 수 있습니다.

워크로드 아이덴티티로 클러스터의 측정항목 사용 설정 섹션의 단계에 따라 이 문제를 해결할 수 있습니다.

커스텀 도메인과 함께 WebSocket 사용

기본적으로 커스텀 도메인 매핑에는 WebSocket이 사용 중지됩니다.

커스텀 도메인에 WebSocket을 사용 설정하려면 다음 명령어를 실행하여 allow_connect: true로 Istio EnvoyFilter 객체를 만듭니다.

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: allowconnect-cluser-local-gateway
  namespace: gke-system
spec:
  workloadSelector:
    labels:
      app: cluster-local-gateway
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      listener:
        portNumber: 80
        filterChain:
          filter:
            name: "envoy.http_connection_manager"
    patch:
      operation: MERGE
      value:
        typed_config:
          "@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"
          http2_protocol_options:
            allow_connect: true
EOF