이 페이지에서는 몇 가지 일반적인 오류의 해결 방법과 문제 해결 전략을 제공합니다.
Cloud Run for Anthos 문제를 해결할 때는 먼저 컨테이너 이미지를 로컬에서 실행할 수 있는지 확인합니다.
애플리케이션이 로컬에서 실행되고 있지 않으면 진단 후 수정해야 합니다. 배포된 프로젝트를 디버깅하려면 Cloud Logging을 사용하세요.
Cloud Run for Anthos의 문제 해결이 필요한 경우 다음 섹션을 참조하여 문제를 해결할 수 있습니다.
또한 Cloud Run for Anthos에서 알려진 문제 및 이를 해결하는 방법에 대한 자세한 내용은 알려진 문제 페이지를 참조하세요.
명령줄 결과 확인
Google Cloud CLI를 사용하는 경우 명령어 결과에서 명령어 성공 여부를 확인합니다. 예를 들어 배포가 종료에 실패하면 실패 이유를 설명하는 오류 메시지가 표시됩니다.
배포 실패는 잘못 구성된 매니페스트 또는 잘못된 명령어로 인해 발생했을 가능성이 큽니다. 예를 들어 다음 출력에 따르면 경로 트래픽 비율 합계가 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
서비스 로그 확인
Google Cloud 콘솔의 Cloud Logging 또는 Cloud Run for Anthos 페이지에서 요청 로그 및 컨테이너 로그를 확인할 수 있습니다. 자세한 내용은 로깅 및 로그 보기를 참조하세요.
Cloud Logging을 사용하는 경우 필터링해야 하는 리소스는 Kubernetes 컨테이너입니다.
서비스 상태 확인
다음 명령어를 실행하여 배포된 Cloud Run for Anthos 서비스 상태를 확인합니다.
gcloud run services describe SERVICE
--format yaml(status)
또는 --format json(status)
을 추가하여 전체 상태를 가져올 수 있습니다. 예를 들면 다음과 같습니다.
gcloud run 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 서비스는 서비스 버전에 대한 현재 라우팅 상태를 나타내는 경로를 관리합니다.
서비스 상태를 보고 경로의 전체 상태를 확인할 수 있습니다.
gcloud run services describe SERVICE --format 'yaml(status)'
status
의 RoutesReady 조건은 경로의 상태를 제공합니다.
다음 명령어를 실행하여 경로 상태를 더 진단할 수 있습니다.
kubectl get route SERVICE -o yaml
status
의 조건은 실패 이유를 설명합니다. 다음이 이에 해당됩니다.
Ready는 서비스가 구성되었고 사용 가능한 백엔드가 있는지 여부를 나타냅니다.
true
인 경우 경로가 올바르게 구성된 것입니다.AllTrafficAssigned는 서비스가 올바르게 구성되었고 사용 가능한 백엔드가 있는지 여부를 나타냅니다. 이 조건의
status
가True
가 아닌 경우 다음을 수행합니다.서비스 버전 간 트래픽 분할의 합계가 100%인지 확인해 보세요.
gcloud run services describe SERVICE
그렇지 않은 경우
gcloud run services update-traffic
명령어를 사용하여 트래픽 분할을 조정합니다.트래픽을 수신하는 버전이 있는지 버전 상태를 확인해 보세요.
IngressReady는 인그레스가 준비되었는지 여부를 나타냅니다. 이 조건의
status
가True
가 아니면 인그레스 상태를 확인해 보세요.CertificateProvisioned는 Knative 인증서가 프로비저닝되었는지 여부를 나타냅니다. 조건의
status
가True
가 아니면 관리 TLS 문제 해결을 시도해 보세요.
상태 조건에 대한 자세한 내용은 Knative 오류 조건 및 보고를 참조하세요.
인그레스 상태 확인
Cloud Run for Anthos는 클러스터 외부에서 들어오는 트래픽을 처리하는 istio-ingress
라는 부하 분산기 Kubernetes 서비스를 사용합니다.
인그레스의 외부 IP 주소를 가져오려면 다음을 사용합니다.
kubectl get svc istio-ingress -n gke-system
EXTERNAL-IP
가 pending
인 경우 아래의 외부 IP가 장기간 pending
상태임을 참조하세요.
버전 상태 확인
Cloud Run for Anthos 서비스의 최신 버전을 가져오려면 다음 명령어를 실행합니다.
gcloud run services describe SERVICE --format='value(status.latestCreatedRevisionName)'
다음 명령어를 실행하여 특정 Cloud Run for Anthos 버전의 상태를 확인합니다.
gcloud run revisions describe REVISION
--format yaml(status)
또는 --format json(status)
을 추가하여 전체 상태를 가져올 수 있습니다.
gcloud run revisions describe REVISION --format yaml(status)
status
의 조건은 실패 이유를 설명합니다. 다음이 이에 해당됩니다.
- Ready는 런타임 리소스가 준비되었는지 여부를 나타냅니다.
true
인 경우 버전이 올바르게 구성된 것입니다. - ResourcesAvailable은 기본 Kubernetes 리소스가 프로비저닝되었는지 여부를 나타냅니다.
이 조건의
status
가True
가 아니면 Pod 상태를 확인해 보세요. - ContainerHealthy는 버전 준비 검사가 완료되었는지 나타냅니다.
이 조건의
status
가True
가 아니면 Pod 상태를 확인해 보세요. - Active는 버전이 트래픽을 수신하는지 여부를 나타냅니다.
이러한 조건의 status
가 True
가 아니면 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
를 자세히 알아보려면 다음 명령어 중 하나를 사용하세요. 유용한 필드는 conditions
및 containerStatuses
입니다.
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 콘솔의 IAM 및 관리자 페이지로 이동하여 추가 할당량을 요청할 수 있습니다.
게이트웨이는 외부 IP 주소가 할당될 때까지 계속 시도합니다. 몇 분 정도 걸릴 수 있습니다.
관리형 TLS 문제 해결
아래의 문제 해결 단계를 사용하여 관리형 TLS 인증서 기능의 일반적인 문제를 해결하세요.
특정 도메인 매핑의 상태 확인
특정 도메인 매핑의 상태를 확인하려면 다음 안내를 따르세요.
다음 명령어를 실행합니다.
gcloud run domain-mappings describe --domain DOMAIN --namespace NAMESPACE
다음과 같이 바꿉니다.
- DOMAIN을 사용 중인 도메인 이름으로 바꿉니다.
- NAMESPACE를 도메인 매핑에 사용하는 네임스페이스로 바꿉니다.
이 명령어의
yaml
결과에서CertificateProvisioned
필드의 조건을 검사하여 오류의 본질을 파악할 수 있습니다.표시된 오류가 있다면 아래 표에 나와 있는 오류 중 하나와 일치해야 합니다. 표에 나와 있는 제안사항에 따라 문제를 해결하세요.
사용자 구성 오류
오류 코드 | 세부 메시지 | 문제 해결 안내 | |
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에서 요청을 제공할 수 없는 경우에 발생할 수 있습니다. |
|
시스템 오류
오류 코드 | 세부 메시지 | 문제 해결 안내 |
OrderErrored
AuthzErrored ChallengeErrored |
이러한 3가지 유형의 오류는 Let's Encrypt에서 도메인 소유권 확인이 실패하는 경우 발생합니다. 이러한 오류는 일반적으로 일시적 오류이며 Cloud Run for Anthos에서 다시 시도합니다. 재시도 지연 시간은 최소 8초에서 최대 8시간까지 차이가 큽니다. 오류를 수동으로 재시도하려면 실패한 주문을 수동으로 삭제하면 됩니다.
|
|
ACMEAPIFailed | 이러한 유형의 오류는 Cloud Run for Anthos가 Let's Encrypt 호출에 실패할 경우에 발생합니다. 일반적으로 일시적 오류이며 Cloud Run for Anthos에서 재시도합니다.
오류를 수동으로 재시도하려면 실패한 주문을 수동으로 삭제하세요.
|
|
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분 후에 만료됩니다.
도메인 매핑 상태를 확인합니다. 시간 초과의 경우 상태 출력에서 다음과 같은 오류 메시지를 찾습니다.
order (test.example.com) timed out (20.0 minutes)
시간 초과 문제의 일반적인 원인은 사용 중인 도메인을
gke-system
의istio-ingress
서비스 IP 주소에 매핑하도록 DNS 레코드가 올바르게 구성되지 않았기 때문입니다. 다음 명령어를 실행하여 DNS 레코드를 확인합니다.host DOMAIN
다음 명령어를 실행하여
gke-system
에서istio-ingress
서비스의 외부 IP 주소를 확인합니다.kubectl get svc istio-ingress -n gke-system
도메인의 외부 IP 주소가 인그레스 IP 주소와 일치하지 않는 경우 올바른 IP 주소에 매핑되도록 DNS 레코드를 다시 구성합니다.
(업데이트된) DNS 레코드가 적용되면 다음 명령어를 실행하여 주문 객체를 삭제하고 TLS 인증서 요청 프로세스를 다시 트리거합니다.
kubectl delete order DOMAIN -n NAMESPACE
다음과 같이 바꿉니다.
- DOMAIN을 사용 중인 도메인 이름으로 바꿉니다.
- NAMESPACE를 사용된 네임스페이스로 바꿉니다.
승인 실패
승인 실패는 DNS 레코드가 적시에 전역적으로 전파되지 않을 때 발생할 수 있습니다. 따라서 Let's Encrypt는 도메인 소유권을 확인할 수 없습니다.
주문 상태를 확인합니다. 상태의
acmeAuthorizations
필드에서 승인 링크를 찾습니다. URL은 다음과 같이 표시됩니다.https://acme-v02.api.letsencrypt.org/acme/authz-v3/1717011827
링크를 엽니다. 다음과 비슷한 메시지가 표시됩니다.
urn:ietf:params:acme:error:dns
이 경우 문제의 원인은 불완전한 DNS 전파입니다.
DNS 전파 오류를 해결하려면 다음 안내를 따르세요.
- 다음 명령어를 실행하여
gke-system
에서istio-ingress
서비스의 외부 IP를 가져옵니다.kubectl get svc istio-ingress -n gke-system
다음 명령어를 실행하여 도메인에 대한 DNS 레코드를 확인합니다.
host DOMAIN
DNS 레코드의 IP 주소가
gke-system
에서istio-ingress
서비스의 외부 IP와 일치하지 않으면 사용자의 도메인을 외부 IP에 매핑하도록 DNS 레코드를 구성합니다.(업데이트된) 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_pilot
이 VirtualServices
를 조정하고 인그레스 게이트웨이로 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-cluster-local-gateway-tb
namespace: gke-system
spec:
workloadSelector:
labels:
istio: ingress-gke-system
configPatches:
- applyTo: NETWORK_FILTER
match:
listener:
portNumber: 8081
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