Red de conocimiento informático - Aprendizaje de código fuente - Aplicación del lado del servidor k8s series-02 integrada

Aplicación del lado del servidor k8s series-02 integrada

Versiones aplicables: Kubernetes v1.22 [estable]

El objetivo completamente descrito no es un objeto completo, solo incluye campos y valores que reflejan la intención del usuario. Esta intención se puede utilizar para crear nuevos objetos o fusionarse con objetos existentes a través del servidor.

El sistema admite que varios usuarios colaboren en el mismo objeto.

El mecanismo de gestión de campos rastrea los cambios en los campos de objetos. Cuando el valor de un campo cambia, su propiedad se transfiere del administrador actual al administrador que aplicó el cambio. Si un campo tiene un valor diferente y es administrado por otro administrador, se desencadenará un conflicto al intentar aplicar una nueva configuración al objeto. Los conflictos activan una advertencia de que la acción puede eliminar cambios realizados por otros colaboradores. Los conflictos pueden ignorarse intencionalmente, en cuyo caso se sobrescribirá el valor y se transferirá la propiedad.

Cuando eliminas un campo de un perfil y luego aplicas el perfil, esto activa la aplicación del lado del servidor para verificar si el campo todavía es propiedad de otro administrador de campo. Si no es así, el campo se elimina del objeto activo; si lo es, se restablece a su valor predeterminado. Las mismas reglas se aplican a listas o funciones.

La aplicación del lado del servidor es a la vez un reemplazo de la aplicación kubectl original y un mecanismo simplificado para que el controlador publique sus propios cambios.

Si las aplicaciones del lado del servidor están habilitadas, el plano de control rastreará los campos administrados por todos los objetos recién creados.

En el contexto de las aplicaciones del lado del servidor, los campos administrados por el usuario significan que el usuario confía y espera que el valor del campo no cambie. El usuario que afirmó por última vez el valor del campo iniciará sesión en el administrador de campo actual. Esto se puede lograr enviando comandos como POST, PUT o PATCH no aplicado (no aplicado) para modificar el valor del campo, o colocando el campo en un archivo de configuración y enviándolo al punto final del servidor del lado del servidor. solicitud. Cuando se utiliza una aplicación del lado del servidor, intentar cambiar un campo administrado por otra persona puede provocar que se rechace la solicitud (consulte Conflictos cuando no se establece la aplicación).

Si dos o más aplicaciones configuran el mismo campo con el mismo valor, perderán la propiedad del campo. Cualquiera que sea la aplicación que inicie intentos posteriores de cambiar el valor del campo Disfrutar resultará en un conflicto. El propietario del campo **** Enjoy puede renunciar a la propiedad del campo simplemente eliminando el campo del archivo de configuración.

La información sobre la gestión de campos se almacena en el campo gestionadoFields, que forma parte de los metadatos del objeto.

Un ejemplo simple de un objeto creado por una aplicación del lado del servidor es el siguiente:

El objeto anterior contiene un administrador único en metadata.managedFields. El administrador contiene información básica sobre la propia entidad administrada, como el tipo de operación, la versión de API y los campos que administra.

Nota: Este campo es administrado por el servidor API y el usuario no puede modificarlo.

Sin embargo, se pueden realizar operaciones de actualización para modificar metadata.managedFields. Recomendamos encarecidamente a los usuarios que no hagan esto, pero es razonable intentarlo cuando los campos administrados entran en un estado inconsistente (lo cual claramente no debería ser así).

El formato de los campos de administración se describe en la documentación de la API.

El administrador identifica el flujo de trabajo que está modificando el objeto (especialmente útil en caso de conflicto), que se puede especificar modificando el parámetro fieldManager de la solicitud. Aunque kubectl utiliza el punto final del servicio kubectl de forma predeterminada, solicita el punto final de la aplicación. Para otras actualizaciones, se calcula a partir del agente de usuario de forma predeterminada.

Esta característica implica dos tipos de operaciones: aplicar (solicitudes PATCH de tipo apply/apply-patch+yaml) y actualizar (todas las demás operaciones que modifican un objeto). Ambas operaciones actualizan los campos de ManagedFields, pero se comportan de forma ligeramente diferente.

Nota:

Utilice application/apply-patch+yaml como valor de Content-Type, ya sea que envíe datos JSON o YAML.

Todos los documentos JSON son YAML válidos.

Por ejemplo, cuando ocurre un conflicto, solo falla la operación de aplicación, no la actualización. Además, las operaciones de aplicación deben identificarse proporcionando un parámetro de consulta de fieldManager, mientras que las operaciones de actualización proporcionan opcionalmente un parámetro de consulta de fieldManager. Finalmente, cuando usa el comando aplicar, no puede mantener campos administrados en objetos en su aplicación.

Un ejemplo de un objeto que contiene varios administradores es:

En este ejemplo, la segunda acción la ejecuta el administrador kube-controller-manager como una actualización. La actualización cambia el valor del campo de datos y hace que el administrador de campo cambie a kube-controller-manager.

Si cambia la operación de actualización a Aplicar, la operación fallará debido a un conflicto de propiedad.

La estrategia de fusión implementada por la aplicación del lado del servidor proporciona un ciclo de vida general de los objetos más estable. Las aplicaciones del lado del servidor intentan fusionar campos según el director responsable de administrarlos, en lugar de vetar los campos según su valor. El propósito de esto es permitir que múltiples entidades principales actualicen el mismo objeto sin interrupciones inesperadas.

Cuando un usuario envía un objeto de "destino completamente descrito" al extremo del servidor de una aplicación del lado del servidor, el servidor lo fusiona con el objeto activo y, si los valores de ambos están duplicados, el valor del perfil tiene prioridad. Si el conjunto de proyectos en el perfil no es un superconjunto de los últimos proyectos en los que trabajó el usuario, se eliminarán todos los proyectos faltantes que no hayan sido administrados por otros solicitantes. Para obtener más información sobre las especificaciones de objetos utilizadas para tomar decisiones de fusión, consulte sigs.k8s.io/structured-merge-diff.

En Kubernetes 1.16 y 1.17, se agregaron etiquetas para permitir a los desarrolladores de API describir las estrategias de combinación admitidas por listas, mapas y estructuras. Estas etiquetas se pueden aplicar a objetos de los tipos correspondientes definidos en la documentación de Go o en el esquema OpenAPI de CRD:

Si no se especifica listType, el servidor API interpretará la etiqueta patchMergeStrategy=merge como listType=map y el correspondiente La etiqueta patchMergeKey se utiliza como valor de listMapKey para la etiqueta patchMergeKey correspondiente.

El tipo de lista atómica es recursivo.

Estas etiquetas se proporcionan como comentarios del código fuente y no es necesario repetirlas como etiquetas de campo.

En casos excepcionales, el autor de un CRD o de un tipo integrado puede desear cambiar la configuración topológica de un campo en su recurso sin aumentar el número de versión. Cambiar la información de topología de un tipo mediante la actualización de un clúster o la actualización de CRD no tiene los mismos resultados que actualizar objetos existentes. Hay dos tipos de cambios: cambiar un campo de mapa/conjunto/granular a atómico y hacer lo contrario.

Cuando un listType, mapType o structType se vuelve atómico a partir de map/set/granular, el propietario de toda la lista, mapa o estructura de objetos existentes se convierte en el propietario de un elemento de esos tipos. Esto significa que cambios adicionales en estos objetos pueden causar conflictos.

Cuando una lista, mapa o estructura se cambia de un tipo atómico a un tipo de mapa/conjunto/granular, el servidor API no podrá obtener una nueva propiedad de estos campos. Por lo tanto, no se producirán conflictos cuando estos campos del objeto se actualicen nuevamente.

Tome el siguiente recurso personalizado como ejemplo:

Antes de que spec.data cambie de un campo atómico a un campo granular, manager-one es el campo spec.data y los campos que lo contienen. (clave1 y el propietario de la clave2). ) Cuando spec.data se convierte en topología granular después de los cambios CRD correspondientes, el administrador uno continúa siendo propietario del campo de nivel superior spec.data (esto significa que es imposible para otros administradores eliminar los datos asignados con nombre sin causar un conflicto). Pero ya no tengo la clave1 y la clave2. Por lo tanto, otros administradores pueden cambiar o eliminar estos campos sin causar conflictos. Por lo tanto, otros administradores pueden cambiar o eliminar estos campos sin causar conflictos.

De forma predeterminada, las aplicaciones del lado del servidor tratan los recursos personalizados como datos no estructurados. Todas las claves se tratan como campos de estructura y todas las listas se tratan como átomos.

Si una definición de recurso personalizada (CRD) define un esquema, contendrá anotaciones similares a las definidas en la sección anterior sobre estrategias de fusión que se utilizarán al fusionar objetos de este tipo.

Los desarrolladores de controladores pueden utilizar aplicaciones del lado del servidor para simplificar la lógica de actualización del controlador. La principal diferencia entre lectura-modificación-escritura y/o aplicación de parches es la siguiente:

Muy recomendado: configurar el controlador para que aplique los conflictos, ya que el controlador no tiene otra forma de resolver los conflictos cuando ocurren plan o medida .

Además de proporcionar control de concurrencia a través de la resolución de conflictos, las aplicaciones del lado del servidor proporcionan una serie de formas colaborativas de transferir la propiedad del campo del usuario al controlador.

Esto se ilustra mejor con un ejemplo. Veamos cómo transferir de forma segura la propiedad de un campo replicado del usuario al controlador utilizando el recurso HorizontalPodAutoscaler y su controlador complementario y habilitando la función de escalado de nivel automático de la implementación.

Supongamos que el usuario define la implementación y establece el campo de réplicas en el valor deseado:

application/ssa/nginx-deployment.yaml

Luego, el usos del usuario La aplicación del lado del servidor crea una implementación de la siguiente manera:

Luego, habilite HPA para la implementación, por ejemplo:

Ahora los usuarios quieren eliminar la replicación de su configuración, por lo que Trabaje siempre con conflictos en el controlador HPA. Sin embargo, aquí hay una situación posible: hay una ventana de tiempo antes de que HPA necesite ajustar la réplica. Si el usuario elimina la réplica antes de que HPA escriba el campo y se convierta en propietario, entonces el servidor API establecerá el valor de la réplica en 1, lo cual. es el valor predeterminado. Esto no es lo que los usuarios quieren que suceda, ni siquiera temporalmente.

Aquí hay dos soluciones:

Primero, el usuario define un nuevo archivo de configuración que contiene solo el campo réplicas:

application/ssa/nginx-deployment- replicas -only.yaml

El usuario define un nuevo archivo de configuración llamado handover-to-hpa field manager para aplicar este archivo de configuración.

En este punto, el usuario puede eliminar la copia del perfil.

application/ssa/nginx-deployment-no-replicas.yaml

Tenga en cuenta que una vez que el controlador HPA establece un nuevo valor para la réplica, el administrador de campo temporal ya no tendrá cualquier campo y se eliminará automáticamente. Aquí no se requiere limpieza.

Los usuarios pueden disfrutar de la propiedad de un campo transfiriendo la propiedad del campo entre ellos configurándolo en el mismo valor en el archivo de configuración. Una vez que un usuario ha disfrutado de la propiedad de un campo, cualquier usuario puede eliminar el campo de su perfil y aplicar los cambios, renunciando así a la propiedad y transfiriéndola a otro usuario.

Un resultado de implementar la detección y resolución de conflictos en aplicaciones del lado del servidor es que los solicitantes siempre obtienen los valores de campo más recientes en el estado local. Sin el último valor, se producirá un conflicto la próxima vez que se realice la operación de aplicación. Cualquiera de las tres opciones para resolver conflictos garantiza que el perfil aplicado por esta aplicación sea el último subconjunto de los campos del objeto en el servidor.

Esto es diferente de las aplicaciones del lado del cliente, donde si otro usuario sobrescribe el valor, el valor caducado permanecerá en el archivo de configuración local de la aplicación. A menos que un usuario actualice un campo específico, ese campo no es preciso y el proveedor de la aplicación no tiene forma de saber si la siguiente operación de la aplicación sobrescribirá los cambios de otro usuario.

Otra diferencia es que los programadores de aplicaciones que utilizan aplicaciones del lado del cliente no pueden cambiar la versión de API que están utilizando, mientras que las aplicaciones del lado del servidor admiten este escenario.

Los métodos del lado del cliente (los usuarios que usan kubectl aplican para administrar los recursos) pueden cambiar al uso de la aplicación del lado del servidor usando la siguiente etiqueta.

De forma predeterminada, la gestión de campos de objetos no entra en conflicto al migrar desde métodos de aplicaciones cliente a aplicaciones del lado del servidor activadas por kubectl.

Nota:

Actualice el último comentario de configuración de la aplicación. De los comentarios se puede inferir que este campo lo gestiona la aplicación cliente. Cualquier campo no administrado por la aplicación cliente causará conflictos.

Por ejemplo, si usa kubectl scale para actualizar el campo de réplicas después de la aplicación cliente, pero el campo no pertenece a la aplicación cliente, se producirá un conflicto cuando se ejecute kubectl apply --server-side. .

Esto aplicará kubectl como administrador de campo para la aplicación del lado del servidor. Como excepción, puede especificar un administrador de campo diferente, no predeterminado, para detener este comportamiento, como se muestra en el siguiente ejemplo. Para las aplicaciones del lado del servidor activadas por kubectl, el administrador de campo predeterminado es kubectl.

Si usa kubectl apply --server-side para administrar un recurso, puede degradarlo a una aplicación cliente directamente usando el comando kubectl apply.

La degradación funciona porque la aplicación del lado del servidor kubectl conserva las últimas anotaciones de configuración de la aplicación.

Esto es adecuado para aplicaciones del lado del servidor que utilizan kubectl como administrador de campo. Como excepción, puede especificar un administrador de campo diferente, no predeterminado, para detener este comportamiento, como se muestra en el siguiente ejemplo. Para las aplicaciones del lado del servidor activadas por kubectl, el administrador de campo predeterminado es kubectl.

Cuando la función de aplicación del lado del servidor está habilitada, el punto final del servidor PATCH aceptará el tipo de contenido adicional application/apply-patch+yaml. Esto permite a los usuarios de aplicaciones del lado del servidor enviar objetos parcialmente especificados en formato YAMl al servidor. Los objetos parcialmente especificados (objetos parcialmente especificados en formato YAMl) se envían a este punto final. Al aplicar un perfil, este debe contener todos los campos que reflejen su intención.

Puedes eliminar todos los campos administrados de un objeto sobrecargándolo con MergePatch, StrategicMergePatch, JSONPatch, Update y todas las operaciones que no sean de aplicación. Esto se puede lograr sobrecargando el campo ManagedFields y dejándolo vacío. Aquí hay dos ejemplos:

Esta operación sobrecarga los campos administrados con una lista que contiene solo una entrada vacía, eliminando así los campos administrados de todo el objeto. Tenga en cuenta que configurar ManagedFields en una lista vacía no restablece los campos. El propósito de esto es que los clientes independientes del campo nunca eliminen los campos administrados.

En escenarios donde la operación de restablecimiento se combina con cambios en campos fuera de ManagedFields, esto hará que ManagedFields se restablezca primero, mientras que otros cambios se retrasarán. Como resultado, la aplicación tomará posesión de todos los campos de la misma solicitud.

Nota: Las aplicaciones del lado del servidor no pueden realizar un seguimiento adecuado de la propiedad de los subrecursos que no aceptan tipos de objetos de recursos. Si utiliza una aplicación del lado del servidor para dichos subrecursos, no se realizará un seguimiento de los campos modificados.

Enlace de referencia:

es.io/zh/docs/reference/using-api/server-side-apply/

Por cierto, me gustaría Felices vacaciones a todos por el Primero de Mayo. Diviértete y no olvides mejorar.

Todos son bienvenidos a presentar diferentes opiniones y discutirlas juntos.

Soy un hombre apasionado y activista.