Versiones y actualizaciones
DeviceChain se distribuye como un conjunto de imágenes de contenedor precompiladas y versionadas, más un chart de Helm. No necesita compilar nada para ejecutarlo: descargue una versión publicada, instale el chart y actualice in situ sin tiempo de inactividad.
La v0.9.0 reemplazó la cadena de migraciones de cada servicio por una única línea base congelada, por lo que
una instancia v0.8.x existente no puede migrarse a ella con helm upgrade: la migración falla con
already exists. En su lugar, recree la instancia. Consulte
La compactación de la línea base de la v0.9.0 más abajo antes de hacer nada más.
Modelo de versionado
Cada versión es una única etiqueta git de versión semántica (vX.Y.Z). Ese único número cubre
todo en conjunto: cada imagen de servicio, el operador, el chart de Helm y la CLI
dcctl se publican todos con la misma versión. No hay desfase de versión por servicio
del que preocuparse: un despliegue es un único número coherente.
- Las versiones estables son
vX.Y.Z(por ejemplo,v1.2.0). La etiqueta:latestsigue a la versión estable más reciente. - Las versiones preliminares son
vX.Y.Z-rc.N(por ejemplo,v1.2.0-rc.1). Estas nunca mueven:latest.
Estabilidad previa a 1.0
Hasta la v1.0.0, cualquier versión —incluida una versión de parche— puede cambiar APIs, esquemas o comportamiento sin una capa de compatibilidad. Esto es deliberado: mientras el modelo de datos aún se está asentando, preferimos un cambio limpio antes que cargar con una capa de compatibilidad que tendríamos que mantener para siempre.
Cada cambio disruptivo se indica al principio de las notas de esa versión. Léalas antes de actualizar. Son la lista autorizada; el número de versión por sí solo no le indica si una versión es segura para su despliegue.
En concreto, antes de la v1.0.0 debe esperar que una versión pueda:
- endurecer la validación, de modo que una solicitud que antes tenía éxito ahora sea rechazada, por lo general porque se estaba aceptando silenciosamente o descartando silenciosamente
- cambiar o eliminar un campo GraphQL, en lugar de marcarlo obsoleto durante un ciclo
- alterar el esquema de la base de datos de formas que una reversión no deshará
- reemplazar por completo la línea base de migraciones, lo que elimina por entero la ruta de
actualización en lugar de limitarse a hacerla unidireccional. Cuando eso ocurre, las notas de la versión lo
indican al principio, y la única vía es recrear la instancia. La
v0.9.0es una versión de este tipo
La propiedad de "actualizar in situ sin tiempo de inactividad" descrita arriba describe la mecánica de una actualización progresiva. No es una promesa de que sus llamadas a la API existentes conserven el mismo significado a través de un incremento de versión previo a 1.0.
Una vez que se publique la v1.0.0, esta sección se reemplaza por una promesa de compatibilidad de versionado semántico normal: cambios disruptivos solo en una versión mayor.
Debido a que las versiones son frecuentes antes de la disponibilidad general (GA), la versión menor marca un hito (una funcionalidad o subsistema significativo que se lanza) y la versión de parche lleva el ritmo continuo de correcciones y endurecimiento. Una versión de parche no es automáticamente una actualización de bajo riesgo durante este período; nuevamente, las notas de la versión son las que se lo indican.
Imágenes
Las imágenes se publican en el Registro de Contenedores de GitHub público bajo
ghcr.io/devicechain-io, por ejemplo, ghcr.io/devicechain-io/device-management. Son
multiarquitectura (linux/amd64 y linux/arm64) y se construyen sobre una base distroless sin
privilegios de root, por lo que se ejecutan como un usuario sin privilegios, sin shell y con una superficie de ataque mínima.
Debido a que el registro es público, no se requieren credenciales para descargar las imágenes publicadas.
Instalación de una versión específica
Fije la etiqueta de imagen a la versión que desea:
helm install dc deploy/helm/devicechain \
--set instance.id=devicechain \
--set image.tag=v1.2.0
El chart de Helm en sí también se publica como un artefacto OCI, por lo que puede instalarlo sin una copia local del repositorio:
helm install dc oci://ghcr.io/devicechain-io/charts/devicechain \
--version 1.2.0 \
--set instance.id=devicechain \
--set image.tag=v1.2.0
Actualizaciones sin tiempo de inactividad
Actualizar a una nueva versión es normalmente un helm upgrade simple, y el chart y los servicios están
diseñados para hacer avanzar a los clientes sin perder tráfico. Hasta ahora hay dos versiones que son
excepciones, ambas documentadas más abajo: la transición a la ingesta duradera, que sigue siendo un
helm upgrade pero tiene un efecto secundario visible, y la v0.9.0, a la que no se puede actualizar en
absoluto. Consulte las notas de la versión a la que va a migrar antes de ejecutar el comando:
helm upgrade dc deploy/helm/devicechain \
--set instance.id=devicechain \
--set image.tag=v1.3.0
Lo que hace que el despliegue sea seguro:
- Aumentar antes de terminar. Cada Deployment usa una estrategia
RollingUpdateconmaxUnavailable: 0ymaxSurge: 1, de modo que un pod nuevo debe pasar su sonda de disponibilidad/readyzantes de que se elimine un pod antiguo. La capacidad nunca disminuye durante el despliegue. - Apagado ordenado / drenaje de conexiones. Cuando se le pide a un pod que termine, primero
informa "no listo" (de modo que el Service deje de enrutarle nuevas solicitudes), espera una breve
ventana de drenaje para que ese cambio se propague, y solo entonces termina el trabajo en curso y
se apaga. Configure la ventana con
shutdownDrainSeconds(por defecto5), mantenida de forma segura por debajo determinationGracePeriodSeconds(por defecto30). - Migraciones de esquema coordinadas. Los servicios ejecutan migraciones de base de datos bajo un bloqueo a nivel de base de datos, de modo que cuando varias réplicas se inician a la vez, exactamente una aplica las migraciones y el resto espera; sin condiciones de carrera, sin DDL duplicado.
Para lograr un verdadero cero tiempo de inactividad, ejecute replicas: 2 (o más) para cada área, de modo que el despliegue siempre tenga
un pod activo sirviendo tráfico. Una sola réplica igualmente tiene una breve brecha mientras se reemplaza su único pod.
Configúrelo globalmente con --set replicas=2, o por área bajo
functionalAreas.<area>.replicas. Un PodDisruptionBudget se genera automáticamente para cualquier
área con más de una réplica, de modo que los drenajes de nodo no puedan expulsar a todas las réplicas a la vez.
La compactación de la línea base de la v0.9.0
La v0.9.0 es la única versión a la que no se puede llegar con helm upgrade.
Antes de ella, el esquema de cada servicio se construía mediante una cadena de migraciones aplicadas en orden.
La v0.9.0 reemplaza todas esas cadenas por una única línea base congelada: una migración por servicio que
crea el esquema completo tal y como está. Una base de datos creada por v0.8.x ya aplicó la cadena antigua, así
que cuando se encuentra con la línea base intenta crear tablas que ya existen y falla con already exists. El
fallo es evidente y ocurre en el arranque; no corrompe nada.
No hay ruta de migración y, antes de la v1.0.0, no la habrá. Mantener una capa de compatibilidad para una forma
de esquema que todavía se está asentando es precisamente el coste que este proyecto ha decidido no asumir
mientras todas las instalaciones siguen siendo tempranas.
Para pasar a la v0.9.0, recree la instancia:
# Exporte antes lo que necesite: esto descarta las bases de datos.
dcctl destroy local devicechain
dcctl bootstrap local devicechain
La protección de destrucción protege las bases de datos frente a una operación normal de
helm, no frente a un dcctl destroy deliberado. Si la instancia contiene telemetría, definiciones de
dispositivos o paneles que le importan, expórtelos antes de empezar. No existe una ruta in situ que los
conserve a través de esta versión.
Es un coste puntual, asumido deliberadamente mientras las únicas instalaciones de la plataforma son tempranas.
A partir de la v0.9.0, un cambio de esquema añade una nueva migración sobre la línea base, lo que vuelve a
ser un helm upgrade normal; por tanto, esta sección describe una única versión, no una nueva política.
La transición única a la ingesta duradera
La versión que introduce la ingesta MQTT duradera cambia la forma en que event-sources recibe
la telemetría de dispositivos: en lugar de suscribirse al broker como cliente MQTT, consume un
flujo de captura duradero que el broker escribe antes de confirmar la recepción al dispositivo. Esto
es lo que evita que se pierda telemetría cuando event-sources está caído.
Cruzar esa versión una vez es un helm upgrade normal, pero espere una breve ventana de
telemetría duplicada y planifique para ello:
- Durante el despliegue, el pod saliente sigue ingiriendo por MQTT mientras el pod entrante ya ha comenzado a consumir el flujo de captura, de modo que los mensajes publicados en ese solapamiento son ingeridos por ambos. La ventana está acotada por cuánto tiempo coexisten los dos pods: el arranque del pod entrante más el drenaje del pod saliente.
- Los eventos que llevan tanto un
altIdcomo unaoccurredTimeprovista por el dispositivo no se ven afectados: la clave de deduplicación del lado de escritura es(tenant, altId, occurredTime), de modo que esos duplicados se colapsan. Un evento con unaltIdpero sinoccurredTimeno se colapsa: el decodificador estampa la hora actual cuando el dispositivo omite una, y las dos copias se decodifican en pods diferentes en instantes diferentes, por lo que obtienen marcas de tiempo diferentes y terminan como dos filas. La telemetría sinaltIdno se deduplica en absoluto. - El solapamiento se prefiere deliberadamente. El orden alternativo —detener el pod antiguo antes de que exista el flujo de captura— pierde cada mensaje que el broker confirma en la brecha, y esa pérdida es silenciosa: al dispositivo se le informa que el mensaje fue aceptado y nunca se almacena. Una lectura duplicada es visible y corregible; una faltante no es ninguna de las dos cosas.
event-sources como Recreatestrategy: Recreate en event-sources produce exactamente el orden con pérdida descrito arriba, porque
termina el pod antiguo antes de que el nuevo cree el flujo de captura. El chart se niega
a renderizar esta configuración en lugar de dejar que descarte telemetría silenciosamente. event-sources
no es un servicio de escritor único y no gana nada con Recreate; una vez realizada la transición puede ejecutar
múltiples réplicas, algo que la ruta de cliente MQTT que reemplaza no podía hacer.
Durabilidad de los datos
La capa de base de datos es intencionalmente independiente del ciclo de vida de la aplicación. Ambas bases de datos se aprovisionan como infraestructura separada con una protección contra destrucción, de modo que actualizar, reinstalar o desinstalar la aplicación nunca las toca. Ese es el caso habitual y es seguro.
La protección resguarda cada base de datos mientras está dentro de la configuración de infraestructura. No resguarda una que se haya sacado fuera de ella: un recurso eliminado de la configuración deja de estar cubierto por las reglas que esa configuración declara, y el plan de eliminación se ejecutará con éxito. Los clústeres de base de datos además son dueños de sus volúmenes, así que eliminar uno se lleva sus datos consigo en lugar de dejar un volumen desasociado.
No edites la base de datos para sacarla de la configuración de infraestructura como forma de reemplazarla.
Actualizar una instancia creada antes de que las bases de datos pasaran al operador es el
único caso en que esto aparece, y se rechaza en tiempo de planificación en lugar de dejarse
al azar. Vuelca primero ambas bases de datos y vuelve a ejecutar el arranque con
--allow-legacy-db-removal, que afirma que te has ocupado de los datos y no verifica nada.
Para una instancia local, dcctl destroy seguido de un arranque nuevo es más simple y
descarta los datos de forma deliberada.
Esto es durabilidad de los volúmenes en ejecución; no es un sustituto de las copias de seguridad programadas y la recuperación a un punto en el tiempo, que se aprovisionan con la infraestructura de producción. Consulte Despliegue y operador para saber cómo se separan las capas de infraestructura y aplicación.