Salida usando Wildcard Hosts

La tarea Acceso a Services Externos y el ejemplo Configurar un Egress Gateway describen cómo configurar el tráfico de salida para hostnames específicos, como edition.cnn.com. Este ejemplo muestra cómo habilitar el tráfico de salida para un conjunto de hosts en un dominio común, por ejemplo *.wikipedia.org, en lugar de configurar cada host por separado.

Antecedentes

Suponga que desea habilitar el tráfico de salida en Istio para los sitios wikipedia.org en todos los idiomas. Cada versión de wikipedia.org en un idioma particular tiene su propio hostname, por ejemplo, en.wikipedia.org y de.wikipedia.org en inglés y alemán, respectivamente. Desea habilitar el tráfico de salida mediante elementos de configuración comunes para todos los sitios de Wikipedia, sin necesidad de especificar cada sitio de idioma por separado.

Antes de empezar

  • Instale Istio con el registro de acceso habilitado y con la política de tráfico de salida de bloqueo por defecto:
$ istioctl install --set profile=demo --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
  • Despliegue la aplicación de ejemplo curl para usarla como fuente de prueba para enviar solicitudes. Si tiene la inyección automática de sidecar habilitada, ejecute el siguiente comando para desplegar la aplicación de ejemplo:

    Zip
    $ kubectl apply -f @samples/curl/curl.yaml@

    De lo contrario, inyecte manualmente el sidecar antes de desplegar la aplicación curl con el siguiente comando:

    Zip
    $ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@)
  • Establezca la variable de entorno SOURCE_POD con el nombre de su pod de origen:

    $ export SOURCE_POD=$(kubectl get pod -l app=curl -o jsonpath={.items..metadata.name})

Configurar el tráfico directo a un host wildcard

La primera y más sencilla forma de acceder a un conjunto de hosts dentro de un dominio común es configurando una ServiceEntry simple con un host wildcard y llamando a los services directamente desde el sidecar. Al llamar a los services directamente (es decir, no a través de un egress gateway), la configuración para un host wildcard no es diferente a la de cualquier otro host (por ejemplo, completamente calificado), solo mucho más conveniente cuando hay muchos hosts dentro del dominio común.

  1. Defina una ServiceEntry para *.wikipedia.org:

    $ kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: ServiceEntry
    metadata:
      name: wikipedia
    spec:
      hosts:
      - "*.wikipedia.org"
      ports:
      - number: 443
        name: https
        protocol: HTTPS
    EOF
  2. Envíe solicitudes HTTPS a https://en.wikipedia.org y https://de.wikipedia.org:

    $ kubectl exec "$SOURCE_POD" -c curl -- sh -c 'curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"; curl -s https://de.wikipedia.org/wiki/Wikipedia:Hauptseite | grep -o "<title>.*</title>"'
    <title>Wikipedia, la enciclopedia libre</title>
    <title>Wikipedia – Die freie Enzyklopädie</title>

Limpieza del tráfico directo a un host wildcard

$ kubectl delete serviceentry wikipedia

Configurar el tráfico del egress gateway a un host wildcard

Cuando todos los hosts wildcard son atendidos por un solo servidor, la configuración para el acceso basado en egress gateway a un host wildcard es muy similar a la de cualquier host, con una excepción: el destino de ruta configurado no será el mismo que el host configurado, es decir, el wildcard. En su lugar, se configurará con el host del único servidor para el conjunto de dominios.

  1. Cree un Gateway de salida para *.wikipedia.org y reglas de ruta para dirigir el tráfico a través del egress gateway y desde el egress gateway al service externo:
$ kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: istio-egressgateway
spec:
  selector:
    istio: egressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    hosts:
    - "*.wikipedia.org"
    tls:
      mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: egressgateway-for-wikipedia
spec:
  host: istio-egressgateway.istio-system.svc.cluster.local
  subsets:
    - name: wikipedia
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: direct-wikipedia-through-egress-gateway
spec:
  hosts:
  - "*.wikipedia.org"
  gateways:
  - mesh
  - istio-egressgateway
  tls:
  - match:
    - gateways:
      - mesh
      port: 443
      sniHosts:
      - "*.wikipedia.org"
    route:
    - destination:
        host: istio-egressgateway.istio-system.svc.cluster.local
        subset: wikipedia
        port:
          number: 443
      weight: 100
  - match:
    - gateways:
      - istio-egressgateway
      port: 443
    route:
    - destination:
        host: www.wikipedia.org
        port:
          number: 443
      weight: 100
EOF
  1. Cree una ServiceEntry para el servidor de destino, www.wikipedia.org:

    $ kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: ServiceEntry
    metadata:
      name: www-wikipedia
    spec:
      hosts:
      - www.wikipedia.org
      ports:
      - number: 443
        name: https
        protocol: HTTPS
      resolution: DNS
    EOF
  2. Envíe solicitudes HTTPS a https://en.wikipedia.org y https://de.wikipedia.org:

    $ kubectl exec "$SOURCE_POD" -c curl -- sh -c 'curl -s https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"; curl -s https://de.wikipedia.org/wiki/Wikipedia:Hauptseite | grep -o "<title>.*</title>"'
    <title>Wikipedia, la enciclopedia libre</title>
    <title>Wikipedia – Die freie Enzyklopädie</title>
  3. Verifique las estadísticas del proxy del egress gateway para el contador que corresponde a sus solicitudes a *.wikipedia.org:

$ kubectl exec "$(kubectl get pod -l istio=egressgateway -n istio-system -o jsonpath='{.items[0].metadata.name}')" -c istio-proxy -n istio-system -- pilot-agent request GET clusters | grep '^outbound|443||www.wikipedia.org.*cx_total:'
outbound|443||www.wikipedia.org::208.80.154.224:443::cx_total::2

Limpieza del tráfico del egress gateway a un host wildcard

$ kubectl delete serviceentry www-wikipedia
$ kubectl delete gateway istio-egressgateway
$ kubectl delete virtualservice direct-wikipedia-through-egress-gateway
$ kubectl delete destinationrule egressgateway-for-wikipedia

Configuración de comodines para dominios arbitrarios

La configuración de la sección anterior funcionó porque todos los sitios *.wikipedia.org pueden ser servidos por cualquiera de los servidores wikipedia.wikipedia.org. Sin embargo, este no siempre es el caso. Por ejemplo, es posible que desee configurar el control de salida para el acceso a dominios wildcard más generales como *.com o *.org. La configuración del tráfico a dominios wildcard arbitrarios introduce un desafío para los gateways de Istio; un gateway de Istio solo se puede configurar para enrutar el tráfico a hosts predefinidos, direcciones IP predefinidas o a la dirección IP de destino original de la solicitud.

En la sección anterior, configuró el virtual service para dirigir el tráfico al host predefinido www.wikipedia.org. En el caso general, sin embargo, no conoce el host o la dirección IP que puede servir a un host arbitrario recibido en una solicitud, lo que deja la dirección de destino original de la solicitud como el único valor con el que enrutar la solicitud. Desafortunadamente, al usar un egress gateway, la dirección de destino original de la solicitud se pierde ya que la solicitud original se redirige al gateway, lo que hace que la dirección IP de destino se convierta en la dirección IP del gateway.

Aunque no es tan fácil y algo frágil, ya que se basa en los detalles de implementación de Istio, puede usar filtros de Envoy para configurar un gateway para admitir dominios arbitrarios utilizando el valor SNI en una solicitud HTTPS, o cualquier TLS, para identificar el destino original al que enrutar la solicitud. Un ejemplo de este enfoque de configuración se puede encontrar en enrutamiento del tráfico de salida a destinos wildcard.

Limpieza

  • Apague el service curl:

    Zip
    $ kubectl delete -f @samples/curl/curl.yaml@
  • Desinstale Istio de su cluster:

    $ istioctl uninstall --purge -y
¿Fue útil esta información?
¿Tienes alguna sugerencia para mejorar?

¡Gracias por tus comentarios!