Despliegue en Kubernetes
TinyMQ v2.9.5 introduce soporte nativo para la orquestación con Kubernetes. Dado que TinyMQ gestiona su propio clustering P2P sin maestro, desplegarlo en K8s es sencillo usando un StatefulSet.
Inicio rápido (kind)
Puedes probar el cluster de forma local usando kind.
# 1. Create a local cluster
kind create cluster --name tinymq-test
# 2. Build the image locally
docker build -t tinymq:dev .
kind load docker-image tinymq:dev --name tinymq-test
# 3. Create the shared cluster secret
kubectl create secret generic tinymq-secrets --from-literal=cluster-secret=super_secret_key
# 4. Apply the manifest
kubectl apply -f k8s/tinymq-cluster.yaml
# 5. Watch the cluster form and elect a leader
kubectl logs -l app=tinymq -f --prefix --max-log-requests 3
El manifest oficial
El manifest oficial (k8s/tinymq-cluster.yaml) despliega un StatefulSet de 3 nodes con un Headless Service para el descubrimiento de peers y un servicio con balanceo de carga para el acceso de clientes.
Decisiones de diseño clave
Desplegar una base de datos con estado en Kubernetes requiere una configuración específica. Estas son las decisiones de diseño incorporadas en el manifest:
1. publishNotReadyAddresses: true
En el Headless Service, configuramos publishNotReadyAddresses: true. Sin esto, tinymq-1 no puede resolver tinymq-0.tinymq-headless durante el arranque progresivo porque los pods aún no están marcados como "Ready". Esto provocaría que la primera elección de leader fallara indefinidamente.
2. TINYMQ_CLUSTER_SELF vía Downward API
Por defecto, los servidores TCP se vinculan a 0.0.0.0. Si un node anuncia 0.0.0.0 como su dirección a los peers, estos no podrán conectarse. Usamos la Downward API para inyectar el nombre DNS específico del pod en TINYMQ_CLUSTER_SELF.
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: TINYMQ_CLUSTER_SELF
value: "$(POD_NAME).tinymq-headless:7901"
3. Tiempo de espera de replicación aumentado
La resolución DNS dentro de los pods de Kubernetes durante el arranque puede ser lenta. El valor por defecto de TINYMQ_CLUSTER_REPLICATE_TIMEOUT de 500ms es insuficiente. El manifest lo sobreescribe a 2s.
4. Aislamiento de puertos
El puerto 7901 (comunicación del cluster) solo está expuesto en el Headless Service. El tinymq-service principal con balanceo de carga solo expone HTTP (7800) y MQTT (1883), protegiendo el protocolo del cluster de los clientes externos.
Resolución de problemas
| Síntoma | Comando | Causa probable |
|---|---|---|
Pods atascados en Pending | kubectl describe pod tinymq-0 | Falta StorageClass por defecto / proveedor de PVC |
CrashLoopBackOff | kubectl logs tinymq-0 --previous | Variable de entorno incorrecta o tinymq-secrets ausente |
| Bucle de elección | kubectl logs -l app=tinymq | grep -E "Election|VOTE|ONLINE" | DNS sin resolver; verifica publishNotReadyAddresses |
SEC-ALERT: Invalid HMAC | kubectl logs tinymq-0 | grep SEC-ALERT | Secret diferente entre pods |
| TCP bloqueado | kubectl exec -it tinymq-0 -- nc -zv tinymq-1.tinymq-headless 7901 | NetworkPolicy bloqueando el puerto 7901 |