Shinyproxy: La mise à jour progressive pour le déploiement de shinyproxy provoque des pods orphelins

Créé le 19 août 2019  ·  7Commentaires  ·  Source: openanalytics/shinyproxy

Bonjour, lorsqu'il y a un changement dans application.yaml et que la mise à jour continue est choisie (avec des répliques définies sur 0 puis de nouveau sur 1) - principalement parce que la nouvelle image shinyproxy doit être téléchargée à partir de l'artefact - Tous les pods précédents qui étaient créé par le ShinyProxy précédent, laissé pour compte en tant que zombie

Reproduire:

  • kubectl obtient tout

NOM PRÊT STATUT REDÉMARRAGE ÂGE
pod/shinyproxy-7f76d48c79-8x9hs 2/2 Course 0 41m

NOM TYPE IP DU CLUSTER PORT(S) IP EXTERNE ÂGE
service/shinyproxy NodePort 172.30.85.1918080:32094/TCP 40m

NOM SOUHAITÉ ACTUELLEMENT À JOUR DISPONIBLE ÂGE
déploiement.apps/shinyproxy 1 1 1 1 41m

NOM SOUHAITÉ ACTUELLEMENT PRÊT ÂGE
replicaset.apps/shinyproxy-7f76d48c79 1 1 1 41m

NOM HÔTE/PORT CHEMIN SERVICES PORT TERMINAISON WILDCARD
route.route.openshift.io/shinyproxy shinyproxy-aap.apps.cpaas.service.test shinyproxyAucun

  • Connectez-vous à l'application (dans mon cas, j'utilise l'authentification LDAP et /app_direct/ vers une application brillante (un nouveau pod pour l'application est lancé) - comme prévu

NOM PRÊT STATUT REDÉMARRAGE ÂGE
pod/shinyproxy-7f76d48c79-8x9hs 2/2 Course 0 43m
pod/sp-pod-e7603441-03ba-470b-925a-22cfba1716de 1/1 Fonctionnement 0 12s

NOM TYPE IP DU CLUSTER PORT(S) IP EXTERNE ÂGE
service/shinyproxy NodePort 172.30.85.1918080:32094/TCP 43m

NOM SOUHAITÉ ACTUELLEMENT À JOUR DISPONIBLE ÂGE
déploiement.apps/shinyproxy 1 1 1 1 43m

NOM SOUHAITÉ ACTUELLEMENT PRÊT ÂGE
replicaset.apps/shinyproxy-7f76d48c79 1 1 1 43m

NOM HÔTE/PORT CHEMIN SERVICES PORT TERMINAISON WILDCARD
route.route.openshift.io/shinyproxy shinyproxy-aap.apps.cpaas.service.test shinyproxyAucun

  • Après la nouvelle construction de l'image shinyproxy :

échelle kubectl --replicas=0 déploiement/shinyproxy
déploiement.extensions/shinyproxy mis à l'échelle

échelle kubectl --replicas=1 déploiement/shinyproxy
déploiement.extensions/shinyproxy mis à l'échelle

  • Une nouvelle image a été téléchargée pour le proxy brillant et le conteneur en cours de création.

NOM PRÊT STATUT REDÉMARRAGE ÂGE
pod/shinyproxy-7f76d48c79-l5fvw 0/2 Création de conteneurs 0 4s
pod/sp-pod-e7603441-03ba-470b-925a-22cfba1716de 1/1 Marche 0 1m

NOM TYPE IP DU CLUSTER PORT(S) IP EXTERNE ÂGE
service/shinyproxy NodePort 172.30.85.1918080:32094/TCP 44m

NOM SOUHAITÉ ACTUELLEMENT À JOUR DISPONIBLE ÂGE
déploiement.apps/shinyproxy 1 1 1 0 45m

NOM SOUHAITÉ ACTUELLEMENT PRÊT ÂGE
replicaset.apps/shinyproxy-7f76d48c79 1 1 0 45m

NOM HÔTE/PORT CHEMIN SERVICES PORT TERMINAISON WILDCARD
route.route.openshift.io/shinyproxy shinyproxy-aap.apps.cpaas.service.test shinyproxyAucun

  • À ce stade, mon application Web ne répond pas - la seule chose à faire est de fermer l'onglet/la fenêtre. Et le pod (pour l'application R) continue de rester sauf s'il est supprimé manuellement.

  • Le pod qui consomme des ressources n'est pas accessible, car le nouveau service pointe vers le déploiement mis à jour et l'application n'est accessible que via une route sur le service

  • Il est également très difficile d'identifier les pods périmés et de les supprimer manuellement.

Commentaire le plus utile

J'ai trouvé une solution à ce problème. Ce n'est pas vraiment un problème dans shinyproxy ou containerproxy car l'application Spring Boot est correctement et gracieusement fermée.

Le problème est le conteneur side-car kubctl proxy . Pour Kubernetes, il n'est pas clair que containerproxy s'appuie sur le conteneur side-car pour communiquer avec Kubernetes lui-même. Ainsi, lors d'un nouveau déploiement, Kubernetes enverra SIGTERM au proxy et au conteneur side-car dans tous les anciens pods. Le conteneur side-car se terminera immédiatement et containerproxy ne pourra pas communiquer avec Kubernetes.

J'ai lu que Kubernetes est sur le point de résoudre ces dépendances de démarrage et d'arrêt dans la v1.18, comme indiqué ici :
https://github.com/kubernetes/enhancements/issues/753
https://banzaicloud.com/blog/k8s-sidecars/

En attendant, il existe une solution de contournement simple pour ajouter l'annotation de cycle de vie suivante au conteneur side-car :

          lifecycle:
            preStop:
              exec:
                command: ["sh", "-c", "sleep 5"] # wait 5 seconds to let shinyproxy remove the pods on graceful shutdown

Tous les 7 commentaires

Salut @ramkumarg1

Lorsque shinyproxy reçoit un signal SIGTERM (lorsque le déploiement est réduit), il doit se terminer normalement en arrêtant d'abord tous les pods d'application. Vous devrez peut-être augmenter la période de grâce terminationGracePeriodSeconds dans la spécification du pod (la valeur par défaut est de 30 s). Si shinyproxy ne parvient pas à se terminer pendant cette période, il recevra un SIGKILL et sera immédiatement résilié, laissant derrière lui des pods orphelins. Plus d'informations ici : https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/

Merci @dseynaev J'ai changé la spécification de déploiement pour inclure terminateGracePeriodSeconds - mais cela n'a pas fait de différence. Le pod a été tué immédiatement - Peut-être que ce problème est lié à https://github.com/kubernetes/kubernetes/issues/47576 où le démarrage de printemps doit gérer SIGTERM avec élégance ?

spec:
  terminationGracePeriodSeconds : 180
  containers:
  - name: shinyproxy

Nous observons le même problème avec les pods zombies, et pour nous, le paramètre de période de grâce de résiliation ne résout pas non plus ce problème.

J'ai le même problème et voici ce qui est enregistré par shiny/containerproxy lors de la résiliation :

2020-01-30 10:56:56.785  INFO 1 --- [           main] e.o.c.ContainerProxyApplication          : Started ContainerProxyApplication in 39.115 seconds (JVM running for 43.619)
2020-01-30 10:57:01.374  INFO 1 --- [  XNIO-2 task-1] io.undertow.servlet                      : Initializing Spring FrameworkServlet 'dispatcherServlet'
2020-01-30 10:57:01.375  INFO 1 --- [  XNIO-2 task-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2020-01-30 10:57:01.507  INFO 1 --- [  XNIO-2 task-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 131 ms
2020-01-30 10:57:26.275  INFO 1 --- [ XNIO-2 task-16] e.o.containerproxy.service.UserService   : User logged in [user: **]
2020-01-30 10:57:35.802  INFO 1 --- [  XNIO-2 task-3] e.o.containerproxy.service.ProxyService  : Proxy activated [user: ***] [spec: insight] [id: 9274ad33-665a-4d47-bab5-6c4b39a618b8]
2020-01-30 10:59:02.376  INFO 1 --- [       Thread-2] ConfigServletWebServerApplicationContext : Closing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext<strong i="6">@2b2948e2</strong>: startup date [Thu Jan 30 10:56:24 GMT 2020]; root of context hierarchy
2020-01-30 10:59:02.377 ERROR 1 --- [pool-4-thread-1] java.io.InputStreamReader                : Error while pumping stream.
java.io.EOFException: null
    at okio.RealBufferedSource.require(RealBufferedSource.java:61) ~[okio-1.15.0.jar!/:na]
    at okio.RealBufferedSource.readHexadecimalUnsignedLong(RealBufferedSource.java:303) ~[okio-1.15.0.jar!/:na]
    at okhttp3.internal.http1.Http1Codec$ChunkedSource.readChunkSize(Http1Codec.java:469) ~[okhttp-3.12.0.jar!/:na]
    at okhttp3.internal.http1.Http1Codec$ChunkedSource.read(Http1Codec.java:449) ~[okhttp-3.12.0.jar!/:na]
    at okio.RealBufferedSource$1.read(RealBufferedSource.java:439) ~[okio-1.15.0.jar!/:na]
    at java.io.InputStream.read(InputStream.java:101) ~[na:1.8.0_171]
    at io.fabric8.kubernetes.client.utils.BlockingInputStreamPumper.run(BlockingInputStreamPumper.java:49) ~[kubernetes-client-4.2.2.jar!/:na]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_171]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_171]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_171]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_171]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_171]
2020-01-30 10:59:02.394  INFO 1 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown
2020-01-30 10:59:02.403  INFO 1 --- [       Thread-2] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans
2020-01-30 10:59:02.514  WARN 1 --- [       Thread-2] .s.c.a.CommonAnnotationBeanPostProcessor : Invocation of destroy method failed on bean with name 'proxyService': eu.openanalytics.containerproxy.ContainerProxyException: Failed to stop container
2020-01-30 10:59:02.525  INFO 1 --- [       Thread-2] io.undertow.servlet                      : Destroying Spring FrameworkServlet 'dispatcherServlet'

J'ai trouvé une solution à ce problème. Ce n'est pas vraiment un problème dans shinyproxy ou containerproxy car l'application Spring Boot est correctement et gracieusement fermée.

Le problème est le conteneur side-car kubctl proxy . Pour Kubernetes, il n'est pas clair que containerproxy s'appuie sur le conteneur side-car pour communiquer avec Kubernetes lui-même. Ainsi, lors d'un nouveau déploiement, Kubernetes enverra SIGTERM au proxy et au conteneur side-car dans tous les anciens pods. Le conteneur side-car se terminera immédiatement et containerproxy ne pourra pas communiquer avec Kubernetes.

J'ai lu que Kubernetes est sur le point de résoudre ces dépendances de démarrage et d'arrêt dans la v1.18, comme indiqué ici :
https://github.com/kubernetes/enhancements/issues/753
https://banzaicloud.com/blog/k8s-sidecars/

En attendant, il existe une solution de contournement simple pour ajouter l'annotation de cycle de vie suivante au conteneur side-car :

          lifecycle:
            preStop:
              exec:
                command: ["sh", "-c", "sleep 5"] # wait 5 seconds to let shinyproxy remove the pods on graceful shutdown

Je peux confirmer que le correctif de @fmannhardt résout ce problème. Merci beaucoup!

salut tout le monde

Avec les versions récentes de ShinyProxy (je ne sais pas quelle version exactement, mais au moins ShinyProxy 2.3.1), il n'est pas nécessaire d'utiliser un sidecar kube-proxy. ShinyProxy détecte automatiquement l'emplacement et l'authentification de l'API Kubernetes.
Je pense donc que ce problème est automatiquement résolu.
Néanmoins, merci pour votre temps et votre enquête!

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

jat255 picture jat255  ·  4Commentaires

fmmattioni picture fmmattioni  ·  3Commentaires

erossini picture erossini  ·  3Commentaires

algo-se picture algo-se  ·  6Commentaires

jfrubioz picture jfrubioz  ·  9Commentaires