Kubernetes 1.31: las estabilizaciones que importan en el día a día
Índice de contenidos
- Puntos clave
- AppArmor deja de ser una anotación
- Sidecars reales, al fin
- DRA: alpha, pero con intención
- Lo que se fue
- El scheduler, más silencioso
- Checklist honesto de upgrade
- Preguntas frecuentes
- ¿Los sidecars nativos de Kubernetes 1.31 ya son estables?
- ¿Puedo usar Dynamic Resource Allocation en producción con Kubernetes 1.31?
- ¿Qué pasa si mi clúster todavía usa los drivers in-tree de CephFS o CephRBD?
- Conclusión
- Fuentes
Actualizado: 2026-07-07
Kubernetes 1.31 no trae fuegos artificiales, pero cierra deudas antiguas: AppArmor llega a GA, los sidecars nativos ya funcionan habilitados por defecto camino a su estable en 1.33, y DRA avanza en alpha hacia la beta. Repaso práctico desde la óptica de quien opera clústeres en producción.
Kubernetes 1.31 se publicó el 13 de agosto de 2024 y es, probablemente, una de las releases más tranquilas de los últimos dos años. No hay ningún titular espectacular, ningún cambio que obligue a reescribir manifiestos, ningún cliente de API rediseñado. Y precisamente por eso merece una lectura detenida: cuando una release no empuja novedades ruidosas, suele estar cerrando deudas antiguas. 1.31 cierra varias, y algunas cambian el día a día de quien opera clústeres mucho más de lo que aparenta.
Puntos clave
-
AppArmor pasa a GA como campo de primera clase en
securityContext, eliminando la dependencia de anotaciones. -
Los sidecars declarados como
initContainersconrestartPolicy: Alwaysllevan ya dos releases habilitados por defecto y se comportan en la práctica con soporte totalmente integrado, aunque la graduación formal a estable no llega hasta 1.33. -
Dynamic Resource Allocation (DRA) con parámetros estructurados sigue en alpha: preparar la arquitectura ahora ahorra trabajo cuando lleguen la beta en 1.32 y el GA en 1.34.
-
Los drivers in-tree de CephFS y CephRBD quedan eliminados: conviene comprobar las
storageclassantes de tocar el control plane. -
El scheduler recibe ajustes incrementales de rendimiento; los clústeres cerca de saturación son quienes más lo notan.
AppArmor deja de ser una anotación
Durante años, aplicar un perfil de AppArmor a un pod se hacía mediante una anotación en el metadata, una convención heredada del pasado que arrastraba todos los problemas de las anotaciones: sin validación de esquema, sin descubrimiento desde kubectl explain, fácil de olvidar en una copia-pega de Helm. En 1.31, AppArmor pasa a GA como un campo de primera clase dentro de securityContext.
apiVersion: v1
kind: Pod
metadata:
name: hardened-web
spec:
securityContext:
appArmorProfile:
type: Localhost
localhostProfile: restricted-web
containers:
- name: app
image: nginx:1.27
El cambio parece cosmético, pero tiene consecuencias prácticas: los admission webhooks pueden validar el perfil como parte del esquema, las herramientas de políticas (OPA/Gatekeeper, Kyverno) tienen una ruta canónica que inspeccionar, y los equipos de compliance dejan de depender de anotaciones que se pierden en rebases de charts. Para quien ya hace hardening con AppArmor, este cambio consolida lo que hasta ahora era una capa frágil y hace realista forzar un perfil base en todo el clúster sin montar un webhook mutante.
Sidecars reales, al fin
La estabilización más esperada. Hasta 1.29 el patrón sidecar era, literalmente, un hack: un contenedor más dentro del pod, sin garantías de orden de arranque respecto al contenedor principal, sin orden de terminación, y con problemas clásicos cuando el proxy moría antes que la aplicación. La solución comunitaria eran scripts de preStop, shareProcessNamespace, y workarounds específicos por service mesh.
En 1.31, los sidecars declarados como initContainers con restartPolicy: Always ya llevan dos releases habilitados por defecto y funcionan tal como se prometió, aunque su graduación formal a estable no llegará hasta 1.33. Arrancan antes del contenedor principal, se reinician de forma independiente si caen, y terminan después de que el principal haya finalizado. Eso resuelve de un plumazo tres dolores:
-
Service meshes que bloqueaban jobs porque el sidecar seguía vivo.
-
Colectores de logs que perdían los últimos bytes antes del shutdown.
-
Proxies de seguridad que arrancaban tarde y dejaban ventana sin tráfico cubierto.
El impacto operativo es enorme para quien corre Istio, Linkerd, Vector o cualquier colector como sidecar. Los manifiestos se simplifican y desaparece una clase entera de incidentes de turno de noche. Entronca directamente con el análisis que hicimos de Kubernetes 1.28 y el patrón sidecar nativo, donde el feature estaba en alpha: aquel artículo explicaba la motivación; 1.31 es la receta definitiva.
DRA: alpha, pero con intención
Dynamic Resource Allocation con parámetros estructurados sigue en alpha en 1.31: la API pasará a v1beta1 en 1.32 y no alcanzará el GA hasta 1.34. Sustituye al viejo modelo de device plugins para GPUs, FPGAs y aceleradores varios por una abstracción basada en claims, similar a cómo funcionan los volúmenes persistentes. Un pod declara qué necesita, un driver lo resuelve, el scheduler reconcilia.
Para single-tenant con una sola GPU por nodo, los device plugins seguían funcionando bien; pero en cuanto entras en territorio de sharing, time-slicing de GPUs, o pools heterogéneos, el modelo viejo se quedaba corto. En 1.31 todavía exige activar feature gates explícitos y no es apto para producción, pero quien esté planificando plataformas de ML o inferencia conviene que lo pruebe en staging ya: el salto a beta en 1.32 y al GA en 1.34 obligará a decisiones de arquitectura y es mejor llegar con la forma del API interiorizada.
Lo que se fue
Los drivers in-tree de CephFS y CephRBD quedan eliminados. Si alguien sigue usando alguno, la migración a los CSI drivers equivalentes es requisito previo al upgrade. Este tipo de eliminaciones es el que provoca sorpresas: el clúster arranca bien, pero los PVCs antiguos quedan huérfanos y no se sabe hasta que un pod reintenta attach. El workflow seguro es un kubectl get storageclass revisando provisioner, cruzado con los PV activos, antes de tocar el control plane.
El scheduler, más silencioso
Las mejoras de scheduler en 1.31 son incrementales, sin una cifra de throughput publicada oficialmente por el proyecto, pero se notan en dos escenarios concretos:
-
Clústeres grandes con muchos pods en
Pendingesperando hueco. -
Cargas con preempción activa donde las decisiones de desalojo eran erráticas.
Nada que justifique un upgrade por sí solo, pero sí que explica por qué clústeres cercanos a saturación se sienten más fluidos tras actualizar. Quien mide el coste real de los nodos con Kubecost u OpenCost verá el impacto en utilización tras el salto.
Checklist honesto de upgrade
Antes de subir desde 1.29 o 1.30 conviene cerrar seis cosas:
-
Informe de deprecaciones limpio en la versión actual.
-
Backup reciente de etcd verificado con
etcdctl snapshot status. -
Drenado de nodos respetando los PDB declarados (y comprobando que los PDB no son imposibles de satisfacer).
-
CSI drivers al día con las matrices de compatibilidad.
-
Prueba real de los service meshes que se vayan a migrar al nuevo modelo de sidecar.
-
Canario de al menos un nodo con la nueva kubelet antes de rodar sobre el resto.
El upgrade en sí, con kubeadm, no tiene misterio: kubeadm upgrade plan, kubeadm upgrade apply v1.31.x, y luego kubelet nodo a nodo respetando los drains. Lo que duele no es el comando; es haberse saltado los seis puntos anteriores. Quien combine esto con una estrategia GitOps, como la descrita en GitOps con ArgoCD, puede validar los manifiestos actualizados contra el nuevo API antes de tocar producción.
Preguntas frecuentes
¿Los sidecars nativos de Kubernetes 1.31 ya son estables?
Funcionan habilitados por defecto desde 1.29 y en 1.31 se comportan tal como se documentan, pero la graduación formal a «stable» no llega hasta la versión 1.33. En la práctica, quien los use en 1.31 ya puede confiar en el orden de arranque y terminación.
¿Puedo usar Dynamic Resource Allocation en producción con Kubernetes 1.31?
No sin reservas: en 1.31 DRA con parámetros estructurados sigue en alpha y exige activar feature gates explícitos en el API server, el scheduler y el kubelet. La API pasa a v1beta1 en 1.32 y alcanza el GA en 1.34.
¿Qué pasa si mi clúster todavía usa los drivers in-tree de CephFS o CephRBD?
Deja de funcionar tras el upgrade a 1.31: hay que migrar antes a los CSI drivers equivalentes (ceph-csi), comprobando las storageclass y los PV activos para evitar PVCs huérfanos.
Conclusión
Kubernetes 1.31 no va a aparecer en las keynotes de ningún evento, y está bien que así sea. Es una release de higiene: saca AppArmor del limbo de las anotaciones, consolida el patrón sidecar camino a su estabilización formal en 1.33, y deja el camino preparado para que DRA avance hacia el GA sin prisas. Para quien lleva clústeres en producción, la pregunta no es si vale la pena actualizar, sino cuánto antes puede hacerse antes de que el hueco con upstream se ensanche y cada salto empiece a acumular su propia deuda técnica.
Lee también la versión en inglés: Kubernetes 1.31: the stabilisations that matter day to day.
Fuentes: Kubernetes v1.31: Elli, anuncio oficial de la release[1] · KEP-4381: Dynamic Resource Allocation con parámetros estructurados[2] · Sysdig: qué hay de nuevo en Kubernetes 1.31[3] · Simplyblock: Kubernetes 1.31 y el día del storage[4]