Shinyproxy: La actualización continua para la implementación de shinyproxy provoca pods huérfanos

Creado en 19 ago. 2019  ·  7Comentarios  ·  Fuente: openanalytics/shinyproxy

Hola, cuando hay un cambio en application.yaml y se elige la actualización continua (con réplicas configuradas en 0 y luego nuevamente en 1), principalmente porque la nueva imagen shinyproxy debe descargarse del artefacto. Todos los pods anteriores que fueron hecho girar por el shinyproxy anterior se queda atrás como zombie

Reproducir:

  • kubectl obtener todo

NOMBRE LISTO ESTADO REINICIA EDAD
pod/shinyproxy-7f76d48c79-8x9hs 2/2 Correr 0 41m

NOMBRE TIPO CLÚSTER-IP IP EXTERNA PUERTO(S) EDAD
servicio/shinyproxy NodePort 172.30.85.1918080:32094/TCP 40m

NOMBRE DESEADO ACTUAL ACTUALIZADO EDAD DISPONIBLE
deployment.apps/shinyproxy 1 1 1 1 41m

NOMBRE DESEADO ACTUAL PREPARADO EDAD
replicaset.apps/shinyproxy-7f76d48c79 1 1 1 41m

NOMBRE HOST/SERVICIOS DE LA RUTA DEL PUERTO TERMINACIÓN DEL PUERTO COMODÍN
ruta.ruta.openshift.io/shinyproxy shinyproxy-aap.apps.cpaas.service.test shinyproxyNinguna

  • Inicie sesión en la aplicación (en mi caso, estoy usando la autenticación LDAP y /app_direct/ en una aplicación brillante (se activa un nuevo módulo para la aplicación), como se esperaba)

NOMBRE LISTO ESTADO REINICIA EDAD
pod/shinyproxy-7f76d48c79-8x9hs 2/2 Correr 0 43m
pod/sp-pod-e7603441-03ba-470b-925a-22cfba1716de 1/1 En funcionamiento 0 12 s

NOMBRE TIPO CLÚSTER-IP IP EXTERNA PUERTO(S) EDAD
servicio/shinyproxy NodePort 172.30.85.1918080:32094/TCP 43m

NOMBRE DESEADO ACTUAL ACTUALIZADO EDAD DISPONIBLE
deployment.apps/shinyproxy 1 1 1 1 43m

NOMBRE DESEADO ACTUAL PREPARADO EDAD
replicaset.apps/shinyproxy-7f76d48c79 1 1 1 43m

NOMBRE HOST/SERVICIOS DE LA RUTA DEL PUERTO TERMINACIÓN DEL PUERTO COMODÍN
ruta.ruta.openshift.io/shinyproxy shinyproxy-aap.apps.cpaas.service.test shinyproxyNinguna

  • Después de la construcción de la nueva imagen shinyproxy:

escala kubectl --replicas=0 despliegue/shinyproxy
deployment.extensions/shinyproxy escalado

escala kubectl --replicas=1 despliegue/shinyproxy
deployment.extensions/shinyproxy escalado

  • Se ha descargado una nueva imagen para el proxy brillante y el contenedor que se está creando.

NOMBRE LISTO ESTADO REINICIA EDAD
pod/shinyproxy-7f76d48c79-l5fvw 0/2 Creación de contenedores 0 4s
pod/sp-pod-e7603441-03ba-470b-925a-22cfba1716de 1/1 Correr 0 1m

NOMBRE TIPO CLÚSTER-IP IP EXTERNA PUERTO(S) EDAD
servicio/shinyproxy NodePort 172.30.85.1918080:32094/TCP 44m

NOMBRE DESEADO ACTUAL ACTUALIZADO EDAD DISPONIBLE
deployment.apps/shinyproxy 1 1 1 0 45m

NOMBRE DESEADO ACTUAL PREPARADO EDAD
replicaset.apps/shinyproxy-7f76d48c79 1 1 0 45m

NOMBRE HOST/SERVICIOS DE LA RUTA DEL PUERTO TERMINACIÓN DEL PUERTO COMODÍN
ruta.ruta.openshift.io/shinyproxy shinyproxy-aap.apps.cpaas.service.test shinyproxyNinguna

  • En esta etapa, mi aplicación web no responde: lo único que se puede hacer es cerrar la pestaña/ventana. Y el pod (para la aplicación R) permanece a menos que se elimine manualmente.

  • No se puede acceder al pod que consume recursos, porque el nuevo servicio apunta a la implementación actualizada y solo se puede acceder a la aplicación a través de una ruta sobre el servicio.

  • También es muy difícil identificar cuáles de los pods son los obsoletos y eliminarlos manualmente.

Comentario más útil

Encontré una solución para este problema. En realidad, esto no es un problema en shinyproxy o containerproxy, ya que la aplicación Spring Boot se cierra correcta y correctamente.

El problema es el contenedor sidecar kubctl proxy . Para Kubernetes, no está claro que containerproxy dependa del contenedor sidecar para comunicarse con el mismo Kubernetes. Por lo tanto, en una nueva implementación, Kubernetes enviará SIGTERM tanto al proxy como al contenedor sidecar en todos los pods antiguos. El contenedor sidecar finalizará de inmediato y containerproxy no podrá comunicarse con Kubernetes.

Leí que Kubernetes está a punto de resolver estas dependencias de inicio y apagado en v1.18 como se documenta aquí:
https://github.com/kubernetes/enhancements/issues/753
https://banzaicloud.com/blog/k8s-sidecars/

Hasta entonces, existe una solución sencilla para colocar la siguiente anotación de ciclo de vida en el contenedor sidecar:

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

Todos 7 comentarios

Hola @ramkumarg1

Cuando shinyproxy recibe una señal SIGTERM (cuando la implementación se reduce), debería terminar correctamente deteniendo todos los módulos de aplicaciones primero. Es posible que deba aumentar el período de gracia terminationGracePeriodSeconds en la especificación del pod (el valor predeterminado es 30 s). Si shinyproxy no puede finalizar dentro de este período, recibirá un SIGKILL y se cancelará de inmediato, dejando pods huérfanos. Más información aquí: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/

Gracias @dseynaev Cambié la especificación de implementación para incluir terminaciónGracePeriodSeconds, pero no marcó la diferencia. El pod se eliminó de inmediato. ¿Quizás este problema está vinculado a https://github.com/kubernetes/kubernetes/issues/47576 donde Spring Boot necesita manejar SIGTERM con gracia?

spec:
  terminationGracePeriodSeconds : 180
  containers:
  - name: shinyproxy

Observamos el mismo problema con los pods de zombis y, para nosotros, la configuración del período de gracia de terminación tampoco resuelve esto.

Tengo el mismo problema y esto es lo que shiny/containerproxy registra al finalizar:

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'

Encontré una solución para este problema. En realidad, esto no es un problema en shinyproxy o containerproxy, ya que la aplicación Spring Boot se cierra correcta y correctamente.

El problema es el contenedor sidecar kubctl proxy . Para Kubernetes, no está claro que containerproxy dependa del contenedor sidecar para comunicarse con el mismo Kubernetes. Por lo tanto, en una nueva implementación, Kubernetes enviará SIGTERM tanto al proxy como al contenedor sidecar en todos los pods antiguos. El contenedor sidecar finalizará de inmediato y containerproxy no podrá comunicarse con Kubernetes.

Leí que Kubernetes está a punto de resolver estas dependencias de inicio y apagado en v1.18 como se documenta aquí:
https://github.com/kubernetes/enhancements/issues/753
https://banzaicloud.com/blog/k8s-sidecars/

Hasta entonces, existe una solución sencilla para colocar la siguiente anotación de ciclo de vida en el contenedor sidecar:

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

Puedo confirmar que la solución de @fmannhardt resuelve esto. ¡Muchas gracias!

Hola a todos

Con las versiones recientes de ShinyProxy (no estoy seguro de qué versión exactamente, pero al menos ShinyProxy 2.3.1) no es necesario usar un sidecar kube-proxy. ShinyProxy detecta automáticamente la ubicación y la autenticación de la API de Kubernetes.
Por lo tanto, creo que este problema se resuelve automáticamente.
Sin embargo, ¡gracias por su tiempo e investigación!

¿Fue útil esta página
0 / 5 - 0 calificaciones