Considere un trabajo con dos contenedores: uno que hace el trabajo y luego termina, y otro que no está diseñado para salir nunca explícitamente, pero proporciona algún tipo de funcionalidad de apoyo como registro o recopilación de métricas.
¿Qué opciones existen para hacer algo como esto? ¿Qué opciones deberían existir?
Actualmente, el trabajo seguirá ejecutándose mientras el segundo contenedor siga ejecutándose, lo que significa que el usuario tiene que modificar el segundo contenedor de alguna manera para detectar cuándo se realiza el primero para que también pueda salir limpiamente.
Esta pregunta se hizo en Stack Overflow hace un tiempo sin mejor respuesta que modificar el segundo contenedor para que sea más compatible con Kubernetes, lo cual no es ideal. Otro cliente me ha mencionado recientemente esto como un punto de dolor para ellos.
@ kubernetes / goog-control-plane @erictune
/sub
Además, el uso de un problema de vida como se sugiere aquí http://stackoverflow.com/questions/36208211/sidecar-containers-in-kubernetes-jobs no funciona ya que el pod se considerará fallado y el trabajo general no se considerará exitoso.
¿Qué tal si declaramos un sondeo de éxito del trabajo para que el trabajo pueda probarlo para detectar el éxito en lugar de esperar a que el pod devuelva 0?
Una vez que la sonda arroja resultados satisfactorios, se puede finalizar el pod.
¿Puede la sonda ejecutarse contra un contenedor que ya ha salido o
¿Será una carrera donde se está derribando?
Otra opción es designar ciertos códigos de salida con un significado especial.
Tanto el "éxito de todo el grupo de anuncios" como el "error de todo el grupo de anuncios" son
útil.
Esto debería estar en el objeto Pod, por lo que es un gran cambio de API.
El jueves 22 de septiembre de 2016 a la 1:41 p.m., Ming Fang [email protected] escribió:
¿Qué tal si declaramos una prueba de éxito del trabajo para que el trabajo pueda probarla?
detecta el éxito en lugar de esperar a que el pod devuelva 0.Una vez que la sonda arroja resultados satisfactorios, se puede finalizar el pod.
-
Recibes esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/kubernetes/kubernetes/issues/25908#issuecomment -249021627,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AHuudjrpVtef6U35RWRlZr3mDKcCRo7oks5qsugRgaJpZM4IiqQH
.
@erictune Buen punto; no podemos sondear un contenedor salido.
¿Podemos designar un contenedor en particular en la vaina como el contenedor de "finalización" para que cuando ese contenedor salga podamos decir que el trabajo se completó?
Los contenedores sidecar tienden a durar mucho tiempo para cosas como el envío y el seguimiento de troncos.
Podemos forzar su rescisión una vez que se complete el trabajo.
¿Podemos designar un contenedor en particular en la vaina como el contenedor de "finalización" para que cuando ese contenedor salga podamos decir que el trabajo se completó?
¿Ha mirado este punto de aquí donde básicamente no establece .spec.completions
y tan pronto como el primer contenedor termina con el código de salida 0, el trabajo está terminado?
Los contenedores sidecar tienden a durar mucho tiempo para cosas como el envío y el seguimiento de troncos.
Podemos forzar su rescisión una vez que se complete el trabajo.
Personalmente, estos me parecen más a RS que a un trabajo, pero esa es mi opinión personal y, lo más importante, no conozco todos los detalles de su configuración.
En general, existen las siguientes discusiones https://github.com/kubernetes/kubernetes/issues/17244 y https://github.com/kubernetes/kubernetes/issues/30243 que también tocan este tema.
@soltysh el enlace que envió anteriormente, el punto 3 hace referencia a la finalización del pod y no a la finalización del contenedor.
Los dos contenedores pueden compartir un EmptyDir y el primer contenedor y escribir un mensaje "Estoy saliendo ahora" en un archivo y el otro puede salir cuando ve ese mensaje.
@erictune Tengo un caso de uso que creo que cae en este cubo y espero que pueda guiarme en la dirección correcta, ya que no parece haber ninguna forma oficial recomendada para resolver este problema.
Estoy usando la biblioteca client-go para codificar todo lo siguiente:
Entonces, tengo un trabajo que básicamente ejecuta una herramienta en un contenedor de un solo contenedor. Tan pronto como la herramienta termine de ejecutarse, se supone que generará un archivo de resultados. Parece que no puedo capturar este archivo de resultados porque tan pronto como la herramienta termina de ejecutarse, el pod se elimina y pierdo el archivo de resultados.
Pude capturar este archivo de resultados si usé HostPath
como VolumeSource y como estoy ejecutando minikube localmente, el archivo de resultados se guarda en mi estación de trabajo.
Pero entiendo que eso no es recomendable y es ideal para contenedores de producción. Entonces, usé EmptyDir
como se sugirió anteriormente. Pero, de nuevo, si hago eso, realmente no puedo capturarlo porque se elimina con el pod.
Entonces, ¿debería resolver mi problema usando también el patrón de contenedor sidecar?
Básicamente, haga lo que sugirió anteriormente. Inicie 2 contenedores en la cápsula cada vez que comience el trabajo. 1 contenedor ejecuta el trabajo y, tan pronto como se realiza el trabajo, arroja un mensaje que es recogido por el otro contenedor, que luego toma el archivo de resultados y lo almacena en algún lugar.
No entiendo por qué necesitaríamos 2 contenedores en primer lugar. ¿Por qué el contenedor de trabajos no puede hacer todo esto por sí solo? Es decir, termine el trabajo, guarde el archivo de resultados en algún lugar, acceda a él / léalo y guárdelo en algún lugar.
@anshumanbh Te sugiero:
hostPath
mount, que es casi lo mismo que 1, y ya lo has probado@soltysh No quiero que el archivo se almacene de forma permanente. En cada ejecución, solo quiero comparar ese resultado con el último resultado. Entonces, la forma en que estaba pensando en hacer esto era comprometerme con un repositorio de github en cada ejecución y luego hacer una diferencia para ver qué cambió. Entonces, para hacer eso, solo necesito almacenar el resultado temporalmente en algún lugar para poder acceder a él y enviarlo a Github. ¿Tener sentido?
@anshumanbh perfectamente claro, y aún así, eso no entra en la categoría de contenedor de
@soltysh, así que considerando que quiero
El problema al que me enfrento es que tan pronto como termina el trabajo, el contenedor sale y pierdo el archivo. Si no tengo el archivo, ¿cómo lo cargo en una unidad compartida como S3 / Google Drive / Dropbox? No puedo modificar el código del trabajo para cargarlo automáticamente en algún lugar antes de que se cierre, por lo que, desafortunadamente, primero tendría que ejecutar el trabajo y luego guardar el archivo en algún lugar ...
Si no puede modificar el código del trabajo, debe ajustarlo de tal manera que pueda cargar el archivo. Si con lo que está trabajando es una imagen, simplemente extiéndala con el código de copia.
@soltysh sí, eso tiene sentido. Yo podría hacer eso. Sin embargo, la siguiente pregunta que tengo es: suponga que necesito ejecutar varios trabajos (piense en ello como ejecutar diferentes herramientas) y ninguna de estas herramientas tiene la parte de carga incorporada. Entonces, ahora, tendría que construir ese contenedor y extender cada una de esas herramientas con la parte de carga. ¿Hay alguna forma de que pueda escribir el contenedor / extensión una vez y usarlo para todas las herramientas?
¿No encajaría el patrón del sidecar en ese caso?
Sí, podría. Aunque probaría con varios contenedores dentro del mismo pod, pattern. Iow. su pod está ejecutando el contenedor de trabajos y, junto con uno adicional, está esperando la salida y cargándola. No estoy seguro de cuán factible es esto, pero ya puede intentarlo.
El conocimiento suave de ping-sidecar haría que la administración de proxies de microservicio como Envoy sea mucho más agradable. ¿Hay algún progreso que compartir?
El estado actual de las cosas es que cada contenedor necesita herramientas agrupadas para coordinar la vida útil, lo que significa que no podemos usar directamente imágenes de contenedores ascendentes. También complica significativamente las plantillas, ya que tenemos que inyectar argv y puntos de montaje adicionales.
Una sugerencia anterior fue designar algunos contenedores como contenedores de "terminación". Me gustaría proponer lo contrario: la capacidad de designar algunos contenedores como "sidecars". Cuando finaliza el último contenedor que no es sidecar en un Pod, el Pod debe enviar TERM
a los sidecars. Esto sería análogo al concepto de "subproceso en segundo plano" que se encuentra en muchas bibliotecas de subprocesos, por ejemplo, Thread.daemon
Python.
Ejemplo de configuración, cuando el contenedor main
termina, el kubelet mataría envoy
:
containers:
- name: main
image: gcr.io/some/image:latest
command: ["/my-batch-job/bin/main", "--config=/config/my-job-config.yaml"]
- name: envoy
image: lyft/envoy:latest
sidecar: true
command: ["/usr/local/bin/envoy", "--config-path=/my-batch-job/etc/envoy.json"]
Como referencia, aquí está la locura de bash que estoy usando para simular el comportamiento de sidecar deseado:
containers:
- name: main
image: gcr.io/some/image:latest
command: ["/bin/bash", "-c"]
args:
- |
trap "touch /tmp/pod/main-terminated" EXIT
/my-batch-job/bin/main --config=/config/my-job-config.yaml
volumeMounts:
- mountPath: /tmp/pod
name: tmp-pod
- name: envoy
image: gcr.io/our-envoy-plus-bash-image:latest
command: ["/bin/bash", "-c"]
args:
- |
/usr/local/bin/envoy --config-path=/my-batch-job/etc/envoy.json &
CHILD_PID=$!
(while true; do if [[ -f "/tmp/pod/main-terminated" ]]; then kill $CHILD_PID; fi; sleep 1; done) &
wait $CHILD_PID
if [[ -f "/tmp/pod/main-terminated" ]]; then exit 0; fi
volumeMounts:
- mountPath: /tmp/pod
name: tmp-pod
readOnly: true
volumes:
- name: tmp-pod
emptyDir: {}
Me gustaría proponer lo contrario: la capacidad de designar algunos contenedores como "sidecars". Cuando finaliza el último contenedor que no es sidecar en un Pod, el Pod debe enviar TERM a los sidecar.
@ jmillikin-stripe Me gusta esta idea, aunque no estoy seguro de si sigue el principio de tratar algunos contenedores de manera diferente en un Pod o introducir dependencias entre ellos. Aferraré a
Aunque, ¿ha marcado # 17244, este tipo de solución se ajusta a su caso de uso? Esto es lo que @erictune mencionó algunos comentarios antes:
Otra opción es designar ciertos códigos de salida con un significado especial.
@ jmillikin-stripe Me gusta esta idea, aunque no estoy seguro de si sigue el principio de tratar algunos contenedores de manera diferente en un Pod o introducir dependencias entre ellos. Aferraré a
Creo que Kubernetes puede necesitar ser flexible sobre el principio de no tratar los contenedores de manera diferente. Nosotros (Stripe) no queremos actualizar el código de terceros como Envoy para tener ganchos de ciclo de vida al estilo de Lamprey, y tratar de adoptar una inversión ejecutiva de estilo Envelope sería mucho más complejo que dejar que Kubelet termine sidecars específicos.
Aunque, ¿ha marcado # 17244, este tipo de solución se ajusta a su caso de uso? Esto es lo que @erictune mencionó algunos comentarios antes:
Otra opción es designar ciertos códigos de salida con un significado especial.
Me opongo firmemente a que Kubernetes o Kubelet interpreten los códigos de error con una granularidad más fina que "cero o distinto de cero". El uso de Borglet de los números mágicos del código de salida fue un error desagradable, y sería mucho peor en Kubernetes, donde una imagen de contenedor en particular podría ser un "principal" o un "sidecar" en diferentes Pods.
¿Quizás los ganchos adicionales del ciclo de vida serían suficientes para resolver esto?
Podría ser:
Esto también podría definir un medio para definir políticas personalizadas para reiniciar un contenedor, o incluso iniciar contenedores que no se inician de forma predeterminada para permitir la conexión en cadena de contenedores (cuando el contenedor a finaliza, inicie el contenedor b)
También falta esto. Ejecutamos un trabajo cada 30 minutos que necesita un cliente VPN para la conectividad, pero parece haber muchos casos de uso en los que esto podría ser muy útil (por ejemplo, cosas que necesitan un proxy kubectl). Actualmente, estoy usando jobSpec.concurrencyPolicy: Replace
como solución pero, por supuesto, esto solo funciona si a.) Puede vivir sin ejecuciones de trabajos en paralelo y b.) El tiempo de ejecución del trabajo es más corto que el intervalo de programación.
EDITAR: en mi caso de uso, sería completamente suficiente tener alguna propiedad en la especificación del trabajo para marcar un contenedor como el que termina y hacer que el trabajo controle el estado de salida y elimine los restantes.
Yo también necesito esto. En nuestro caso, es un trabajo que utiliza el contenedor de proxy cloudsql como un servicio adicional.
¿Qué hay de la posibilidad de agregar una anotación que se asigne al nombre del contenedor "principal" en el pod? De esa manera, la especificación de la cápsula no necesita modificarse de ninguna manera.
Por la naturaleza de cómo están diseñados los Pods, esto parece un caso de uso muy común. @soltysh @erictune ¿ algún plan para trabajar en esto pronto? Me alegro de ayudar donde sea posible :)
También necesita esta característica. Para nuestro caso de uso :
la vaina A tiene contenedores
Lo que quiero : cuando el contenedor A1 se complete con éxito, la vaina A se complete con éxito. ¿Podemos simplemente etiquetar el contenedor A1 como contenedor principal , cuando el contenedor principal sale, cuando sale la cápsula? @erictune (Esta idea también es descrita por @mingfang )
Hola chicos, veo que este problema ha estado abierto durante un mes. ¿Qué es lo último en esto? Tenemos un caso de uso, donde queremos ejecutar un trabajo. El trabajo ejecuta un contenedor main
con algunos sidecar containers
. Queremos que el trabajo salga cuando salga el contenedor main
. ¿Es el estado del arte compartir un file
para enviar un signal
entre los contenedores?
No me importaría comenzar a trabajar en esto, me gustaría saber si alguien podría revisar los próximos RP si lo hago (tal vez después de kubecon).
cc @erictune @ a-robinson @soltysh
@andrewsykim, ¿qué enfoque tomaría? Además, sé que lo estoy agregando aquí, ¿qué se necesitaría para agregar soporte para dependencias? Como el contenedor main
no debería comenzar hasta que los sidecars se hayan inicializado
Como el contenedor principal no debería comenzar hasta que los sidecars se hayan inicializado
Creo que este caso no es un problema ya que main
debería poder verificar cuándo se inicializa el sidecar (o usar una sonda de preparación). Este no es el caso de este problema porque main
habría salido :)
Terminé escribiendo un script simple que observa la API de kubernetes y termina los trabajos con una anotación coincidente y cuyo contenedor principal ha salido. No es perfecto, pero responde a una necesidad fundamental. Puedo compartirlo si la gente está interesada.
@ajbouh Personalmente agradecería que compartieras eso como una esencia. Estaba a punto de escribir algo similar
@nrmitchi Aquí está la esencia del yaml que escribí. Es muy scripty, pero quizás sea un buen punto de partida para usted, en términos de qué API usar y cómo obtener algo que funcione. Puedo responder preguntas sobre lo que está haciendo si tiene alguna pregunta.
https://gist.github.com/ajbouh/79b3eb4833aa7b068de640c19060d126
Tengo el mismo caso de uso de proxy de Cloud SQL que @mrbobbytables. Para conectarse de forma segura a la nube SQL, se recomienda usar el proxy, pero ese proxy no termina cuando se realiza el trabajo, lo que da como resultado hacks locos o monitoreo que se parece a lo siguiente. ¿Hay algún camino a seguir en esto?
@ amaxwell01 Con respecto a la participación de Cloud SQL Proxy en esto, había abierto un problema con Google que podría destacar o ver actualizaciones: https://issuetracker.google.com/issues/70746902 (editar: y lamento algunas frases que usé allí en el calor del momento; lamentablemente no puedo editarlo)
Gracias @abevoelker . Estoy siguiendo tu publicación allí. Además tus comentarios me hicieron reír 👍
También nos afecta este problema.
Tenemos varios comandos de administración de django en nuestros microservicios que pueden ejecutarse en cronjobs k8s pero no tienen éxito debido al sidecar cloudsqlproxy que no se detiene al completar el trabajo.
¿Alguna actualización sobre cuándo podríamos tener una solución?
El patrón de contenedor sidecar se usa cada vez más y muchos de nosotros no podremos usar trabajos y cronjobs de k8s hasta que esto se resuelva.
Solo quería agregar mi +1 para esto. Tengo el mismo problema de GCE Cloud SQL Proxy que todos los demás. Me está matando ... el despliegue del timón falla, lo que a su vez falla en la aplicación de terraform.
Realmente me gustaría ver algún tipo de resolución sobre esto ... solo de @ajbouh parece que podría funcionar ... pero cielos, eso es hacky.
Para cualquier otra persona que requiera cloudsql-proxy
, ¿encajaría en su caso de uso ejecutar cloudsql-proxy
como un DaemonSet? En mi caso, tenía una implementación persistente y un CronJob que requería el proxy, por lo que tenía sentido separarlo de los pods individuales y, en su lugar, adjuntar una instancia por nodo.
Sí,
Hemos decidido eliminar los sidecars proxy de cloudsql y hemos creado un grupo de
proxies de cloudsql en su espacio de nombres central, funciona perfectamente y permite
mover la escalabilidad y simplificar las implementaciones.
Ahora podemos ejecutar trabajos y cronjobs sin ningún problema.
El miércoles 7 de febrero de 2018 a las 9:37 a.m., Rob Jackson [email protected]
escribió:
Para cualquier otra persona que requiera el proxy cloudsql, ¿se ajustaría a su caso de uso para
ejecutar el proxy de cloudsql como un DaemonSet? En mi caso tuve un persistente
Implementación y un CronJob que requiere el proxy, por lo que tenía sentido desconectar
de pods individuales y, en su lugar, adjunte una instancia por nodo.-
Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/kubernetes/kubernetes/issues/25908#issuecomment-363710890 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/ACAWMwetx6gA_SrHL_RRbTMJVOhW1FKLks5tSW7JgaJpZM4IiqQH
.
Interesante, usar un deamonset parece una buena opción. @ RJacksonm1 & @devlounge : ¿cómo funciona el descubrimiento del proxy SQL en la nube cuando se utilizan conjuntos de demonios?
Encontré esto que parece que funcionará ...
https://buoyant.io/2016/10/14/a-service-mesh-for-kubernetes-part-ii-pods-are-great-until-theyre-not/
Básicamente implica usar algo como esto para obtener la IP del host:
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
@ RJacksonm1 - ¿ hostPort
funcionara? Constantemente obtengo connection refused
cuando lo uso junto con el enfoque fieldPath: spec.nodeName
🤔
Editar: Me he asegurado de que spec.nodeName
esté comunicando correctamente y estoy en GKE v1.9.2-gke.1
@cvallance Tengo un servicio configurado para exponer el DaemonSet, al que mi aplicación puede acceder a través de DNS. Esto no garantiza que la aplicación se comunicará con la instancia cloudsql-proxy
ejecuta en el mismo host que él mismo, pero sí garantiza que cloudsql-proxy
escalará con el clúster como un todo (originalmente tenía el proxy como Implementación y HorizontalPodAutoscaler, pero encontró que aumentaba / reducía demasiado, lo que causaba errores MySQL has gone away
en la aplicación). Supongo que esto no está en el verdadero espíritu de un DaemonSet ... 🤔
@ RJacksonm1 : lo hizo funcionar con hostPort
y spec.nodeName
... ahora se conectarán directamente al DaemonSet en su nodo 😄
El comando de proxy de CloudSql no funciona:
-instances={{ .Values.sqlConnectionName }}=tcp:{{ .Values.internalPort }}
Laboral:
-instances={{ .Values.sqlConnectionName }}=tcp:0.0.0.0:{{ .Values.internalPort }}
🤦♂️
¿Hay algo que podamos hacer para impulsar este tema?
Ha estado abierto durante casi 2 años y todavía solo tenemos soluciones
Sospecho que incluso si me ofrezco como voluntario para implementar esto, no podré hacerlo, ya que necesita la aprobación de los chicos internos con respecto a qué solución implementar, cambios de API, etc.
¿Hay algo que pueda hacer para ayudar a hacer esto?
Como referencia, hice una versión de sidecar en la nube-sql-proxy de la solución alternativa de @ jmillikin-stripe donde un archivo en un volumen compartido comunica el estado al sidecar.
Funciona bien, pero es, con mucho, el truco más desagradable en mi configuración de K8s :(
apiVersion: batch/v1
kind: Job
metadata:
name: example-job
spec:
template:
spec:
containers:
- name: example-job
image: eu.gcr.io/example/example-job:latest
command: ["/bin/sh", "-c"]
args:
- |
trap "touch /tmp/pod/main-terminated" EXIT
run-job.sh
volumeMounts:
- mountPath: /tmp/pod
name: tmp-pod
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
command: ["/bin/sh", "-c"]
args:
- |
/cloud_sql_proxy --dir=/cloudsql -instances=example:europe-west3:example=tcp:3306 -credential_file=/secrets/cloudsql/credentials.json &
CHILD_PID=$!
(while true; do if [[ -f "/tmp/pod/main-terminated" ]]; then kill $CHILD_PID; echo "Killed $CHILD_PID as the main container terminated."; fi; sleep 1; done) &
wait $CHILD_PID
if [[ -f "/tmp/pod/main-terminated" ]]; then exit 0; echo "Job completed. Exiting..."; fi
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
- name: cloudsql
mountPath: /cloudsql
- mountPath: /tmp/pod
name: tmp-pod
readOnly: true
restartPolicy: Never
volumes:
- name: cloudsql-instance-credentials
secret:
secretName: cloudsql-instance-credentials
- name: cloudsql
emptyDir:
- name: tmp-pod
emptyDir: {}
backoffLimit: 1
¿Alguien interno del proyecto puede comentar sobre el progreso de este problema?
El mismo problema aquí
cc @ kubernetes / sig-apps-feature-orders @ kubernetes / sig-node-feature-orders
¿Tendría sentido permitir que los usuarios especifiquen (por nombre) los contenedores en un trabajo que desean ver completos con éxito para marcar el pod de trabajos como terminado (con otros contenedores detenidos), así:
apiVersion: batch/v2beta1
kind: Job
metadata:
name: my-job
namespace: app
spec:
template:
spec:
containers:
- name: my-container
image: my-job-image
...
- name: cloudsql-proxy
image: gcr.io/cloudsql-docker/gce-proxy:1.11
...
backoffLimit: 2
jobCompletedWith:
- my-container
Es decir, el pod se ejecutará, espere hasta que my-container
salga correctamente y luego simplemente termine cloudsql-proxy
.
EDITAR: Desplazándome hacia arriba en este hilo, ahora veo que esto se ha propuesto anteriormente. ¿Puede @erictune o alguien más volver a elaborar sobre por qué esto no funcionaría?
sí, creo que sería perfecto. Solo algo que le permite ver el estado del trabajo y continuar la canalización una vez que se haya completado
Sí, sería perfecto.
Me gusta esta idea @jpalomaki
Una preocupación que tengo con el enfoque de resolver esto puramente dentro del controlador de trabajo es que el Pod continuará ejecutándose después de que finalice el trabajo. Actualmente, el Pod entra en la fase Terminado y el Nodo puede liberar esos recursos.
Puede hacer que el controlador de trabajo elimine el Pod cuando el controlador decida que está hecho, pero eso también sería diferente del comportamiento actual, donde el registro del Pod terminado permanece en el servidor API (sin consumir recursos del nodo).
Por estas razones, me parece más limpio abordar esto en el nivel de la API de Pod, si es que lo hace. El nodo es lo único que debería estar metiendo la mano y matando contenedores individuales porque los contenedores de "finalización" que le interesan ya terminaron. Esto podría tomar la forma de una API de nivel de pod que le permite especificar la noción de qué contenedores debe esperar, o una API de nivel de pod para permitir que los agentes externos (p. Ej., El controlador de trabajos) obliguen al pod a finalizar sin eliminar realmente la vaina.
También estoy buscando una solución para cargar archivos producidos por un contenedor si el contenedor del procesador salió correctamente.
No estoy seguro de entender el argumento de @mingfang en contra de que el contenedor sidecar observe el estado del contenedor a través de la API k8s para saber si y cuándo comenzar a cargar o salir. Cuando el contenedor del sidecar sale de la vaina y el trabajo debe salir correctamente.
Otro pensamiento, que parece un truco, pero me gustaría saber qué tan malo sería convertir el contenedor de producción de datos en un contenedor de inicio, y tener el contenedor de carga de datos (que ya no necesitaría ser un contenedor de sidecar ) se inicia automáticamente solo después de que el contenedor del procesador se haya cerrado correctamente. En mi caso, también necesitaría un contenedor de descarga de datos como primer contenedor de inicio, para proporcionar datos al contenedor de procesamiento. Si esta es una idea particularmente mala, me encantaría saber por qué.
¿No resolvería este problema promocionar el sidecar a un concepto de k8 de primera clase? Kubelet podrá terminar el pod si todos los contenedores en ejecución están marcados como sidecar.
FWIW, solucioné esto simplemente implementando el proxy de Cloud SQL como una implementación regular ( replicas: 1
) e hice que mi Job
y CronJob
usaran a través de un type: ClusterIP
Servicio. Los trabajos se completan bien ahora.
Me encantaría tener un puesto oficial sobre esto.
Si no vamos a tener algún soporte de la API, al menos deberíamos tener las soluciones alternativas documentadas oficialmente para que la gente sepa qué hacer cuando se encuentre con este problema.
No estoy seguro de a quién hacer ping o cómo llamar la atención sobre esto ...
Sería muy bueno que se solucionara este problema. Además de que el trabajo nunca desaparece, el estado general del pod es aparentemente incorrecto:
Init Containers:
initializer:
State: Terminated
Reason: Completed
Exit Code: 0
Started: Wed, 21 Mar 2018 17:52:57 -0500
Finished: Wed, 21 Mar 2018 17:52:57 -0500
Ready: True
Containers:
sideCar:
State: Running
Started: Wed, 21 Mar 2018 17:53:40 -0500
Ready: True
mainContainer:
State: Terminated
Reason: Completed
Exit Code: 0
Started: Wed, 21 Mar 2018 17:53:41 -0500
Finished: Wed, 21 Mar 2018 17:55:12 -0500
Ready: False
Conditions:
Type Status
Initialized True
Ready False
PodScheduled True
Lo que es interesante es tener en cuenta el Estado y Listo para initContainer (Terminado, Completado, Listo = Verdadero) y el contenedor de la aplicación principal (Terminado, Completado, Listo = Falso). Eso parece estar impulsando el estado de Falso sobre Pod Ready, en mi opinión, incorrectamente. Esto está provocando que este Pod se marque como un problema en nuestros paneles.
Tengo otro cliente que se encuentra con este problema específicamente con el proxy de Cloud SQL. Les gustaría no tener que ejecutarlo como un servicio persistente para permitir que los trabajos cron accedan a Cloud SQL.
@yuriatgoogle La solución más fácil sigue siendo bash y emptyDir "magic" como: https://github.com/kubernetes/kubernetes/issues/25908#issuecomment -365924958
Es un truco, pero tendrá que funcionar. Sin ofender a @phidah.
Definitivamente parece que mucha gente quiere esto por una variedad de razones. Sería bueno contar con algún apoyo oficial. Tuve el mismo problema con nuestro propio sidecar y trabajos, así que hice que el sidecar usara la api de kube para ver el estado del otro contenedor en el pod, si terminaba con un completed
el sidecar saldría 0, si cometió un error, el sidecar saldría 1. Quizás no sea la solución más elegante, pero funcionó sin necesidad de que nuestros desarrolladores cambiaran mucho. el código está aquí si alguien está interesado: https://github.com/uswitch/vault-creds/blob/master/cmd/main.go#L132.
Esto me recuerda a una canción de Gorillaz M1 A1 ...
¿Hola? Hellooooooo? ¿Hay alguien ahí?
Sí, consigamos algo de tracción +1
Entonces, las soluciones propuestas que requieren cambios ascendentes son:
sidecar: true
por @ jmillikin-stripejobCompletedWith
por @jpalomakiSolución temporal para sidecar, una hacky (pero funciona):
cloudsql-proxy
sidecar de @phidahMe encantaría ver la respuesta del mantenedor de Kubernetes con respecto a las soluciones propuestas y, por favor, dénos recomendaciones sobre cómo resolver este caso de uso utilizando la versión existente de Kubernetes. ¡Gracias!
Acabo de descubrir este hilo después de pasar un día tratando de escribir un agente de registro que cargaría el stdout / stderr de mi tarea de renderizado en una base de datos, solo para descubrir que la presencia del agente en el pod significaría que el trabajo nunca terminaría.
De las sugerencias dadas anteriormente, me gusta el 'sidecar: verdadero' el mejor, ya que es simple y al grano, muy comprensible para un desarrollador como yo. Probablemente lo llamaría algo ligeramente diferente, ya que 'sidecar' es realmente un patrón de diseño de pod que se aplica a más que solo trabajos e implica otras cosas además de los requisitos de finalización. Si me disculpa, probablemente lo llamaría algo como 'ambient: true' para indicar que el trabajo se puede considerar completado incluso si esta tarea todavía se está ejecutando. Otras palabras pueden ser "auxiliar" o "apoyo".
También me encontré con este problema, para el mismo flujo de trabajo que muchos otros han descrito (un contenedor de sidecar que se usa para hacer conexiones proxy o recopilar métricas, y no tiene ningún propósito después de que el otro contenedor en el pod sale con éxito).
Una sugerencia anterior fue designar algunos contenedores como contenedores de "terminación". Me gustaría proponer lo contrario: la capacidad de designar algunos contenedores como "sidecars". Cuando finaliza el último contenedor que no es sidecar en un Pod, el Pod debe enviar TERM a los sidecar.
Esta es también mi solución ideal. Podría sugerir SIGHUP en lugar de SIGTERM; ¡este parece ser el caso de uso exacto para el que la semántica de SIGHUP es relevante! - pero estaría feliz con cualquiera de los dos.
Tal como está, la ejecución de trabajos en Kubernetes requiere parchear manualmente las imágenes de contenedores ascendentes para manejar la comunicación entre contenedores específica de Kubernetes cuando finaliza el contenedor sin sidecar, o intervenir manualmente para terminar el sidecar de cada trabajo para que el pod zombie no lo haga. andar. Ninguno es particularmente agradable.
Estaría dispuesto a hacer un parche para esto, pero me gustaría recibir alguna orientación de @ kubernetes / sig-apps-feature-request antes de profundizar en cualquier código. ¿Estamos de acuerdo con agregar un campo sidecar
a la especificación del pod para que esto funcione? Dudo en realizar cambios en las especificaciones de la cápsula sin estar seguro de que lo queremos. ¿Quizás usar anotaciones por ahora?
@andrewsykim He estado siguiendo este problema por un tiempo (simplemente no he intentado abordarlo yo mismo), pero sugeriría que solo use anotaciones por ahora.
Mi razonamiento es que:
¿Pensamientos?
Hola, hablé con algunos de los chicos de sig-apps en kubecon sobre este problema, básicamente no es algo que esté en su hoja de ruta inmediata, pero es algo que creen que es un caso de uso válido. Están muy abiertos a que alguien de la comunidad aborde esto.
Creé un PR para una propuesta de mejora para resolver esto, así que espero que esto genere alguna discusión https://github.com/kubernetes/community/pull/2148.
¡Gracias por armar eso @ Joseph-Irving! Parece que hay más detalles que deben abordarse para esto, así que me detendré en hacer cualquier trabajo hasta entonces :)
problema-persistente-a-largo-plazo :(
cc @ kow3ns @janetkuo
Sin querer complicar más el asunto, también sería útil poder ejecutar un contenedor de estilo "sidecar" junto con initContainers
.
Mi caso de uso es similar al de las personas aquí, necesito ejecutar el proxy SQL en la nube al mismo tiempo que un initContainer que ejecuta migraciones de bases de datos. Como los initContainers se ejecutan uno a la vez, no veo una forma de hacerlo, excepto para ejecutar el proxy como un servicio de implementación +, pero espero que haya otros casos de uso (administración de registros, etc.) en los que eso no sería un trabajo adecuado alrededor.
@mcfedr Hay una propuesta de mejora razonablemente activa que podría apreciar esa observación con respecto al comportamiento del contenedor de inicio. No me queda claro si eso está dentro del alcance de esta propuesta o una mejora relacionada, pero creo que está lo suficientemente relacionado como para que tenga sentido plantearlo para su consideración.
A pesar de los posibles problemas de implementación / compatibilidad, su modelo ideal presumiblemente sería que los contenedores de inicio de sidecar se ejecutaran simultáneamente con contenedores de inicio de no sidecar, que continúan ejecutándose secuencialmente como ahora, y que los sidecars terminen antes de que se inicien los contenedores de secuencia principal.
por lo que vale, también me gustaría expresar la necesidad de ignorar los sidecars que aún se ejecutan como CloudSQL Proxy et.al.
Me las arreglé para matar el contenedor de cloudsql después de 30 segundos, ya que sé que mi script no tomaría tanto tiempo. Aquí está mi enfoque:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: schedule
spec:
concurrencyPolicy: Forbid
schedule: "*/10 * * * *"
startingDeadlineSeconds: 40
jobTemplate:
spec:
completions: 1
template:
spec:
containers:
- image: someimage
name: imagename
args:
- php
- /var/www/html/artisan
- schedule:run
- command: ["sh", "-c"]
args:
- /cloud_sql_proxy -instances=cloudsql_instance=tcp:3306 -credential_file=some_secret_file.json & pid=$! && (sleep 30 && kill -9 $pid 2>/dev/null)
image: gcr.io/cloudsql-docker/gce-proxy:1.11
imagePullPolicy: IfNotPresent
name: cloudsql
resources: {}
volumeMounts:
- mountPath: /secrets/cloudsql
name: secretname
readOnly: true
restartPolicy: OnFailure
volumes:
- name: secretname
secret:
defaultMode: 420
secretName: secretname
Y me está funcionando.
¿Ven algún inconveniente en este enfoque?
Como creo que también están relacionados y son fácilmente adaptables para CronJobs, esta es mi solución: https://github.com/GoogleCloudPlatform/cloudsql-proxy/issues/128#issuecomment -413444029
Se basa en una de las soluciones alternativas publicadas aquí, pero usa preStop
porque está destinado a implementaciones. Atrapar el sidecar funcionaría de maravilla.
Siguiendo este problema. También se usa el contenedor cloud_sql_proxy como sidecar en cronjob
Usé la implementación de tiempo de espera de @stiko
Simplemente agregar a la conversación la solución propuesta por @ oxygen0211 sobre el uso de Reemplazar es una solución decente por ahora, asegúrese de verificarlo si se encuentra con este problema como lo hice yo.
https://github.com/kubernetes/kubernetes/issues/25908#issuecomment -327396198
Tenemos este KEP aprobado provisionalmente https://github.com/kubernetes/community/pull/2148 , todavía tenemos algunas cosas en las que debemos estar de acuerdo, pero esperamos que llegue a un lugar donde el trabajo pueda comenzar relativamente pronto . Tenga en cuenta que los KEP se trasladarán a https://github.com/kubernetes/enhancements el día 30, por lo que si desea seguirlo, estará allí.
Hasta que llegue el soporte de sidecar, puede usar una solución de nivel de ventana acoplable que se puede eliminar fácilmente más adelante: https://gist.github.com/janosroden/78725e3f846763aa3a660a6b2116c7da
Utiliza un contenedor privilegiado con un conector acoplable montado y etiquetas de kubernetes estándar para administrar contenedores en el trabajo.
Estábamos teniendo el mismo problema con Istio y su sidecar, y lo que decidimos hacer es eliminar el pod a través de curl + preStop hook como este.
dale a tu trabajo una regla mínima de RBAC como esta
apiVersion: v1
kind: ServiceAccount
metadata:
name: myservice-job
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: myservice-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["delete"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: myservice-job-rolebinding
subjects:
- kind: ServiceAccount
name: myservice-job
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: myservice-role
y POD_NAME
y POD_NAMESPACE
a su ENV así
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
y finalmente, agregue un gancho preStop como
lifecycle:
preStop:
exec:
command:
- "/bin/bash"
- "-c"
- "curl -X DELETE -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://$KUBERNETES_SERVICE_HOST/api/v1/namespaces/$POD_NAMESPACE/pods/$POD_NAME?gracePeriodSeconds=1"
Un poco desordenado pero un poco más seguro y menos delicado que intentar matar el contenedor de la ventana acoplable correcto.
Solo lancé esto aquí, pero preparé un controlador hace un tiempo que estaba destinado a monitorear los cambios de pod en ejecución y enviar un SIGTERM a los contenedores de sidecar de manera adecuada. Definitivamente no es el más robusto y, sinceramente, no lo he usado en un tiempo, pero puede ser de ayuda.
Gracias a @jpalomaki en https://github.com/kubernetes/kubernetes/issues/25908#issuecomment -371469801 por la sugerencia de ejecutar cloud_sql_proxy
como una implementación con ClusterIP
servicio, y a @ cvallance en https://github.com/kubernetes/kubernetes/issues/25908#issuecomment -364255363 para el consejo sobre la configuración de tcp:0.0.0.0
en el parámetro cloud_sql_proxy
instances
para permitir que no -conexiones locales al proceso. Juntos, hicieron que sea sencillo permitir que los trabajos cron usen el proxy.
problema a largo plazo (nota para mí mismo)
Mismo problema. Buscando una forma o documentos oficiales sobre cómo usar GKE
trabajo cron con Cloud SQL
Nota al margen:
Google actualizó su Cloud SQL -> Conectando desde la documentación Connecting using the Cloud SQL Proxy Docker image
puedes Connecting using a private IP address
Entonces, si está aquí por la misma razón por la que yo estoy aquí (debido a cloud_sql_proxy), puede usar ahora la nueva función de IP privada
Nota al margen:
Google actualizó su Cloud SQL -> Conectando desde la documentaciónConnecting using the Cloud SQL Proxy Docker image
puedesConnecting using a private IP address
Entonces, si está aquí por la misma razón por la que yo estoy aquí (debido a cloud_sql_proxy), puede usar ahora la nueva función de IP privada
¿La función de IP privada parece necesaria para eliminar todo el clúster y volver a crear uno ...?
@cropse Eso solo es necesario si su clúster no es nativo de VPC.
Hice una solución para este problema, no es la gran solución, pero funcionó, espero que esto ayude antes de que se agregue la función, y VPC es una forma de solucionarlo, pero eliminar todo el clúster sigue siendo doloroso.
Solo para agregar mis dos centavos: las pruebas de timón también se rompen si se produce la inyección de istio sidecar ya que la cápsula nunca se completa.
@dansiviter puede verificar mi solución alternativa, ya probé en mi proyecto con helm.
¡Espero ver esto implementado! :)
tenemos el mismo problema con los trabajos normales cuando se le inyecta un proxy de Istio, por encima de eso también queremos esto porque queremos ejecutar trabajos de CI con Prow.
por ejemplo, contenedor de la aplicación Rails + contenedor de la base de datos del sidecar para realizar pruebas.
@cropse Gracias. No lo he probado ya que tendríamos que configurarlo para todas las pruebas. Solo permitimos que el Pod (las pruebas de timón no permiten el trabajo, desafortunadamente) falle y confiamos en inspeccionar manualmente el registro hasta que este problema se solucione a largo plazo. Sin embargo, también se está convirtiendo en un problema para otros trabajos, por lo que es posible que tengamos que reconsiderar esa posición.
Para su información, el problema de seguimiento de esta función está aquí https://github.com/kubernetes/enhancements/issues/753 si la gente quiere seguir adelante, tenemos un KEP, hicimos algunos prototipos (hay una rama / video de POC ), todavía es necesario aclarar algunos de los detalles de implementación antes de que esté en un estado implementable.
Nota al margen:
Google actualizó su Cloud SQL -> Conectando desde la documentaciónConnecting using the Cloud SQL Proxy Docker image
puedesConnecting using a private IP address
Entonces, si está aquí por la misma razón por la que yo estoy aquí (debido a cloud_sql_proxy), puede usar ahora la nueva función de IP privada
Estuve aquí por la misma razón, sin embargo, nuestro Cloud SQL se aprovisionó antes de que esta función estuviera lista. Combiné sugerencias anteriores y obtuve esto (probablemente no sea ideal, pero funciona) para mi gráfico de timón de dbmate migrator.
containers:
- name: migrator
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ["/bin/bash", "-c"]
args:
- |
/cloud_sql_proxy -instances={{ .Values.gcp.project }}:{{ .Values.gcp.region }}:{{ .Values.gcp.cloudsql_database }}=tcp:5432 -credential_file=/secrets/cloudsql/credentials.json &
ensure_proxy_is_up.sh dbmate up
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: mysecret
key: DATABASE_URL
volumeMounts:
- name: cloudsql-instance-credentials
mountPath: /secrets/cloudsql
readOnly: true
volumes:
- name: cloudsql-instance-credentials
secret:
secretName: cloudsql-instance-credentials
ensure_proxy_is_up.sh
#!/bin/bash
until pg_isready -d $(echo $DATABASE_URL); do
sleep 1
done
# run the command that was passed in
exec "$@"
¿Sería un buen momento para una noción de contenedores sidecar en Kubernetes y permitir la limpieza de vainas en función de si los contenedores que no son sidecar han terminado?
@Willux Estoy en el
@krancour gracias por la actualización. Debo haberme perdido ese detalle. No hubo mucha actividad aquí últimamente, así que solo quería asegurarme de que haya algo en curso :)
Como referencia, hice una versión de sidecar en la nube-sql-proxy de la solución alternativa de @ jmillikin-stripe donde un archivo en un volumen compartido comunica el estado al sidecar.
Funciona bien, pero es, con mucho, el truco más desagradable en mi configuración de K8s :(
apiVersion: batch/v1 kind: Job metadata: name: example-job spec: template: spec: containers: - name: example-job image: eu.gcr.io/example/example-job:latest command: ["/bin/sh", "-c"] args: - | trap "touch /tmp/pod/main-terminated" EXIT run-job.sh volumeMounts: - mountPath: /tmp/pod name: tmp-pod - name: cloudsql-proxy image: gcr.io/cloudsql-docker/gce-proxy:1.11 command: ["/bin/sh", "-c"] args: - | /cloud_sql_proxy --dir=/cloudsql -instances=example:europe-west3:example=tcp:3306 -credential_file=/secrets/cloudsql/credentials.json & CHILD_PID=$! (while true; do if [[ -f "/tmp/pod/main-terminated" ]]; then kill $CHILD_PID; echo "Killed $CHILD_PID as the main container terminated."; fi; sleep 1; done) & wait $CHILD_PID if [[ -f "/tmp/pod/main-terminated" ]]; then exit 0; echo "Job completed. Exiting..."; fi volumeMounts: - name: cloudsql-instance-credentials mountPath: /secrets/cloudsql readOnly: true - name: cloudsql mountPath: /cloudsql - mountPath: /tmp/pod name: tmp-pod readOnly: true restartPolicy: Never volumes: - name: cloudsql-instance-credentials secret: secretName: cloudsql-instance-credentials - name: cloudsql emptyDir: - name: tmp-pod emptyDir: {} backoffLimit: 1
¿Alguien interno del proyecto puede comentar sobre el progreso de este problema?
¿Es justo suponer que esta es la mejor opción para aquellos de nosotros que trabajamos en el canal de versión estable de GKE, que probablemente no se pondrá al día con Kubernetes 1.18 durante unos meses como mínimo?
@Datamance en este punto, el KEP para abordar este problema parece que está indefinidamente en espera .
Publiqué hace un tiempo este comentario , que era mi antigua solución. No estoy tratando de presionar mis propias cosas aquí, solo ese comentario se ha perdido en los "100 comentarios más ..." de github y pensé que resurgirlo podría ser útil nuevamente.
@nrmitchi gracias por
Descubrimos un enfoque diferente, si agrega lo siguiente a sus contenedores de Pod:
securityContext: capabilities: add: - SYS_PTRACE
luego podrá grep del Pid en otros contenedores, ejecutaremos lo siguiente al final de nuestro contenedor principal:
sql_proxy_pid=$(pgrep cloud_sql_proxy) && kill -INT $sql_proxy_pid
@krancour me alegro de haber ayudado. Si miras la red en ese repositorio, hay un par de bifurcaciones que están casi definitivamente en un lugar mejor que el original, y podría ser mejor construir a partir de / usar.
IIRC, el tenedor de limonada-hq tenía algunas adiciones útiles.
@nrmitchi , he estado mirando el código, pero puede ser más rápido preguntarte ...
¿Puede comentar brevemente sobre los requisitos previos que puedan existir que no se mencionan en el archivo README?
Por ejemplo, ¿las imágenes en las que se basan sus sidecares requieren algún conocimiento especial de esta solución? Por ejemplo, ¿necesitan escuchar en un puerto específico una señal del controlador? O tal vez deben incluir un cierto caparazón (¿bash?)
@krancour Comenzaré mi respuesta con una nota de que esta solución se escribió hace un par de años y mi memoria puede estar un poco oxidada.
Fue diseñado en ese momento de tal manera que los contenedores en cuestión no necesitaban ser conscientes de la solución alternativa. Usábamos principalmente aplicaciones de terceros en sidecar (por ejemplo, creo que stripe / veneur era una) y no queríamos bifurcar / modificar.
El único requisito de los sidecars es que escuchen correctamente una señal SIGTERM y luego se apaguen. Recuerdo haber tenido algunos problemas con el código de terceros que se ejecutaba en sidecars que esperaban una señal diferente y tenían que solucionarse, pero en realidad el controlador debería haber permitido que se especificara la señal enviada (es decir, SIGINT en lugar de SIGTERM).
No necesitan escuchar ningún puerto en busca de una señal, ya que el controlador usa un exec
para señalar el proceso principal del sidecar directamente. IIRC en el momento en que esa funcionalidad se copió del código de Kubernetes porque no existía en el cliente. Creo que esto existe en el cliente oficial ahora y probablemente debería actualizarse.
Descubrimos un enfoque diferente, si agrega lo siguiente a sus contenedores de Pod:
securityContext: capabilities: add: - SYS_PTRACE
luego podrá grep del Pid en otros contenedores, ejecutaremos lo siguiente al final de nuestro contenedor principal:
sql_proxy_pid=$(pgrep cloud_sql_proxy) && kill -INT $sql_proxy_pid
@ ruiyang2015 gracias por este truco.
Sin embargo, si alguien lo implementa, asegúrese de comprender las implicaciones de compartir un proceso ns entre los contenedores
@nrmitchi
utiliza un ejecutivo para señalar el proceso principal del sidecar directamente
Esa es parte de la razón por la que pregunté ... Supongo que, específicamente, me pregunto si esto no funciona para contenedores basados en imágenes construidas FROM scratch
.
@krancour Punto justo, nunca fui y lo probé con contenedores que estaban fuera de scratch
. Mirando el código (o mi versión original; esto podría haber cambiado en bifurcado) parece que va a depender de bash
, pero debería poder modificarse.
dependerá de bash, pero debería poder modificarse
Claro, pero mientras se esté ejecutando, siempre dependerá de algún binario que esté presente en el contenedor y, para un contenedor de scratch, no hay nada, excepto lo que ponga allí explícitamente. 🤷♂
Dada esa limitación, no puedo usar esto para un caso de uso donde los contenedores que se están ejecutando pueden ser totalmente arbitrarios y especificados por un tercero. Ah, y también tengo contenedores de Windows en juego.
En su lugar, mencionaré lo que voy a decidir. Probablemente sea demasiado torpe para la mayoría de los casos de uso, pero lo menciono en caso de que el caso de uso de otra persona sea lo suficientemente similar al mío como para salirse con la suya ...
Puedo permitirme el lujo de simplemente _eliminar_ una cápsula cuyo contenedor "principal" ha salido, siempre que registre primero el estado de salida. Así que terminaré escribiendo un controlador que monitoreará algún contenedor designado (a través de anotaciones) para su finalización, registrará su éxito o falla en un almacén de datos que ya rastrea el estado del "trabajo" y luego eliminará el pod por completo.
Por si acaso, probablemente pondré un poco de retraso en la eliminación de la vaina para maximizar las posibilidades de mi agregación de registro central de obtener las últimas líneas de la salida del contenedor principal antes de que sea torpedeado.
Torpe, pero puede funcionar para algunos.
@krancour Totalmente cierto. Tal como está, el controlador no funcionará para bases de uso arbitrarias. Honestamente, nunca volví e intenté abstraer parte de la implementación para respaldar otros casos porque realmente pensé que el KEP mencionado anteriormente se habría fusionado y habría hecho que la necesidad de esta funcionalidad fuera discutible.
Dado que este problema tiene como 4 años, el KEP no ha desaparecido todavía, y el estado del arte es un script de shell en línea pirateado que reemplaza cada punto de entrada, decidí codificar el truco "estándar" (lápidas en un volumen compartido ) en un binario Go que se puede convertir fácilmente en imágenes de contenedores mediante una compilación de varias etapas.
https://github.com/karlkfi/kubexit
Hay algunas formas de usarlo:
Editar: v0.2.0 ahora admite "dependencias de nacimiento" (inicio diferido) y "dependencias de muerte" (terminación automática).
Comentario de drive-by: esto se ve exactamente como https://github.com/kubernetes/enhancements/issues/753
@vanzin, como se ha señalado antes , KEP está en espera indefinida.
Mi caso de uso para esto es que Vault proporciona credenciales para que se ejecute un CronJob. Una vez que se realiza la tarea, el sidecar de Vault todavía se está ejecutando con el trabajo en un estado pendiente y eso hace que el sistema de monitoreo piense que algo anda mal. Es una pena lo que pasó con el KEP.
Comentario más útil
Como referencia, aquí está la locura de bash que estoy usando para simular el comportamiento de sidecar deseado: