Kubernetes: Reinicio continuo de las vainas

Creado en 2 sept. 2015  ·  108Comentarios  ·  Fuente: kubernetes/kubernetes

kubectl rolling-update es útil para implementar de forma incremental un nuevo controlador de replicación. Pero si tiene un controlador de replicación existente y desea hacer un reinicio continuo de todos los pods que administra, se ve obligado a realizar una actualización no operativa a un RC con un nuevo nombre y la misma especificación. Sería útil poder hacer un reinicio continuo sin necesidad de cambiar el RC o dar la especificación RC, por lo que cualquier persona con acceso a kubectl podría iniciar fácilmente un reinicio sin preocuparse por tener la especificación localmente, asegurándose de que sea la misma / actualizado, etc. Esto podría funcionar de diferentes formas:

  1. Un nuevo comando, kubectl rolling-restart que toma un nombre de RC y borra gradualmente todos los pods controlados por el RC y permite que el RC los vuelva a crear.
  2. Igual que 1, pero en lugar de eliminar cada pod, el comando itera a través de los pods y emite algún tipo de comando de "reinicio" para cada pod de forma incremental (¿existe? ¿Es este un patrón que preferimos?). La ventaja de este es que las cápsulas no se reequilibrarían innecesariamente con otras máquinas.
  3. kubectl rolling-update con una bandera que le permite especificar solo un RC antiguo, y sigue la lógica de 1 o 2.
  4. kubectl rolling-update con una bandera que le permite especificar solo un RC antiguo, y genera automáticamente un RC nuevo basado en el anterior y procede con la lógica de actualización continua normal.

Todas las opciones anteriores necesitarían las opciones MaxSurge y MaxUnavailable introducidas recientemente (ver # 11942) junto con verificaciones de preparación en el camino para asegurarse de que el reinicio se realiza sin eliminar todos los pods.

@nikhiljindal @ kubernetes / kubectl

areapp-lifecycle kinfeature lifecyclfrozen prioritbacklog siapps

Comentario más útil

¡De acuerdo, kubectl rollout restart ha fusionado!

Todos 108 comentarios

cc @ironcladlou @ bgrant0607

¿Cuál es el caso de uso para reiniciar los pods sin ningún cambio en la especificación?

Tenga en cuenta que no habrá forma de revertir el cambio si los pods comenzaron a fallar cuando se reiniciaron.

Siempre que los servicios entren en algún estado de cuña o indeseable (conexiones agotadas y ahora estancadas, mal estado interno, etc.). Por lo general, es uno de los primeros pasos de solución de problemas si un servicio se está comportando gravemente mal.

Si el primer pod falla cuando se reinicia, esperaría que deje de continuar o que continúe intentando iniciar el pod.

Además, un reinicio continuo sin cambios en las especificaciones reasigna los pods en el
grupo.

Sin embargo, también me gustaría poder hacer esto sin reprogramar el
vainas. Eso podría ser un cambio de etiqueta continuo, pero puede generar una nueva dinámica
config o borre el estado del archivo local.

El miércoles 2 de septiembre de 2015 a las 12:01 a. M., Sam Ghods [email protected] escribió:

Siempre que los servicios entren en un estado de cuña o indeseable (al máximo
conexiones y ahora están bloqueadas, mal estado interno, etc.). Por lo general es
uno de los primeros pasos de solución de problemas si el servicio es grave
portarse mal.

Si el primer pod falla cuando se reinicia, esperaría que cesara
continuar o continuar intentando iniciar el pod.

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/kubernetes/kubernetes/issues/13488#issuecomment -136931790
.

Clayton Coleman | Ingeniero jefe, OpenShift

@smarterclayton ¿Es como mi opción 2 mencionada anteriormente? Aunque, ¿por qué se cambiarían las etiquetas?

Re. wedged: Para eso están las sondas de vivacidad.

Re. reequilibrio: ver # 12140

Si apoyáramos esto, lo agregaría al # 9043; se requiere el mismo mecanismo.

Supongo que esto sería más para una situación en la que el módulo está vivo y responde a las comprobaciones, pero aún debe reiniciarse. Un ejemplo es un servicio con un caché en memoria o un estado interno que se corrompe y debe borrarse.

Siento que pedir que se reinicie una aplicación es un caso de uso bastante común, pero tal vez sea incorrecto.

La corrupción sería solo una cápsula, que podría ser eliminada y reemplazada por el RC.

El otro caso mencionado fuera de línea fue volver a leer la configuración. Es peligroso hacerlo implícitamente, porque los reinicios por cualquier motivo provocarían que los contenedores carguen la nueva configuración. Sería mejor hacer una actualización continua para enviar una nueva referencia de configuración versionada (por ejemplo, en una var env) a los pods. Esto es similar a lo que motivó # 1353.

@ bgrant0607 ¿hemos decidido que no queremos hacer esto?

@gmarek Nada, por ahora. Ya están en marcha demasiadas cosas.

¿Podemos tener un hito post v1.1 (o algo) para las cosas que consideramos importantes, pero carecemos de personas que las arreglen de inmediato?

Yo también sería un fanático de esta función, no querrás que te obliguen a cambiar de etiqueta para cada actualización menor que quieras implementar.

Soy fanático de esta función. Caso de uso: actualice fácilmente todos los pods para usar una imagen de la ventana acoplable recién enviada (con imagePullPolicy: Always ). Actualmente utilizo una pequeña solución pirata: actualización continua con o sin la etiqueta :latest en el nombre de la imagen.

Otro caso de uso: Actualización de secretos.

Realmente me gustaría ver esta función. Ejecutamos aplicaciones de nodo en kubernetes y actualmente tenemos ciertos casos de uso en los que reiniciamos los pods para borrar el pseudo almacenamiento en caché de la aplicación.

Esto es lo que estoy haciendo por ahora:

kubectl get pod | grep 'pod-name' | cut -d " " -f1 - | xargs -n1 -P 10 kubectl delete pod

Esto elimina 10 pods a la vez y funciona bien en una configuración de controlador de replicación. No aborda ninguna inquietud, como la asignación de grupos o los nuevos grupos que no se inician. Es una solución rápida cuando se necesita.

Realmente me gustaría poder hacer un reinicio continuo.
La razón principal es que alimentaremos las variables ENV en los pods usando ConfigMap y luego, si cambiamos la configuración, debemos reiniciar los consumidores de ese ConfigMap.

Sí, hay muchos casos en los que realmente desea reiniciar el pod / contenedor sin cambios dentro ...
Configuraciones, caché, reconexión a servicios externos, etc. Realmente espero que se desarrolle la función.

Pequeño trabajo alrededor (uso implementaciones y quiero cambiar las configuraciones sin tener cambios reales en la imagen / pod):

  • crear configMap
  • cree la implementación con la variable ENV (la usará como indicador para su implementación) en cualquier contenedor
  • actualizar configMap
  • actualizar implementación (cambiar esta variable ENV)

k8s verá que se ha cambiado la definición de la implementación y comenzará el proceso de reemplazo de los pods
PD:
si alguien tiene una mejor solución, por favor comparta

Gracias @paunin

@paunin Ese es exactamente el caso en el que lo necesitamos actualmente: tenemos que cambiar los valores de ConfigMap que son muy importantes para los servicios y deben implementarse en los contenedores en minutos hasta algunas horas. Si no ocurre ninguna implementación mientras tanto, todos los contenedores fallarán al mismo tiempo y tendremos un tiempo de inactividad parcial de al menos algunos segundos.

from (un poco relacionado con # 9043): una línea del enfoque de RESTART_ es la variable de entorno, y se establece en una marca de tiempo ISO:

kubectl patch deployment mydeployment \
-p'{"spec":{"template":{"spec":{"containers":[{"name":"mycontainer","env":[{"name":"RESTART_","value":"$(date -uIseconds)"}]}]}}}}'

(tenga en cuenta que, por alguna razón, las variables de entorno que comienzan con _ simplemente parecen desaparecer, y env numérico value s causan errores, deben ser cadenas)

@paunin @rcoup Hacemos algo muy similar hoy en día, tenemos una var env literalmente llamada "DUMMY_VAR_FOR_NO_OP_DEPLOYMENT".

Parece que la solución correcta aquí le permitiría reiniciar una implementación y reutilizar la mayoría de los parámetros de implementación para implementaciones como MinReadyCount, al tiempo que permite anulaciones de la línea de comandos, como aumentar el paralelismo para situaciones de emergencia en las que necesita que todo rebote de inmediato.

algún progreso en esto?

Siento que esta adición es una hinchazón innecesaria de la API CLI. Esto se puede lograr fácilmente actualizando los valores de las variables del entorno de implementación como lo sugiere @paunin .

También nos gustaría ver esto para implementaciones, tal vez como kubectl restart deployment some-api

Kubernetes puede reiniciar Pods por todo tipo de razones, pero el administrador del clúster no puede hacerlo.
Entiendo la postura moral de que 'apagarlo y encenderlo nuevamente' puede no ser una forma deseada de operar ... pero también creo que debería estar bien permitir que las personas que lo deseen reinicien una implementación sin recurrir al rango de trucos menos apetitosos como:

  • eliminar pods
  • etiquetas falsas
  • variables de entorno ficticias
  • Mapas de configuración ficticios asignados a la variable de entorno
  • reiniciando los nodos trabajadores
  • cortando la energía al centro de datos 😄

'No, no, no voy a reiniciar nada, solo estoy corrigiendo un error tipográfico en esta etiqueta aquí' 😛

Esta función será útil junto con kubectl apply : apply actualizará las configuraciones, incluidos los controladores de replicación, pero los pods no se reiniciarán.

Entonces necesitamos un método para reiniciar estos pods de manera azul-verde.

@DmitryRomanenko ¿qué tal cambiar de ReplicationControllers a Implementaciones? Eso le permitirá ejecutar actualizaciones de ReplicaSets (sucesor de ReplicationController).

@kargakis no es posible: las implementaciones actualizan solo conjuntos de réplicas y pods.
Con kubectl apply también actualizamos ConfigMaps, Services, etc.

@DmitryRomanenko si el problema es "Quiero reiniciar Pods cuando se actualice ConfigMap / Secret", entonces la posible solución es tener versiones para su ConfigMap y Secrets, y hacer que esa versión sea parte de su especificación de implementación. Entonces, con kubectl apply ing, se cambia la especificación de Implementación y se recrean los pods.
En otras situaciones, no veo por qué los pods deben reiniciarse (me refiero a la actualización de Servicio / Ingreso / etc.).

@tyranron , ¡gracias! ¿Cuál es la mejor forma de versión ConfigMap s? ¿Debo crear un nuevo mapa de configuración con un nombre diferente para la nueva implementación?

@DmitryRomanenko realmente puedes, ¿por qué no? Pero en este caso debes tener cuidado de quitar los viejos. Por otro lado, puede resultar útil para la reversión. Pero en la mayoría de los casos, basta con especificar la versión mediante etiquetas.

Creo que la mejor solución aquí podría ser algún tipo de observador o comprobador de suma hash en el objeto configmap . Lo que debería activar el reinicio de objetos / pods relacionados (cualquier cosa usa ese configmap , secret ). Aunque no estoy seguro de que sea algo accesible en la arquitectura k8s ...

También creo que es mejor tener el control del objeto configmap|secret para activar el reinicio en los cambios o no.

@tyranron ,

Entonces, con la aplicación de kubectl, se cambia la especificación de Implementación y se recrean los pods.

¿Podrías explicar? ¿Debería usar kubectl apply -f new_config.yml con implementaciones actualizadas, y estas implementaciones se reiniciarán de forma continua?

@DmitryRomanenko sí , exactamente.

@DmitryRomanenko con la aplicación de nuevas especificaciones está actualizando la implementación , y en la actualización de la implementación se activa el reinicio si se cambió su especificación.

Por defecto, la estrategia de reinicio es RollingUpdate , pero también puede especificar otra explícitamente.

Los problemas se vuelven obsoletos después de 90 días de inactividad.
Marque el problema como nuevo con /remove-lifecycle stale .
Los problemas obsoletos se pudren después de 30 días adicionales de inactividad y finalmente se cierran.

Evite que los problemas se cierren automáticamente con un comentario /lifecycle frozen .

Si es seguro cerrar este problema ahora, hágalo con /close .

Envíe sus comentarios a sig-testing, kubernetes / test-infra y / o @fejta .
/ ciclo de vida obsoleto

Un pequeño cambio en la solución de @rcoup : asegúrese de que date se evalúe dentro del shell:

kubectl patch deployment mydeployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"mycontainer","env":[{"name":"RESTART_","value":"'$(date +%s)'"}]}]}}}}'

/ remove-lifecycle stale
/ ciclo de vida congelado

He estado usando el modo Swarm durante algún tiempo, que se considera menos flexible que Kubernetes, puedo reiniciar las tareas de servicio (lea: pods de implementación), simplemente haciendo una actualización forzada (sin cambios en las especificaciones) como en docker service update --force <service-name> . Esperaría que Kubernetes también hiciera esto.
En cuanto a los mapas de configuración y los secretos, swarm no te permite editarlos, debes rotarlos en su lugar. Para ello, crea nuevos mapas de configuración / secretos, actualiza la especificación del servicio para usar los nuevos y luego elimina los más antiguos. Veo que esto es típicamente lo que se recomienda anteriormente al versionar sus configmaps / secerts y actualizar las implementaciones que los usan. Para ser honesto, ¡este comportamiento de rotación es una de las principales razones por las que dejé Swarm! Es muy inconveniente tener una copia local, actualizar luego crear nuevos recursos y finalmente actualizar los recursos dependientes. Agregue a eso, los secretos en swarm no se pueden leer desde la API, debe montarlos dentro de cualquier contenedor (o ejecutivo dentro de un contenedor que los use), luego cat sus archivos.
En una nota relacionada, utilicé openshift durante algún tiempo y creo que reinicia automáticamente los pods en env / configmap / secret change. Sin embargo, me quedo corregido.

debería ser responsabilidad de la aplicación observar cambios en el sistema de archivos, como se mencionó, puede usar sumas de verificación en el mapa de configuración / secreto y forzar reinicios de esa manera

pero si no desea cambiar la configuración en absoluto y simplemente hacer un reinicio continuo con una pausa arbitraria, una tubería simple hace el trabajo (esta duerme 30 segundos entre el pod terminado)

kubectl get po -l release=my-app -o name | cut -d"/" -f2 | while read p;do kubectl  delete po $p;sleep 30;done

tenga en cuenta que si presiona ctrl + c, no es fácil reiniciar donde lo dejó

@ so0k , comando alternativo:

kubectl get pods|grep somename|awk '{print $1}' | xargs -i sh -c 'kubectl delete pod -o name {} && sleep 4'

Dos años y medio después y la gente todavía está creando nuevas soluciones, con variables env ficticias, etiquetas dumy, ConfigMap y sidecars de observadores secretos, escalando a cero y scripts de shell de actualización continua para simular la capacidad de activar una actualización continua. ¿Sigue siendo esto algo que los administradores de clústeres no deberían poder hacer honestamente, sin los trucos?

27081 # 33664 https://github.com/kubernetes/helm/issues/2639

https://stackoverflow.com/questions/41735829/update-a-deployment-image-in-kubernetes

kubectl scale --replicas=0 deployment application
kubectl scale --replicas=1 deployment application

https://stackoverflow.com/questions/40366192/kubernetes-how-to-make-deployment-to-update-image

Otro truco es ejecutar inicialmente:

kubectl set image deployment/my-deployment mycontainer=myimage:latest

y luego:

kubectl set image deployment/my-deployment mycontainer=myimage

En realidad, activará la actualización continua, pero asegúrese de que también haya configurado imagePullPolicy: "Siempre".

Otro truco que encontré, donde no tienes que cambiar el nombre de la imagen, es cambiar el valor de un campo que activará una actualización continua, como terminationGracePeriodSeconds. Puede hacer esto usando kubectl edit deployment your_deployment o kubectl apply -f your_deployment.yaml o usando un parche como este:

kubectl patch deployment your_deployment -p \
  '{"spec":{"template":{"spec":{"terminationGracePeriodSeconds":31}}}}'

http://rancher.com/docs/rancher/v1.4/en/cattle/upgrading/

# Force an upgrade even though the docker-compose.yml for the services didn't change
$ rancher-compose up --force-upgrade

@ so0k @KIVagant Eliminar pods significa tiempo de inactividad, incluso cuando se ejecutan varias instancias. Cuando alguien ejecuta un solo pod con strategy.rollingUpdate.maxUnavailable = 0 una implementación regular crea primero un nuevo pod antes de finalizar el existente. El truco kubectl patch deployment desencadena este comportamiento, la eliminación de pods no lo hace. Realmente me gustaría una forma no pirata de desencadenar este comportamiento a pedido.

Por ejemplo, al ejecutar imágenes desde hub.docker.com, la misma etiqueta se puede parchear para actualizaciones de seguridad. Realmente me gustaría "extraer las imágenes más recientes" y realizar una actualización continua para cualquier imagen desactualizada.

El lanzamiento de las actualizaciones de ConfigMap / Secret es # 22368
El lanzamiento más fácil de nuevas imágenes es el n. ° 1697
Las actualizaciones continuas en el lugar son # 9043

Reinicie en las compilaciones de imágenes: https://github.com/GoogleCloudPlatform/freshpod
Presentación de un truco en la cumbre de Helm con una anotación basada en plantilla para desencadenar implementaciones de implementación: https://www.youtube.com/watch?v=dSw0w1x96ak

@ bgrant0607 Creo que el caso de uso importante que no está cubierto por otras entradas es este: https://github.com/kubernetes/kubernetes/issues/13488#issuecomment -136946912

@ghodss escribió:
Supongo que esto sería más para una situación en la que el módulo está vivo y responde a las comprobaciones, pero aún debe reiniciarse. Un ejemplo es un servicio con un caché en memoria o un estado interno que se corrompe y debe borrarse.

Siento que pedir que se reinicie una aplicación es un caso de uso bastante común, pero tal vez sea incorrecto.

Me gustaría forzar un reinicio continuo para borrar todo el estado de la aplicación sin trucos manuales.

Tengo un resumen similar basado en el enfoque que @paunin , pero debería funcionar para el caso más general. Se basa en la salida JSON y usa jq para analizar. Tengo esto cargado en mi bashrc como una función para poder llamarlo en cualquier lugar

kubectl-restart() {
  kubectl get deploy $1 -o json | jq \
    'del(
      .spec.template.spec.containers[0].env[]
      | select(.name == "RESTART_"))
    | .spec.template.spec.containers[0].env += [{name: "RESTART_", value: now|tostring}]' | kubectl apply -f -
}

Esto me permite simplemente decir: kubectl-restart my-deployment-name y "actualizará" la var RESTART_ env en el primer contenedor a la marca de tiempo actual. Estoy lejos de ser un experto en jq, por lo que puede haber una mejor manera de hacerlo, pero básicamente elimina el antiguo RESTART_ env var de la salida (si existe) y luego lo agrega de nuevo allí con el tiempo actual.

Sin embargo, me parece muy extraño que no haya una forma nativa de hacer esto ... Ciertamente, una sala llena de ingenieros estaría de acuerdo en que la capacidad de "apagarlo y volver a encenderlo" es algo que nos gustaría tener.

Ese es un buen truco y todo, pero tiene un gran inconveniente. La próxima vez que implemente, usando kubectl apply -f , ese componente se reiniciará si tiene una var env RESTART_xxx incluso si nada más cambia. En otras palabras, provoca reinicios falsos en la próxima implementación si alguna vez se reinició entre la última implementación y esta implementación. No es ideal...

Es por eso que la funcionalidad de reinicio continuo debe integrarse en el controlador de implementación, no en la parte superior.

Escribí una función bash para lograr la estrategia de "implementación de parches de terminationGracePeriodSeconds " @whereisaaron citado en su comentario anterior (fuente: https://stackoverflow.com/a/40368520/90442).

# $1 is a valid namespace
function refresh-all-pods() {
  echo
  DEPLOYMENT_LIST=$(kubectl -n $1 get deployment -o json|jq -r .items[].metadata.name)
  echo "Refreshing pods in all Deployments"
  for deployment_name in $DEPLOYMENT_LIST ; do
    TERMINATION_GRACE_PERIOD_SECONDS=$(kubectl -n $1 get deployment "$deployment_name" -o json|jq .spec.template.spec.terminationGracePeriodSeconds)
    if [ "$TERMINATION_GRACE_PERIOD_SECONDS" -eq 30 ]; then
      TERMINATION_GRACE_PERIOD_SECONDS='31'
    else
      TERMINATION_GRACE_PERIOD_SECONDS='30'
    fi
    patch_string="{\"spec\":{\"template\":{\"spec\":{\"terminationGracePeriodSeconds\":$TERMINATION_GRACE_PERIOD_SECONDS}}}}"
    kubectl -n $1 patch deployment $deployment_name -p $patch_string
  done
  echo
}

Comente / actualícelo a través de la esencia aquí . Me haré eco de los comentarios de otros de que sería mejor si esto no fuera necesario.

Solo a modo de una justificación más específicamente relacionada con kube, el reinicio también permite volver a ejecutar un contenedor de inicio, que se puede usar para transferir claves, actualizar la configuración o cualquier cosa para la que use contenedores de inicio.

@ kubernetes / sig-apps-feature-request @ kow3ns @janetkuo

@gjcarneiro ¿Tenía una var env RESTART_xxx en la configuración que aplicó, o no? De lo contrario, esperaría aplicar para ignorar la var env adicional en el estado en vivo.

cc @apelisse

@gjcarneiro Sí, el problema con el script @mattdodge es que está usando aplicar, por lo que el cambio se guardará en la última anotación aplicada. La secuencia de comandos podría corregirse mediante el uso de un parche u otro método para actualizar la implementación.

Me encantaría tener esta función. Parece muy básico y necesario.

No hay progreso aquí ni en # 22368, le sigh :-(

¿Alguien puede recomendar una solución rápida y sucia para reiniciar un DaemonSet después de que se haya actualizado el ConfigMap montado (el nombre sigue siendo idéntico)?

Gracias por el consejo :-)

Openshift tiene el concepto de desencadenantes de implementación, que desencadenan una implementación en el cambio de imagen, webhook o cambio de configuración. Sería una muy buena característica tener en Kubernetes. Además de las implementaciones manuales, por supuesto.

Además, el repositorio de Docker tiene historial, por lo que no hay ninguna razón por la que la reversión no pueda funcionar: el pod generado a partir de .spec.template puede usar el formato image-tag:@digest al extraer imágenes para contenedores. La reversión usaría el ID de resumen del lanzamiento anterior.

No estoy seguro de haber entendido correctamente. En caso de que esto ayude a alguien.

Parece que si actualiza el valor de una etiqueta debajo del pod> plantilla> metadatos, se lleva a cabo una actualización continua después de kubectl apply -f file.yaml

Por lo tanto, siempre puede tener una etiqueta para su versión y, siempre que desee realizar una actualización continua, cambie la versión y aplique el archivo.

Claro, la desventaja es que la próxima vez que quieras hacer una implementación, harás kubectl apply -f some.yaml , ¿verdad? Normalmente, si nada cambia en some.yaml entonces no se reinicia nada, esa es una de las mejores cosas de Kubernetes.

Pero imagine lo que sucede después de cambiar una etiqueta para reiniciar una implementación. En la siguiente implementación de software normal, realiza kubectl apply -f some.yaml como de costumbre, pero debido a que el archivo yaml no contiene la misma etiqueta, la implementación se reiniciará innecesariamente.

@gjcarneiro Si no apply cuando realiza un cambio, la anotación kubectl.kubernetes.io/last-applied-configuration no se actualizará, por lo que el próximo apply no provocará otro reinicio.

Estoy firmemente a favor de agregar un comando de reinicio continuo a kubectl, pero mientras tanto estoy usando lo siguiente (basado en las soluciones anteriores):

kubectl patch deployment mydeployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"mycontainer","env":[{"name":"RESTART_","value":"'$(date +%s)'"}]}]}}}}'

Parametrice esto y agréguelo como una función en su .bashrc y es una buena solución provisional.

Ah, genial, no lo sabía, ¡gracias!

No necesito el alias de bash, en mi empresa creamos mi propia interfaz web para administrar Kubernetes usando Python + aiohttp y ya usa patch. Pensé en el código abierto, solo he sido un vago ...

Parece que la gente está repitiendo las mismas soluciones alternativas en este hilo. Lea el hilo completo antes de publicar aquí.

@joelittlejohn Ejecuté tu macro y

@Macmee Depende de la configuración de su implementación. El comando anterior simplemente cambia la implementación. Luego, los pods se actualizan de acuerdo con la implementación strategy definida por su implementación. Esto es como cualquier otro cambio en la implementación.

La única forma en que esto reemplazará todos los pods al mismo tiempo es si su .spec.strategy.rollingUpdate.maxUnavailable permite.

También necesitamos esta característica. Un caso de uso también de nuestro lado es que usamos spring-cloud-config-server respaldado por y scm, para nuestra aplicación spring-boot. Cuando cambiamos una propiedad de configuración, la aplicación spring-boot debe reiniciarse para poder obtener el nuevo cambio de configuración, por lo que también necesitamos este tipo de desencadenador de reinicio elegante sin tener que realizar una nueva implementación.

@japzio Como sugirió Helm , una suma de verificación del mapa de configuración en las anotaciones es una buena manera de manejar ese caso.

¿Ha habido alguna actualización sobre esto? También queremos tener esta función. @ bgrant0607 @nikhiljindal

@ bholagabbar-mt ¿Cuál es su caso de uso?

cc @ kow3ns @janetkuo

@ bgrant0607 @ kow3ns @janetkuo El caso de uso de nuestros sistemas es múltiple.

  1. Actualización de secretos: estoy seguro de que te das cuenta de que hay muchas empresas, como la mía, que han construido sus propias abstracciones sobre kubernetes. Tenemos nuestro propio sistema de gestión de contenedores que está orquestado sobre kubernetes. Por lo tanto, el comentario de sugerencia secreta del

  2. Esto es un poco complicado, pero el alcance general, como sugirió alguien, es corregir un comportamiento anormal. Tenemos 4-5 aplicaciones Java pesadas que se ejecutan en el marco de Play. Nos encontramos con una situación en la que el consumo de memoria de nuestros pods de Java aumenta linealmente y luego reinicia los pods cuando se alcanza el límite de memoria. Este es un problema de Java documentado con un problema de desbordamiento de pila y un problema de Kubernetes asociado. El reinicio continuo de todos los pods en un período de 3 a 4 horas restablecería el consumo de memoria y permitiría que nuestras aplicaciones funcionen sin problemas y sin picos.

Con suerte, esto fue lo suficientemente convincente y esta característica puede ser utilizada por alguien para el desarrollo.

@ bholagabbar-mt simplemente cambia una variable de entorno y activará una implementación continua:

kubectl patch deployment mydeployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"mycontainer","env":[{"name":"LAST_MANUAL_RESTART","value":"'$(date +%s)'"}]}]}}}}'

@montanaflynn Esto es perfecto. Integramos este cambio en nuestros sistemas hoy mismo y funciona bien. ¡Gracias una tonelada!

cc @huzhengchuan

Otro caso de uso para esto: debido a un problema de seguridad en containerd, me gustaría reiniciar todos los pods. https://seclists.org/oss-sec/2019/q1/119 O el clúster se cae por completo o se reinicia de forma continua. ¡Tener un comando de reinicio marcaría una gran diferencia!

actualización , solución alternativa:

kubectl set env --all deployment --env="LAST_MANUAL_RESTART=$(date +%s)" --namespace=...
kubectl set env --all daemonset --env="LAST_MANUAL_RESTART=$(date +%s)" --namespace=...

@realfresh son las mejores prácticas. agregue annotation:{creatTime: 12312312} en ranchero!

kubectl set env deployment mydeployment --env="LAST_RESTART=$(date)" --namespace ...

parece ser un comando mínimo que hace el trabajo para una implementación. Es un ejemplo de uso de configuración imperativa.

cc @monopole @apelisse

~ Dos ~ Tres años y medio después y la gente todavía está elaborando nuevas soluciones, con variables env ficticias, etiquetas ficticias ,

Las actualizaciones continuas siguen siendo una actividad bastante popular para algo que aparentemente no tiene un caso de uso 😄

problema a largo plazo (nota para uno mismo)

  1. No veo una manera de hacer esto sin dejar que la lógica imperativa se filtre en una API declarativa, rompiendo así nuestra convención de mantener las API declarativas e implementando un comportamiento imperativo en los controladores, e introduciendo incompatibilidades con la mayoría de las prácticas de CI / CD.
  2. Podría imaginar una API y un controlador RollingRestart donde la creación de un recurso RollingRestart hizo que el controlador reiniciara los Pods 1 por 1 mediante el desalojo (respetando así los presupuestos de interrupción), pero dicho controlador podría implementarse como un CRD (es decir, veo la razón por la cual tenemos que hacer esto en árbol).
  3. El enfoque declarativo, por ejemplo, agregar una anotación lastRestartedAt = TIMESTAMP no me parece un truco.
  4. Si alguien desea ofrecer un diseño declarativo y una contribución para implementar esta función (en árbol o de otro modo), considere la posibilidad de crear un KEP PR contra el repositorio de mejoras . Si se puede diseñar una implementación declarativa e integrada, me complacerá revisar / shepard en las API de cargas de trabajo. Si se ofrece un controlador CRD como [2], podríamos patrocinarlo en SIG Apps como una extensión patrocinada por la comunidad.

El enfoque declarativo, por ejemplo, agregar una anotación lastRestartedAt = TIMESTAMP no me parece un truco.

No es un truco, solo debería haber una línea de comandos abreviada para ello.

Alguien podría crear un complemento de krew que envíe el parche. kubectl restart-deployment <deployment_name> ?

kubectl rollout restart que parchea una implementación / daemonset / statefulset para activar una nueva 'implementación'?

Eso está en línea con el enfoque de @ kow3ns (3), y tiene algún sentido ya que luego puede ver / pausar / reanudar el lanzamiento que acaba de comenzar con los otros comandos kubectl rollout .

@whereisaaron Veré si puedo enviar un parche para eso (juego de palabras no intencionado)

Para implementar nuevos secretos y mapas de configuración, mi recomendación sigue siendo # 22368: cree nuevos. Eso proporciona un medio tanto para controlar el lanzamiento como para retroceder. Solo necesitamos terminar GC de objetos antiguos:
https://github.com/kubernetes/community/pull/1163
https://github.com/kubernetes/community/pull/2287

Sin embargo, es razonable documentar y / o admitir (en kustomize, kubectl o un complemento de kubectl) la forma recomendada de hacer un reinicio continuo con la API existente.

cc @monopolo

En cuanto a nuevas imágenes, CI / CD o un controlador que resuelve etiquetas para digerir: # 1697.

El descheduler (https://github.com/kubernetes-incubator/descheduler) o algo parecido debía realizar el movimiento de pods insatisfechos, que podría consumir el estado del contenedor, las métricas principales e incluso las métricas personalizadas:

https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/rescheduler.md
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/rescheduling.md

Además, documentación oficial sobre cómo manejar secretos y configmap: https://kubectl.docs.kubernetes.io/pages/app_management/secrets_and_configmaps.html

El reinicio continuo es muy necesario. Un ejemplo es que obtenemos todos los secretos de SSM de AWS. Si cambiamos algún secreto de SSM, nos gustaría hacer un reinicio continuo para que los pods recuperen la última versión cuando se inicien. Además, algunas veces hay problemas de aplicaciones que necesitan un reinicio continuo hasta que la solución real llegue a producción.

¡De acuerdo, kubectl rollout restart ha fusionado!

Es genial escucharlo después de casi 4 años, ¡gracias!

Creo que el RP combinado solo admite implementaciones, ¿es correcto?

Algunas personas en este tema han expresado la necesidad de reiniciar también conjuntos de demonios y conjuntos de estado.

@apelisse, ¿también hay una manera de hacer esto a través de sdk o simplemente kubectl?

@ e-nikolov ¿Qué es el SDK?

Me refiero al cliente Go que se puede usar para hablar con kubernetes desde programas Go.

No, tendría que volver a implementar la lógica (muy simple) que se implementa en kubectl.

¡Bien, el reinicio del lanzamiento de kubectl se ha fusionado!

¿Qué versión de kubectl lo tendrá?

¿Qué versión de kubectl lo tendrá?

Kubernetes 1.15

Nuestro clúster de GKE en el canal de lanzamiento "rápido" se actualizó a Kubernetes 1.16 y ahora kubectl rollout restart dejó de funcionar:

implementación de kubectl reiniciar implementación myapp
error: comando desconocido "reiniciar implementación myapp"

@nikhiljindal preguntó hace un tiempo sobre el caso de uso para actualizar las implementaciones sin ningún cambio en las especificaciones. Tal vez lo estemos haciendo de una manera no óptima, pero aquí está: nuestros modelos de aprendizaje automático previamente entrenados se cargan en la memoria desde Google Cloud Storage. Cuando los archivos de modelo se actualizan en GCS, queremos reiniciar la implementación de nuestra implementación de K8S, que extrae los modelos de GCS.

Aprecio que no podemos revertir la implementación con archivos de modelos anteriores fácilmente, pero esa es la compensación que adoptamos para acercar los modelos lo más posible a la aplicación y evitar una llamada de red (como algunos podrían sugerir).

hola @dimileeh

¿Sabes qué versión de kubectl estás usando ahora? y que versión usaste antes? Me encantaría saber si hubo una regresión, pero al mismo tiempo me sorprendería que la característica hubiera desaparecido por completo.

Con respecto a lo de GCS, y sabiendo muy poco sobre su caso de uso, lo siento si no tiene sentido: sugeriría que el modelo gcs obtenga un nombre diferente cada vez que se modifique (tal vez sufijo con su hash), y eso el nombre se incluiría en la implementación. La actualización de la implementación para usar los nuevos archivos desencadenaría automáticamente una implementación. Esto le da la capacidad de retroceder a una implementación / modelo anterior, tener una mejor comprensión de los cambios que se producen en los modelos, etc.

hola @apelisse , ¡gracias por tu respuesta!

Cuando ejecuto kubectl version desde Google Cloud Terminal, obtengo lo siguiente:

Client Version: version.Info{Major:"1", Minor:"13+", GitVersion:"v1.13.11-dispatcher", GitCommit:"2e298c7e992f83f47af60cf4830b11c7370f6668", GitTreeState:"clean", BuildDate:"2019-09-19T22:20:12Z", GoVersion:"go1.11.13", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"16+", GitVersion:"v1.16.0-gke.20", GitCommit:"d324c1db214acfc1ff3d543767f33feab3f4dcaa", GitTreeState:"clean", BuildDate:"2019-11-26T20:51:21Z", GoVersion:"go1.12.11b4", Compiler:"gc", Platform:"linux/amd64"}

Cuando intenté actualizar kubectl a través de gcloud components update , decía que ya estaba usando las últimas versiones de todos los productos. Por lo tanto, creo que mi versión de kubectl se mantuvo igual mientras el clúster K8S se actualizó de 1.15 a 1.16.

La documentación de Kubenetes 1.17, 1.16 y 1.15 no tiene nada sobre la función kubectl rollout restart . Entonces me pregunto si su valiosa contribución podría haber desaparecido de 1.16.


Gracias por su sugerencia sobre el control de versiones del modelo, tiene mucho sentido. Pensamos en eso, pero luego, dado que reentrenamos a nuestros modelos todos los días, pensamos que comenzaríamos a acumular demasiados modelos (y son bastante pesados). Por supuesto, podríamos usar algún script para limpiar versiones antiguas después de un tiempo, pero hasta ahora hemos decidido mantenerlo simple confiando en kubectl rollout restart y sin preocuparnos por el control de versiones del modelo :)

Muchas gracias por ese enlace, ¡me aseguraré de que se actualice!

El jueves 19 de diciembre de 2019 a las 12:40 p.m. Dmitri Lihhatsov [email protected]
escribió:

Ah, gracias, estaba mirando aquí:
https://v1-16.docs.kubernetes.io/docs/reference/kubectl/cheatsheet/

-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/kubernetes/kubernetes/issues/13488?email_source=notifications&email_token=AAOXDLCDSTPYK6EGBQWSRADQZPL5BA5CNFSM4BOYZ5Z2YY3PNVWWK3TUL52HS4DFVDVREXHG43V
o darse de baja
https://github.com/notifications/unsubscribe-auth/AAOXDLHWCU4T6NCSHOYZIELQZPL5BANCNFSM4BOYZ5ZQ
.

@dimileeh PTAL https://github.com/kubernetes/website/pull/18224 (seleccionaré las ramas relevantes una vez que esto se fusione).

@dimileeh Creo que descubrí lo que está mal con tu versión de kubectl, estaremos trabajando en ello.

Sí, también tenemos el caso de uso de reiniciar el pod sin cambio de código, después de actualizar el mapa de configuración. Esto es para actualizar un modelo de AA sin volver a implementar el servicio.

@anuragtr con las últimas versiones que puede ejecutar

kubectl rollout restart deploy NAME

Estaba usando un comando personalizado para eso [1], ¡me alegro de que ahora esté en el kubectl estándar! Gracias

[1] https://github.com/mauri870/kubectl-renew

@anuragtr con las últimas versiones que puede ejecutar

kubectl rollout restart deploy NAME

@countrogue

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

Temas relacionados

mml picture mml  ·  3Comentarios

arun-gupta picture arun-gupta  ·  3Comentarios

theothermike picture theothermike  ·  3Comentarios

montanaflynn picture montanaflynn  ·  3Comentarios

broady picture broady  ·  3Comentarios