Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

Kubernetes en la práctica

 

En este capítulo se presentan algunos de los objetos y funciones fundamentales de Kubernetes.

Imagine que tiene un conjunto Pod que debe alojarse en una máquina con ciertas especificaciones (SSD HD, ubicación física, potencia de procesamiento, etc.) o que desea buscar o agrupar sus pods para una administración más fácil. ¿Qué debe hacer? Las etiquetas son el camino hacia la marcha. En Kubernetes, las etiquetas se adjuntan a un objeto.

Deje’que los s utilicen etiquetas para iniciar una caja Pod en un equipo determinado.

Ellas

En Kubernetes, cualquier objeto puede identificarse mediante una etiqueta.

Puede asignar varias etiquetas por objeto, pero debe evitar utilizar demasiadas etiquetas o muy pocas; Si hay demasiados, se conseguirá confundir y será muy pocas las que haya ganado’. proporcione las ventajas reales de agrupar, seleccionar y buscar.

La práctica recomendada es asignar etiquetas para indicar:

  • ID. de aplicación/programa con este conjunto Pod

  • Propietario (que administra este conjunto Pod/aplicación)

  • Etapa (conjunto Pod/aplicación en la versión de desarrollo/pruebas/producción)

  • Requisitos de recursos (SSD, CPU, almacenamiento)

  • Ubicación (ubicación preferida/zona/centro de datos para ejecutar este conjunto Pod/aplicación)

Bien, deje’que asigne etiquetas para (stage: testingdezone: production) a dos nodos, respectivamente, y después intente iniciar un conjunto Pod en un nodo que tenga la etiqueta (stage: testing):

Ahora,’comencemos a lanzar un pod básico de nginx con la etiqueta stage: testing en el nodeSelector y confirmar que estará en un nodo etiquetado con stage: testing. Kube-Scheduler utiliza las etiquetas mencionadas en la sección nodeSelector del YAML POD para seleccionar el nodo en el que iniciar la caja Pod:

Note

Kube-Scheduler escoge el nodo basándose en varios factores, como requerimientos de recursos individuales y colectivos, hardware, software o restricciones políticas, especificaciones de afinidad y antiafinidad, localización de datos, interferencias entre cargas de trabajo y plazos.

Note

Puede asignar un conjunto Pod a un nodo determinado sin rótulos, agregando el argumento nodeName: nodeX bajo las especificaciones del archivo YAML donde nodeX es el nombre del nodo.

Cryptography

Como en muchas otras plataformas, suele haber más de un usuario (o equipo) trabajando en un clúster de Kubernetes. Supongamos que un conjunto Pod llamado webserver1 ha sido creado por un departamento de DevOps, pero cuando el Departamento de ventas intenta iniciar una caja Pod con el mismo nombre, el sistema le dará un error:

Error from server (AlreadyExists): error when creating "webserver1.yaml": pods "webserver1" already exists

Kubernetes ha’ganado, permitir que el mismo nombre de objeto para los recursos Kubernetes aparezca más de una vez en el mismo ámbito.

Los espacios de nombres proporcionan el ámbito del recurso Kubernetes, como proyecto/inquilino en OpenStack. Los nombres de los recursos deben ser únicos en un espacio de nombres, pero no en los espacios de nombres. Es’una forma natural de dividir los recursos de clúster entre varios usuarios.

Kubernetes se inicia con tres espacios de nombres iniciales:

  • valor predeterminado: Espacio de nombres predeterminado para los objetos que no tienen ningún otro espacio de nombres.

  • Kube-System: Espacio de nombres para objetos creados por el sistema Kubernetes.

  • Kube-público: Inicialmente creado por la herramienta kubeadm al implementar un clúster. Por Convención, el propósito de este espacio de nombres es hacer que algunos recursos sean legibles para todos los usuarios sin autenticación. Existe principalmente en Kubernetes clusters de arranque stapped solo con la herramienta kubeadm.

Crear un espacio de nombres

Crear un espacio de nombres es bastante sencillo. El comando kubectl hace la magia. ’No es necesario tener un archivo YAML:

Y ahora se crea el nuevo espacio de nombres:

Ahora, la caja de dev webserver1 del espacio’de nombres dev ganó un conflicto con webserver1 Pod en el espacio de nombres sales :

Cupo

Ahora puede aplicar restricciones que limiten el consumo de recursos por espacio de nombres, de manera similar al inquilino de OpenStack. Por ejemplo, puede limitar la cantidad de objetos que se pueden crear en un espacio de nombres, la cantidad total de recursos de proceso que pueden consumir los recursos, etc. La restricción en K8S se denomina quota. He’aquí un ejemplo:

En este caso, acabamos de crear la cuota de cuota, onepod, y la restricción que – le hemos dado es pods = 1, por lo que solo se permite crear un conjunto Pod en este espacio de nombres:

Y, a continuación, cree una caja Pod dentro de la misma:

Eso funciona bien, por lo que’ahora vamos a crear un segundo conjunto Pod:

Lo encontramos inmediatamente al superar el error de la cuota. Deje’que s elimine la cuota de cuota: onepod. Este nuevo conjunto de Pod se creará después de que se quite la cuota:

ReplicationController

Ha aprendido cómo iniciar una caja Pod que representa los contenedores de su archivo YAML en el capítulo 2. Una pregunta puede aparecer en su contenedor: ¿Qué sucede si necesito tres pods que son exactamente iguales (cada uno ejecuta un contenedor de Apache) para asegurarse de que el servicio Web parezca más sólido? Cambio el nombre en el archivo YAML repetir los mismos comandos para crear los pods requeridos? ¿O quizás con una secuencia de Shell? Kubernetes ya tiene los objetos para abordar esta demanda con RC- ReplicationController, o RS– ReplicaSet.

Una ReplicationController (RC) garantiza que se esté ejecutando un número específico de réplicas del conjunto Pod al mismo tiempo. En otras palabras, un controlador de replicación garantiza que una Pod o un conjunto homogéneo de pods siempre está activo y disponible.

Creación de un RC

A’continuación, crearé un RC con un ejemplo. Primero, cree un archivo YAML para un objeto RC llamado WebServer:

Recuerde que Kind indica el tipo de objeto que define este archivo YAML, es un RC en lugar de un pod. En los metadatos, se muestra’el nombre RC s como webserver. Spec es la especificación detallada de este objeto RC, y las réplicas: 3 indica que se clonará el mismo conjunto POD para asegurarse de que el número total de pods creado por RC sea siempre de tres. Por último, la plantilla proporciona información acerca de los contenedores que se ejecutarán en la caja Pod, el mismo que se vio en un archivo Pod YAML. A continuación, utilice este archivo YAML para crear el objeto RC:

Si es lo suficientemente rápido, puede capturar el estado intermedio al crear los nuevos conjuntos de Pod:

Finalmente, verá tres pods lanzados:

RC funciona directamente con el conjunto Pod. Los flujos de trabajo se muestran en la Figure 1.

Figure 1: Flujos de trabajo de RC
Flujos de trabajo de RC

Con el parámetro replicas especificado en el archivo YAML del objeto RC, el controlador de duplicación Kubernetes, que se ejecuta como parte del proceso Administrador de Kube-Controller-Manager en el nodo Master, seguirá supervisando el número de pods en ejecución generados por RC y iniciará automáticamente otros nuevos si alguno de ellos fallara. Lo más importante para aprender es que los conjuntos de Pod individuales se pueden morir en cualquier momento, pero el pool en general está siempre en funcionamiento, lo que hace que sea un servicio sólido. Lo entenderá mejor cuando aprenda el servicio Kubernetes.

Probar RC

Puede probar un impacto de’RC s eliminando uno de los pods. Para eliminar un recurso con kubectl, utilice el subcomando kubectl delete:

Como puede ver, cuando se termina un conjunto Pod, se genera inmediatamente un nuevo conjunto Pod. Finalmente, el conjunto Pod antiguo desaparecerá y el nuevo conjunto Pod estará activo y en ejecución. El número total de pods que se ejecutan permanecerá inalterado.

También puede escalar hacia arriba o hacia abajo las réplicas con RC. Por ejemplo, para aumentar la escala desde el número de 3 al 5:

RC ofrece otras ventajas. En realidad, dado que esta abstracción es tan popular y muy utilizada, dos objetos muy similares, la implementación de – ReplicaSet e implementar, se han desarrollado con características más eficaces. En términos generales, puede llamarles RC de nueva generación. Por ahora,’deje de explorar más características de RC y mueva nuestro enfoque a estos dos objetos nuevos.

Antes de pasar al siguiente objeto, puede eliminar el RC:

ReplicaSet

ReplicaSet objeto, o RS, es prácticamente igual que un objeto RC, con tan solo una excepción – importante la apariencia del selector:

RC utiliza solamente selectores de igual a , mientras que RS es compatible con un formato de selector adicional, basado en el definido. Funcionalmente, las dos formas de selectores realizan el – mismo trabajo—que selecciona la caja Pod con una etiqueta coincidente:

Se crea una RS que inicia un conjunto Pod, exactamente lo mismo que lo haría una RC. Si comparas el kubectl describe en los dos objetos:

Como puede ver, en su mayor parte, las salidas son iguales, con la única excepción del formato de selector. También puede ajustar la escala de la RS de la misma manera que lo haría con RC:

Antes de pasar al siguiente objeto, elimine la reinterface:

Implementación

Puede que se pregunte por qué Kubernetes tiene objetos diferentes para hacer casi el mismo trabajo. Como se mencionó anteriormente, las características de RC se han ampliado a través de RS y la implementación. Hemos’visto el RS, que ha hecho el mismo trabajo de RC, solo con un formato de selector diferente. Ahora vamos’a desproteger el otro objeto nuevo, implementar – la implementación y explorar las características que provienen.

Crear una implementación

Si simplemente cambia el atributo Kind de ReplicaSet a Deployment,’obtendrá el archivo YAML de un objeto de implementación:

Crear una implementación con el kubectl mando

En realidad, la implementación es un nivel de abstracción relativamente superior al de RC y RS. La implementación no crea un conjunto Pod directamente, y el comando Descripción revela lo siguiente:

Flujo de trabajo de implementación

Cuando se crea una implementación, se crea automáticamente un conjunto de réplicas. Los pods definidos en el objeto de implementación se crean y supervisan mediante’la implementación s REPLICASET.

El flujo de trabajo se muestra en la Figure 2:

Figure 2: Flujo de trabajo de implementación
Flujo de trabajo de implementación

Es posible que aún se pregunte por qué es necesario utilizar RS como una capa más en el mismo nivel’de implementación y en la siguiente respuesta.

Actualización sucesiva

La característica actualización sucesiva es una de las características más eficaces que incluye el objeto de implementación. A’continuación, demuestre la característica con un caso de prueba para explicar cómo funciona.

Note

De hecho, existe una función de actualización gradual similar para el antiguo objeto RC. La implementación tiene bastantes inconvenientes en comparación con la nueva versión admitida por la implementación. En este libro, nos centraremos en la implementación nueva con la implementación.

Caso de prueba: Actualización sucesiva

Suponga que tiene una nginx-deployment, con réplica = 3 y 1.7.9 de imagen Pod. Deseamos actualizar la imagen de la versión 1.7.9 a la nueva versión 1.9.1 de la imagen. Con kuberctl puede usar la opción definir imagen y especificar el nuevo número de versión para activar la actualización:

Ahora vuelva a comprobar la información de la implementación:

Hay dos cambios que puede observar aquí:

  • Se actualiza la versión de la imagen en la implementación

  • Se crea un nuevo RS nginx-Deployment-6fdbb596db, con una réplica establecida en 1

Y con el nuevo RS con la réplica en 1, se genera un nuevo conjunto Pod (el cuarto):

El nuevo conjunto Pod se proporciona con la nueva imagen:

Mientras la antigua caja Pod aún está en la imagen antigua:

’Esperemos y siga comprobando el estado… de los pods finalmente se terminarán todos los pods antiguos y se ejecutarán – tres nuevos pods los nombres Pod confirmamos que son nuevos:

Así que la actualización se realiza y todos los pods se ejecutan con la nueva versión de la imagen.

Cómo funciona

Espera, es posible que esto no se actualice, se debe llamar un reemplazo, ya que Kubernetes utilizó tres nuevos pods con nuevas imágenes para reemplazar los pods antiguos. Hablando de forma precisa, esto es cierto. Pero así es cómo funciona. La’filosofía de Kubernetes s es que los pods son más baratos, – y la sustitución es fácil Imagínese qué cantidad de trabajo será cuando tenga que iniciar sesión en cada conjunto Pod, desinstalar imágenes antiguas, limpiar el entorno, solo para instalar una nueva imagen. Veamos’más detalles de este proceso y comprenda por qué se denomina actualización sucesiva.

Cuando se actualiza la caja Pod con nuevo software, el objeto de implementación introduce un nuevo RS que iniciará el proceso de actualización del conjunto Pod. La idea aquí es no iniciar sesión en el conjunto Pod existente y, en su lugar, hacer que la imagen se actualice en contexto, el nuevo RS crea simplemente un nuevo conjunto Pod equipado con el nuevo lanzamiento de software. Una vez que este nuevo conjunto (y adicional) esté activo y en funcionamiento, el RS original se reducirá en uno, por lo que el número total de pods en marcha permanecerá sin cambios. El nuevo RS continuará utilizándose en una sola vez y el original de RS se reducirá en una escala. Este proceso se repite hasta que el número de pods creado por el nuevo RS alcance el número de réplica original definido en la implementación, y eso es cuando se terminan todos los pods de RS originales. El proceso se representa en la Figure 3.

Figure 3: Introducción a la implementación
Introducción a la implementación

Como puede ver, todo el proceso de crear un nuevo RS, escalar el nuevo RS, y reducir simultáneamente el antiguo uno al mismo tiempo, está completamente automatizado y se encarga de todo el objeto de implementación. Es una implementación que está implementando y impulsando el objeto ReplicaSet, que, en este sentido, funciona solo como un back-end.

Por este motivo, la implementación se considera un objeto de capa superior en Kubernetes y la razón por la que se recomienda oficialmente que no utilice nunca ReplicaSet solo, sin implementación.

Record

La implementación también tiene la capacidad de registrar todo el proceso de las actualizaciones sucesivas, por si es necesario, puede revisar el historial de actualizaciones después de que finalice el trabajo de actualización:

Pausa/reanudar/deshacer

Además, también puede pausar/reanudar el proceso de actualización para comprobar los cambios antes de continuar:

Puede incluso deshacer la actualización cuando se producen errores durante la ventana de mantenimiento:

Normalmente, esto se hace cuando se rompe algo en la implementación. En comparación con la cantidad de trabajo que se tarda en preparar para actualizar el software durante las ventanas de mantenimiento de los viejos tiempos, ésta es una característica sorprendente para todo el que sufrió la actualización de software.

Tip

Es similar a la Junos comando de restauración mágica que probablemente utilice todos los días cuando necesite revertir rápidamente los cambios realizados en el enrutador.

Secretos

Todos los sistemas de red modernos necesitan tratar con la información delicada, como el nombre de usuario, contraseñas, claves SSH, etc., en la plataforma. Lo mismo se aplica a los pods en un entorno Kubernetes. Sin embargo, exponer esta información en las especificaciones de Pod como CLEARTEXT puede introducir problemas de seguridad y se necesita una herramienta o método para resolver el – problema al menos para evitar las credenciales de texto sin cifrar lo máximo posible.

El objeto Secrets Kubernetes se ha diseñado específicamente para – codificar todos los datos confidenciales y exponerlos a los pods de una manera controlada.

La definición oficial de los secretos de Kubernetes es:

"Un secreto es un objeto que contiene una pequeña cantidad de datos confidenciales, como una contraseña, un testigo o una clave. En cualquier otro caso, dicha información podría colocarse en una especificación Pod o en una imagen; colocarlo en un objeto secreto permite controlar mejor cómo se utiliza y reduce el riesgo de exposición accidental. "

Los usuarios pueden crear secretos y el sistema también crea secretos. Para usar un secreto, una Pod debe hacer referencia al secreto.

Hay muchos tipos diferentes de secretos, cada uno de ellos sirve a un caso de uso específico, y también hay muchos métodos para crear un secreto y muchas maneras distintas de hacer referencia a él en un conjunto Pod. Una explicación completa de los secretos queda fuera del ámbito de este libro, por lo que debe consultar la documentación oficial para obtener todos los detalles y realizar un seguimiento de todos los cambios actualizados.

En este caso’, se examinarán algunos tipos de secretos comúnmente utilizados. También aprenderá varios métodos para crear un secreto y cómo hacer referencia a él en sus pods. Una vez que llegue al final de la sección, debe comprender las ventajas principales de un objeto de secretos Kubernetes y cómo puede contribuir a mejorar la seguridad de su sistema.

Comencemos’con unos cuantos términos secretos:

  • Opaco: Este tipo de secreto puede contener pares de clave/valor arbitrarios, por lo que se trata como datos no estructurados desde la perspectiva de Kubernetes’ . Todos los demás tipos de secretos tienen contenido constante.

  • Kubernetes.io/Dockerconfigjson: Este tipo de secreto se utiliza para autenticar con un registro de contenedor privado (por ejemplo, un servidor Juniper) para extraer su propia imagen privada.

  • TLS: Un secreto TLS contiene una clave privada y un certificado de TLS. Se utiliza para asegurar una entrada. Verá un ejemplo de un ingreso con un secreto TLS en el capítulo 4.

  • Kubernetes.io/service-account-token: Cuando los procesos que se ejecutan en contenedores de un conjunto Pod tienen acceso al servidor API, deben ser autenticados como una cuenta concreta (por ejemplo, de forma predeterminada, la cuenta). Una cuenta asociada con un conjunto Pod se denomina cuenta de servicio. Kubernetes.io/service-account-token tipo de secreto contiene información acerca de la cuenta de servicio de Kubernetes. En este’libro, logramos no haber elaborado este tipo de secreto y cuenta de servicio.

  • Secreto opaco: El secreto del tipo opaco representa datos – arbitrarios del usuario que normalmente deseará colocar algún tipo de datos confidenciales en secreto, por ejemplo, nombre de usuario, contraseña, NIP de seguridad, etc., casi todo lo que cree es sensible y desea llevar a la caja Pod.

Definir secreto opaco

Primero, para que nuestros datos confidenciales parezcan menos confidenciales, permita’que los pueda codificar con la herramienta Base64:

A continuación, coloque la versión codificada de los datos en un archivo YAML de definición de secreto:

De manera alternativa, puede definir el mismo secreto directamente desde kubectl CLI, con la opción--from-literal:

En cualquier caso, se generará un secreto:

Consultar secreto opaco

A continuación, tendrá que utilizar el secreto en una caja Pod-y la información de usuario contenida en el secreto se transferirá al conjunto Pod. Como se mencionó anteriormente, existen varias maneras de hacer referencia al secreto opaco en una caja Pod y, en consecuencia, el resultado será diferente.

Normalmente, la información de usuario procedente de un secreto puede aparecer en un contenedor de una de estas formas:

  • Archivos

  • Variables de entorno

Ahora,’veamos cómo se utiliza el secreto para generar variables de entorno en un contenedor:

Generar el conjunto Pod y el contenedor desde este archivo YAML:

Log en el contenedor y verifica las variables de entorno generadas:

Los datos confidenciales originales codificados con base64 se encuentran ahora en el contenedor!

Dockerconfigjson secreto

El secreto dockerconfigjson, como lo indica el nombre, transporta la información de credenciales de cuenta de Dock que normalmente está almacenada en el archivo. Docker/config. JSON. La imagen en un conjunto pod de Kubernetes puede señalar a un registro de contenedor privado. En ese caso, Kubernetes necesita autenticarlo con ese registro para poder extraer la imagen. El tipo de secreto de dockerconfigjson está diseñado para este propósito.

Datos de credenciales de Docker

El método más directo para crear un tipo de kubernetes.io/dockerconfigjson secreto es proporcionar información de inicio de sesión directamente con el comando kubectl y dejar que genere el secreto:

Compruebe la creación de la clave secreta:

Note

Solo la primera línea de la salida es el secreto que acaba de crear. La segunda línea es un kubernetes.io/service-account-token tipo de secreto que el sistema Kubernetes crea automáticamente cuando la configuración del contrail está en funcionamiento.

Ahora, examine los detalles del secreto:

No es sorprendente que’no vea ninguna información confidencial en forma de texto no cifrado. Hay una parte de datos del resultado en la que puede ver una cadena muy larga como el valor de la clave: dockerconfigjson. Parece que su aspecto se ha transformado a partir de los datos originales, pero al menos no incluye – información confidencial ya más después de que todo el propósito del uso de un secreto sea mejorar la seguridad del sistema.

Sin embargo, la transformación se realiza mediante codificación, no cifrado, por lo que todavía hay una forma de recuperar manualmente la información confidencial original: solo hay que canalizar el valor de Key. dockerconfigjson a la herramienta Base64, y volver a ver la información original sobre el nombre de usuario y la contraseña:

Algunas de las características más destacadas de este resultado son:

  • La herramienta Python-mjson. se usa para dar formato a los datos JSON descodificados antes de mostrarlos en el terminal.

  • Hay un par clave-valor de autenticación. Es el testigo generado basándose en la información de autenticación que dio (nombre de usuario y contraseña).

  • Más adelante, cuando esté equipado con este secreto, un conjunto Pod utilizará este token en lugar del nombre de usuario y la contraseña para autenticarse en el hub.juniper.net del registro privado del acoplador con el fin de extraer una imagen del acoplador.

Tip

Esta’es otra forma de descodificar los datos directamente del objeto secreto:

El servicio --output=xxxx opción filtra la kubectl obtener salida, por lo que solo se muestra el valor de. dockerconfigjson en datos. A continuación, el valor se canaliza en Base64 con la opción--Decode (alias de-d) para obtenerlo descodificado.

Un secreto del registro-acoplador creado manualmente, como esto, solo funcionará con un registro privado único. Para admitir varios registros de contenedor privado, puede crear un secreto a partir del archivo de credenciales del acoplador.

Archivo de credenciales de Docker (~/. Docker/config. JSON)

Como el nombre de la clave. dockerconfigjson en el secreto que creamos indica, cumple una función similar a la del archivo de configuración del acoplador: . Docker/config. JSON. En realidad, puede generar el secreto directamente desde el archivo de configuración del acoplador.

Para generar la información de credenciales del acoplador, compruebe primero el archivo de configuración del acoplador:

No’hay nada aquí. Según el uso de la configuración, es posible que vea resultados diferentes, pero la cuestión es que este archivo de configuración de Docker se actualizará automáticamente cada vez que inicie sesión en un nuevo registro:

El archivo mydockerpass. txt es la contraseña de inicio de sesión del nombre de usuario JNPR-FieldUser213. Guardar la contraseña en un archivo y, a continuación, canalizarla al comando de inicio de sesión del acoplador con la opción--Password-stdin tiene la ventaja de que no expone la contraseña CLEARTEXT en el historial del shell.

Tip

Si desea que pueda escribir la contraseña directamente, recibirá una advertencia descriptiva de que esto no es seguro.

Ahora, la información de credenciales de Docker se genera en el config.json archiva

El proceso de inicio de sesión crea o actualiza una config.json archivo que contiene el token de autorización. ’Crear un secreto a partir de la .docker/config.json archiva

Archivo YAML

También puede crear un secreto directamente desde un archivo YAML de la misma manera que crea otros objetos como servicio o ingreso.

Para codificar manualmente el contenido de la .docker/config.json archiva

A continuación, ponga el valor codificado en Base64 de la .docker/config.json archivar como datos en la parte inferior del archivo YAML:

Tenga en cuenta que en Base64 se trata la codificación, en lugar del – cifrado, se considera lo mismo que el texto sin formato. Por lo tanto, compartir este archivo pone en peligro el secreto.

Consulte Secret en Pod

Después de crear un secreto, se puede hacer referencia a él mediante un conjunto Pod/RC o implementación para poder extraer una imagen del registro privado. Existen muchas formas de hacer referencia a los secretos. En esta sección se examinará el uso de imagePullSecrets bajo Pod spec para referirse al secreto.

Una imagePullSecret es una forma de pasar un secreto que contiene una contraseña del registro de imágenes del acoplador (u otra) a kubelet para que pueda extraer una imagen privada en nombre de su conjunto Pod.

Crear un conjunto Pod que extraiga el contenedor de cSRX Juniper del repositorio privado:

Ahora, genere la caja Pod:

El cSRX está activo y está en funcionamiento:

Y en segundo plano, el conjunto Pod se autentica a sí mismo en el registro privado, extrae la imagen e inicia el contenedor cSRX:

Como vimos a partir de nuestra prueba, los objetos secretos se crean independientemente de los pods, y la inspección de las especificaciones del objeto no proporciona la información confidencial directamente en la pantalla.

Los secretos no se escriben en el disco, sino que se almacenan en un sistema de archivos tmpfs, únicamente en los nodos que los necesitan. Además, los secretos se eliminan cuando se elimina la caja Pod que depende de ellos.

En la mayoría de las distribuciones de Kubernetes nativas, la comunicación entre los usuarios y el servidor de la API está protegida por SSL/TLS. Por lo tanto, los secretos transmitidos a través de estos canales están protegidos adecuadamente.

Cualquier Pod especificado no tiene acceso a los secretos utilizados por otro Pod, lo que facilita la encapsulación de datos importantes en distintos pods. Cada contenedor de un conjunto Pod debe solicitar un volumen de secreto en su volumeMounts para que sea visible dentro del contenedor. Esta característica puede usarse para construir particiones de seguridad en el nivel Pod.

Vida

Cuando una caja Pod crea una instancia, termina y se mueve de un nodo a otro y, por lo tanto, cambia su dirección IP, ¿cómo hacemos el seguimiento de eso para obtener funcionalidades ininterrumpidas del conjunto Pod? Incluso si la caja de’Pod no se mueve, ¿cómo llega el tráfico a grupos de pods a través de una sola entidad?

La respuesta a ambas preguntas es Kubernetes servicio.

El servicio es una abstracción que define un conjunto lógico de pods y una política, por la que puede acceder a ellos. Consideremos que los servicios son de su perdedora en – un’restaurante de gran tamaño este puesto’es en lugar de cocinar: en vez de eso, es una abstracción de todo lo happing en la cocina y solo tiene que enfrentarse a este único espera.

El servicio es un equilibrador de carga de capa 4 que expone las funciones del conjunto Pod a través de una dirección IP y un puerto específicos. El servicio y los pods se vinculan a través de etiquetas como RS. Y existen’tres tipos diferentes de servicios:

  • ClusterIP

  • NodePort

  • Multiplexor

Servicio ClusterIP

El servicio clusterIP es el servicio más sencillo, y el modo predeterminado si no se especifica el ServiceType. La Figure 4 ilustra cómo funciona el servicio clusterIP.

Figure 4: Servicio ClusterIP
Servicio ClusterIP

Puede ver que el servicio ClusterIP se expone en un clusterIP y en un puerto de servicio. Cuando los pods de cliente necesitan acceder al servicio que envía solicitudes hacia este puerto de clusterIP y servicio. Este modelo funciona genialmente si todas las solicitudes proceden del mismo clúster. La naturaleza de la clusterIP limita el ámbito del servicio para que solo esté dentro del clúster. En general, de forma predeterminada, el clusterIP no es accesible externamente.

Crear servicio ClusterIP

El archivo YAML parece bastante sencillo y se explica por sí mismo. Se define una service/service-web-clusterip con el puerto de servicio 8888, que se asigna a targetPort, que significa puerto de contenedor 80 en algún conjunto Pod. El selector indica que cualquier Pod con una etiqueta y una aplicación: WebServer será la solicitud de servicio de backend Pod responding.

Bien, ahora genere el servicio:

Utilizados kubectl comandos para comprobar rápidamente el servicio y los objetos de pod de back-end:

El servicio se creó correctamente, pero no hay pods para el servicio. Esto se debe a que no hay un conjunto Pod con una etiqueta que coincida con el selector en el servicio. Por lo tanto, solo es necesario crear una caja Pod con la etiqueta adecuada.

Ahora, puede definir un conjunto Pod directamente, pero teniendo en cuenta las ventajas de RC y la implementación a pods, según se ha explicado anteriormente, el uso de’RC o la implementación es más práctico (pronto veremos el porqué).

A modo de ejemplo,’Supongamos que define un objeto de implementación denominado WebServer:

El servidor WebServer de implementación tiene una aplicación de etiquetas: servidor webserver, coincidiendo con el selector definido en nuestro servicio. El servicio replicas: 1 indica al controlador que inicie solo un conjunto Pod en este momento. Veamos’:

Y, inmediatamente, el conjunto Pod se elige como el back-end.

Breves resúmenes acerca del anterior kubectl get svc el resultado del comando es:

  • El servicio obtuvo una clusterIP, o IP de servicio, de 10.101.150.135 asignados del grupo de direcciones IP del servicio.

  • El puerto de servicio es 8888 como el que se define en YAML.

  • De forma predeterminada, el tipo de protocolo es TCP si no se declara en el archivo YAML Puede utilizar el protocolo: UDP para declarar un servicio UDP.

  • El POD back-end puede estar ubicado con el selector de etiqueta.

Tip

El ejemplo que se muestra aquí utiliza un selector de igualdad (-l) para ubicar el conjunto pod de back-end, pero también puede usar una sintaxis basada en conjuntos para archivar el mismo efecto. Por ejemplo: kubectl get pod -o wide -l 'app in (webserver)'.

Comprobar servicio ClusterIP

Para comprobar que el servicio funciona realmente, deje’que s inicie otro Pod como cliente para iniciar una solicitud HTTP hacia el servicio. Para esta prueba, se’inicia e inicia sesión en una caja pod de cliente y se utiliza el comando rizo para enviar una solicitud HTTP al servicio. Puede’ver que el mismo Pod se utiliza como cliente para enviar solicitudes a lo largo de este libro:

Crear la caja pod de cliente:

Tip

La caja de cliente no es más que un conjunto de Pod generado basado en la misma imagen, cualquiera que sea la implementación de WebServer y sus pods. Esto es lo mismo que con los servidores físicos y las máquinas virtuales: nada hace que un servidor deje de hacer’el trabajo cliente:

La solicitud HTTP para el servicio llega a un conjunto Pod que ejecuta la aplicación del servidor Web, que responde con una página HTML.

Para demostrar mejor qué Pod proporciona el servicio, deje’que configure una imagen Pod personalizada que ejecute un simple servidor Web. El servidor web está configurado de tal forma que, cuando reciba una solicitud, devolverá una página HTML sencilla con un nombre de host y una dirección IP Pod local incorporados. De este modo, el doblez devuelve algo más significativo en nuestra prueba.

El código HTML devuelto parece relativamente adecuado para leerlo, pero hay una forma de hacerlo más fácil de ver:

La herramienta w3m es un navegador web ligero basado en consola que está instalado en el host. Con w3m puede representar una página web HTML en texto, que es más legible que la página HTML.

Ahora que se verifica el servicio, las solicitudes de servicio se han redirigido al conjunto pod de back-end correcto, con una IP Pod of 10.47.255.238 y un nombre pod de WebServer-7c7c458cc5-vl6zs.

Especificar un ClusterIP

Si desea tener un clusterIP específico, puede mencionarlo en la especificación. Las direcciones IP deben encontrarse en el grupo IP del servicio.

Aquí’enaquí s un ejemplo de YAML con determinados clusterIP:

Servicio NodePort

El segundo tipo general de servicio, NodePort, expone un servicio en cada IP de’nodo en un puerto estático. Asigna el puerto estático de cada nodo con un puerto de la aplicación en la caja Pod, tal como se muestra en la Figure 5.

Figure 5: Servicio NodePort
Servicio NodePort

A continuación, figuran algunos aspectos destacados de este archivo YAML de servicios:

  • selector: El selector de etiqueta que determina qué conjunto de pods se destina a este servicio; aquí, cualquier conjunto Pod con la aplicación de etiquetas: el servidor WebServer será seleccionado por este servicio como back-end.

  • Port: Este es el puerto de servicio.

  • TargetPort: Puerto Real utilizado por la aplicación en el contenedor. Aquí, it’s el puerto 80, ya que planeamos ejecutar un servidor Web.

  • NodePort: Puerto en el host de cada nodo del clúster.

Deje’que s cree el servicio:

  • Escríba El tipo de servicio predeterminado es ClusterIP. En este ejemplo, establecemos el tipo en NodePort.

  • NodePort: De forma predeterminada, Kubernetes asigna puertos de nodo en el rango 30000-32767, si no se menciona en la especificación. Esto puede cambiarse mediante la marca --service-node-port-range. El servicio NodePort también se puede establecer el valor, pero asegúrese de’que lo hace en el rango configurado

  • Endpoints: PodIP y el puerto de contenedor expuesto. La solicitud de servicio a IP y al puerto de servicio se dirigirá aquí, y 10.47.255.252:80 indica que hemos creado un conjunto Pod que tiene una etiqueta coincidente con el servicio, por lo que su dirección IP está seleccionada como uno de los extremos.

Note

Para esta prueba, asegúrese de que hay al menos un conjunto Pod con la etiqueta app:webserver funciona. Los pods de secciones anteriores se crean con esta etiqueta. Volver a crear la pod de cliente es’suficiente si ya las quitó.

Ahora podemos probarlo mediante el comando rizo para activar una solicitud HTTP que apunta a cualquier dirección IP del nodo:

Con la potencia del servicio NodePort, puede tener acceso al servidor Web que se ejecuta en el conjunto Pod desde cualquier nodo a través de la nodePort 32001:

Servicio del equilibrador de carga

El tercer servicio, el servicio equilibrador de carga , va un paso más allá del servicio NodePort al exponer el servicio de forma externa mediante un’equilibrador de carga de proveedor en la nube. El servicio de equilibrador de carga por su propia naturaleza incluye automáticamente todas las características y funciones de los servicios NodePort y ClusterIP.

Kubernetes los clústeres que se ejecutan en proveedores de nube admiten la disposición automática de un equilibrador de carga. La única diferencia entre los tres servicios es el valor Type (tipo). Para volver a usar el mismo archivo de YAML de servicio de NodePort y crear un servicio del equilibrador de carga, solo tiene que establecer el tipo en LoadBalancer:

La nube verá esta palabra clave y se creará un equilibrador de carga. Mientras tanto, se asigna una balancerIP de carga pública externa para que sirva como dirección IP virtual de front-end. El tráfico que llega a este loadbalancerIP se redirigirá al conjunto Pod del backend de servicio. Tenga en cuenta que este proceso de redirección sólo es una operación de capa de transporte. El loadbalancerIP y el puerto se traducirán a Private back-’end clusterIP y IT s targetPort. No implica ninguna actividad de capa de aplicación. No hay nada como analizar una dirección URL, una solicitud HTTP de proxy, etc., como lo que sucede en el proceso de proxy HTTP. Dado que loadbalancerIP es accesible de forma pública, cualquier host de Internet que tenga acceso a él (y el puerto de servicio) puede tener acceso al servicio que proporciona el clúster Kubernetes.

Desde el punto de’vista de un host de Internet, cuando solicita servicio, se refiere a este puerto público de servicio de loadbalancerIP Plus externo, y la solicitud llegará al pod de back-end. El loadbalancerIP actúa como puerta de enlace entre el servicio dentro del clúster y el mundo exterior.

Algunos proveedores de nube le permiten especificar el loadBalancerIP. En esos casos, el equilibrador de carga se crea con el loadBalancerIP especificado por el usuario. Si no se especifica el campo loadBalancerIP, el equilibrador de carga se configura con una dirección IP efímera. Si especifica un loadBalancerIP pero su proveedor de nube no admite la característica, se omitirá el campo loadbalancerIP que establezca.

El modo en que un equilibrador de carga se implementa en el servicio de equilibrador de carga es específico del proveedor. Un equilibrador de carga GCE puede funcionar de una manera totalmente diferente con un equilibrador de carga de AWS. Hay una demostración detallada de cómo funciona el servicio del equilibrador de carga en un entorno de Contrail Kubernetes en el capítulo 4.

IP externas

Exponer el servicio fuera del clúster también puede lograrse mediante el externalIPs ,. He’aquí un ejemplo:

De la Service Spec, externalIPs se puede especificar junto con cualquiera de los tipos de servicio. Las direcciones IP externas no se administran mediante Kubernetes y son responsabilidad del administrador de clústeres.

Note

Las direcciones IP externas son distintas a las de loadbalancerIP, que son las asignadas por el administrador de clústeres, mientras que las IP externas vienen con el equilibrador de carga creado por el clúster que la admite.

Implementación del servicio: Kube-proxy

De forma predeterminada, Kubernetes utiliza el módulo de proxy de Kube para los servicios, pero los proveedores de CNI pueden tener sus propias implementaciones para servicios.

Kube-proxy se puede implementar en uno de los tres modos siguientes:

  • modo de proxy de espacio de usuario

  • modo de proxy iptables

  • modo de proxy IPVS

Cuando el tráfico llega a un nodo’, lo reenvía a uno de los pods back-end a través de un plano de reenvío Kube implementado. En este libro no se abordarán explicaciones detalladas ni comparaciones de estos tres modos, pero puede consultar Kubernetes sitio web oficial para obtener más información. En el capítulo 4 se ilustra cómo Juniper Contrail como proveedor de interfaz de red de contenedor (CNI) implementa el servicio.

Puntos

Hay un objeto que Haven’exploró hasta ahora: EP o Endpoint. Nos’enteramos de que se elige un conjunto o grupo de pods específico con etiquetas coincidentes como el back-end a través del selector de etiquetas, de modo que el tráfico de solicitudes de servicio será redirigido a ellos. La información de puerto e IP de los pods coincidentes se mantiene en el objeto de extremo. Los pods pueden morir y generar cualquier momento, lo más probable es que la gravedad de la terminación de la caja Pod cause que los nuevos pods se regeneren con nuevas direcciones IP. Durante este proceso dinámico, los puntos de conexión siempre se actualizarán en consecuencia, para reflejar las IP pod de back-end actuales, de modo que la redirección de tráfico de servicio actuará correctamente. (Los proveedores CNI que tienen su propia implementación de servicios actualizan el back-end del servicio basándose en los objetos de extremo.)

Este es un ejemplo para mostrar algunos pasos rápidos para comprobar el servicio, el extremo correspondiente y la caja Pod, con etiquetas coincidentes.

Para crear un servicio:

Para enumerar el punto de conexión:

Para localizar la caja Pod con la etiqueta utilizada por el selector en servicio:

Y, por último, escale los pods de back-end:

Ahora vuelva a comprobar los extremos y verá que se han actualizado de la forma correspondiente:

Servicio sin selector

En el ejemplo anterior, el sistema Kubernetes genera automáticamente el objeto endpoints cada vez que se crea un servicio y existe al menos un conjunto Pod con una etiqueta coincidente. Pero otro caso de uso de extremo es un servicio que no tiene definido un selector de etiquetas en el que puede asignar manualmente el servicio a la dirección de red’y al puerto en el que se ejecuta, agregando manualmente un objeto de extremo. A continuación, puede conectar el extremo con el servicio. Esto puede ser muy útil en algunos escenarios, por ejemplo, en una instalación en la que tiene un servidor Web de fondo ejecutándose en un servidor físico y que todavía desea integrarlo en un servicio Kubernetes. En ese caso, solo tiene que crear el servicio de la manera habitual y, a continuación, crear un extremo con una dirección y un puerto que señalen al servidor Web. Que’s. El servicio no se preocupa por el tipo de back-end, simplemente redirige el tráfico de solicitudes de servicio exactamente de la misma manera que si todo back-end fuera un conjunto Pod.

Entrada

Ahora que ahora’ha visto maneras de exponer un servicio a clientes fuera del clúster, otro método es Ingress. En la sección servicio, servicio funciona en capa de transporte. En realidad, tiene acceso a todos los servicios a través de direcciones URL.

La entrada , o la de corta, es otro concepto principal de Kubernetes que permite el enrutamiento http/https que no existe en el servicio. La entrada se crea a partir del servicio. Con la entrada, puede definir reglas basadas en URL para distribuir rutas HTTP/HTTPS a varios servicios back-end diferentes, por lo tanto, la entrada expone los servicios a través de rutas HTTP/HTTPS. Después, las solicitudes se reenviarán a cada servicio’de los pods backend correspondientes.

Entrada frente a servicio

Existen similitudes entre el servicio del equilibrador de carga y las ingresiones. Ambos pueden exponer servicio fuera del clúster, pero hay algunas diferencias significativas.

Capa de operación

La entrada funciona en la capa de aplicación del modelo de red OSI, mientras que el servicio funciona únicamente en el nivel de transporte. La entrada comprende el protocolo HTTP/HTTPS, este servicio solo actúa sobre el reenvío basado en IP y en el puerto, lo que significa que no se preocupa por los detalles del Protocolo de la capa de aplicación (HTTP/HTTPS). Las entrada pueden funcionar en el nivel de transporte, pero el servicio hace lo mismo, de modo’que tampoco tiene sentido que la entrada lo haga, a menos que haya una razón especial para hacerlo.

Modo de reenvío

El proxy de la capa de aplicación se hace muy prácticamente de la misma manera que un equilibrador de carga Web tradicional. Un proxy típico de equilibrador de carga web que se encuentra entre el equipo A (cliente) y B (servidor), funciona en la capa de aplicación. Es consciente de los protocolos de la capa de aplicación (HTTP/HTTPS), por lo que la interacción entre el cliente y el servidor no parece transparente para el equilibrador de carga. Básicamente, crea dos conexiones cada una con el origen, (A) y el destino, (B), el equipo. El equipo A no sabe siquiera de la existencia del equipo B. Para el equipo A, el proxy es el único elemento al que habla y que no le preocupa cómo y dónde obtiene el proxy sus datos.

Número de IP públicas.

Cada servicio de la entrada necesita una dirección IP pública si está expuesta directamente en el exterior del clúster. Cuando la entrada es un front-end a todos estos servicios, una IP pública es suficiente para facilitar la vida de los administradores de la nube.

Objeto de entrada

Antes de profundizar en el objeto Ingress, la mejor forma de hacerse una idea es mirar la definición de YAML:

Puede ver que parece bastante sencillo. La especificación define solo un elemento – que son las reglas. Las reglas indican que un host, que es el Juniper dirección URL, puede tener dos rutas posibles en la cadena de la dirección URL. La ruta de acceso es cualquier cosa que siga al host en la dirección URL, en este caso, son/dev y/QA. A continuación, cada ruta se asocia a un servicio diferente. Cuando la entrada vea que llegan solicitudes HTTP, se envía a través de proxy el tráfico de cada servicio de ruta de URL asociado. Cada servicio, como hemos’aprendido en esta sección de servicio, entregará la solicitud a su ruta de acceso de back-end correspondiente. Que’lo compartiron. En realidad, es uno de los tres tipos de inentradas que Kubernetes admite – hoy ingresos de fan-out sencillos. Los otros dos tipos de entrada se tratarán más adelante en este capítulo.

Acerca de URL, host y ruta de acceso

Los términos host y ruta se usan frecuentemente en la documentación de entrada de Kubernetes. El host es un nombre de dominio completo del servidor. La ruta de acceso o dirección URL es el resto de la parte de cadena después del host en una dirección URL. Si el caso es una de las que tienen un puerto en la dirección URL, entonces es la cadenadespués del puerto.

Eche un vistazo a la siguiente dirección URL:

El host es www.juniper.net, lo que siga al puerto 1234 se denomina ruta, mi/recurso en este ejemplo. Si una dirección URL no tiene ningún puerto, las cadenas que siguen al host serán la ruta de acceso. Para obtener más detalles, puede leer el documento RFC 1738, pero para el propósito de este libro, comprender lo que se introduce aquí será suficiente.

Si ahora piensa que Kubernetes establece algunas reglas y que las reglas son solo para indicar al sistema que dirija las solicitudes entrantes a diferentes servicios, basadas en las direcciones URL, básicamente se trata de un alto nivel. La Figure 6 ilustra la interdependencia entre los tres objetos Kubernetes: entrada, servicio y conjunto Pod.

Figure 6: Entrada, servicio y conjunto Pod
Entrada, servicio y conjunto Pod

En la práctica hay otras cosas que debe comprender, para tratar las reglas de entrada, necesita al menos un componente más denominado el controlador de entrada.

Controladora de entrada

Un controlador de entrada es responsable de la lectura de las reglas de entrada y, a continuación, la programación de las reglas en el proxy, – que realiza el trabajo real que distribuye el tráfico en función del host o la dirección URL.

Los controladores de entrada los suelen implementar otros proveedores. Los distintos entornos de Kubernetes tienen distintos controladores de entrada en función de la necesidad del clúster. Cada controladora de entrada cuenta con su propia implementación para programar las reglas de entrada. La conclusión es que debe haber un controlador de entrada en ejecución en el clúster.

Algunos proveedores de controladores de entrada son:

  • nginx

  • gce

  • haproxy

  • fichero

  • f5

  • istio

  • personalizar

Puede implementar cualquier número de controladores de entrada dentro de un clúster. Al crear una entrada, debe anotar cada entrada con las Ingress adecuadas. clase para indicar qué controlador de entrada debe utilizarse (si existe más de una en el clúster) o no.

La anotación utilizada en los objetos de entrada se explicará en la sección anotación.

Ejemplos de entrada

Existen tres tipos de Ingress:

  • Ingreso de servicio único

  • Entrada de fanout sencilla

  • Entrada de hospedaje virtual basada en nombres

’Echamos un vistazo a las sencillas fanout Ingress, por lo’que ahora veamos un ejemplo YAML File, para los otros dos tipos de Ingress.

Ingreso de servicio único

Ésta es la forma más sencilla de entrada. La entrada recibirá una dirección IP externa, por lo que el servicio se puede exponer al público, sin embargo, no tiene reglas definidas, por lo que no analiza el host ni la ruta de acceso en las direcciones URL. Todas las solicitudes van al mismo servicio.

Entrada de fanout sencilla

Lo extraídamos al principio de esta sección. En comparación con la entrada de servicio único, las fanout de entrada sencilla son más prácticas. ’No solo puede exponer el servicio a través de una IP pública, sino que también puede hacer enrutamiento de URL o salida de fan basada en la ruta de acceso. Éste es un escenario de uso muy común cuando una compañía desea dirigir el tráfico a cada uno de’los servidores dedicados de su departamento según el sufijo de dirección URL después del nombre de dominio.

Host virtual INGRESS

El host virtual basado en nombres es similar a la fanout de la entrada simple que puede realizar el enrutamiento de URL basado en reglas. La potencia única de este tipo de entrada es que permite enrutar el tráfico HTTP hacia varios nombres de host con la misma dirección IP. El ejemplo aquí puede no ser práctico (a menos que un día se fusionen los dos dominios) pero es lo suficientemente bueno como para exhibir la idea. En el archivo YAML se definen dos hosts, “las direcciones URL juniperhr” y “junipersales” , respectivamente. Aunque la asignación de entrada se realizará con una sola IP pública, según el host de la dirección URL, las peticiones hacia la misma IP pública seguirán estando enrutadas hacia los distintos servicios de servidor. Eso’es lo que se denomina un ingreso de alojamiento virtual y’s es un estudio de caso muy detallado en el capítulo 4 para que lo explore.

Note

También es posible combinar una sencilla entrada de fanout y un host virtual en uno solo, pero los detalles no se explican aquí.

Controlador de entrada múltiple

Puede tener varias controladoras de entrada en un clúster, pero es necesario que el clúster sepa cuál elegir. Por ejemplo, en el capítulo 4’hablamos acerca de’contrail controlador de entrada integrado, que no nos impide instalar otro controlador de ingress de terceros, como el controlador nginx Ingress. En su lugar, acabamos teniendo dos controladores de entrada en el mismo clúster con los nombres:

  • opencontrail (predeterminado)

  • nginx

La’implementación de contrail s es la predeterminada, por lo’que no tendrá que seleccionarla específicamente. Para seleccionar nginx como la controladora de ingreso, utilice esta anotación. Kubernetes.io/ingress.class:

Esto le indicará’a contrail s opencontrail de la entrada del controlador que omita la configuración de entrada.

Directiva de red Kubernetes

El modelo de red Kubernetes requiere que todos los pods tengan acceso a todos los demás pods de forma predeterminada. Esto se denomina red plana porque sigue un modelo Allow-any-any . Simplifica de forma significativa el diseño e implementación de las redes de Kubernetes y hace que sea mucho más escalable.

Note

En el capítulo 4 se detallan los requisitos que Kubernetes aplica en las implementaciones de red.

La seguridad es una preocupación importante. En realidad, en muchos casos es necesario un determinado nivel de métodos de segmentación de red para garantizar que solo determinados pods puedan comunicarse entre sí, y que es cuando la política de la red Kubernetes se incorpora a la imagen. Una directiva de red Kubernetes define los permisos de acceso para grupos de Juniper de la misma manera que un grupo de seguridad de la nube se usa para controlar el acceso a las instancias de VM.

Kubernetes admite la Directiva de red a través del objeto NetworkPolicy, que es un recurso Kubernetes como un conjunto de miembros, como Pod, Service,’Ingress y muchas otras que se aprendieron anteriormente en este capítulo. El rol del objeto de directiva de red es definir cómo se permite que los grupos de Juniper se comuniquen entre sí.

A’continuación, examine cómo funciona la Directiva de red de Kubernetes:

  1. 1Initially, en un clúster de Kubernetes, todos los pods no se aíslan de forma predeterminada y funcionan en un modelo allow-any-any, por lo que cualquier Pod puede comunicarse con cualquier otro Pod.

  2. 2. Aplique ahora una directiva de red denominada directiva1 a. En la Directiva directiva1, usted define una regla para permitir explícitamente que el conjunto Pod a hable con la Pod B. En este caso,’deje que s llame a POD a un pod de destino , ya que es la caja Pod en la que actuará la Directiva de red.

  3. 3. A partir de este momento, ocurrirán algunas cosas:

    • La pod de destino a puede comunicarse con la Pod B y sólo puede hablar con la Pod b, ya que B es el único conjunto Pod permitido en la política. Debido a la naturaleza de las reglas de políticas, puede llamar a la regla una lista blanca.

    • En el caso del pod de destino A solamente, se rechazarán todas las conexiones que no estén explícitamente permitidas por la lista blanca de esta política de red. ’No es necesario definirlo explícitamente a la directiva1, porque se aplicará según la naturaleza de la Directiva de red Kubernetes. Deje’que se llame a esta política implícita denegar todas las políticas.

    • Como en el caso de otros pods no objetivo, por ejemplo, Pod B o Pod C, que no se aplican con la directiva1, ni a ninguna otra política de red, continuará siguiendo el modelo "Allow-any-any". Por lo tanto, no se ven afectados y pueden seguir comunicándose con todos los demás pods del clúster. Esta es otra directiva implícita, que es permitir todas las políticas.

  4. Suponiendo que también desea que pod a pueda comunicarse con Pod C, debe actualizar la Directiva de red directiva1 y sus reglas para permitirlo de forma explícita . En otras palabras, debe seguir actualizando la lista blanca para permitir más tipos de tráfico.

Como puede ver, al definir una directiva, se aplicarán al menos tres políticas en el clúster:

  • Explícito de la directiva1: Se trata de la Directiva de red definida, con las reglas de la lista blanca que permite determinados tipos de tráfico para el conjunto Pod seleccionado.

  • Denegar implícitamente toda la Directiva de red: Esto deniega el resto del tráfico que no se encuentra en la lista blanca de la caja pod de destino.

  • Activar implícitamente todas las políticas de red: Esto permite cualquier otro tráfico para los otros pods no objetivo que no estén seleccionados por la directiva1. Disponemos’que vea denegar todo y volver a permitir todas las políticas en el capítulo 8.

Estas son algunas de las características más destacadas de la Directiva de red Kubernetes.

  • Específico del conjunto Pod: La especificación de políticas de red se aplica a un conjunto Pod o a un grupo de pods basado en la etiqueta, igual que RC o deploy do.

  • Reglas basadas en listas blancas: reglas explícitas que componen una lista blanca, y cada regla describe cierto tipo de tráfico que se permitirá. Cualquier otro tráfico no descrito por ninguna regla de la lista blanca será rechazado para la caja de los pod de destino.

  • Permitir todo todo implícito: Un conjunto de transformadores solo se verá afectado si lo selecciona una directiva de red como destino y solo se verá afectado por la Directiva de red de selección. La ausencia de una directiva de red aplicada a una caja Pod indica que se permite implícitamente esta directiva a este conjunto Pod. En otras palabras, si un conjunto Pod sin destino continúa su modelo de red allow-any-any.

  • Separación de entrada y salida: Es necesario definir reglas de políticas para una dirección específica. La dirección puede ser entrada, salida, ninguna o ambas cosas.

  • Basado en flujo (frente a paquetes): Una vez permitido el paquete de inicio, también se permitirá el paquete de retorno en el mismo flujo. Por ejemplo, supongamos que una directiva de ingreso aplicada al encajal A permite una solicitud HTTP de entrada y, a continuación, se permitirá toda la interacción HTTP para el conjunto Pod A. Esto incluye el establecimiento de la conexión TCP tridireccional y todos los datos y confirmaciones en ambas direcciones.

Note

El componente de red implementa las directivas de red, por lo que debe usar una solución de red compatible con la Directiva de red. Si solo crea el recurso NetworkPolicy sin un controlador para implementarlo, no tendrá ningún efecto. En este libro Contrail es un componente de red con la Directiva de red implementada. En el capítulo 8,’verá cómo funcionan estas directivas de red en contrail.

Definición de directiva de red

Como todos los demás objetos de Kubernetes, la Directiva de red puede definirse en un archivo YAML. Echemos’un vistazo a un ejemplo (el mismo ejemplo se utilizará en el capítulo 8):

Echemos’un vistazo a la parte de especificaciones de este archivo YAML, ya que las demás secciones son algo explicativos. La especificación tiene la siguiente estructura:

Aquí puede ver que un archivo YAML de definición de directiva de red puede dividirse lógicamente en cuatro secciones:

  • podSelector: Define la selección de pods. Identifica a los pods a los que se aplicará la política de red actual.

  • policyTypes: Especifica el tipo de reglas de directiva: Entrada, salida o ambas.

  • entrada Define las reglas de la política de entrada para los Juniper de destino.

  • salida Define las reglas de la Directiva de salida para los Juniper de destino.

A continuación’, examinaremos cada sección con más detalle.

Selección de pods de destino

Al definir una directiva de red, Kubernetes necesita saber a qué Juniper desea que actúe esta Directiva. De manera similar a cómo selecciona el servicio sus Juniper de back-end, la política de red selecciona los pods a los que se aplicará según las etiquetas:

Aquí, todos los pods que tienen la etiqueta app: webserver-dev la política de red selecciona como Juniper de destino. Todo el siguiente contenido en la especificación se aplicará solo a los pods de destino.

Tipos de políticas

En la segunda sección se definen los policyTypes para los pods de destino:

PolicyTypes puede ser ingreso, salida o ambos. Y ambos tipos definen los tipos de tráfico específicos en forma de una o más reglas, como se explica a continuación.

Reglas de políticas

Las secciones entrada y salida definen la dirección del tráfico, desde la perspectiva de los pods’ de destino seleccionados. Por ejemplo, considere el siguiente ejemplo simplificado:

Si damos por hecho que el pod de destino es WebServer-pod de desarrollador y solo hay un conjunto Pod-dev en el clúster con una etiqueta de cliente1-dev, se producirán dos cosas:

  1. Dirección de entrada: el servidor WebServer de Pod-dev puede aceptar una sesión TCP con un puerto de destino 80, iniciado desde Pod client1-dev. Esto explica por qué dijimos Kubernetes la Directiva de red está basada en el flujo en lugar de en el paquete. No se pudo establecer la conexión TCP si la Directiva hubiera sido diseñada para el paquete porque al recibir la sincronización TCP entrante, la devolución de sincronización TCP-ACK de salida se habría rechazado sin una directiva de salida coincidente.

  2. Dirección de salida: Pod WebServer: dev puede iniciar una sesión TCP con el puerto de destino 8080, hacia el conjunto Pod-dev.

Tip

Para que continúe la conexión de salida, el otro extremo necesita definir una directiva de entrada para permitir la conexión entrante.

Reglas de directiva de red

Cada instrucción from o to define una regla en la Directiva de red:

  • Una instrucción from define una regla de la Directiva de entrada.

  • Una instrucción to define una regla de directiva de salida

  • Ambas reglas pueden tener opcionalmente sentencias ports, que se tratarán más adelante.

Por lo tanto, puede definir varias reglas para permitir modos de tráfico complejos para cada dirección:

Cada regla identifica los puntos de conexión de red en los que los pods de destino se pueden comunicar. Los puntos de conexión de red se pueden identificar mediante distintos métodos:

  • ipBlock: Selecciona los pods basados en un bloque de direcciones IP.

  • namespaceSelector: Selecciona los pods basados en la etiqueta del espacio de nombres.

  • podSelector: Selecciona los pods basados en la etiqueta de la caja Pod.

Note

PodSelector selecciona diferentes cosas cuando se utiliza en distintos lugares de un archivo YAML. Anteriormente (en Spec), seleccionó Juniper al que se aplica la política de red’, lo que nos encontramos denominado pods de destino. Aquí, en una regla (en de o hasta (to)), selecciona los pods con los que se comunica la caja pod de destino. A veces llamamos a estos podso extremosde emparejamiento de pods.

Por lo tanto, la estructura YAML de una regla puede ser similar a la siguiente:

Por ejemplo:

Aquí, los puntos de conexión de la red de entrada son las subredes 10.169.25.20/32; o todos los pods en espacios de nombres que tengan el proyecto Label: jtac o los pods que tienen la aplicación de etiqueta: cliente1-dev en el espacio de nombres actual (espacio de nombres de Target POD) y el punto de red de salida es Pod dbserver-dev. ’Los puertos llegarán pronto a las piezas.

Y frente o

’También es posible especificar solo unos cuantos pods de espacios de nombres, en lugar de comunicarse con todos los pods. En nuestro ejemplo, podSelector se utiliza a todos, lo que supone el mismo espacio de nombres que el pod de destino. Otro método es usar podSelector junto con un namespaceSelector. En ese caso, los espacios de nombres a los que pertenecen los pods son aquellos que tienen etiquetas coincidentes con namespaceSelector, en lugar del mismo’que el espacio de nombres Pod s de destino.

Por ejemplo, si damos por hecho que el pod de destino es WebServer-dev y su espacio de nombres es dev, y solo la calidad de espacio de nombres tiene un proyecto de etiqueta = coincidencia de QA en la namespaceSelector:

Aquí, el conjunto de destinos solo se puede comunicar con aquellos pods que estén en el espacio de nombres de AC y (not OR) con la etiqueta app: client1-qa.

Tenga cuidado en este caso porque es totalmente diferente a la definición siguiente, lo que permite que el conjunto pod de destino hable con esos pods: en espacios de nombres qaO (not AND) con etiqueta app: client1-qa en el dispositivo de’espacio de nombres Pod s de destino:

Protocolo y puertos

También es posible especificar puertos para una regla de entrada y salida. El tipo de protocolo también se puede especificar junto con un puerto de protocolo. Por ejemplo:

Los puertos en la entrada indican que los pods de destino pueden permitir el tráfico entrante para los puertos y el protocolo especificados. Puertos en salida indican que los pods de destino pueden iniciar el tráfico en los puertos y protocolos especificados. Si no se menciona el puerto, se permiten todos los puertos y protocolos.

Explicación línea a línea

A’continuación, echemos un vistazo a nuestro ejemplo en detalle:

Ahora debe saber exactamente lo que la Directiva de red está intentando imponer.

Líneas 1-3: Pod WebServer: dev lo selecciona la política, por lo que es el pod de destino; se aplicarán todas las reglas de políticas siguientes, y solo lo será.

Líneas 4-6: la política definirá reglas tanto para el tráfico de entrada como para el de salida.

Líneas 7-19: entrada sección define la política de entrada.

Línea 8: contra y 17: puertos, estas dos secciones definen una regla de directiva en la Directiva de entrada.

Líneas 9-16: estas ocho líneas en la línea desde: sección redactar una lista blanca de entrada:

  • Líneas 9-10: todos los datos que entran con la dirección IP de origen 10.169.25.20/32 pueden acceder al servidor webpod de destino-dev.

  • Líneas 11-13: Any pods en namespace jtac puede acceder a WebServer de Target Pod-dev.

  • Líneas 14-16: cualquier pods con la etiqueta client1-dev puede acceder a WebServer de Target Pod-dev.

Líneas 17-19: la sección de puertos es la segunda (y la opcional) parte de la misma regla de directiva. Solo el puerto TCP 80 (servicio Web) en WebServer del pod de destino-dev está expuesto y se puede acceder a él. Se denegará el acceso a todos los demás puertos.

Líneas 20-26: salida sección define la Directiva de salida.

Líneas 21: como y la línea 24: puertos, estas dos secciones definen una regla de directiva en la Directiva de salida.

  • Líneas 21-24: estas cuatro líneas bajo: sección componen una lista blanca de salida, la caja de destino puede enviar tráfico de salida al desarrollo de la Pod dbserver.

Línea 25: la sección de puertos es la segunda parte de la misma regla de políticas. El servidor WebServer-pod de destino solo puede iniciar una sesión TCP con el puerto de destino 80 a otros pods.

’... Y no todo. Si no recuerda al principio de este capítulo, hablamos acerca del modelo predeterminado de red Allow-any-any de Kubernetes y las políticas de denegación-todos, permitir-todo IMPLÍCITAS, se dará cuenta de que hasta ahora acabamos de explicar la parte explícita de la misma (directiva1 en nuestra sección Introducción a la Directiva de red). Después de esto, existen dos políticas más implícitas:

Denegar toda la Directiva de red: para el servidor WebServer-dev del pod de destino, deniega todo el tráfico que no es lo permitido explícitamente en las listas blancas anteriores, lo que implica al menos dos reglas:

  • entrada deniegue todo el tráfico entrante destinado al servidor WebServer de destino-dev (distinto de lo que se define en la lista blanca de entrada).

  • salida deniegue todo el tráfico saliente del servidor WebServer-dev de destino, distinto de lo que se define en la lista blanca de salida.

Una directiva de permitir todas las redes permite todo el tráfico de otros pods que no son objetivos de esta política de red, tanto en la entrada como en la salida.

Note

En el Chapter 8’, profundizaremos más en profundidad estas políticas de red implícitas y sus reglas en contrail implementación.

Crear Directiva de red

Puede crear y verificar la Directiva de red del mismo modo que crea otros objetos de Kubernetes:

En el capítulo 8’, configuramos un entorno de prueba para comprobar con más detalle el efecto de esta directiva de red.

Sonda de vida

¿Qué sucede si la aplicación en el conjunto Pod se ejecuta pero’no puede servir para su propósito principal, por cualquier razón? Asimismo, las aplicaciones que se ejecutan durante mucho tiempo pueden pasar a Estados rotos y, si éste es el último caso, es una llamada que informa de un problema en una aplicación que podría corregirse fácilmente con el reinicio de la caja Pod. Los sondeos de vida son una característica de Kubernetes específicamente diseñada para este tipo de situaciones. Las sondas de vida envían de forma regular una solicitud predefinida a la caja Pod y, a continuación, reinician la caja Pod si se produce un error en la solicitud. El sondeo de la vida utilizado con más frecuencia es la solicitud GET de HTTP, pero también puede abrir el socket TCP o, incluso, emitir un comando.

El siguiente es un ejemplo de sondeo HTTP GET request, en el que el initialDelaySeconds es el tiempo de espera antes del primer intento de solicitud HTTP GET en el puerto 80, ejecutará el sondeo cada 20 segundos según lo especificado en periodSeconds. Si se produce un error, la caja Pod se reiniciará automáticamente. Tienes la opción de especificar la ruta de acceso, que es solo el sitio web principal. También puede enviar la sonda con un encabezado personalizado. Echemos un vistazo rápido:

Ahora,’deje que s inicie este conjunto, luego inicie sesión en él para finalizar el proceso que se encarga de la solicitud HTTP GET:

Puede ver que la caja Pod se ha reiniciado automáticamente y que también puede ver el motivo de dicho reinicio en el evento:

Éste es un ejemplo de sondeo de socket TCP. Una sonda de socket de TCP es similar a las sondas HTTP GET request, pero abre el socket TCP:

El comando es como las sondas de socket HTTP GET y TCP. Sin embargo, el sondeo ejecutará el comando en el contenedor:

Sonda de preparación

Una sonda de vida garantiza que la caja Pod está en buen estado de salud, pero que para algunas’aplicaciones no es suficiente. Algunas aplicaciones necesitan cargar archivos de gran tamaño antes de empezar. Puede que piense si ha establecido un valor superior initialDelaySeconds valor, el problema se resuelve, pero no es una solución eficiente. La sonda de preparación es una solución especialmente para los servicios de Kubernetes, ya que el conjunto Pod no recibirá el tráfico hasta que esté listo. Siempre que se produce un error en el sondeo Readiness, se quita el extremo del Pod del servicio y éste se vuelve a agregar cuando el sondeo Readiness se realiza correctamente. La sonda de preparación se configura de la misma manera que la sonda de vida:

Note

Se’recomienda utilizar tanto el sondeo de preparación como el sondeo de la vida, por lo que el sondeo de funcionamiento reinicia el conjunto Pod si falla y la sonda de preparación garantiza que la caja Pod está lista antes de obtener tráfico.

Parámetros de sondeo

Los sondeos tienen varios parámetros que puede utilizar para controlar más de forma precisa el comportamiento de las comprobaciones de la preparación y la vida.

  • initialDelaySeconds: Número de segundos que deben transcurrir antes de que el contenedor se haya iniciado antes de que se inicien sondeos o comprobaciones de preparación.

  • periodSeconds: La frecuencia (en segundos) con la que se realizará la sonda. El valor predeterminado es 10 segundos. El valor mínimo es 1.

  • timeoutSeconds: Número de segundos después de los cuales se agota el tiempo de la sonda. El valor predeterminado es 1 segundo. El valor mínimo es 1.

  • successThreshold: Mínimo de éxitos consecutivos para que la sonda se considere satisfactoria después de haber fallado. El valor predeterminado es 1. Debe ser 1 para la vida. El valor mínimo es 1.

  • failureThreshold: Cuando se inicia un conjunto Pod y se produce un error en la sonda, Kubernetes intentará failureThreshold momentos antes de abandonar la instalación. Liberar en caso de sondeo de vida significa reiniciar el conjunto Pod. Si se trata de una sonda de preparación, la caja Pod-se marcará como no leída. El valor predeterminado es 3. El valor mínimo es 1.

Y los sondeos HTTP tienen parámetros adicionales que se pueden establecer en httpGet:

  • host: Nombre de host con el que se conecta, que de forma predeterminada es la IP del conjunto Pod. Es probable que desee establecer “el” host en httpHeaders en lugar.

  • scheme: Esquema que se utiliza para conectar con el host (HTTP o HTTPS). El valor predeterminado es HTTP.

  • path: Ruta de acceso a Access en el servidor HTTP.

  • httpHeaders: Encabezados personalizados que se van a establecer en la solicitud. HTTP admite encabezados repetidos.

  • port: Nombre o número del puerto al que se tiene acceso en el contenedor. El número debe estar comprendido entre 1 y 65535.

Anotación

Ya ha visto cómo se utilizan las etiquetas en Kubernetes para identificar, seleccionar y organizar objetos. Sin embargo, las etiquetas son solo una manera de adjuntar metadatos a objetos Kubernetes.

Otra forma son las anotaciones, que es un mapa de clave/valor que adjunta a los objetos metadatos no identificadores. La anotación tiene muchos casos de uso, como, por ejemplo, adjuntar:

  • punteros para el registro y el análisis

  • números de teléfono, entradas de directorio y sitios web

  • marcas de hora, hashes de imagen y direcciones del registro

  • red, espacios de nombres

  • y, tipos de la controladora de entrada

A’continuación se muestra un ejemplo para anotaciones:

Las anotaciones se pueden usar para asignar información de red a los pods, y en el capítulo’9 se observa cómo una anotación Kubernetes puede indicar a Juniper contrail que conecte una interfaz a una determinada red. Elegante.

Antes de ver las anotaciones en acción,’deje que cree primero una red con una configuración mínima basada en la definición de recursos personalizada de la red Kubernetes de hecho. NetworkAttachmentDefinition se utiliza aquí para indicar la CNI, así como los parámetros de la red a los que se conectará a la interfaz Pod:

El servicio type, awesome-plugin, es el nombre de la CNI que podría ser flannel, Calico, Contrail-K8s-CNI, etc.

Crear un conjunto Pod y usar anotaciones para conectar su interfaz a una red denominada net-a:

Note

Según la definición de recurso personalizado de red Kubernetes oficial, el k8s.v1.cni.cncf.io/networks de anotación se utiliza para representar NetworkAttachmentDefinition y tiene dos formatos:

Note

Para mantener la compatibilidad con las implementaciones de Kubernetes existentes, todos los pods deben estar conectados a la cluster-wide red predeterminada, que significa incluso si conectó una interfaz Pod a una red específica, este conjunto Pod tendría dos interfaces: una conectada a la cluster-wide red predeterminada y la otra conectada a la red especificada en el argumento anotación (net-a en este caso).