Comunicación segura y encriptada entre los clústeres de Anthos mediante Anthos Service Mesh

Last reviewed 2021-04-30 UTC

En este documento, se explica a los ingenieros de redes y plataformas y seguridad que administran clústeres de Kubernetes cómo manejar la comunicación externa y entre clústeres con las puertas de enlace de entrada y salida de Anthos Service Mesh. En el documento, se describe cómo usar Anthos Service Mesh para encriptar y ayudar a proteger el tráfico saliente (salida) de cargas de trabajo implementadas en un clúster de Kubernetes a cargas de trabajo que se ejecutan en otro clúster de Kubernetes. Las técnicas que se describen a continuación muestran cómo usar certificados diferentes para la comunicación mutua, encriptada y de clúster a clúster.

La orientación de este documento se basa en los requisitos de los clientes de usar una autoridad certificadora (CA) raíz específica para la comunicación dentro del clúster. Es posible que encuentres estos requisitos en mercados muy regulados, como los servicios financieros o la atención médica. La guía que se presenta aquí también permite el uso de extremos que no sean de clústeres de Kubernetes, como proveedores de permisos financieros o una interfaz de API para datos sensibles. Esta orientación es especialmente relevante para las organizaciones que deben cumplir con políticas de auditoría y seguridad estrictas.

Puedes operar y manejar la comunicación encriptada sin tocar las cargas de trabajo que se ejecutan en los clústeres. Para obtener orientación sobre cómo configurar tus propios clústeres, sigue el instructivo complementario.

Introducción

Cuando las empresas comienzan a adoptar Kubernetes por primera vez, a menudo comienzan con un solo clúster, y la mayoría de las comunicaciones permanecen dentro de él. Luego, la interacción entre espacios de nombres se vuelve cada vez más importante, y un proveedor de políticas de red como Calico o Cillium puede ayudar. Sin embargo, a medida que crecen los entornos de contenedores, se vuelve más relevante garantizar que la comunicación pueda ocurrir de forma segura entre los servicios externos y tus contenedores que se ejecutan dentro de clústeres de Kubernetes.

La política de red es una excelente manera de abordar los conceptos de seguridad tradicionales, como crear reglas de firewall internas del clúster, pero su uso es limitado fuera del clúster. Se puede permitir el acceso a solo una dirección IP, pero no hay control sobre el contenido o la identidad. Por lo tanto, se requiere un concepto más versátil, lo que también te ayuda a encriptar el tráfico hacia otros servicios externos. Se ofrece un enfoque en el siguiente diagrama.

Encriptación del tráfico mediante un certificado privado (secreto) con una contraparte pública.

En el mundo de las aplicaciones, la encriptación suele realizarse con TLS (seguridad de la capa de transporte). Esto significa que puedes encriptar el tráfico mediante un certificado privado (secreto) con una contraparte pública, como se muestra en el diagrama anterior. La parte receptora posee el certificado público, que se usa para verificar que la información provenga de una fuente confiable. El tráfico web HTTPS usa TLS para garantizar comunicaciones seguras y encriptadas entre un cliente y un servidor web. En este caso, el certificado público proviene de una entidad de confianza (como Google Trust Services), también conocida como CA, que forma parte de la Infraestructura de clave pública (PKI). TLS verifica la identidad del servidor, pero no la del cliente.

En los casos en los que también se debe verificar el cliente, se requiere la autenticación mutua o mTLS. Esta última se usa cuando el remitente y el receptor deben identificarse ante la otra parte, como se muestra en el siguiente diagrama.

Encriptación del tráfico mediante autenticación mutua (mTLS).

Este método se usa con frecuencia para aplicaciones que necesitan una capa de seguridad adicional. En la industria financiera, los reguladores suelen requerir mTLS para la información de identificación personal (PII).

Anthos Service Mesh

Anthos Service Mesh es una solución de malla de servicios administrada por Google basada en OSS Istio. Esto significa que es 100% compatible con la API de Istio. Anthos Service Mesh puede proporcionar la funcionalidad de mTLS a nivel de la plataforma, en lugar de hacerlo dentro del código de la aplicación. Esto significa que se puede aplicar a los servicios sin que tengas que codificar cada uno de ellos. Las operaciones como la rotación de certificados también forman parte de Anthos Service Mesh. Este documento se centra en la mTLS y las funciones de comunicación externa de Anthos Service Mesh. Existen muchas otras características, como la inserción de errores, el balanceo de cargas avanzado y la administración de errores.

Cuando se enruta todo el tráfico a través de proxies de sidecar (Envoy), las mallas de servicios como Anthos Service Mesh liberan al desarrollador de las tareas menos relevantes (pero importantes) como la encriptación y el manejo de certificados. Gracias al uso de un proxy transparente, las mallas de servicios pueden habilitar funciones de L7 potentes, como el enrutamiento de llamadas HTTP y HTTPS según la información del encabezado. Sin embargo, Anthos Service Mesh también admite el encapsulamiento y la encriptación del tráfico, lo que puede ayudar a mejorar la seguridad.

Configuración de ejemplo: comunicación de MySQL entre clústeres

Puedes usar esta situación cuando quieras tener una comunicación segura y confiable entre servicios de diferentes clústeres. En este ejemplo, la aplicación cliente MySQL se comunica con una carga de trabajo de base de datos del servidor MySQL que se ejecuta en un clúster de Kubernetes diferente, como se muestra en el siguiente diagrama.

Aplicación cliente MySQL que se comunica con una carga de trabajo de base de datos del servidor MySQL que se ejecuta en un clúster de Kubernetes diferente.

Aunque las mallas de servicios suelen funcionar en OSI L7, también puedes usar algunas de sus funciones para controlar las comunicaciones de L4.

A continuación, te mostramos lo que necesitas para que el concepto funcione:

  • La comunicación entre las aplicaciones y los clústeres debe estar encriptada.
  • La comunicación entre el cliente y el servidor debe estar verificada de forma mutua (mTLS).
  • Las cargas de trabajo del cliente y del servidor no necesitan cambiar.

Aunque puedes configurar la base de datos MySQL para aceptar solo conexiones encriptadas, esa configuración requiere que cambies el cliente de base de datos, que tal vez no controlas totalmente.

Existen varias formas de abordar estos requisitos con Anthos Service Mesh. Una forma es crear un plano de control compartido de Istio entre clústeres y hacer que los servicios se comuniquen entre sí porque pertenecen a una única malla de servicios lógica. Puedes hacerlo con los clústeres de GKE habilitados para Anthos mediante Anthos Service Mesh en un proyecto único o varios proyectos.

Sin embargo, debido a que hay un requisito de tener una cadena de confianza independiente para la comunicación entre clústeres, puedes usar el enfoque de puerta de enlace de salida <–> puerta de enlace de entrada con mTLS.

Las puertas de enlace de entrada y salida son proxies de Envoy que residen en los límites de la malla.

Puedes configurarlos para controlar el flujo del tráfico hacia y desde el servicio. Esto también funciona para extremos que no son de Kubernetes y te permite usar diferentes certificados para la comunicación encriptada.

Configura la entrada y la salida de la malla de servicios de Anthos

En la situación anterior, manejas la comunicación segura de clúster a clúster con las puertas de enlace de salida y entrada entre los clústeres respectivos.

¿Qué es una puerta de enlace de salida?

La salida significa que el tráfico sale de la malla de servicios. Una puerta de enlace de salida proporciona un punto de salida controlado para ese tráfico.

En el caso de un pod en el que se insertó el proxy de sidecar, si no hay ninguna configuración adicional, el tráfico destinado a un servicio que reside fuera de la malla (por ejemplo, un servicio de API pública) se enruta del pod al proxy de sidecar. En un clúster de GKE (y la mayoría de los otros clústeres de Kubernetes), la dirección IP del nodo usa una NAT para traducir el tráfico del proxy de sidecar, que fluye directamente a la dirección externa del servicio. En el siguiente diagrama, se muestra esta configuración.

El cliente llama al servidor, que representa el servicio externo.

En este diagrama, el cliente llama al servidor, que representa el servicio externo. Para la malla, este tráfico es saliente, por lo que debes configurar la puerta de enlace de salida del cliente (por ejemplo, el cliente MySQL).

Configura la puerta de enlace de salida para enviar la llamada al servicio externo. Una vez que el servicio externo procesa la solicitud y muestra la respuesta, vuelve a pasar por la puerta de enlace de salida al proxy de cliente y, por último, al Pod que emite la llamada (por ejemplo, el cliente MySQL).

¿Qué es una puerta de enlace de entrada?

Entrada se refiere a tráfico que fluye a la malla de servicios. Una puerta de enlace de entrada expone los servicios al mundo exterior (es decir, fuera de la malla de servicios) y controla el modo de acceso a estos servicios. Es comparable con un objeto Ingress de Kubernetes.

Con una puerta de enlace de entrada, puedes definir un solo punto de entrada controlado en el que el tráfico entra en la malla. Inicialmente, el tráfico ingresa a través del balanceador de cargas, que se crea mediante la definición de un servicio de puerta de enlace de entrada. A partir de allí, la solicitud se reenvía al proxy de sidecar y, desde este, se reenvía al pod. El pod puede procesar la solicitud y mostrar la respuesta siguiendo la misma ruta en sentido inverso. En el siguiente diagrama, se muestra esta configuración.

El tráfico ingresa a través de un balanceador de cargas y la solicitud se reenvía a un proxy de sidecar y a un Pod.

Este tráfico entrante se dirige a la malla del otro clúster (VPC 2). Por lo tanto, debes configurar la puerta de enlace de entrada del lado del servidor para manejar esas llamadas.

La configuración del servidor de la puerta de enlace de entrada reenvía la llamada al servicio interno. Después de que el servicio interno procesa la solicitud, la respuesta que muestra vuelve a pasar a través de la puerta de enlace de entrada al cliente.

Combina la funcionalidad de entrada y salida para la TLS mutua

Como se mencionó antes, para el lado del cliente, debes definir una puerta de enlace de salida que actúe como un punto de salida controlado de la malla de servicios. Para asegurarse de que el tráfico que salga de la malla a través de la puerta de enlace se encripte por medio de mTLS, puedes usar una técnica llamada TLS de origen. Configura una puerta de enlace de salida a fin de crear una TLS de origen para el tráfico a servicios externos.

Cuando el tráfico que sale de la malla de servicios del lado del cliente se encripta, debes asegurarte de que el lado del servidor pueda identificarse ante el cliente y descifrar el tráfico encriptado.

Para ello, debes usar la puerta de enlace de entrada como un único punto de entrada a la malla. Configura la puerta de enlace de entrada para que espere tráfico mutuamente encriptado.

Descripción general de la arquitectura de la malla

El siguiente diagrama describe lo que se necesita para implementar este concepto en la situación de MySQL sin cambiar nada en la aplicación o en el servidor.

En la VPC 1, verás que el clúster de cliente que ejecuta el cliente MySQL accede al servidor. El servidor se encuentra en la VPC 2.

El lado del cliente tiene más configuraciones que el del servidor, ya que necesitas ajustar un poco más las coincidencias de tráfico y el enrutamiento para garantizar que la aplicación use la puerta de enlace de salida. Sin embargo, esta configuración se realiza en el primer momento, lo que significa que tienes que hacerlo una sola vez. Una vez que la implementas, es bastante fácil de mantener.

Un beneficio de implementar este concepto con Kubernetes es que todos los elementos de configuración se almacenan en archivos YAML. Esto significa que todo el constructo se puede usar en un repositorio con versión, lo que te permite realizar un seguimiento de los cambios y revertirlos con facilidad si es necesario.

El lado del cliente

Esta subsección examina la configuración del cliente. Cada elemento que ves en el diagrama tiene una función distinta en la malla para controlar cómo se enruta el tráfico a través de la puerta de enlace de salida para que llegue a su destino, el servidor MySQL.

El enrutamiento de tráfico es solo una parte de la funcionalidad requerida. Otros elementos controlan la encriptación del tráfico, de forma completamente transparente, para garantizar que la comunicación siempre sea segura. En las siguientes secciones, se examinan los elementos para comprender mejor su función y su forma de operar en este caso.

Configuración del cliente en la que se muestra cómo se enruta el tráfico a través de la puerta de enlace de salida hacia el servidor MySQL.

Entrada de servicio

Una malla de servicios crea su propio registro de servicio en un clúster de Kubernetes. El plano de control usa este registro para configurar los proxies de sidecar adicionales como una tabla de enrutamiento. Los servicios que se ejecutan en Kubernetes se descubren de manera automática y se agregan al registro de malla de servicios. Los servicios que no se ejecutan dentro del clúster de Kubernetes no se pueden detectar de forma automática, pero se pueden definir con ServiceEntries. De esta manera, el cliente puede usar una entrada como un nombre de host para conectarse a servicios externos.

En Anthos Service Mesh, se usan nombres de dominio completamente calificados (FQDN) para identificar todos los servicios. El FQDN es la parte más importante de este constructo porque los certificados se basan en el nombre de host. Aunque es posible cambiar el FQDN, significa que también debes volver a generar todos los certificados necesarios.

Para habilitar la comunicación, debes configurar la malla de servicios para que detecte llamadas al servicio externo a fin de enrutar el tráfico de forma adecuada. La malla te permite definir una entrada de servicio que apunte a ese servicio externo.

Este constructo se llama MESH_EXTERNAL y es ideal para estos casos de uso. También puedes especificar lo que buscas. Debido a que se trata de un caso de uso L4 y solo puedes controlar la dirección IP y el puerto, debes indicarle a la malla el protocolo y los puertos específicos que, en este caso, son TCP y el puerto 3306 (el puerto de protocolo estándar de MySQL). Además, la contraparte del servidor (como se muestra en el diagrama anterior) escucha en el puerto 13306 (la puerta de enlace de salida del clúster del servidor). Por último, debes indicarle a tu entrada de servicio que capte el tráfico con esta etiqueta de puerto.

En el siguiente ejemplo de entrada de servicio YAML, se ilustra esta configuración:

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
 name: mysql-external
spec:
 hosts:
   - mysql.fqdn.example
 location: MESH_EXTERNAL
 ports:
   - number: 3306
     name: tcp
     protocol: TCP
   - number: 13306
     name: tls
     protocol: TLS
 resolution: DNS
 endpoints:
   - address: mysql.fqdn.example
     ports:
       tls: 13306

Con el campo hosts, puedes configurar el FQDN del servicio externo o puedes especificar que el campo location sea MESH_EXTERNAL. También debes especificar los valores ports que usa el servicio externo, en este caso, 13306 y 3306. 13306 será el puerto expuesto de la puerta de enlace de entrada del servidor. Es importante especificar ambos en esta entrada de servicio. Para el protocolo, debes especificar TLS, ya que esta conexión proporciona comunicación TLS basada en L4.

Una vez que hayas definido la entrada de servicio, la malla podrá escuchar llamadas y cambiar el enrutamiento según estas reglas.

Las entradas de servicio deben estar basadas en entradas de direcciones IP o DNS existentes, lo que significa que el nombre de DNS ya debería poder resolverse mediante un servidor DNS. Por ejemplo, puedes usar un servicio de DNS principal dentro de Kubernetes y agregarle entradas que no estén presentes en kube-dns. No puedes usar la entrada de servicio para crear una entrada de DNS.

Servicio virtual

El servicio virtual es una definición que se usa para afectar los patrones de enrutamiento de tráfico. Usa el servicio virtual para asegurarte de que las llamadas desde el cliente MySQL a la entrada de servicio se enruten hacia la puerta de enlace de salida. Por lo tanto, puedes configurar un servicio virtual para enrutar el tráfico en función de factores muy diferentes. En un caso de uso de L7, estos factores van más allá del enrutamiento de tráfico. Por ejemplo, puedes indicarle al servicio virtual cómo reaccionar si no se puede acceder a un destino. En este ejemplo, se usa un subconjunto de esta funcionalidad a fin de enrutar el tráfico coincidente solo a la puerta de enlace de salida para su procesamiento posterior.

Se utiliza el servicio virtual para enrutar el tráfico desde el Pod a través del proxy a la puerta de enlace de salida y desde la puerta de enlace de salida al servicio externo.

En el diagrama anterior, se muestra cómo puedes usar el servicio virtual para enrutar el tráfico desde el pod a través del proxy hasta la puerta de enlace de salida y desde la puerta de enlace de salida al servicio externo.

También debes especificar el puerto de tu puerta de enlace de salida (externo), que es 15443 de forma predeterminada. Este puerto se configura en la puerta de enlace de salida una vez que lo creas. Puedes elegir cualquier otro puerto libre, pero necesitarás aplicar un parche a la puerta de enlace para abrir el puerto elegido.

En el siguiente fragmento de código, se muestra cómo podría ser una definición de servicio virtual de este tipo:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: direct-mysql-through-egress-gateway
spec:
 hosts:
   - mysql.fqdn.example
 gateways:
   - istio-egressgateway-mysql
   - mesh
 tcp:
   - match:
       - gateways:
           - mesh
         port: 3306
     route:
       - destination:
           host: istio-egressgateway.istio-system.svc.cluster.local
           subset: mysql
           port:
             number: 15443
         weight: 100
   - match:
       - gateways:
           - istio-egressgateway-mysql
         port: 15443
     route:
       - destination:
           host: mysql.fqdn.example
           port:
             number: 13306
         weight: 100

El campo hosts que contiene la URL del FQDN se usa para aplicar las reglas de coincidencia específicamente en la URL determinada. La primera cláusula match se define en la malla, que es una palabra clave reservada y se aplica a todas las puertas de enlace dentro de la malla. El primer bloque route se define para indicarle a la malla qué hacer si la coincidencia es verdadera. En este caso, envía el tráfico coincidente a la puerta de enlace de salida. Aquí se define el puerto de salida además del peso de la ruta. El bloque también menciona un valor subset, que defines más adelante.

La segunda cláusula match se aplica a la puerta de enlace de salida. El segundo bloque route agregado a la segunda cláusula match configura la malla para enviar el tráfico a la entrada del clúster del servidor mediante el campo host con el FQDN de entrada y especificando el puerto 13306.

En el siguiente paso, debes programar la inserción de certificados en la puerta de enlace para que funcione la comunicación de mTLS.

Reglas de destino

Ahora que has identificado correctamente tu tráfico (entrada de servicio) y lo has enrutado desde el pod a través del proxy hasta la puerta de enlace (servicio virtual), el siguiente paso es encriptar el tráfico. Usa las reglas de destino para encriptar el tráfico. Estas reglas de una malla de servicios se aplican al tráfico después del enrutamiento y se usan para introducir el balanceo de cargas y otras funciones de administración de tráfico.

Aplicación de reglas de destino al tráfico después del enrutamiento.

En este caso, debes usar reglas de destino para definir un patrón de balanceo de cargas estándar y, también, agregar certificados para habilitar extremos mediante la comunicación mTLS. Para realizar este paso, se hace coincidir el FQDN del servidor MySQL, se expone a través de la puerta de enlace de entrada del clúster del servidor y se define una regla mTLS.

La siguiente definición es un ejemplo de este tipo de regla de destino:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: egressgateway-for-mysql
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
    - name: mysql
      trafficPolicy:
        loadBalancer:
          simple: ROUND_ROBIN
        portLevelSettings:
          - port:
              number: 15443
            tls:
              mode: ISTIO_MUTUAL
              sni: mysql.fqdn.example

El campo host se establece en el FQDN del clúster de la puerta de enlace de salida. La primera regla de destino realiza la encriptación del tráfico de la malla interna mediante el modo ISTIO_MUTUAL (con el FQDN de la puerta de enlace de salida). En el fragmento de código, debes definir un subset, que se usa para crear un balanceo de cargas round robin y establecer (reemplazar) el puerto como 15443. La puerta de enlace de salida usa este puerto para enviar el tráfico.

Es importante que configures el campo tls de forma correcta, ya que define la política de la malla interna (ISTIO_MUTUAL). En el campo sni (indicación del nombre del servicio), agrega el FQDN de la puerta de enlace de entrada del clúster del servidor.

La segunda regla de destino encripta el tráfico con los certificados de CA raíz personalizados, antes de enviarlos a través de la puerta de enlace de salida:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: originate-mtls-for-mysql
spec:
 host: mysql.fqdn.example
 trafficPolicy:
   loadBalancer:
     simple: ROUND_ROBIN
   portLevelSettings:
   - port:
       number: 13306
     tls:
       mode: MUTUAL
       credentialName: client-credential
       sni: mysql.fqdn.example

El campo host se vuelve a configurar con el FQDN externo. El campo trafficPolicy establece el modo del balanceador de cargas en ROUND_ROBIN. También establece el puerto en 13306 y el modo tls en MUTUAL, porque ahora usas los certificados de CA raíz personalizados y la contraparte, la puerta de enlace de entrada que también usa tls MUTUAL, debe identificarse con los mismos certificados de CA raíz firmados. Con este puerto, el tráfico puede fluir a través del clúster del servidor mediante su puerta de enlace de entrada para llegar a la base de datos MySQL.

Por lo general, la encriptación con los certificados de CA raíz personalizados se realiza mediante el servicio de descubrimiento de Secrets de Envoy (SDS) mediante un Secret en Kubernetes que contiene los certificados. Para agregar el nombre del Secret a la regla de destino, usa el campo credentialName.

En resumen, el tráfico ahora hace lo siguiente:

  • MySQL lo emite con transparencia hacia un FQDN externo. Este FQDN existe en el registro de malla.
  • Se encripta mediante una regla de destino con certificados internos de malla.
  • Se enruta a la puerta de enlace mediante un servicio virtual.
  • Se encripta con una CA raíz personalizada mediante una regla de destino (esto es diferente de la CA de malla que se usa para los certificados de malla).
  • Se reenvía a través de la puerta de enlace de salida en modo mTLS.

El lado del servidor

En esta situación, el lado del servidor es más fácil de configurar que el lado del cliente. Todo lo que requiere es una puerta de enlace de entrada y una entrada de servicio virtual para enrutar el tráfico al servidor de la base de datos MySQL, como se muestra en el siguiente diagrama.

Configuración del servidor con una puerta de enlace de entrada y una entrada de servicio virtual que enruta el tráfico al servidor MySQL.

La puerta de enlace de entrada del clúster del servidor

La puerta de enlace de entrada expone el puerto 13306. Puede ser cualquier puerto, pero, en este caso, se agrega un “1” frente al puerto estándar de MySQL para una identificación más fácil. Por motivos de seguridad, no recomendamos exponer el puerto MySQL estándar (3306) directamente a Internet.

Debido a que la puerta de enlace de entrada de Istio predeterminada no escucha en el puerto 13306, debes agregar esta funcionalidad. En el siguiente fragmento de código de ejemplo, se instala el puerto 13306 en la puerta de enlace:

[{
  "op": "add",
  "path": "/spec/ports/0",
  "value": {
    "name": "tls-mysql",
    "protocol": "TCP",
    "targetPort": 13306,
    "port": 13306
  }
}]

Puedes almacenar este código en un archivo JSON y usarlo con el comando de parche kubectl para aplicarlo al servicio de puerta de enlace de entrada.

Para procesar el tráfico de forma correcta, la puerta de enlace de entrada debe configurarse en el modo MUTUAL.

En este punto, la puerta de enlace de entrada desencripta el tráfico entrante mediante el uso del certificado de su almacén de credenciales y lo envía a la malla, donde se usan los certificados internos de malla para volver a encriptarlo. En el siguiente fragmento de código de ejemplo, se muestra cómo se puede configurar esto:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
 name: gateway-mysql
spec:
 selector:
   istio: ingressgateway # Istio default gateway implementation
 servers:
 - port:
     number: 13306
     name: tls-mysql
     protocol: TLS
   tls:
     mode: MUTUAL
     credentialName: mysql-credential
   hosts:
   - "mysql.fqdn.example"

En este ejemplo, la puerta de enlace de entrada estándar de Istio se usa en el campo selector. Con el campo servers, puedes configurar los valores del puerto number (13306) y protocol (TLS) que la entrada debe esperar. Es importante asignarle un nombre único al puerto.

Define tls y proporciona un Secret que contenga el certificado firmado por la misma CA raíz que se usa con la puerta de enlace de salida mediante el campo credentialName. El certificado debe almacenarse en un Secret de Kubernetes.

Por último, debes hacer coincidir el tráfico que dirige el FQDN de la base de datos de MySQL. La resolución de nombres para este FQDN configurado como hosts debe establecerse en la dirección IP pública de la puerta de enlace de entrada.

El servicio virtual del clúster del servidor

Una vez que el tráfico haya entrado en la malla a través del puerto 13306 desde la puerta de enlace de salida del clúster del cliente (origen), debes identificar este tráfico y asegurarte de que llegue al servidor de la base de datos MySQL. Para ello, define un servicio virtual:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: mysql-virtual-service
spec:
 hosts:
   - "mysql.fqdn.example"
 gateways:
   - gateway-mysql
 tcp:
   - route:
     - destination:
         port:
           number: 3306
         host: mysql.default.svc.cluster.local

Para enviar el tráfico al servicio de la base de datos de MySQL, debes volver a verificar el host FQDN con el campo hosts. Además, debes usar el campo gateways para configurar dónde aplicar esta definición de servicio virtual. Este es el objeto de puerta de enlace que definiste en el archivo YAML anterior. Configura el campo tcp, ya que es tráfico de L4, y configura el campo route para que apunte al servicio de Kubernetes de la base de datos de MySQL. Debes especificar el nombre del servicio en el campo host mediante el FQDN interno del clúster de Kubernetes.

La base de datos de MySQL recibe solicitudes del cliente en el puerto “3306”. El tráfico atraviesa el proxy de sidecar del servidor de base de datos de MySQL.

La base de datos de MySQL puede obtener solicitudes del cliente en el puerto 3306. El tráfico atraviesa el proxy de sidecar del servidor de la base de datos de MySQL. En el servidor de la base de datos de MySQL, parece una solicitud de acceso local sin encriptar.

Una vez que el servidor responde la llamada, el tráfico viaja de vuelta al cliente con la misma ruta. Para el cliente, esto se ve como si una base de datos local respondiera su llamada.

El tráfico se encripta tres veces con diferentes certificados que van de un cliente a otro, lo que ayuda a proteger la comunicación entre cliente y servidor.

La primera vez que se encripta o desencripta el tráfico, está dentro de la malla del cliente con certificados que usan la CA de la malla.

La segunda vez, se encripta el tráfico cuando sale de la malla por la puerta de enlace de salida mediante un certificado de una CA raíz personalizada. Luego, el tráfico se autentica y se desencripta en la puerta de enlace de entrada mediante un certificado firmado por la misma CA raíz personalizada.

La última (tercera) vez, el tráfico se encripta o desencripta dentro de la malla del servidor cuando pasa por la puerta de enlace de entrada al servidor MySQL. Como esto se realiza dentro de la malla, se vuelven a usar los certificados de la CA de la malla.

En este caso, la comunicación entre los dos clústeres se debe encriptar con la CA raíz mencionada. Si aplicas esta configuración, es posible manejar esta parte sin depender de los certificados internos de malla y de la aplicación en sí.

Con este paso adicional, esta configuración también te permite rotar fácilmente estos certificados con regularidad sin cambiar la CA de malla de los clústeres de Kubernetes respectivos.

¿Qué sigue?