Résoudre les problèmes liés à Cloud Run pour Anthos sur Google Cloud

Cette page présente des stratégies de dépannage et des solutions pour certaines erreurs courantes.

Lors de la résolution de problèmes liés à Cloud Run pour Anthos sur Google Cloud, vérifiez d'abord que vous pouvez exécuter votre image de conteneur localement.

Si votre application ne s'exécute pas localement, vous devrez diagnostiquer et résoudre le problème. Pour déboguer un projet déployé, vous devez utiliser Cloud Logging.

Lors de la résolution de problèmes liés à Cloud Run pour Anthos sur Google Cloud, consultez les sections suivantes afin de trouver des solutions possibles.

Vérifier le résultat de la ligne de commande

Si vous utilisez l'outil de ligne de commande gcloud, vérifiez le résultat de votre commande pour voir si elle a réussi ou non. Par exemple, si votre déploiement a échoué, un message d'erreur décrivant la raison de l'échec devrait être affiché.

Les échecs de déploiement sont probablement dus à un manifeste mal configuré ou à une commande incorrecte. Par exemple, le résultat suivant indique que vous devez configurer le pourcentage de trafic acheminé pour que le total soit égal à 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

Vérifier les journaux de votre service

Vous pouvez utiliser Cloud Logging ou la page "Cloud Run for Anthos sur Google Cloud" de Cloud Console pour vérifier les journaux de requêtes et les journaux du conteneur. Pour plus de précisions, consultez la page Journaliser et afficher les journaux.

Si vous utilisez Cloud Logging, la ressource sur laquelle vous devez filtrer est Conteneur Kubernetes.

Vérifier l'état du service

Exécutez la commande suivante pour obtenir l'état d'un service Cloud Run for Anthos déployé sur Google Cloud :

gcloud kuberun core services describe SERVICE

Vous pouvez ajouter --format yaml(status) ou --format json(status) pour obtenir l'état complet, par exemple :

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

Les conditions dans status peuvent vous aider à déterminer la cause de l'échec. Les conditions peuvent inclure True, False ou Unknown :

Pour en savoir plus sur les conditions d'état, consultez la section Signalement d'erreur Knative.

Vérifier l'état de la route

Chaque service Cloud Run for Anthos sur Google Cloud gère une route qui représente l'état de routage actuel par rapport aux révisions du service.

Pour vérifier l'état général de la route, consultez l'état du service :

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

La condition RoutesReady dans status indique l'état de la route.

Vous pouvez analyser plus en détail l'état de la route en exécutant la commande suivante :

kubectl get route SERVICE -o yaml

Les conditions dans status fournissent le motif d'un échec. par exemple les éléments suivants :

  • Ready indique si le service est configuré et dispose de backends disponibles. Si la valeur est true, la route est configurée correctement.

  • AllTrafficAssigned indique si le service est configuré correctement et dispose de backends disponibles. Si status de cette condition n'est pas défini sur True :

  • IngressReady indique que l'entrée est prête. Si status de cette condition n'est pas défini sur True, vérifiez l'état d'entrée.

  • CertificateProvisioned indique si les certificats Knative ont été provisionnés. Si status de cette condition n'est pas défini sur True, essayez de résoudre les problèmes liés aux certificats TLS gérés.

Pour en savoir plus sur les conditions d'état, consultez la section Création de rapports et conditions d'erreur Knative.

Vérifier l'état de l'entrée

Cloud Run for Anthos sur Google Cloud utilise un service d'équilibrage de charge Kubernetes appelé istio-ingress qui gère le trafic entrant depuis l'extérieur du cluster.

Pour obtenir l'adresse IP externe de votre entrée, utilisez :

kubectl get svc istio-ingress -n gke-system

Si le champ EXTERNAL-IP est défini sur pending, consultez ci-dessous la section EXTERNAL-IP est pending pendant longtemps.

Vérifier l'état de la révision

Pour obtenir la dernière révision pour votre service Cloud Run for Anthos sur Google Cloud, exécutez la commande suivante :

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

Exécutez la commande suivante pour obtenir l'état d'une révision Cloud Run for Anthos spécifique sur Google Cloud :

gcloud kuberun core revisions describe REVISION

Vous pouvez ajouter --format yaml(status) ou --format json(status) pour obtenir l'état complet :

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

Les conditions dans status fournissent les raisons d'un échec. par exemple les éléments suivants :

  • Ready indique si les ressources d'environnement d'exécution sont prêtes. Si la valeur est true, la révision est configurée correctement.
  • ResourcesAvailable indique si les ressources Kubernetes sous-jacentes ont été provisionnées. Si status de cette condition n'est pas défini sur True, vérifiez l'état du pod.
  • ContainerHealthy indique si la vérification de préparation de la révision est terminée. Si status de cette condition n'est pas défini sur True, vérifiez l'état du pod.
  • Active : indique si la révision reçoit du trafic.

Si l'un des status de ces conditions n'est pas défini sur True, vérifiez l'état du pod.

Vérifier l'état du pod

Pour obtenir les pods de tous vos déploiements, exécutez la commande suivante :

kubectl get pods

Ceci devrait répertorier tous les pods dont l'état est bref. Exemple :

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

Choisissez-en un et utilisez la commande suivante pour afficher des informations détaillées sur son status. Voici quelques champs conditions et containerStatuses utiles :

kubectl get pod POD-NAME -o yaml

EXTERNAL-IP affiche l'état <pending> depuis longtemps

Parfois, il est possible que vous ne receviez pas d'adresse IP externe immédiatement après la création d'un cluster, mais qu'une adresse IP externe apparaisse avec l'état pending. Par exemple, cela peut se produire en appelant la commande suivante :

Pour obtenir l'adresse IP externe de la passerelle d'entrée Istio, exécutez la commande suivante :

kubectl get svc istio-ingress -n gke-system

où le résultat ressemble à ce qui suit :

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

La valeur EXTERNAL-IP de l'équilibreur de charge est l'adresse IP que vous devez utiliser.

Cela peut signifier que vous avez épuisé votre quota d'adresses IP externes dans Google Cloud. Vous pouvez vérifier la cause possible en appelant la commande suivante :

kubectl describe svc istio-ingress -n gke-system

Un résultat semblable à celui-ci doit s'afficher :

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

Si le résultat indique que le quota IN_USE_ADDRESSES a été dépassé, vous pouvez demander un quota supplémentaire en accédant à la page IAM et admin de Google Cloud Console.

La passerelle poursuivra les tentatives jusqu'à ce qu'une adresse IP externe soit attribuée. Cette opération peut prendre quelques minutes.

Résoudre les problèmes liés aux certificats TLS gérés

Suivez les étapes de dépannage ci-dessous pour résoudre les problèmes généraux liés à la fonctionnalité de certificats TLS gérés.

Vérifier l'état d'un mappage de domaine spécifique

Pour vérifier l'état d'un mappage de domaine spécifique, procédez comme suit :

  1. Exécutez la commande suivante :

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

    Remplacer

    • DOMAIN par le nom du domaine que vous utilisez ;
    • NAMESPACE par l'espace de noms que vous utilisez pour le mappage de domaine.
  2. Dans les résultats yaml de cette commande, examinez la condition du champ CertificateProvisioned pour déterminer la nature de l'erreur.

  3. Si une erreur s'affiche, elle doit correspondre à l'une des erreurs répertoriées dans les tableaux ci-dessous. Pour résoudre le problème, suivez les instructions figurant dans les tableaux.

Erreurs de configuration utilisateur

Code d'erreur Message détaillé Instructions de dépannage
DNSErrored DNS record is not configured correctly. Need to map domain [XXX] to IP XX.XX.XX.XX (L'enregistrement DNS n'est pas configuré correctement. Associez le domaine [XXX] à l'adresse IP XX.XX.XX.XX) Suivez les instructions fournies pour configurer correctement l'enregistrement DNS.
RateLimitExceeded 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/ (la commande a été rejetée car un trop grand nombre de certificats a déjà été généré pour cet ensemble exact de domaines : test.example.com)

Contactez Let's Encrypt afin d'augmenter le quota de certificats pour cet hôte.
InvalidDomainMappingName DomainMapping name %s cannot be the same as Route URL host %s. Le nom DomainMapping ne peut pas être exactement le même que celui de l'hôte de la route vers lequel il est mappé. Utilisez un domaine différent pour le nom DomainMapping.
ChallengeServingErrored System failed to serve HTTP01 request (Le système n'a pas réussi à répondre à la requête HTTP01). Cette erreur peut se produire si le service istio-ingress ne parvient pas à traiter la requête de Let's Encrypt pour valider la propriété du domaine.
  1. Assurez-vous que votre service istio-ingress est accessible depuis l'Internet public sans utiliser le cloud privé virtuel.
  2. Assurez-vous que votre service istio-ingress accepte les requêtes provenant de l'URL http://DOMAIN/.well-known/acme-challenge/..., où DOMAIN correspond au domaine en cours de validation.

Erreurs système

Code d'erreur Message détaillé Instructions de dépannage
OrderErrored

AuthzErrored

ChallengeErrored

Ces trois types d'erreurs se produisent en cas d'échec de validation de la propriété du domaine par Let's Encrypt.

Ces erreurs sont généralement des erreurs temporaires et Cloud Run pour Anthos effectue de nouvelles tentatives.

Le délai entre les tentatives croît exponentiellement, avec un minimum de 8 secondes et un maximum de 8 heures.

Si vous souhaitez relancer manuellement la commande, supprimez d'abord celle qui a échoué :

kubectl delete order DOMAIN -n NAMESPACE

ACMEAPIFailed Ce type d'erreur se produit lorsque Cloud Run pour Anthos n'a pas réussi à appeler Let's Encrypt. Il s'agit généralement d'une erreur temporaire et Cloud Run pour Anthos effectue de nouvelles tentatives.

Si vous souhaitez relancer manuellement la commande, supprimez d'abord celle qui a échoué :

kubectl delete order DOMAIN -n NAMESPACE

UnknownErrored Ce message indique une erreur système inconnue, qui ne devrait se produire que très rarement dans le cluster GKE. Si cette erreur apparaît, contactez l'assistance Cloud pour obtenir de l'aide pour le débogage.

Vérifier l'état de la commande

L'état de la commande enregistre le processus d'interaction avec Let's Encrypt et peut donc être utilisé pour résoudre les problèmes liés à Let's Encrypt. Si nécessaire, vérifiez l'état de la commande en exécutant la commande suivante :

kubectl get order DOMAIN -n NAMESPACE -oyaml

Remplacer

  • DOMAIN par le nom du domaine que vous utilisez ;
  • NAMESPACE par l'espace de noms que vous utilisez pour le mappage de domaine.

Si la commande a été acceptée, les résultats contiendront les certificats émis ainsi que d'autres informations.

Dépassement du quota Let's Encrypt

Vérifiez l'état de DomainMapping. Si vous dépassez le quota Let's Encrypt, un message d'erreur s'affiche dans le DomainMapping, comme suit :

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/'

Consultez la documentation de Let's Encrypt sur les limites de débit pour augmenter le quota de certificats.

Expiration de la commande

Un objet Commande expire au bout de 20 minutes s'il ne peut toujours pas obtenir de certificats.

  1. Vérifiez l'état du mappage de domaine. Pour l'expiration, recherchez un message d'erreur tel que celui-ci dans le résultat renvoyé :

    order (test.example.com) timed out (20.0 minutes)
  2. L'expiration est souvent due au fait que votre enregistrement DNS n'est pas configuré correctement pour mapper le domaine que vous utilisez avec l'adresse IP du service istio-ingress sous gke-system. Exécutez la commande suivante pour vérifier l'enregistrement DNS :

    host DOMAIN
  3. Exécutez la commande suivante pour vérifier l'adresse IP externe du service istio-ingress sous gke-system :

    kubectl get svc istio-ingress -n gke-system

    Si l'adresse IP externe de votre domaine ne correspond pas à l'adresse IP d'entrée, reconfigurez votre enregistrement DNS pour effectuer le mappage avec l'adresse IP appropriée.

  4. Une fois l'enregistrement DNS (mis à jour) effectif, exécutez la commande suivante pour supprimer l'objet Commande afin de relancer le processus de demande de certificat TLS :

    kubectl delete order DOMAIN -n NAMESPACE

    Remplacer

    • DOMAIN par le nom du domaine que vous utilisez ;
    • NAMESPACE par l'espace de noms que vous utilisez.

Échecs d'autorisation

Des échecs d'autorisation peuvent se produire lorsqu'un enregistrement DNS n'est pas propagé globalement à temps. Par conséquent, Let's Encrypt ne parvient pas à valider la propriété du domaine.

  1. Vérifiez l'état de la commande. Recherchez le lien d'autorisation dans le champ de l'état acmeAuthorizations. L'URL doit se présenter comme suit :

    https://acme-v02.api.letsencrypt.org/acme/authz-v3/1717011827
  2. Ouvrez le lien. Si un message semblable à celui-ci s'affiche :

    urn:ietf:params:acme:error:dns

    le problème est dû à une propagation DNS incomplète.

  3. Pour résoudre l'erreur de propagation DNS, procédez comme suit :

    1. Obtenez l'adresse IP externe du service istio-ingress sous gke-system en exécutant la commande suivante :
      kubectl get svc istio-ingress -n gke-system
    2. Vérifiez votre enregistrement DNS pour le domaine en exécutant la commande suivante :

      host DOMAIN

      Si l'adresse IP de l'enregistrement DNS ne correspond pas à l'adresse IP externe du service istio-ingress sous gke-system, configurez votre enregistrement DNS pour mapper le domaine de l'utilisateur avec l'adresse IP externe.

    3. Une fois l'enregistrement DNS (mis à jour) effectif, exécutez la commande suivante pour supprimer l'objet Commande afin de relancer le processus de demande de certificat TLS :

      kubectl delete order DOMAIN -n NAMESPACE

    Remplacer

    • DOMAIN par le nom du domaine que vous utilisez ;
    • NAMESPACE par l'espace de noms que vous utilisez pour le mappage de domaine.

Échec du déploiement sur un cluster privé : erreur lors de l'appel du webhook

Il est possible que votre pare-feu ne soit pas configuré correctement si votre déploiement sur un cluster privé échoue avec le message suivant :

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)

Pour en savoir plus sur les modifications de pare-feu requises pour procéder au déploiement sur un cluster privé, consultez la section Activer les déploiements sur un cluster privé.

État du rapport sur les services d'IngressNotConfigured

Si IngressNotConfigured s'affiche dans l'état de votre service, vous devrez peut-être redémarrer le déploiement istio-pilot dans l'espace de noms gke-system. Cette erreur, qui a été plus fréquemment observée sur Kubernetes 1.14, peut se produire si les services sont créés avant que istio_pilot ne soit prêt à commencer le rapprochement des VirtualServices et avant la transmission de la configuration Envoy aux passerelles d'entrée.

Pour résoudre ce problème, effectuez un scaling vertical du déploiement suivi d'un scaling horizontal à l'aide de commandes semblables à celle-ci :

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

Métriques de comptage et de latence des requêtes manquantes

Si vous avez activé Workload Identity et que vous n'avez pas accordé certaines autorisations au compte de service utilisé par votre service, il est possible que celui-ci ne puisse pas générer de métriques de comptage et de latence des requêtes.

Pour résoudre ce problème, suivez la procédure décrite dans la section Activer les métriques sur un cluster avec Workload Identity.

Utiliser des WebSockets avec des domaines personnalisés

Par défaut, les WebSockets sont désactivés pour les mappages de domaines personnalisés.

Pour activer les Websockets pour vos domaines personnalisés, exécutez la commande suivante afin de créer un objet Istio EnvoyFilter ayant l'attribut allow_connect: true :

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