Kubernetes 1.19: una descripción general de las principales innovaciones

Hoy, 25 de agosto, se llevará a cabo una nueva versión de Kubernetes (se retrasó casi 2 meses en total) : 1,19. Siguiendo la tradición de nuestro blog, estamos hablando de los cambios más significativos de la nueva versión.







La información utilizada para preparar este material se toma de la tabla de seguimiento de mejoras de Kubernetes , CHANGELOG-1.19 , la descripción general de Sysdig , así como problemas relacionados, solicitudes de extracción, propuestas de mejora de Kubernetes (KEP).



Comencemos con algunas innovaciones importantes de naturaleza bastante general ...



Con el lanzamiento de Kubernetes 1.19, la "ventana de soporte" para las versiones de Kubernetes se ha incrementado de 9 meses (es decir, las últimas 3 versiones) a 1 año (es decir, 4 versiones). ¿Por qué?



Resultó que debido a la alta velocidad del desarrollo del proyecto (lanzamientos importantes frecuentes), los administradores de clústeres de Kubernetes no tienen tiempo para actualizar sus instalaciones. Los autores del KEP correspondiente se refieren a una encuesta realizada por el grupo de trabajo a principios del año pasado y mostró que alrededor de un tercio de los usuarios de Kubernetes están lidiando con versiones obsoletas de K8 que se ejecutan en producción:





(En el momento de la encuesta, la versión actual de Kubernetes era 1.13, es decir, todos los usuarios de K8s 1.9 y 1.10 funcionaron con versiones que ya no eran compatibles en ese momento).



Por lo tanto, se supone que una extensión de 3 meses del período de soporte para las versiones de Kubernetes (la publicación de parches que solucionan los problemas encontrados en el código) garantizará que más del 80% de los usuarios trabajarán en versiones compatibles de K8 (en lugar del 50-60% asumido en este momento ).



Otra gran desarrollo: un estándar para los registros estructurados ha sido desarrollado ... El sistema de registro actual en el plano de control no garantiza una estructura uniforme para los mensajes y referencias de objetos en Kubernetes, lo que complica el procesamiento de dichos registros. Para solucionar este problema, se introduce una nueva estructura de mensajes en logs, para lo cual se ha ampliado la librería klog con nuevos métodos que brindan una interfaz estructurada para generar logs, así como métodos auxiliares para identificar objetos K8s en logs.



Simultáneamente con la migración a klog v2, se realiza la transición a un nuevo formato de salida de logs en JSON , lo que simplificará la ejecución de las solicitudes a los logs y su procesamiento. Para ello, aparece una bandera --logging-format, que por defecto usa el formato de texto antiguo.



Dado que el repositorio de Kubernetes es enorme y los autoresLos KEP de tala estructurada son realistas y centrarán sus esfuerzos en dar vida a nuevas ideas en los mensajes más comunes.



Una ilustración del registro usando los nuevos métodos en klog:



klog.InfoS("Pod status updated", "pod", "kubedns", "status", "ready")

I1025 00:15:15.525108       1 controller_utils.go:116] "Pod status updated" pod="kubedns"


klog.InfoS("Pod status updated", "pod", klog.KRef("kube-system", "kubedns"), "status", "ready")

I1025 00:15:15.525108       1 controller_utils.go:116] "Pod status updated" pod="kube-system/kubedns" status="ready"


klog.ErrorS(err, "Failed to update pod status")

E1025 00:15:15.525108       1 controller_utils.go:114] "Failed to update pod status" err="timeout"


Usando formato JSON:



pod := corev1.Pod{Name: "kubedns", Namespace: "kube-system", ...}
klog.InfoS("Pod status updated", "pod", klog.KObj(pod), "status", "ready")


{
   "ts": 1580306777.04728,
   "v": 4,
   "msg": "Pod status updated",
   "pod":{
      "name": "nginx-1",
      "namespace": "default"
   },
   "status": "ready"
}


Otra innovación importante (y muy relevante) es el mecanismo para informar sobre API obsoletas , implementado inmediatamente como una versión beta (es decir, activo en instalaciones por defecto). Como se explica por los autores, en muchos Kubernetes capacidad obsoleta constantemente, permaneciendo en diferentes estados y con diferente tiempo s perspectivas mi. Hacer un seguimiento de ellos, leer detenidamente todas las notas de la versión y limpiar manualmente las configuraciones / ajustes es casi imposible.



Para resolver este problema, ahora, cuando se utiliza la API obsoleta, se agrega un encabezado a sus respuestas Warning, que se reconoce en el lado del cliente (client-go) con posibilidad de diferentes respuestas: ignorar, deduplicar, registrar. En la utilidad kubectl, enseñaron cómo enviar estos mensajes a stderr, resaltar el mensaje en la consola con color y también agregaron una bandera --warnings-as-errorscon un nombre que se explica por sí mismo.



Además de esto, se han agregado métricas especiales para informar el uso de API obsoletas y anotaciones de auditoría.



Finalmente, los desarrolladores asistieron al avance de las funciones de Kubernetes desde la versión beta . Como ha demostrado la experiencia del proyecto, algunas funciones nuevas y cambios en la API estaban "atascados" en el estado Beta debido a que ya estaban activados automáticamente (por defecto) y no requerían ninguna acción adicional por parte de los usuarios.



Para evitar que esto suceda, se sugiere enviar automáticamente a la lista de obsolescencia aquellas funciones que han estado en beta durante 6 meses (dos versiones) y no cumplen con ninguna de estas condiciones:



  1. cumplen con los criterios de GA y son promovidos a un estado estable;
  2. tienen una nueva beta que deja obsoleta la beta anterior.


Y ahora para otros cambios en Kubernetes 1.19, categorizados por sus respectivos SIG.



Bóvedas



Los nuevos objetos CSIStorageCapacity están destinados a mejorar el proceso de programación de los pods que utilizan volúmenes CSI: no se colocarán en nodos que se hayan quedado sin espacio de almacenamiento. Para hacer esto, la información sobre el espacio disponible en disco se almacenará en el servidor API y estará disponible para los controladores CSI y el programador. El estado de implementación actual es la versión alfa; consulte KEP para obtener más detalles .



Otra innovación en la versión alfa es la capacidad de definir volúmenes efímeros directamente en las especificaciones del pod, volúmenes en línea efímeros genéricos ( KEP). Los volúmenes efímeros se crean para pods específicos en el momento en que se generan y se eliminan cuando salen. Podrían haberse definido antes (incluso directamente en la especificación, es decir, mediante el método en línea), pero el enfoque existente, habiendo demostrado la coherencia de la función en sí, no cubría todos los casos de su uso.



El nuevo mecanismo ofrece una API simple para definir volúmenes efímeros para cualquier controlador con soporte de aprovisionamiento dinámico (anteriormente, esto requeriría una modificación del controlador). Le permite trabajar con cualquier volumen efímero (tanto CSI como en árbol, como EmptyDir), y también brinda soporte para otra característica nueva (descrita anteriormente): rastrear el espacio de almacenamiento disponible.



Un ejemplo de un objeto de Kubernetes de alto nivel que usa un nuevo volumen efímero (genérico en línea):



apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: scratch
          mountPath: /scratch
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: scratch
        ephemeral:
          metadata:
            labels:
              type: fluentd-elasticsearch-volume
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: "scratch-storage-class"
            resources:
              requests:
                storage: 1Gi


Aquí, el controlador DaemonSet crea pods con nombres de vista fluentd-elasticsearch-b96sd, después de lo cual se agregará un PersistentVolumeClaim para dicho pod fluentd-elasticsearch-b96sd-scratch.



Y la última función de almacenamiento completamente nueva, presentada como una versión alfa, es un nuevo campo csidriver.spec.SupportsFSGrouppara que los controladores CSI indiquen la compatibilidad con los permisos basados ​​en FSGroup ( KEP ). Motivación: un cambio de propiedad de un volumen CSI se realiza antes de que se monte en un contenedor, sin embargo, no todos los tipos de almacenamiento admiten dicha operación (por ejemplo, NFS), por lo que ahora puede provocar errores.



Hasta la versión beta (es decir, las inclusiones predeterminadas):





/ Kubelet



Seccomp se ha declarado estable (GA) . En particular, estos trabajos llevaron a la transición a campos para seccomp en la API en lugar de anotaciones declaradas obsoletas (los nuevos Kubelets ignoran las anotaciones) y afectaron a PodSecurityPolicy .



Se ha agregado un nuevo campo a PodSpec fqdnInHostnamepara permitirle establecer el FQDN (Nombre de dominio completo) para el host del pod . El objetivo es mejorar la compatibilidad con aplicaciones heredadas en Kubernetes. Así es como los autores explican sus intenciones:



« Unix Linux-, Red Hat CentOS, FQDN- hostname. , , Kubernetes, . ».


El valor predeterminado será falsemantener el comportamiento anterior (para Kubernetes). Estado de la función: versión alfa, que se prevé declarar estable en la próxima versión (1.20).



Se decidió abandonar las métricas de aceleración recopiladas por Kubelet . Se propone recopilar dichas métricas mediante agentes de supervisión externos a través de la API PodResources. Esta API en sí se creó precisamente con el objetivo de eliminar todas las métricas específicas del dispositivo del repositorio principal de Kubernetes, lo que permite a los proveedores implementarlas sin realizar cambios en el núcleo de Kubernetes. La API de PodResources está en versión beta (la puerta de funciones es responsable de ella KubeletPodResources) y pronto estará estable. Para la versión actual, el proceso de abandono está en estado alfa, los detalles están en KEP .



A partir de ahora, Kubelet se puede construir sin Docker : con esto "sin" los autores significan la ausencia de cualquier código específico de Docker y la dependencia del paquete Golang docker/docker. El objetivo final de esta iniciativa es llegar a un Kubelet completamente "sin docker" (es decir, sin dependencia de Docker). Puede leer más sobre la motivación, como siempre, en KEP . Esta oportunidad recibió inmediatamente el estado GA.



Node Topology Manager, que alcanzó su versión beta en la última versión de K8, ahora tiene la capacidad de nivelar los recursos a nivel de pod.



Programador



En Kubernetes 1.18, escribimos sobre la configuración global para la distribución uniforme de pod (Even Pod Spreading) , pero luego se decidió posponer esta función en función de los resultados de las pruebas de rendimiento. Ahora está en Kubernetes (en estado alfa).



La esencia de la innovación es la adición de restricciones globales ( DefaultConstraints), que permiten regular las reglas para distribuir pods a un nivel superior, a nivel de clúster, y no solo en PodSpec(a través topologySpreadConstraints), como era hasta ahora. La configuración predeterminada será similar al complemento actual DefaultPodTopologySpread:



defaultConstraints:
  - maxSkew: 3
    topologyKey: "kubernetes.io/hostname"
    whenUnsatisfiable: ScheduleAnyway
  - maxSkew: 5
    topologyKey: "topology.kubernetes.io/zone"
    whenUnsatisfiable: ScheduleAnyway


Los detalles están en KEP .



Otra característica relacionada con Even Pod Spreading: la distribución de un grupo de pods por dominios de falla (regiones, zonas, nodos, etc.), transferidos de alfa a beta (habilitado por defecto).



Otras tres funciones del planificador han logrado un "aumento" similar:





Redes



El recurso Ingress finalmente se declara estable y tiene una versión v1en la API. En este sentido, se han presentado bastantes actualizaciones en la documentación correspondiente. Se debe prestar especial atención a los cambios que percibe el usuario en este PR : por ejemplo, hay cambios de nombre como spec.backendspec.defaultBackend, serviceNameservice.name, servicePortservice.port.number...



El campo AppProtocol para Servicios y Endpoints, así como la API EndpointSlice (kube-proxy en Linux se inicia use EndpointSlices de forma predeterminada, pero permaneció en alfa para Windows) y soporte SCTP .



kubeadm



Se introducen dos funciones nuevas (en versión alfa) para la utilidad kubeadm.



El primero es utilizar parches para modificar los manifiestos generados por kubeadm. Ya era posible modificarlos usando Kustomize (en alfa), sin embargo, los desarrolladores de kubeadm decidieron que usar parches regulares era la forma preferida (ya que Kustomize se convierte en una dependencia innecesaria, lo cual no es bienvenido).



Ahora bien, es posible aplicar parches primas (por medio de una bandera --experimental-patches) para los comandos kubeadm init, joiny upgrade, además de sus fases. La implementación basada en Kustomize (marca --experimental-kustomize) quedará obsoleta y se eliminará.



La segunda característica es un nuevo enfoque para trabajar con configuraciones de componentescon el que trabaja kubeadm. La utilidad genera, valida, establece valores predeterminados, almacena configuraciones (en forma de ConfigMaps) para componentes de clúster de Kubernetes como Kubelet y kube-proxy. Con el tiempo, quedó claro que esto trae una serie de dificultades: ¿cómo distinguir entre las configuraciones generadas por kubeadm o enviadas por el usuario (y si no, qué hacer con la migración de configuraciones)? ¿Qué campos con valores predeterminados se generaron automáticamente y cuáles se establecieron intencionalmente?.



Para resolver estos problemas, se presenta un gran conjunto de cambios , que incluyen: rechazo a establecer valores predeterminados (esto debe ser realizado por los propios componentes), delegación de la validación de la configuración componentes, firmando cada ConfigMap generado, etc.



Y otra característica menos significativa para kubeadm es una puerta de características llamada PublicKeysECDSA, que incluye la capacidad de crear un clúster [vía kubeadm init] con certificados ECDSA. kubeadm alpha certs renewTambién se proporciona la actualización de certificados existentes (a través de ), pero no hay mecanismos para cambiar fácilmente entre RSA y ECDSA.



Otros cambios



  • El estado GA recibió 3 características en el campo de la autenticación: API CertificateSigningRequest , restricción del acceso del nodo a ciertas API (a través de un complemento de admisión NodeRestriction), bootstrap y renovación automática del certificado del cliente de Kubelet.
  • La nueva API de eventos también se declaró estable con un enfoque modificado de la deduplicación (para evitar sobrecargar el clúster con eventos).
  • (kube-apiserver, kube-scheduler, etcd ) debian distroless. : , ( — KEP).
  • Kubelet Docker runtime target-, TargetContainerName EphemeralContainer ( ).
  • « » .status.conditions, API .
  • kube-proxy IPv6DualStack Windows ( feature gate).
  • La puerta de función con un nombre que se explica por sí mismo CSIMigrationvSphere(migración del complemento integrado, en árbol, para vSphere al controlador CSI) se ha trasladado a la versión beta.
  • Para bandera kubectl run agregada--privileged .
  • Se ha agregado un nuevo punto de extensión al programador - PostFilter, - que comienza después de la fase Filter.
  • La compatibilidad con Cri-containerd en Windows ha llegado a la versión beta.


Cambios de dependencia:



  • versión de CoreDNS incluida en kubeadm - 1.7.0;
  • cri-tools 1.18.0;
  • CNI (interfaz de red de contenedores) 0.8.6;
  • etcd 3.4.9;
  • la versión de Go utilizada es 1.15.0-rc.1.


PD



Lea también en nuestro blog:






All Articles